Ying
Ying

Reputation: 1954

How to vectorize matlab function input when NaN could be the input?

I wrote a function which I hope to have vectorized input and output:

function output = myfunction(input1,input2)
if input1 == 0
    output = equation1 ;
else
    output = equation2 ;
end

I tested it with input1 = 0 and input1 = 0.5 and myfunction works right. input1 and input2 are actually 3D matrices. I am trying to have more efficient computation instead of running a loop for an element by element calculation.

If input1 are all nonzero elements, myfunction works correctly. It seems like once I input a matrix with zero and nonzero elements, it cannot go through the if-statement correctly. My function will give me NaN for the element that has input1==0.

How can I change it so that myfunction can take either a number or a matrix in an if-statement?

Thank you!

[EDIT:]

The actual function looks like this:

function output = myfunction( input1 , frequency , input2 , input3 )

zero_ind = input1 == 0 ;
output = zeros(size(input1)) ;
output(zero_ind) = input3(zero_ind) / frequency ./ input2(zero_ind) ; ;
temp1(~zero_ind) = input1(~zero_ind) / frequency ;
temp2(~zero_ind) = input2(~zero_ind) * frequency ;
output(~zero_ind) = input3(~zero_ind) .*  ( 1 + temp1(~zero_ind)).^temp2(~zero_ind) .* temp1(~zero_ind) ./ ( ( 1 + temp1(~zero_ind) ).^temp2(~zero_ind) - 1 ) ;   

Upvotes: 1

Views: 55

Answers (1)

EBH
EBH

Reputation: 10450

Here is a general suggestion for vectorizing. This should be changed properly to your kind of calculations:

function output = myfunction(input1,input2)
zero_ind = input1==0; % this replaces the if statement
output = zeros(size(input1)); % initialize output to wanted size and shape
output(zero_ind) = input2(zero_ind).^2; % equation1
output(~zero_ind) = input1(~zero_ind).*input2(~zero_ind); % equation2
end

The main idea is to use logical indexing instead of the if statement. I assume here (among other things, I guess) that all your inputs and output are the same sizes. This could be relaxed, but it depends on the specific calculation you do.

EDIT:

In response to your edit with the real function, here is my suggestion (I changed the input names just to make it a little more compact):

function output = myfunction(in1,frequency,in2,in3)
temp1 = in1/frequency ;
temp2 = in2*frequency ;
output = in3.*(1+temp1).^temp2.*temp1./((1+temp1).^temp2-1);
zero_ind = in1 == 0;
output(zero_ind) = in3(zero_ind)./frequency./in2(zero_ind); 
end

What I did is calculating all output like there are no zeros in in1, and then replace only the places in output that corresponds to a zero in in1 to another value. This way you use zero_ind only when necessary, and minimize the indexing operation.

Upvotes: 1

Related Questions