Path: news.mathworks.com!not-for-mail
From: "Sven" <sven.holcombe@gmail.deleteme.com>
Newsgroups: comp.soft-sys.matlab
Subject: Re: N-dimensional find
Date: Wed, 18 Feb 2009 22:42:01 +0000 (UTC)
Organization: The MathWorks, Inc.
Lines: 70
Message-ID: <gni2rp$3ja$1@fred.mathworks.com>
References: <gnhibi$s1m$1@fred.mathworks.com> <gnhrhd$llc$1@fred.mathworks.com>
Reply-To: "Sven" <sven.holcombe@gmail.deleteme.com>
NNTP-Posting-Host: webapp-03-blr.mathworks.com
Content-Type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: 8bit
X-Trace: fred.mathworks.com 1234996921 3690 172.30.248.38 (18 Feb 2009 22:42:01 GMT)
X-Complaints-To: news@mathworks.com
NNTP-Posting-Date: Wed, 18 Feb 2009 22:42:01 +0000 (UTC)
X-Newsreader: MATLAB Central Newsreader 1326470
Xref: news.mathworks.com comp.soft-sys.matlab:519271


Thanks all,

The short-term solution I've chosen which has cleaned up my code quite a bit is a combination of suggestions:
BW = rand(10,20)>.8 % Make the image
[A, B] = max(BW) % Hijack the max function
B(BW(B==1)==0) = 0 % Account for all-zero columns


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.

I can think of how to make it generic enough for a 2D image called by
find_2d(BW,1)
OR
find_2d(BW,2)

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 ;)

Cheers,
Sven.


"Matt Fig" <spamanon@yahoo.com> wrote in message <gnhrhd$llc$1@fred.mathworks.com>...
> 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.
> 
> 
> 
> %--------------------------------------------------------------------------%
> function [] = find_idx_dim()
> % Demonstrate three different techniques for finding the index of the first
> % non-zero element of each column in a binary matrix.
> BW = round(rand(1000));  % A binary matrix.
> % BW = rand(1000)>.9;  % A sparse binary matrix.  Try this out too.
> t = zeros(1,3);  % For timings.
> 
> tic
> [FI1,FI1] =  max(BW); % Technique 1.
> t(1) = toc;
> 
> tic
> FI2 = zeros(1,size(BW,2));  % Technique 2.
> [R,C] = find(cumsum(cumsum(BW))==1);
> FI2(C) = R;
> t(2) = toc;
> 
> tic
> FI3 = getidx(BW);  % Technique 3, Call subfunction.
> t(3) = toc;
> 
> % Show the relative times and if all are equal.
> fprintf('\n%s%3.1f\t%3.1f\t%3.1f','Relative times:   ',t/min(t)) 
> if all(FI1==FI2 & FI1==FI3')  % check for equality.
>     fprintf('%s\n\n','    and all are equal')
> else
>     fprintf('%s\n\n','    and all are not equal')
> end
> 
> function idx = getidx(BW)
> % Subfunction that finds the first 1 index in each column.
> [r,c] = size(BW);
> idx = zeros(r,1);
> for ii = 1:c
>     for kk = 1:r
>         if BW(kk,ii)==1
>             idx(ii) = kk;
>             break
>         end
>     end
> end 
> 
> %--------------------------------------------------------------------------%