f



more efficient 'find' with 'and'

Hi, I have the following code, but it runs quite slowly:
 
for k=1:1000
a=find(and((b(:,1)==c(k)),(b(:,2)==d(k))));
end

Is there a more efficient method? Thanks for your help.
0
Dave
6/7/2010 10:23:20 PM
comp.soft-sys.matlab 211266 articles. 19 followers. lunamoonmoon (257) is leader. Post Follow

4 Replies
555 Views

Similar Articles

[PageSpeed] 9

Dave Brackett wrote:
> Hi, I have the following code, but it runs quite slowly:
> 
> for k=1:1000
> a=find(and((b(:,1)==c(k)),(b(:,2)==d(k))));
> end
> 
> Is there a more efficient method? 

I will assume for this discussion that you do something with "a" inside the 
loop: if you do not, then "a" will be the same as if you had only done k=1000

You could try the following for speed:

T = bsxfun('eq', b(:,1), c) & bsxfun('eq', b(:,2), d);
a = arrayfun(@(C) find(T(:,C)), 1:size(T,2), 'UniformOutput', 0);


If I recall correctly, an approach some people have mentioned in the past is

for k=1:1000
   a1 = find(b(:,1)==c(k));
   a = a1(b(a1,2)==d(k));
end

This is most efficient if the number of elements likely to be found is 
relatively low -- use the least likely test first so as to reduce the amount 
of testing needed for the more probable one.

Would the values to be searched for happen to be non-negative integer values 
less than 256? If so, then there are tricks you can play using strmatch. If 
the values are non-negative integers that could be 256 to 65536, then there 
are tricks you can play using strfind.
0
Walter
6/7/2010 11:28:19 PM
Walter Roberson <roberson@hushmail.com> wrote in message <hujvdm$gu6$1@canopus.cc.umanitoba.ca>...
> Dave Brackett wrote:
> > Hi, I have the following code, but it runs quite slowly:
> > 
> > for k=1:1000
> > a=find(and((b(:,1)==c(k)),(b(:,2)==d(k))));
> > end
> > 
> > Is there a more efficient method? 
> 
> I will assume for this discussion that you do something with "a" inside the 
> loop: if you do not, then "a" will be the same as if you had only done k=1000
> 
> You could try the following for speed:
> 
> T = bsxfun('eq', b(:,1), c) & bsxfun('eq', b(:,2), d);
> a = arrayfun(@(C) find(T(:,C)), 1:size(T,2), 'UniformOutput', 0);
> 
> 
> If I recall correctly, an approach some people have mentioned in the past is
> 
> for k=1:1000
>    a1 = find(b(:,1)==c(k));
>    a = a1(b(a1,2)==d(k));
> end
> 
> This is most efficient if the number of elements likely to be found is 
> relatively low -- use the least likely test first so as to reduce the amount 
> of testing needed for the more probable one.
> 
> Would the values to be searched for happen to be non-negative integer values 
> less than 256? If so, then there are tricks you can play using strmatch. If 
> the values are non-negative integers that could be 256 to 65536, then there 
> are tricks you can play using strfind.

Thanks. could you clarify what 'C' is in the arrayfun line that you suggest please? Also, to answer your questions: 1) I was writing to a file using an fprintf statement within the loop. 2) the values are unfortunately not integers and are not all less than 256.

Thanks again.
0
Dave
6/8/2010 6:41:07 AM
alla = find(ismember(b, [c(:) d(:)], 'rows'));
for a = reshape(alla, 1, [])
   % do something
end

% Bruno
0
Bruno
6/8/2010 6:56:06 AM
Dave Brackett wrote:
> Walter Roberson <roberson@hushmail.com> wrote in message 

>> You could try the following for speed:
>>
>> T = bsxfun('eq', b(:,1), c) & bsxfun('eq', b(:,2), d);
>> a = arrayfun(@(C) find(T(:,C)), 1:size(T,2), 'UniformOutput', 0);

> Thanks. could you clarify what 'C' is in the arrayfun line that you 
> suggest please?

arrayfun() applies the given function to each member of the array.

@(C) find(T(:,C))

is close to being equivalent to

function output = findT(T, C)
   output = find(T(:,C))
end

without having to code the function. It is an anonymous function with a 
single parameter which has been given the "dummy variable" name C.

In this context, arrayfun() is acting as the for loop

a = cell(size(T,2),1);
for C = 1 : size(T,2)
   a{C} = find(T(:,C));
end
0
roberson (2980)
6/8/2010 4:07:04 PM
Reply: