3

我有一个奇点为零的函数。结果值应该在该点 1。

但是,我无法理解如何创建一个内联函数,该函数对 x 或 y = 0 处的 x 和 y 值进行特殊处理。

例如,该功能可以是

f = @(x,y) ( 1./x + 1./y ); 
4

4 回答 4

3

用一个反问来回答你的问题:你为什么希望它是内联的?

作为一般规则,保持内联函数简单。如果需要更多功能,请使用专用功能:

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

话虽如此,当然有方法可以内联(参见其他答案)。

但正如您所指出的,您的实际功能更复杂,所以......为什么内联?

于 2012-08-08T09:49:47.390 回答
2

作为肮脏的技巧,您可以将 x 替换为x + (x==0)

那么如果 x 等于 0,那么分母中就会有 0+1。


在某些情况下,您还可能滥用“短路”运算符。

喜欢~isfinite(f(x)) || f(x)

于 2012-08-08T07:24:59.357 回答
2

创建以下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
   )
于 2012-08-08T08:48:15.853 回答
0

我认为这大致是大多数人在这种情况下想要的。

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]))

并将结果添加到您的原始号码。

于 2015-05-23T01:22:46.440 回答