tags:

views:

413

answers:

5

Say I have the following basic if-statement:

if (A ~= 0)
   % do something like divide your favorite number by A
else
   % do something like return NaN or infinity
end

The problem is that A is not a simple number but a vector. Matlab returns true if no element in A is 0. What I am looking for is a vectorized? way of perforimg the if-statement above for each element in A.

Actually, I simply want to do this as fast as possible.

A: 

Are you looking for all non-zero elements? You can do this a couple of ways.

nonzero = find(A); % returns indicies to all non-zero elements of A
y = x./A(nonzero); % divides x by all non-zero elements of A
                   % y will be the same size as nonzero

Or for a one-liner, you can use a conditional in place of indicies

y = x./A(A~=0); % divides x by all non-zero elements of A
Scottie T
This statement will cause y to be shorter than A if any element of A is zero, which may or may not be desired.
Mark Ruzon
A: 

What you need to do is identify the elements you want to operate on. I would use FIND. I store the results in VI (Valid Indicies) and use that to populate the matrix.

clear
clc

den = [2 0 2; 0 2 0; -2 -2 -2]
num = ones(size(den));
frac = nan(size(den));

vi = (den ~=0)

frac(vi) = num(vi)./den(vi)

vi = (den == 0)

frac(vi) = nan %just for good measure...
MatlabDoug
fyi: you don't need to use find, you can use boolean matrices directly. The value of find is to extract particular index values, and/or to save memory space if only a few values are true.
Jason S
removed FIND as requested by JASON S
MatlabDoug
+2  A: 

Vectorized ifs don't exist, but there are some options. If you want to test for all or any elements true, use the all or any function.

Here's one example of conditionally modifying values of a matrix:

b = A ~= 0;      % b is a boolean matrix pointing to nonzero indices
                 % (b could be derived from some other condition,
                 %  like b = sin(A)>0
A(b) = f(A(b))   % do something with the indices that pass
A(~b) = g(A(~b)) % do something else with the indices that fail
Jason S
I didn't realise b (the boolean matrix) existed until you pointed it out. Thanks!
AnnaR
A: 
B = zeros(size(A));
B(A~=0) = FAV./A(A~=0);  
B(A==0) = NaN;
KitsuneYMG
+1  A: 

In general, to perform one operation on some elements of a matrix and another operation on the remaining elements, a one-line solution is:

Z = B .* X + ~B .* Y;

where B is a logical matrix. As an example,

Z = (A == 0) .* -1 + (A ~= 0) .* A;

copies A but assigns -1 everywhere that A is zero.

However, because the question deals with infinity or NaNs, it can be done even more succinctly:

Z = FAV ./ A; % produces inf where A == 0
Z = (A ~= 0) .* FAV ./ A; % produces NaN where A == 0
Mark Ruzon
+1: Clever one-liner!
gnovice

related questions