One neat trick that you can often use when calculating the Euclidean distance is to change the algorithm to work with the quadratic Euclidean distance - this eliminates the expensive square root function that is not needed, for example, if you just want to find the largest or minimum distance in the set.
Thus, the inner cycle can become:
distSquared(j) = sum((des1(i, :) - des2(j, :)).^2);
In your case, it's hard to change the line
if (vals(1) < distRatio * vals(2))
Which is equivalent
if (vals(1)^2 < (distRatio * vals(2))^2)
or
if (vals(1)^2 < (distRatio^2) * (vals(2)^2))
And if you get the values ββfrom distSquared instead of eucl , you can use
if (valSquared(1) < (distRatio^2) * valSquared(2))
Finally, you could pull out the inner loop by rewriting the subtraction as follows:
countRowsDes2 = size(des2, 1); % this line outside the loop %... now inside the loop des1expand = repmat(des1(i, :), countRowsDes2, 1); % copy this row distSquared = sum((des1expand - des2).^2, 2); % sum horizontally
Where I used repmat to copy the line des1(i, :) and made sum work with horizontal dimension using the second dimension argument.
Putting it all together
distRatio = 0.5; distRatioSq = distRatio^2; % distance ratio squared countRowsDes1 = size(des1, 1); % number of rows in des1 countRowsDes2 = size(des2, 1); % number of rows in des2 match = zeros(countRowsDes1, 1); % pre-initialize with zeros for i = i:size(des1, 1) des1expand = repmat(des1(i, :), countRowsDes2, 1); % copy row i of des1 distSquared = sum((des1expand - des2).^2, 2); % sum horizontally [valsSquared, index] = sort(distSquared); if (valsSquared(1) < distRatioSq * valsSquared(2)) match(i) = index(1); % else zero by initialization end