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 in matrix

Subject: find in matrix

From: Grzegorz Knor

Date: 24 Sep, 2010 10:20:06

Message: 1 of 9

Hi,
suppose that i have a matrix A and vector a, for example:

A = rand(1234,11);
a = rand(1,11);

And now, for each column I want to find the first number greater than the corresponding number in the vector a.

My solution:

idx = NaN(1,11);
for k=1:11
idx(k) = find(A(:,k)>=a(k),1,'first');
end

Is there a more optimal way?

regards

Subject: find in matrix

From: Ben

Date: 24 Sep, 2010 12:05:52

Message: 2 of 9

Hi,

You might try this:
 
C= ones(size(A,1),1)*a;
S = sign(A-C);
[z,idx] = max(S);

For your answer without a for-loop.

Grz Ben

Subject: find in matrix

From: Grzegorz Knor

Date: 24 Sep, 2010 12:59:06

Message: 3 of 9

Ben <benvoeveren@gmail.com> wrote in message <762824383.107588.1285329982163.JavaMail.root@gallium.mathforum.org>...
> Hi,
>
> You might try this:
>
> C= ones(size(A,1),1)*a;
> S = sign(A-C);
> [z,idx] = max(S);
>
> For your answer without a for-loop.
>
> Grz Ben

Nice solution, but it is slower than mine.
Besides i found error in both solutions. When you haven't greater value, it should give NaN.
I fixed error in my solution, and compared the time:

==========================================
clear all
clc
N = 1000;
t = zeros(N,2);
for n = 1:N
    disp(['step ' num2str(n) '/' num2str(N)])
clear A a C S z idx1 idx k
A = rand(1234,11);
a = rand(1,11);
tic
C= ones(size(A,1),1)*a;
S = sign(A-C);
[z,idx1] = max(S);
t(n,1) = toc;
tic
idx = NaN(1,11);
for k=1:11
    tmp = find(A(:,k)>=a(k),1,'first');
    if ~isempty(tmp)
idx(k) = tmp;
    end
end
t(n,2) = toc;
end
plot(t)
ylabel('time [s]')
xlabel('step')
legend('Ben','Grzegorz')
==========================================

Any other ideas?

Subject: find in matrix

From: Matt J

Date: 24 Sep, 2010 14:14:05

Message: 4 of 9

Here's a one-line solution, but don't know how it compares speed-wise to the others,

[~,theResult]=max( bsxfun(@gt,A,a),[],1);

Subject: find in matrix

From: Matt J

Date: 24 Sep, 2010 14:24:05

Message: 5 of 9

"Matt J " <mattjacREMOVE@THISieee.spam> wrote in message <i7ibnc$7ee$1@fred.mathworks.com>...
> Here's a one-line solution, but don't know how it compares speed-wise to the others,
>
> [~,theResult]=max( bsxfun(@gt,A,a),[],1);

Or, if you want a test based on ">=" instead of ">", then as follows

 [~,theResult]=max( bsxfun(@ge,A,a),[],1);

Subject: find in matrix

From: Bruno Luong

Date: 24 Sep, 2010 14:40:11

Message: 6 of 9

All the proposed methods waste the time of building full-size intermediate vectors, whereas the test can break as soon as the first element is found. The saving time depends of course the location the first element, but for random values as tested, none of the above method can beat this one:
 
idx = NaN(1,11);
for k=1:11
    ak = a(k);
    for j=1:size(A,1)
        if A(j,k)>= ak
            idx(k) = j;
            break
        end
    end
end

Bruno

Subject: find in matrix

From: Jan Simon

Date: 24 Sep, 2010 17:01:22

Message: 7 of 9

Dear Bruno,

Very engaged to suggest fast FOR loops in CSSM.

On my test data and Matlab 2009a, this was perhaps a little bit faster. But I'm not sure because of the noise induced by the small and random testdata.

idx = NaN(1,11);
s1 = size(A, 1); % Needs time, move out of the loops
for k=1:11
    ak = a(k);
    Ak = A(:, k); % Skip solving the 2nd index repeatedly
    for j=1:s1
        if Ak(j)>= ak
            idx(k) = j;
            break;
        end
    end
end

Jan

Subject: find in matrix

From: Bruno Luong

Date: 24 Sep, 2010 21:08:05

Message: 8 of 9

"Jan Simon" <matlab.THIS_YEAR@nMINUSsimon.de> wrote in message <i7ilh2$j0$1@fred.mathworks.com>...

> s1 = size(A, 1); % Needs time, move out of the loops

This is a good idea.


> Ak = A(:, k); % Skip solving the 2nd index repeatedly

However this is not, since Matlab will move the entire column in new memory. Matlab is not smart enough to use the pointer and share the data with A(:,k).

Bruno

Subject: find in matrix

From: Grzegorz Knor

Date: 25 Sep, 2010 19:40:20

Message: 9 of 9

Thank you all for your replies :)

Grzegorz

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