如何对将数组缩减为标量的函数进行矢量化——或关闭警告消息?

How to vectorize a function that reduces an array to a scalar—or shut off the warning message?

我正在绘制 LogSumExp 函数的曲面图。此函数与 max, 类似,因为它采用一组数字和 returns(近似)这些数字的最大值;不像 max, LogSumExp 函数是平滑的。为了理解 LogSumExp 函数,我希望看到它使用仅包含两个数字集的输入绘制,作为曲面图的 x 和 y 坐标。

以下代码:

function lse = lse(x)
   lse = log(sum(exp(x)));
end

fsurf(@(x,y) lse([x y]))

绘制图形(成功!)但产生此警告消息:

Warning: Function behaves unexpectedly on array inputs. To improve
performance, properly vectorize your function to return an output with
the same size and shape as the input arguments. 
> In matlab.graphics.function.FunctionSurface>getFunction
In matlab.graphics.function/FunctionSurface/updateFunction
In matlab.graphics.function/FunctionSurface/set.Function
In matlab.graphics.function.FunctionSurface
In fsurf>singleFsurf (line 267)
In fsurf>@(f)singleFsurf(cax,{f},extraOpts,args) (line 233)
In fsurf>vectorizeFsurf (line 233)
In fsurf (line 206) 

从 Internet 搜索和其他 Whosebug 答案中,我了解到 fsurf 尝试将向量直接传递给函数以便返回向量,因为这比调用一次函数产生更快的性能对于每个 (x, y) 对。

然而,根据定义,LogSumExp 函数将向量简化为标量,因此我什至不确定是否可以对其进行向量化。

有没有办法向量化 LogSumExp?如果没有,有没有办法阻止警告消息?

考虑 max 函数。它可以以两种方式(或其变体)使用:

  1. max(x, y) 计算 xy:

    的最大值 element-wise
    >> max([10 20], [0 30]) 
    ans =
        10    30
    
  2. max(x, [], n) 沿其维度 n:

    计算 x 的最大值
    >> max([10 20; 0 30], [], 1)
    ans =
        10    30
    

您已经使用第一种方法定义了 lse 函数。但是,second 更适合矢量化。要使用第二种方法定义 lse,请注意 sum 也可以这样工作,语法为 sum(x, n):

function lse = lse(x, n)
   lse = log(sum(exp(x), n));
end

然后可以将传递给 fsurf 的匿名函数定义为 @(x,y) lse(cat(3, x, y), 3),使用参数 xyfsurf将其称为 are 矩阵 (即 2 维度)。因此,

fsurf(@(x,y) lse(cat(3, x, y), 3))

生成没有警告的图: