1
$\begingroup$

I would like a discrete distance measure between two binary vectors (or strings). Like HammingDistance but I want the vectors to be considered closer if they have more matches that are separated by zeros (or a default value).

For example: given the four vectors and distance measure thedistancemeasure

           vec1={1,0,0,0,0,1,0,1};
           vec2={1,0,1,0,0,1,0,0};

           vec3={1,0,0,0,1,1,0,0};
           vec4={0,1,0,0,1,1,0,0};

such that.

  thedistancemeasure[vec1,vec2]< thedistancemeasure[vec3,vec4]

True

The measure likes small group of matches that are well separated versus a large group of matches that are "connected" or less seperated.

The amount of zeros shouldn't matter, but if it does, I prefers more zeros to give a smaller measure. The more separated the better.

If possible I also want the measure to give even closer distances for higher count of well separated correctly matched ones, for example.

            vec5={1,0,0,1,0,1,0,1};
            vec6={1,0,0,1,0,0,0,1};

would give.

 thedistancemeasure[vec1,vec2]>thedistancemeasure[vec5,vec6]

True

The size of the vectors would always be fixed.

It might be possible using the output from ListCorrelate since it should give the position correlations between lists.

$\endgroup$
10
  • $\begingroup$ Do you want the distance function or maybe an function for pairs of pairs is enough. $\endgroup$
    – Kuba
    May 18, 2015 at 9:54
  • $\begingroup$ @Kuba for pairs is enough $\endgroup$
    – lalmei
    May 18, 2015 at 9:55
  • $\begingroup$ Since vec3 and vec4 are identical, shouldn't they have distance? $\endgroup$ May 18, 2015 at 10:12
  • $\begingroup$ @Guesswhoitis. I know right, it is a bit confusing how to accomplish this. Maybe I misunderstood Kuba's question. $\endgroup$
    – lalmei
    May 18, 2015 at 10:20
  • $\begingroup$ Oops, I meant to say that the two vectors have zero distance. $\endgroup$ May 18, 2015 at 10:22

2 Answers 2

2
$\begingroup$
ClearAll[distF1, distF2]
distF1 = With[{p = Intersection @@ (Flatten@ SparseArray[#]["NonzeroPositions"]&/@ #)}, 
         -Length @ p] &;
distF2 = With[{p = Intersection @@ (Flatten@SparseArray[#]["NonzeroPositions"]&/@#)},
         -Total[Differences@p]] &;

Example:

vec1 = {1, 0, 0, 0, 0, 1, 0, 1};
vec2 = {1, 0, 1, 0, 0, 1, 0, 0};
vec3 = {1, 0, 0, 0, 1, 1, 0, 0};
vec4 = {0, 1, 0, 0, 1, 1, 0, 0};
vec5 = {1, 0, 0, 1, 0, 1, 0, 1};
vec6 = {1, 0, 0, 1, 0, 0, 0, 1};
vecs = {vec1, vec2, vec3, vec4, vec5, vec6};
pairs = Partition[vecs, 2];
plabels = {"v1v2", "v3v4", "v5v6"};

Sort pairs lexicographically in ascending order using the distance function distF1 and breaking ties with the distance function distF2:

SortBy[pairs, {distF1, distF2}] /. Thread[pairs -> plabels]
{"v5v6", "v1v2", "v3v4"}
$\endgroup$
1
$\begingroup$

I have trouble following your examples but perhaps you can Split your vectors and compare length:

vec1 = {1, 0, 0, 0, 0, 1, 0, 0};
vec3 = {0, 0, 0, 0, 1, 1, 0, 0};
vec5 = {1, 0, 0, 1, 0, 0, 0, 1};

Length /@ Split /@ {vec1, vec3, vec5}
{4, 3, 5}

Combine this with HammingDistance or alternatives with whatever weighting you prefer.

$\endgroup$
1
  • $\begingroup$ I changed the example so they are not comparing two identical vectors, thanks. This looks like the way forward! $\endgroup$
    – lalmei
    May 18, 2015 at 10:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.