Write function for bsxfun with if/else

137 views Asked by At

In my code, I need to divide each values of a matrix by the values of another. I could use A./B but some elements in B are 0. I know that if B(i,j) = 0 so A(i,j) = 0 too and I want to have 0/0 = 0. So I wrote a function div and I use bsxfun but I don't have 0, I have NaN :

A = [1,0;1,1];
B = [1,0;1,2];
function n = div(a,b)
   if(b==0)
      n = 0;
   else
      n = a./b;
   end
end
C = bsxfun(@div,A,B);
3

There are 3 answers

0
Ander Biguri On BEST ANSWER

Why not just replace the unwanted values after?

C=A./B;
C(A==0 & B==0)=0;

You could do C(isnan(C))=0;, but this will replace all NaN, even the ones not created by 0/0. If zeros always happen together then just C(B==0)=0; will do

0
user10259794 On

If you know your non-zero values in B are never smaller than a very small number eps (for example 1e-300), a simple trick is to add eps to B. All non-zero values are unchanged, while all zero values become eps. When dividing 0/eps you get the wished result.

0
Cris Luengo On

The reason this is happening is because bsxfun doesn't process the arrays element-wise. Consequently, your function doesn't get two scalars in. It is actually called only once. Your if statement does not work for non-scalar values of b.

Replacing bsxfun with arrayfun will call your function with scalar inputs, and will yield the expected result:

>> C = arrayfun(@div,A,B)
C =
    1.0000         0
    1.0000    0.5000

Nonetheless, either of the other two answers will be more efficient:

>> C = A./B;
>> C(B==0) = 0   % Ander's answer
C =
    1.0000         0
    1.0000    0.5000

or

C = A./(B+eps)   % user10259794's answer
C =
    1.0000         0
    1.0000    0.5000