Ben*_*itz 4 matlab vectorization suppress-warnings
我正在绘制LogSumExp函数的曲面图。该函数与max类似,它接受一组数字并返回(大约)这些数字中的最大值;与 max不同, LogSumExp 函数是平滑的。为了理解 LogSumExp 函数,我希望看到它是用仅由两个数字组成的输入来绘制的,用作曲面图的 x 和 y 坐标。
下面的代码:
function lse = lse(x)
lse = log(sum(exp(x)));
end
fsurf(@(x,y) lse([x y]))
Run Code Online (Sandbox Code Playgroud)
绘制图表(成功!)但会产生以下警告消息:
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)
Run Code Online (Sandbox Code Playgroud)
从互联网搜索和其他 StackOverflow 答案中,我了解到尝试fsurf将向量直接传递给函数以获得向量,因为这比为每个 ( x, y ) 对调用一次函数产生更快的性能。
然而,根据定义,LogSumExp 函数将向量简化为标量,因此我什至不确定是否可以对其进行向量化。
有没有办法对 LogSumExp 进行矢量化?如果没有,有没有办法阻止警告消息?
考虑一下max功能。它可以通过两种方式(或其变体)使用:
max(x, y)x计算和的元素最大值y:
>> max([10 20], [0 30])
ans =
10 30
Run Code Online (Sandbox Code Playgroud)
max(x, [], n)x计算沿其维度的最大值n:
>> max([10 20; 0 30], [], 1)
ans =
10 30
Run Code Online (Sandbox Code Playgroud)
您已经lse使用第一种方法定义了您的函数。然而,第二种更适合矢量化。要lse使用第二种方法进行定义,请注意,sum也可以采用这种方式,语法如下sum(x, n):
function lse = lse(x, n)
lse = log(sum(exp(x), n));
end
Run Code Online (Sandbox Code Playgroud)
然后可以将传递给的匿名函数fsurf定义为,使用调用它的参数是矩阵(即维度)@(x,y) lse(cat(3, x, y), 3)这一事实。因此,xyfsurf 2
fsurf(@(x,y) lse(cat(3, x, y), 3))
Run Code Online (Sandbox Code Playgroud)
产生没有警告的情节: