我有一个奇点为零的函数。结果值应该在该点 1。
但是,我无法理解如何创建一个内联函数,该函数对 x 或 y = 0 处的 x 和 y 值进行特殊处理。
例如,该功能可以是
f = @(x,y) ( 1./x + 1./y );
用一个反问来回答你的问题:你为什么希望它是内联的?
作为一般规则,保持内联函数简单。如果需要更多功能,请使用专用功能:
function val = f(x,y)
if ~all(size(x)==size(y))
error('sizes must match');
val = zeros(size(x));
zero_x = x==0;
zero_y = y==0;
not_zero = ~zero_x & ~zero_y;
zero = ~not_zero;
val(not_zero) = 1./x(not_zero) + 1./y(not_zero);
val(zero) = 1;
end
话虽如此,当然有方法可以内联(参见其他答案)。
但正如您所指出的,您的实际功能更复杂,所以......为什么内联?
作为肮脏的技巧,您可以将 x 替换为x + (x==0)
那么如果 x 等于 0,那么分母中就会有 0+1。
在某些情况下,您还可能滥用“短路”运算符。
喜欢~isfinite(f(x)) || f(x)
创建以下iif.m
函数文件,驻留在您的工作文件夹中,或者如果您在其他函数中使用它甚至作为子函数(脚本当然不能包含子函数):
function val = iif(expr, truepart, falsepart)
if isscalar(truepart)
truepart=truepart(ones(size(expr)));
end
if isscalar(falsepart)
falsepart=falsepart(ones(size(expr)));
end
val = arrayfun(@iif_scalar, expr, truepart, falsepart);
end
function val = iif_scalar(expr,truepart,falsepart)
if expr
val = truepart;
else
val = falsepart;
end
end
并按如下方式使用它:
f = @(x,y) iif(x==0 | y==0, 1, 1./x + 1./y );
我iif
尽可能保持函数的通用性,你可以在向量、标量、混合标量和向量,甚至矩阵上使用它。例如,在上面我使用了 2 个向量和一个标量:
iif( ...
x==0 | y==0 ,... % expression if x or y are 0 => vector
1 , ... % scalar obviously
1./x + 1./y ... % function of x and y => vector
)
我认为这大致是大多数人在这种情况下想要的。
1+sum([repmat(nan,~**0**,1) 0])
答案 = NaN
1+sum([repmat(nan,~**1**,1) 0])
答案 = 1
现在概括:
zero2nanElseNum_inline = @(x) x*(1+sum([repmat(nan,~x,1) 0]))
zero2nanElseNum_inline(0)
答案 = NaN
zero2nanElseNum_inline(10)
答案 = 10
zero2nanElseNum_inline(1)
答案 = 1
对于手头的特定情况,您可以简单地获取代码片段:
sum([repmat(nan,~**0**,1) 0])
把它喂给isnan:
isnan(sum([repmat(nan,~**0**,1) 0]))
并将结果添加到您的原始号码。