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:
Find function

Subject: Find function

From: Gordon

Date: 22 Nov, 2008 07:24:04

Message: 1 of 7

I’m attempting to run a find command on two vectors A and B, I want to find the number of occurrences in vector a that are <= every occurrence in vector b. I can do this easily with a for loop, but it takes forever to run on large vectors. Here is my code…

y=zeros(length(a),1);
for i = 1:length(a)
   a1 = a(i);
   y(i) = length(find(b <= a1));
end

a= [1;1;2;3;4;5;7;9;3]
b=[ 1;2;3;4;1;2;3;3;3;4;1;1;2;3;4]
y= [4;4;7;12;15;15;15;15;12]

This works fine with small vectors, but I want to do this with very large vectors. Is there any way to do this in Matlab without using the For Loop?

Any help would be appreciated.

Subject: Find function

From: Johan Carlson

Date: 22 Nov, 2008 08:33:04

Message: 2 of 7

"Gordon " <mloomis@gmail.com> wrote in message <gg8c2k$s8d$1@fred.mathworks.com>...
> I’m attempting to run a find command on two vectors A and B, I want to find the number of occurrences in vector a that are <= every occurrence in vector b. I can do this easily with a for loop, but it takes forever to run on large vectors. Here is my code…
>
> y=zeros(length(a),1);
> for i = 1:length(a)
> a1 = a(i);
> y(i) = length(find(b <= a1));
> end
>
> a= [1;1;2;3;4;5;7;9;3]
> b=[ 1;2;3;4;1;2;3;3;3;4;1;1;2;3;4]
> y= [4;4;7;12;15;15;15;15;12]
>
> This works fine with small vectors, but I want to do this with very large vectors. Is there any way to do this in Matlab without using the For Loop?
>
> Any help would be appreciated.
>
>

Try this:

A = reshape(repmat(a',length(b),1),length(a)*length(b),1);
B = repmat(b,length(a),1);
y = sum(reshape(B<=A,length(b),length(a)));

/JC

Subject: Find function

From: Roger Stafford

Date: 22 Nov, 2008 09:24:02

Message: 3 of 7

"Gordon " <mloomis@gmail.com> wrote in message <gg8c2k$s8d$1@fred.mathworks.com>...
> I’m attempting to run a find command on two vectors A and B, I want to find the number of occurrences in vector a that are <= every occurrence in vector b. I can do this easily with a for loop, but it takes forever to run on large vectors. Here is my code…
>
> y=zeros(length(a),1);
> for i = 1:length(a)
> a1 = a(i);
> y(i) = length(find(b <= a1));
> end
>
> a= [1;1;2;3;4;5;7;9;3]
> b=[ 1;2;3;4;1;2;3;3;3;4;1;1;2;3;4]
> y= [4;4;7;12;15;15;15;15;12]
>
> This works fine with small vectors, but I want to do this with very large vectors. Is there any way to do this in Matlab without using the For Loop?
>
> Any help would be appreciated.

  Gordon, you have described your problem one way but have computed quite a different quantity. For each element of a you have counted the number of elements in b that it is less than or equal to. This is very different from "the number of occurrences in vector a that are <= every occurrence in vector b". The one is a vector as long as a is and the other is a single scalar number.

  To do what your for-loop does, try this:

 [p,p] = sort([a,b]);
 t = length(b)-cumsum(p>length(a));
 q = 1:length(p); q(p) = q;
 y = t(q(1:length(a)));

  To do what you described in words would only require taking the 'min' of b and counting how many a's are less than equal to that minimum. I doubt if that is what you meant.

Roger Stafford

Subject: Find function

From: Roger Stafford

Date: 22 Nov, 2008 09:32:01

Message: 4 of 7

"Roger Stafford" <ellieandrogerxyzzy@mindspring.com.invalid> wrote in message <gg8j3i$3ih$1@fred.mathworks.com>...
> ......
> [p,p] = sort([a,b]);
> t = length(b)-cumsum(p>length(a));
> q = 1:length(p); q(p) = q;
> y = t(q(1:length(a)));
> ......

Note: The way I wrote that assumed that a and b are row vectors.

Roger Stafford

Subject: Find function

From: Bruno Luong

Date: 22 Nov, 2008 09:35:02

Message: 5 of 7

"Gordon " <mloomis@gmail.com> wrote in message <gg8c2k$s8d$1@fred.mathworks.com>...
> I’m attempting to run a find command on two vectors A and B, I want to find the number of occurrences in vector a that are <= every occurrence in vector b. I can do this easily with a for loop, but it takes forever to run on large vectors. Here is my code…
>
> y=zeros(length(a),1);
> for i = 1:length(a)
> a1 = a(i);
> y(i) = length(find(b <= a1));
> end
>
> a= [1;1;2;3;4;5;7;9;3]
> b=[ 1;2;3;4;1;2;3;3;3;4;1;1;2;3;4]
> y= [4;4;7;12;15;15;15;15;12]
>
> This works fine with small vectors, but I want to do this with very large vectors. Is there any way to do this in Matlab without using the For Loop?
>
> Any help would be appreciated.
>

This do not require to duplicate in 2D and takes less RAM.
 
[ua trast I]=unique(a);
n=cumsum(histc(b,ua));
y=n(I)

You need to check about the correctness with "<=" and "<" of the code. If it does not meet the comparison requirement, work on reverse-sign arrays.

Bruno

Subject: Find function

From: Roger Stafford

Date: 23 Nov, 2008 00:50:17

Message: 6 of 7

"Gordon " <mloomis@gmail.com> wrote in message <gg8c2k$s8d$1@fred.mathworks.com>...
> I’m attempting to run a find command on two vectors A and B, I want to find the number of occurrences in vector a that are <= every occurrence in vector b. I can do this easily with a for loop, but it takes forever to run on large vectors. Here is my code…
>
> y=zeros(length(a),1);
> for i = 1:length(a)
> a1 = a(i);
> y(i) = length(find(b <= a1));
> end
>
> a= [1;1;2;3;4;5;7;9;3]
> b=[ 1;2;3;4;1;2;3;3;3;4;1;1;2;3;4]
> y= [4;4;7;12;15;15;15;15;12]
>
> This works fine with small vectors, but I want to do this with very large vectors. Is there any way to do this in Matlab without using the For Loop?
>
> Any help would be appreciated.

  I realized belatedly that the code I sent you has its inequality testing backwards with respect to the for-loop code you gave. Here is the corrected version. It now assumes that a and b are column vectors. For large arrays it should be considerably faster than your for-loop method.

 [p,p] = sort([b;a]);
 t = cumsum(p<=length(b));
 q = (1:length(p)); q(p) = q;
 y = t(q(length(b)+1:end));

Roger Stafford

Subject: Find function

From: Gordon

Date: 26 Nov, 2008 00:23:01

Message: 7 of 7

Roger,
Thanks for the help, this solution worked great! Thanks to everyone else who replyed.
ML

"Roger Stafford" <ellieandrogerxyzzy@mindspring.com.invalid> wrote in message <gga9c9$l1c$1@fred.mathworks.com>...
> "Gordon " <mloomis@gmail.com> wrote in message <gg8c2k$s8d$1@fred.mathworks.com>...
> > I’m attempting to run a find command on two vectors A and B, I want to find the number of occurrences in vector a that are <= every occurrence in vector b. I can do this easily with a for loop, but it takes forever to run on large vectors. Here is my code…
> >
> > y=zeros(length(a),1);
> > for i = 1:length(a)
> > a1 = a(i);
> > y(i) = length(find(b <= a1));
> > end
> >
> > a= [1;1;2;3;4;5;7;9;3]
> > b=[ 1;2;3;4;1;2;3;3;3;4;1;1;2;3;4]
> > y= [4;4;7;12;15;15;15;15;12]
> >
> > This works fine with small vectors, but I want to do this with very large vectors. Is there any way to do this in Matlab without using the For Loop?
> >
> > Any help would be appreciated.
>
> I realized belatedly that the code I sent you has its inequality testing backwards with respect to the for-loop code you gave. Here is the corrected version. It now assumes that a and b are column vectors. For large arrays it should be considerably faster than your for-loop method.
>
> [p,p] = sort([b;a]);
> t = cumsum(p<=length(b));
> q = (1:length(p)); q(p) = q;
> y = t(q(length(b)+1:end));
>
> Roger Stafford
>

Tags for this Thread

No tags are associated with 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