Matlab 多用途polyval函数的性能改进

Matlab 多用途polyval函数的性能改进,matlab,performance,polynomial-math,Matlab,Performance,Polynomial Math,关于在Matlab中使用polyval函数,我有一个简单的性能问题 目前,我有一个x向量,它可以相当长(>1000个标量)。我想对每个x应用不同的多项式形式 多项式形式存储在2d数组中,并应用于循环中,如下面的代码所示。优化polyval时,代码相对较快,但循环可能较长,性能至关重要,因为它是一个目标函数,在一个过程中可以计算数千次 关于如何提高性能有什么想法吗 谢谢 % ---------- Objective Function ------------------ function [obj

关于在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
% -------------------------------------------------

您可以手动线性化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.

此外,如果要计算每个多项式的每个x值,可以使用:

res = x.^d*p.'; %using only matrix multiplication


我觉得你的问题有点让人困惑,但我认为这正是你想要的:

polyvalue = sum(poly_objective .* x(:).^(numel(x)-1:-1:0), 2);
请注意,上面使用了。对于R2016b之前的版本,请使用:

例子 随机数据:

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

最快的方法可能是直接计算不同的多项式,去掉循环(如或所示)。然而,这里有一个关于
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
太棒了,所以这一直是你使用的评估。您可能会发现删除这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

poly_物镜的大小是多少?是否确保
长度(x)
等于
大小(多边形目标,1)
?另外,您是否需要根据您的代码仅求其和的单个多项式的结果?感谢您在下面的回复。你说得对,我只需要总数。这会改变问题(和答案)吗?不,我不知道如何加快我的答案来计算总和。只需获取
polyvalue
,然后获得
sum(polyvalue)
谢谢!非常有用。3个非常好的答案,观点不同,但观点趋同!这也是我在MATLAB内置软件中找到的最好的评论,我同意:-)
>> polyvalue = sum(poly_objective .* x(:).^(numel(x)-1:-1:0), 2)
polyvalue =
  13.545710504297881
  16.286929525147158
  13.289183623920710
   5.777980886766799
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
✓ isscalar(x)
✓ nargin < 3 
✓ length(p) > 0
✓ isfinite(x)
✓ all(isfinite(p(:)))
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