Biometric matching score calculator I'm working on a biometric matching system and I would like to have few suggestions regarding vectorizing the following code:

% tpol and ipol 
% column 1: x co-ordinate of the feature
% column 2: y co-ordinate of the feature
% column 3: angle orientation
% column 4: type of feature

ref_points=size(tpol,1); %number of rows=number of reference image points
   in_points=size(ipol,1); %number of rows=number of input image points
   radsize=7*ones(ref_points,1); %Radius size
   angsize=11* ones(ref_points,1); %Angle size
   radlow=-radsize./2;  % Lower Radius 
   radhigh=radsize./2; % Upper Radius
   anglow=-angsize./2;  % Lower Angle
   anghigh=angsize./2; % Upper Angle
   epsillon=10; 
   mscore=0; % initializing the matching score

   for i=1:ref_points
      for j=1:in_points
        rdiff=tpol(i,1)-ipol(j,1);    % Difference between the x-coordinate
        ediff=tpol(i,2)-ipol(j,2);      % Difference between the y-coordinate
        thetadiff=tpol(i,3)-ipol(j,3);   %Difference between the orientation 
        if ((radlow(i) &lt; rdiff) &amp;&amp; (rdiff &lt; radhigh(i)) &amp;&amp; (anglow(i) &lt; ediff) &amp;&amp; ...
            (ediff &lt; anghigh(i)) &amp;&amp; (abs(thetadiff) &lt; epsillon) &amp;&amp; ...
            (tpol(i,4)==ipol(j,4)))
            mscore=mscore+1;
            tpol(i,4)=3; %Change type of the feature to know that the line was used
        end
      end
    end
  end


ipol and tpol are the input image and reference image points respectively. They are both a matrix of size (A x 4) each, A being the number of features detected in each image.

I asked this question on Mathworks for which I received the following answer:

    r = [-3.5 3.5];  % Lower Radius and Upper Radius
    a = [-5.5 5.5];  % Lower Angle and Upper Angle
    epsillon=10;

    % Vectorized computation of rdiff,ediff,thetadiff i.e. x,y-co-ordinate
    % and orientation
    pol = bsxfun(@minus,tpol,permute(ipol,[3 2 1])); 
    p = all([bsxfun(@gt,pol(:,1:2,:),[r(1),a(1)]) &amp; bsxfun(@lt,pol(:,1:2,:),[r(2),a(2)]),...
     pol(:,3,:) &lt; ep, pol(:,4,:) == 0],2);
    mscore = nnz(p);
    tpol(any(p,3),4) = 4;


I checked the mscore received from the original code and verified it with the solution provided by plugging in one "if condition" at a time. All the "if conditions" provided me the same mscore except for:


if ((tpol(i,4)==ipol(j,4))

  
  and

p= all ([pol(:,4,:) == 0],2);



It would be very helpful if someone could help me out with this. The for loop takes a long time when the points detected are many.

The input data can be downloaded from Google Drive
Regarding the vectorized code:


permute can be considered a "Zero-cost operation".
Logical operations are performed fastest using bsxfun.
Arithmetic operations are fastest using bsxfun.


Therefore, it's close to impossible to improve the performance of the vectorized code you've posted.



Now, the question is: Is it correct?

It's hard to tell without knowing the exact data, but just by reading the code and your comments, I would think it is.

The reason why I think it is correct, even though the if conditions didn't return the same result:

You're comparing floating point values using ==. Check out Is floating point math broken?

When checking for equality, you should always use some tolerance. Have a look at the example below, where we are comparing 0.3 with 0.1 + 0.2:

x = 0.1;
y = 0.2;
z = 0.3;
the_same = (z == (x + y))
the_same =
     0
the_same = abs(z - (x + y)) &lt; eps
the_same =
     1