在matlab中加速程序

Speeding up program in matlab

提问人:MartinYakuza 提问时间:5/8/2020 最后编辑:MartinYakuza 更新时间:5/12/2020 访问量:116

问:

我有 2 个功能:

ccexpan- 计算函数多项式与第一类基的切比谢多项式中的节点的插值系数。fN

csum- 使用 的系数计算参数的值(使用 Clenshaw 算法)。tcccexpan

这是我到目前为止所写的:

function c = ccexpan(f,N)

z = zeros (1,N+1);
s = zeros (1,N+1);

for i = 1:(N+1)
    z(i) = pi*(i-1)/N;
end

t = f(cos(z));

for k = 1:(N+1)
    s(k) = sum(t.*cos(z.*(k-1)));
    s(k) = s(k)-(f(1)+f(-1)*cos(pi*(k-1)))/2;
end

c = s.*2/N;

和:

function y = csum(t,c)

M = length(t);
N = length(c);
y = t;
b = zeros(1,N+2);

for k = 1:M
    for i = N:-1:1
        b(i) = c(i)+2*t(k)*b(i+1)-b(i+2);
    end
    y(k)=(b(1)-b(3))/2;
end

不幸的是,这些程序非常缓慢,而且也略微不准确。请给我一些关于如何加快速度以及如何提高准确性的提示。

性能 MATLAB 数值方法 浮动精度 多项式

评论

1赞 Ander Biguri 5/8/2020
您是否分析了您的代码?
0赞 MartinYakuza 5/8/2020
@AnderBiguri不,我不知道它是什么,我是matlab的新手。
0赞 Daniel 5/8/2020
它会生成一个报告,告诉您执行时间花在哪里:mathworks.com/help/matlab/matlab_prog/...
0赞 MartinYakuza 5/8/2020
@Daniel报告说,这运行了 40 秒和 271 秒,其中 50 秒是“自我时间”。所以我想我应该优化?csumccexpanccexpan
1赞 Ander Biguri 5/8/2020
该报告还允许您查看功能内部,并了解其中哪些部分需要时间。在某些时候,如果你运行了数百万次,那会很慢。

答:

3赞 greengrass62 5/9/2020 #1

在可能的情况下,尽量远离循环结构。乍一看,我会用你的第一个换取循环

for i = 1:(N+1)
    z(i) = pi*(i-1)/N;
end

并替换为

i=1:(N+1)
z = pi*(i-1)/N

我没有检查你们其余的代码,但上面的例子肯定会加快你的代码速度。第二种策略是在可能的情况下组合循环。

评论

0赞 MartinYakuza 5/11/2020
当我用这个索引索引我的矩阵时,如何做到这一点?还是嵌套循环?你能举一个 ccexpan 中另一个循环的例子吗?
0赞 greengrass62 5/12/2020
你能提供一个你通过的 f 和 N 的例子吗?(我假设 f 是一个函数,但在不知道 f 的形式的情况下,我不确定如何为 ccexpan 中的第二个循环的转换提供建议)。
0赞 MartinYakuza 5/12/2020
我在问题的开头写了参数的含义 - 是一个函数,并且是一个标量fN
0赞 greengrass62 5/12/2020
你能给我一个函数 f 的例子吗?(重要的是要知道 f 返回的是标量还是向量。如果它返回一个向量,它是列还是行等)
0赞 MartinYakuza 5/12/2020
f 是标量,一个变量函数,例如。f = @(x) 1/(1+15*x.*x)
0赞 greengrass62 5/12/2020 #2

马丁

请考虑以下策略。

% create hypothetical N and f
N = 3
f = @(x) 1./(1+15*x.*x) 

% calculate z and t
i=1:(N+1)
z = pi*(i-1)/N
t = f(cos(z))

% make a column vector of k's
k = (1:(N+1))'

% do this: s(k) = sum(t.*cos(z.*(k-1)))
s1 = t.*cos(z.*(k-1))    % should be a matrix with one row for each row of k
                         % via implicit expansion
s2 = sum(s1,2)           % row sum, i.e., one value for each row of k

% do this: s(k) = s(k)-(f(1)+f(-1)*cos(pi*(k-1)))/2
s3 = s2 - (f(1)+f(-1)*cos(pi*(k-1)))/2

% calculate c
c  = s3 .* 2/N

评论

0赞 greengrass62 5/12/2020
我认为这将带您完成整个功能。
0赞 greengrass62 5/12/2020
如果这有效,请告诉我,我将清理我的整个帖子以进行整合。
0赞 MartinYakuza 5/12/2020
我不知道为什么,但不幸的是它的工作速度稍慢。
0赞 MartinYakuza 5/12/2020
此外,出于某种原因,我已经编辑了这个问题,显然在嵌套循环中工作得更快。csum
0赞 greengrass62 5/13/2020
您将需要提供/创建一个完整的可重现示例(主程序和所有功能)以进一步诊断。嵌套循环不应更快。