3
\$\begingroup\$

I'm learning MATLAB (still trying to "think in vectors") and have the following piece of code:

stats = regionprops(bwconncomp(mask), 'all');

% find the object nearest our nucleus
smallest_dist = flintmax;
location = [cell_x, cell_y];
for j = 1:numel(stats)
    stat = stats(j);
    dist = pdist([location;[stat.Centroid]], 'euclidean');
    if dist < smallest_dist
        regions{channel} = stat; 
        smallest_dist = dist;
    end
end  

All that is doing is searching through a struct array for the region which has a location (centroid) closest to my known cell's X/Y. I'm sure this is not canonical and that it could be improved.

\$\endgroup\$
2
\$\begingroup\$

I think this comes pretty close. The use of arrayfun() or other *fun()-Operations is very often better than for loops.

Your code was not working out of the box. Thus, I created code, which is directly executable:

function minimalExample()
    target.x = 10;
    target.y = 5;

    source(1) = struct('x', 1, 'y', 3);
    source(2) = struct('x', 5, 'y', 15);

    [~, minIndex] = min(arrayfun(@(x) (myDistance(x, target)), source));

    minSource = source(minIndex);
    disp(minSource);

    function d = myDistance(source, target)
        d = (source.x - target.x)^2 + (source.y - target.y)^2;
        d = sqrt(d);
    end
end
\$\endgroup\$
  • \$\begingroup\$ Thanks for the answer, I'll accept it. As it's been almost two weeks since posting I have learned mroe about MATLAB and changed this to use arrayfun myself (actually, I used arrayfun to implement minby, so it's now minby(stats, @(s)(pdist([p, [s.Centroid]], 'euclidean')));, which uses find(x,'first') internally). Again though, thanks. \$\endgroup\$ – Ed S. May 26 '14 at 17:52
  • \$\begingroup\$ I just found this code review page. Great, you found *fun() already. There are millions of great applications for those and most of the time they are more readable than vectorized versions with a lot of reshape and repmat. \$\endgroup\$ – Lukas May 26 '14 at 18:13
  • \$\begingroup\$ For the record: If performance is of interest: Arrayfun is horribly slow compared to normal for-loops in 99% of the cases. \$\endgroup\$ – Stewie Griffin Jul 16 '16 at 15:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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