Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
more efficient 'find' with 'and'

Subject: more efficient 'find' with 'and'

From: Dave Brackett

Date: 7 Jun, 2010 22:23:20

Message: 1 of 5

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.

Subject: more efficient 'find' with 'and'

From: Walter Roberson

Date: 7 Jun, 2010 23:28:19

Message: 2 of 5

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.

Subject: more efficient 'find' with 'and'

From: Dave Brackett

Date: 8 Jun, 2010 06:41:07

Message: 3 of 5

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.

Subject: more efficient 'find' with 'and'

From: Bruno Luong

Date: 8 Jun, 2010 06:56:06

Message: 4 of 5

alla = find(ismember(b, [c(:) d(:)], 'rows'));
for a = reshape(alla, 1, [])
   % do something
end

% Bruno

Subject: more efficient 'find' with 'and'

From: Walter Roberson

Date: 8 Jun, 2010 16:07:04

Message: 5 of 5

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

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us