Reputation: 3019
Let us say I have the following:
M = randn(10,20);
T = randn(1,20);
I would like to threshold each column of M
, by each entry of T
. For example, find all indicies of all elements of M(:,1)
that are greater than T(1)
. Find all indicies of all elements in M(:,2)
that are greater than T(2)
, etc etc.
Of course, I would like to do this without a for-loop. Is this possible?
Upvotes: 2
Views: 1256
Reputation: 8593
You can use bsxfun
to do things like this, but it may not be faster than a for loop (more below on this).
result = bsxfun(@gt,M,T)
This will do an element wise comparison and return you a logical matrix indicating the relationship governed by the first argument. I have posted code below to show the direct comparison, indicating that it does return what you are looking for.
%var declaration
M = randn(10,20);
T = randn(1,20);
% quick method
fastres = bsxfun(@gt,M,T);
% looping method
res = false(size(M));
for i = 1:length(T)
res(:,i) = M(:,i) > T(i);
end
% check to see if the two matrices are identical
isMatch = all(all(fastres == res))
This function is very powerful and can be used to help speed up processes, but keep in mind that it will only speed things up if there is a lot of data. There is a bit of background work that bsxfun
must do, which can actually cause it to be slower.
I would only recommend using it if you have several thousand data points. Otherwise, the traditional for-loop will actually be faster. Try it out for yourself by changing the size of the M
and T
variables.
Upvotes: 3
Reputation: 3574
You can replicate the threshold vector and use matrix comparison:
s=size(M);
T2=repmat(T, s(1), 1);
M(M<T2)=0;
Indexes=find(M);
Upvotes: 1
Reputation: 88
You can use bsxfun
like this:
I = bsxfun(@gt, M, T);
Then I
will be a logcial matrix of size(M)
with ones where M(:,i) > T(i)
.
Upvotes: 5