<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/244823</link>
    <title>MATLAB Central Newsreader - N-dimensional find</title>
    <description>Feed for thread: N-dimensional find</description>
    <language>en-us</language>
    <copyright>&amp;copy;1994-2012 by MathWorks, Inc.</copyright>
    <webmaster>webmaster@mathworks.com</webmaster>
    <generator>MATLAB Central Newsreader</generator>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <ttl>60</ttl>
    <image>
      <title>MathWorks</title>
      <url>http://www.mathworks.com/images/membrane_icon.gif</url>
    </image>
    <item>
      <pubDate>Wed, 18 Feb 2009 18:00:18 -0500</pubDate>
      <title>N-dimensional find</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/244823#629215</link>
      <author>Sven </author>
      <description>Hi there,&lt;br&gt;
&lt;br&gt;
I've noticed myself running the following style of loop quite a bit when trying to find the 'first' pixel in an image along a dimension. This is somewhat like measuring from the top row of an image towards the bottom row of the image, and recording the first collision with an &quot;on&quot; pixel.&lt;br&gt;
&lt;br&gt;
% BW is some binary image&lt;br&gt;
&lt;br&gt;
firstIdxs = zeros(size(BW,2);&lt;br&gt;
for i=1:size(BW,2)&lt;br&gt;
&amp;nbsp;&amp;nbsp;idx = find(BW(:,i),1,'first');&lt;br&gt;
&amp;nbsp;&amp;nbsp;if ~isempty(idx)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;firstIdxs(i) = idx;&lt;br&gt;
&amp;nbsp;&amp;nbsp;end&lt;br&gt;
end&lt;br&gt;
&lt;br&gt;
I see this as analogous to using, say, sum(BW, 2) to sum along the 2nd dimension, whereas I'm trying to do something like find(BW, dim).&lt;br&gt;
&lt;br&gt;
Is there a faster solution? Or, perhaps more relevant: is there a solution that doesn't clutter up my .m files as much as this implementation? If not, I'll just have to function-ize this one.&lt;br&gt;
&lt;br&gt;
Cheers,&lt;br&gt;
Sven.</description>
    </item>
    <item>
      <pubDate>Wed, 18 Feb 2009 19:21:54 -0500</pubDate>
      <title>Re: N-dimensional find</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/244823#629235</link>
      <author>Peter Boettcher</author>
      <description>&quot;Sven&quot; &amp;lt;sven.holcombe@gmail.deleteme.com&amp;gt; writes:&lt;br&gt;
&lt;br&gt;
&amp;gt; Hi there,&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; I've noticed myself running the following style of loop quite a bit&lt;br&gt;
&amp;gt; when trying to find the 'first' pixel in an image along a&lt;br&gt;
&amp;gt; dimension. This is somewhat like measuring from the top row of an&lt;br&gt;
&amp;gt; image towards the bottom row of the image, and recording the first&lt;br&gt;
&amp;gt; collision with an &quot;on&quot; pixel.&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; % BW is some binary image&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; firstIdxs = zeros(size(BW,2);&lt;br&gt;
&amp;gt; for i=1:size(BW,2)&lt;br&gt;
&amp;gt;   idx = find(BW(:,i),1,'first');&lt;br&gt;
&amp;gt;   if ~isempty(idx)&lt;br&gt;
&amp;gt;     firstIdxs(i) = idx;&lt;br&gt;
&amp;gt;   end&lt;br&gt;
&amp;gt; end&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; I see this as analogous to using, say, sum(BW, 2) to sum along the 2nd&lt;br&gt;
&amp;gt; dimension, whereas I'm trying to do something like find(BW, dim).&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; Is there a faster solution? Or, perhaps more relevant: is there a&lt;br&gt;
&amp;gt; solution that doesn't clutter up my .m files as much as this&lt;br&gt;
&amp;gt; implementation? If not, I'll just have to function-ize this one.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
Not sure about faster, but you could abuse the behavior of max:&lt;br&gt;
&lt;br&gt;
[dummy firstIdxs] = max(logical(BW));&lt;br&gt;
&lt;br&gt;
That is, 1 is the max value, and the location of that max value is the&lt;br&gt;
one you're looking for.  &quot;help max&quot; says that the first maximum is the&lt;br&gt;
one that counts.&lt;br&gt;
&lt;br&gt;
If this is faster, it's only because the loop overhead is bad.  The find&lt;br&gt;
solution technically only has to look at the values up to the first 1 in&lt;br&gt;
each column, where the max solution has to look at every single value in&lt;br&gt;
the matrix.&lt;br&gt;
&lt;br&gt;
-Peter</description>
    </item>
    <item>
      <pubDate>Wed, 18 Feb 2009 19:54:01 -0500</pubDate>
      <title>Re: N-dimensional find</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/244823#629243</link>
      <author>Jos </author>
      <description>&quot;Sven&quot; &amp;lt;sven.holcombe@gmail.deleteme.com&amp;gt; wrote in message &amp;lt;gnhibi$s1m$1@fred.mathworks.com&amp;gt;...&lt;br&gt;
&amp;gt; Hi there,&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; I've noticed myself running the following style of loop quite a bit when trying to find the 'first' pixel in an image along a dimension. This is somewhat like measuring from the top row of an image towards the bottom row of the image, and recording the first collision with an &quot;on&quot; pixel.&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; % BW is some binary image&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; firstIdxs = zeros(size(BW,2);&lt;br&gt;
&amp;gt; for i=1:size(BW,2)&lt;br&gt;
&amp;gt;   idx = find(BW(:,i),1,'first');&lt;br&gt;
&amp;gt;   if ~isempty(idx)&lt;br&gt;
&amp;gt;     firstIdxs(i) = idx;&lt;br&gt;
&amp;gt;   end&lt;br&gt;
&amp;gt; end&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; I see this as analogous to using, say, sum(BW, 2) to sum along the 2nd dimension, whereas I'm trying to do something like find(BW, dim).&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; Is there a faster solution? Or, perhaps more relevant: is there a solution that doesn't clutter up my .m files as much as this implementation? If not, I'll just have to function-ize this one.&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; Cheers,&lt;br&gt;
&amp;gt; Sven.&lt;br&gt;
&lt;br&gt;
Something like this?&lt;br&gt;
&lt;br&gt;
bw = rand(10) &amp;gt; .8 ;&lt;br&gt;
&lt;br&gt;
firstidx = zeros(1,size(bw,2)) ;&lt;br&gt;
[R,C] = find(cumsum(cumsum(bw))==1) ;&lt;br&gt;
firstidx(C) = R  % we need some care for all-zero columns&lt;br&gt;
&lt;br&gt;
although I think the double cumsum makes it slower than a for-loop ;-)&lt;br&gt;
&lt;br&gt;
hth&lt;br&gt;
Jos</description>
    </item>
    <item>
      <pubDate>Wed, 18 Feb 2009 20:37:01 -0500</pubDate>
      <title>Re: N-dimensional find</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/244823#629265</link>
      <author>Matt Fig</author>
      <description>If it is speed you are after (and it sounds like maybe it isn't), it might be worth it to make a sub function with not one, but two loops (blasphemy!).  Try this out, the speed gain will depend on the size of BW and it's sparsity.  Run it a couple of times.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
%--------------------------------------------------------------------------%&lt;br&gt;
function [] = find_idx_dim()&lt;br&gt;
% Demonstrate three different techniques for finding the index of the first&lt;br&gt;
% non-zero element of each column in a binary matrix.&lt;br&gt;
BW = round(rand(1000));  % A binary matrix.&lt;br&gt;
% BW = rand(1000)&amp;gt;.9;  % A sparse binary matrix.  Try this out too.&lt;br&gt;
t = zeros(1,3);  % For timings.&lt;br&gt;
&lt;br&gt;
tic&lt;br&gt;
[FI1,FI1] =  max(BW); % Technique 1.&lt;br&gt;
t(1) = toc;&lt;br&gt;
&lt;br&gt;
tic&lt;br&gt;
FI2 = zeros(1,size(BW,2));  % Technique 2.&lt;br&gt;
[R,C] = find(cumsum(cumsum(BW))==1);&lt;br&gt;
FI2(C) = R;&lt;br&gt;
t(2) = toc;&lt;br&gt;
&lt;br&gt;
tic&lt;br&gt;
FI3 = getidx(BW);  % Technique 3, Call subfunction.&lt;br&gt;
t(3) = toc;&lt;br&gt;
&lt;br&gt;
% Show the relative times and if all are equal.&lt;br&gt;
fprintf('\n%s%3.1f\t%3.1f\t%3.1f','Relative times:   ',t/min(t)) &lt;br&gt;
if all(FI1==FI2 &amp; FI1==FI3')  % check for equality.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fprintf('%s\n\n','    and all are equal')&lt;br&gt;
else&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fprintf('%s\n\n','    and all are not equal')&lt;br&gt;
end&lt;br&gt;
&lt;br&gt;
function idx = getidx(BW)&lt;br&gt;
% Subfunction that finds the first 1 index in each column.&lt;br&gt;
[r,c] = size(BW);&lt;br&gt;
idx = zeros(r,1);&lt;br&gt;
for ii = 1:c&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for kk = 1:r&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if BW(kk,ii)==1&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;idx(ii) = kk;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br&gt;
end &lt;br&gt;
&lt;br&gt;
%--------------------------------------------------------------------------%</description>
    </item>
    <item>
      <pubDate>Wed, 18 Feb 2009 22:42:01 -0500</pubDate>
      <title>Re: N-dimensional find</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/244823#629289</link>
      <author>Sven </author>
      <description>Thanks all,&lt;br&gt;
&lt;br&gt;
The short-term solution I've chosen which has cleaned up my code quite a bit is a combination of suggestions:&lt;br&gt;
BW = rand(10,20)&amp;gt;.8 % Make the image&lt;br&gt;
[A, B] = max(BW) % Hijack the max function&lt;br&gt;
B(BW(B==1)==0) = 0 % Account for all-zero columns&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
I think that Matt's double for-loop probably is the fastest, and I am thinking of adding something like it to the file exchange (or Matt, you're more than welcome to add it if you'd like!). I would probably modify it a little to allow you to input the direction ala the SUM(BW,DIR), or MAX(X,[],DIM) functions.&lt;br&gt;
&lt;br&gt;
I can think of how to make it generic enough for a 2D image called by&lt;br&gt;
find_2d(BW,1)&lt;br&gt;
OR&lt;br&gt;
find_2d(BW,2)&lt;br&gt;
&lt;br&gt;
Perhaps when I get a moment I'll try and work out how to make it work in ND.  Unless of course, someone already knows ;)&lt;br&gt;
&lt;br&gt;
Cheers,&lt;br&gt;
Sven.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&quot;Matt Fig&quot; &amp;lt;spamanon@yahoo.com&amp;gt; wrote in message &amp;lt;gnhrhd$llc$1@fred.mathworks.com&amp;gt;...&lt;br&gt;
&amp;gt; If it is speed you are after (and it sounds like maybe it isn't), it might be worth it to make a sub function with not one, but two loops (blasphemy!).  Try this out, the speed gain will depend on the size of BW and it's sparsity.  Run it a couple of times.&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; %--------------------------------------------------------------------------%&lt;br&gt;
&amp;gt; function [] = find_idx_dim()&lt;br&gt;
&amp;gt; % Demonstrate three different techniques for finding the index of the first&lt;br&gt;
&amp;gt; % non-zero element of each column in a binary matrix.&lt;br&gt;
&amp;gt; BW = round(rand(1000));  % A binary matrix.&lt;br&gt;
&amp;gt; % BW = rand(1000)&amp;gt;.9;  % A sparse binary matrix.  Try this out too.&lt;br&gt;
&amp;gt; t = zeros(1,3);  % For timings.&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; tic&lt;br&gt;
&amp;gt; [FI1,FI1] =  max(BW); % Technique 1.&lt;br&gt;
&amp;gt; t(1) = toc;&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; tic&lt;br&gt;
&amp;gt; FI2 = zeros(1,size(BW,2));  % Technique 2.&lt;br&gt;
&amp;gt; [R,C] = find(cumsum(cumsum(BW))==1);&lt;br&gt;
&amp;gt; FI2(C) = R;&lt;br&gt;
&amp;gt; t(2) = toc;&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; tic&lt;br&gt;
&amp;gt; FI3 = getidx(BW);  % Technique 3, Call subfunction.&lt;br&gt;
&amp;gt; t(3) = toc;&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; % Show the relative times and if all are equal.&lt;br&gt;
&amp;gt; fprintf('\n%s%3.1f\t%3.1f\t%3.1f','Relative times:   ',t/min(t)) &lt;br&gt;
&amp;gt; if all(FI1==FI2 &amp; FI1==FI3')  % check for equality.&lt;br&gt;
&amp;gt;     fprintf('%s\n\n','    and all are equal')&lt;br&gt;
&amp;gt; else&lt;br&gt;
&amp;gt;     fprintf('%s\n\n','    and all are not equal')&lt;br&gt;
&amp;gt; end&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; function idx = getidx(BW)&lt;br&gt;
&amp;gt; % Subfunction that finds the first 1 index in each column.&lt;br&gt;
&amp;gt; [r,c] = size(BW);&lt;br&gt;
&amp;gt; idx = zeros(r,1);&lt;br&gt;
&amp;gt; for ii = 1:c&lt;br&gt;
&amp;gt;     for kk = 1:r&lt;br&gt;
&amp;gt;         if BW(kk,ii)==1&lt;br&gt;
&amp;gt;             idx(ii) = kk;&lt;br&gt;
&amp;gt;             break&lt;br&gt;
&amp;gt;         end&lt;br&gt;
&amp;gt;     end&lt;br&gt;
&amp;gt; end &lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; %--------------------------------------------------------------------------%</description>
    </item>
    <item>
      <pubDate>Fri, 08 May 2009 12:03:03 -0400</pubDate>
      <title>Re: N-dimensional find</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/244823#648422</link>
      <author>Andrew Jackson</author>
      <description>&quot;Sven&quot; &amp;lt;sven.holcombe@gmail.deleteme.com&amp;gt; wrote in message &amp;lt;gni2rp$3ja$1@fred.mathworks.com&amp;gt;...&lt;br&gt;
&amp;gt; Thanks all,&lt;br&gt;
&amp;gt; &lt;br&gt;
&amp;gt; The short-term solution I've chosen which has cleaned up my code quite a bit is a combination of suggestions:&lt;br&gt;
&amp;gt; BW = rand(10,20)&amp;gt;.8 % Make the image&lt;br&gt;
&amp;gt; [A, B] = max(BW) % Hijack the max function&lt;br&gt;
&amp;gt; B(BW(B==1)==0) = 0 % Account for all-zero columns&lt;br&gt;
&amp;gt; &lt;br&gt;
...&lt;br&gt;
&lt;br&gt;
If anyone is trying to use this neat trick with *sparse* logical matrices in R2009a, be aware that a MATLAB bug causes a crash: &lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://www.mathworks.com/matlabcentral/newsreader/view_thread/246673&quot;&gt;http://www.mathworks.com/matlabcentral/newsreader/view_thread/246673&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
So, if your matrix is sparse and you want your code to be R2009a-compliant, you'll have to do something like:&lt;br&gt;
&lt;br&gt;
[A, B] = max(spones(BW)) % converts BW to double to prevent bug&lt;br&gt;
&lt;br&gt;
Took me a while to work out what was causing new crashes when moving to R2009a!&lt;br&gt;
&lt;br&gt;
AJ</description>
    </item>
    <item>
      <pubDate>Fri, 08 May 2009 13:21:50 -0400</pubDate>
      <title>Re: N-dimensional find</title>
      <link>http://www.mathworks.com/matlabcentral/newsreader/view_thread/244823#648442</link>
      <author>Steven Lord</author>
      <description>&lt;br&gt;
&quot;Andrew Jackson&quot; &amp;lt;andrewj@eml.cc&amp;gt; wrote in message &lt;br&gt;
news:gu171n$rg$1@fred.mathworks.com...&lt;br&gt;
&amp;gt; &quot;Sven&quot; &amp;lt;sven.holcombe@gmail.deleteme.com&amp;gt; wrote in message &lt;br&gt;
&amp;gt; &amp;lt;gni2rp$3ja$1@fred.mathworks.com&amp;gt;...&lt;br&gt;
&amp;gt;&amp;gt; Thanks all,&lt;br&gt;
&amp;gt;&amp;gt;&lt;br&gt;
&amp;gt;&amp;gt; The short-term solution I've chosen which has cleaned up my code quite a &lt;br&gt;
&amp;gt;&amp;gt; bit is a combination of suggestions:&lt;br&gt;
&amp;gt;&amp;gt; BW = rand(10,20)&amp;gt;.8 % Make the image&lt;br&gt;
&amp;gt;&amp;gt; [A, B] = max(BW) % Hijack the max function&lt;br&gt;
&amp;gt;&amp;gt; B(BW(B==1)==0) = 0 % Account for all-zero columns&lt;br&gt;
&amp;gt;&amp;gt;&lt;br&gt;
&amp;gt; ...&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; If anyone is trying to use this neat trick with *sparse* logical matrices &lt;br&gt;
&amp;gt; in R2009a, be aware that a MATLAB bug causes a crash:&lt;br&gt;
&amp;gt;&lt;br&gt;
&amp;gt; &lt;a href=&quot;http://www.mathworks.com/matlabcentral/newsreader/view_thread/246673&quot;&gt;http://www.mathworks.com/matlabcentral/newsreader/view_thread/246673&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
FYI, that's bug report 529803 if you want to track it.&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://www.mathworks.com/support/bugreports/&quot;&gt;http://www.mathworks.com/support/bugreports/&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
*snip*&lt;br&gt;
&lt;br&gt;
-- &lt;br&gt;
Steve Lord&lt;br&gt;
slord@mathworks.com </description>
    </item>
  </channel>
</rss>

