关于在Matlab上使用polyval函数,我有一个简单的性能问题。
当前,我有一个向量x,该向量可能会很长(> 1000标量)。我想对每个x应用不同的多项式形式。
多项式形式存储在2d数组中,并像下面的代码一样在循环中应用。由于优化了polyval,因此代码相对较快,但是循环可能很长,并且性能至关重要,因为它是一个目标函数,可以在一个过程中计算数千次。
关于如何提高性能的任何想法?
谢谢
% ---------- Objective Function ------------------
function [obj] = obj(x, poly_objective)
polyvalue = zeros(length(x),1);
for index = 1: length(x)
polyvalue (index) = polyval(poly_objective(index,:), x(index));
end
obj= -sum(polyvalue );
end
% -------------------------------------------------
答案 0 :(得分:1)
您可以手动线性化for循环,这是一个示例:
p = [3,2,1;
5,1,3]; %polynomial coeff
x = [5,6].'; %the query points
d = size(p,2)-1:-1:0; %the power factors
res = sum(x.^d.*p,2); %process all the polynome without for loop.
使用
res =
86
189
此外,如果您要为每个多项式评估每个x值,则可以使用:
res = x.^d*p.'; %using only matrix multiplication
使用
res =
p1 p2
x1 86 133
x2 121 189
答案 1 :(得分:1)
我发现您的问题有点令人困惑,但是我认为这符合您的要求:
polyvalue = sum(poly_objective .* x(:).^(numel(x)-1:-1:0), 2);
请注意,以上使用implicit expansion。对于R2016b之前的Matlab版本,请使用bsxfun
:
polyvalue = sum(poly_objective .* bsxfun(@power, x(:), (numel(x)-1:-1:0)), 2);
随机数据:
>> x = rand(1,4);
>> poly_objective = randi(9,4,4);
您的代码:
>> polyvalue = zeros(length(x),1);
for index = 1: length(x)
polyvalue (index) = polyval(poly_objective(index,:), x(index));
end
>> polyvalue
polyvalue =
13.545710504297881
16.286929525147158
13.289183623920710
5.777980886766799
我的代码:
>> polyvalue = sum(poly_objective .* x(:).^(numel(x)-1:-1:0), 2)
polyvalue =
13.545710504297881
16.286929525147158
13.289183623920710
5.777980886766799
答案 2 :(得分:1)
最快的方法可能是直接评估不同的多项式,从而消除循环(如obchardon或Luis所示)。不过,这是有关polyval
性能的说明...
如果在命令窗口中键入edit polyval
,则可以看到polyval
函数的源代码。特别是在顶部附近有以下条件评估:
nc = length(p);
if isscalar(x) && (nargin < 3) && nc>0 && isfinite(x) && all(isfinite(p(:)))
% Make it scream for scalar x. Polynomial evaluation can be
% implemented as a recursive digital filter.
y = filter(1,[1 -x],p);
y = y(nc);
return
end
我认为"Make it scream"
注释是开发人员告诉我们的,这是通过该函数的非常快捷的方法!在旁边;这也是我在内置的MATLAB中找到的最好的注释。
因此,让我们尝试满足此if
语句的条件...
✓ isscalar(x)
✓ nargin < 3
✓ length(p) > 0
✓ isfinite(x)
✓ all(isfinite(p(:)))
出色,因此这始终是您使用的评估。您可能会发现删除这5条支票的速度有所提高,只需这样做即可代替polyval
。就您的变量而言,如下所示:
y = filter(1,[1 -x(index)],poly_objective(index,:));
polyvalue (index) = y(size(poly_objective,2));
% Note you should get size(poly_objective,2) outside your loop