使用 if/else 为 bsxfun 编写函数

Write function for bsxfun with if/else

在我的代码中,我需要 divide 矩阵的每个值乘以另一个矩阵的值。我可以使用 A./B 但 B 中的某些元素为 0。我知道如果 B(i,j) = 0 那么 A(i,j) = 0 也是,我想要 0/0 = 0。所以我写了一个函数 div 并且我使用 bsxfun 但我没有 0,我有 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);

为什么不直接替换不需要的值呢?

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

您可以 C(isnan(C))=0;,但这将替换所有 NaN,甚至是那些不是由 0/0 创建的。如果零总是一起出现,那么 C(B==0)=0; 就可以了

如果你知道 B 中的非零值永远不会小于一个非常小的数字 eps(例如 1e-300),一个简单的技巧是将 eps 添加到 B。所有非零值都不变,而所有零值都变成了 eps。当除以 0/eps 时,您会得到想要的结果。

发生这种情况的原因是 bsxfun 没有按元素处理数组。因此,您的函数不会获得两个标量。它实际上只被调用一次。您的 if 语句不适用于 b.

的非标量值

bsxfun 替换为 arrayfun 将使用标量输入调用您的函数,并将产生预期结果:

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

尽管如此,其他两个答案中的任何一个都会更有效率:

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

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