如何存储和重用在for循环系数

10视图(30天)
Matlab代码的子程序重复执行一个for循环的两倍。大型模拟测试时,这个子程序叫做超过10 ^ 6次。我很好奇如果我可以改变/重用子程序的一部分,这样我就可以提高性能。
我原来的Matlab代码(测试数据)如下所示。
%测试数据
clc;清晰的所有;
M = 30;
N = 30;
Nx = 32;
f_n_m =兰德(Nx、N + 1 M + 1);
ε= 0.3;
δ= 0.4;
SumType =兰迪(3,1);
f = 0 (Nx, 1);
多项式系数= 0 (N + 1, M + 1);
%原始实现
j = 1: Nx
%这两个for循环可以执行一次,而不是Nx倍?
r = 0: N
s = 0: M
多项式系数(r + 1, s + 1) = f_n_m (j r + 1, s + 1);
结束
结束
如果(SumType = = 1)
%我的代码调用分离子例程需要多项式系数的值。
%出于测试目的,我把f (j) =测试数据。这三个如果
%在我的代码语句调用外部函数。
f (j) =多项式系数(j) *ε*δM * N *;
elseif(SumType = = 2)
f (j) = 2 *多项式系数(j) *ε*δM * N *;
elseif(SumType = = 3)
f (j) = 3 *多项式系数(j) *ε*δM * N *;
结束
结束
我的第一个(坏的管理者)的想法是上面的代码更改为下面的代码。
f2 = 0 (Nx, 1);
coeff2 = 0 (N + 1, M + 1);
%将两个for循环
j = 1: Nx
r = 0: N
s = 0: M
coeff2 (r + 1, s + 1) = f_n_m (j r + 1, s + 1);
结束
结束
结束
%然后运行原来的for循环
j = 1: Nx
如果(SumType = = 1)
f2 (j) = coeff2 (j) *ε*δM * N *;
elseif(SumType = = 2)
f2 (j) = 2 * coeff2 (j) *ε*δM * N *;
elseif(SumType = = 3)
f2 (j) = 3 * coeff2 (j) *ε*δM * N *;
结束
结束
%,这给了不同的答案,因为违背一个f (j)
% j值而f2 (j)计算的所有值。
diff =规范(f-f2正)%大
我很好奇如果有更高效的写作方式
j = 1: Nx
%开始内部两个for循环
r = 0: N
s = 0: M
多项式系数(r + 1, s + 1) = f_n_m (j r + 1, s + 1);
结束
结束
%结束内心的两个for循环
如果(SumType = = 1)
f (j) =%外部函数多项式系数,ε,三角洲,N, M
elseif(SumType = = 2)
f2 (j) =%不同的外部函数多项式系数,ε,三角洲,N, M
elseif(SumType = = 3)
f2 (j) =%的第三个外部函数多项式系数,ε,三角洲,N, M
结束
结束
这样循环的内部双只计算一次,而不是Nx倍。这是一个限制函数是这样写的吗?

接受的答案

每•艾萨克森
每•艾萨克森 2021年7月23日
警告:我不完全理解你的代码和我说可能不是你真正的相关项目。
“%这两个for循环可以执行一次,而不是Nx倍?” 简短的回答是否定的,因为 多项式系数 是2 d和 f_n_m 是3 d的。也许,你可以 多项式系数 3 d。取决于你如何使用 多项式系数。
“f (jj) =多项式系数(jj) * *δε* N * M;” 是什么 多项式系数(jj) 应该返回?这是线性索引,返回一个标量。
建议:更换两个for循环 alt_coeff = f_n_m (:,:, jj);。 请注意,我有修改的索引 f_n_m jj 是第三个索引。运行函数 cssm1 () 概要文件()。alt_coeff 大大提高了速度。
cssm1
ans =“快乐的结局”
函数出= cssm1
%测试数据
% clc;清除所有;
M = 30;
N = 30;
Nx = 32;
f_n_m =兰德(N + 1, M + 1, Nx);
ε= 0.3;
δ= 0.4;
SumType =兰迪(3,1);
f = 0 (Nx, 1);
多项式系数= 0 (N + 1, M + 1);
%原始实现
jj = 1: Nx
%这两个for循环可以执行一次,而不是Nx倍?
r = 0: N
s = 0: M
多项式系数(r + 1, s + 1) = f_n_m (r + 1, s + 1, jj);
结束
结束
alt_coeff = f_n_m (:,:, jj);
如果(SumType = = 1)
%我的代码调用分离子例程需要多项式系数的值。
%出于测试目的,我把f (j) =测试数据。这三个如果
%在我的代码语句调用外部函数。
f (jj) =多项式系数(jj) *ε*δM * N *;
elseif(SumType = = 2)
f (jj) = 2 *多项式系数(jj) *ε*δM * N *;
elseif(SumType = = 3)
f (jj) = 3 *多项式系数(jj) *ε*δM * N *;
结束
结束
了=“快乐的结局”;
结束
3评论
马修凯赫
马修凯赫 2021年7月24日
编辑:马修凯赫 2021年7月25日
谢谢你的有用的信息和评论。——解决评论
第一个评论:我所有的Matlab代码创建维度的顺序(Nx、N + 1 M + 1)。这是服从,没有意义。我始终创建循环,Nx(最大的价值)在N和M较小。本地测试
M = 20;
N = 20;
Nx = 32;
f_n_m =兰德(N + 1, M + 1, Nx);
f_n_m_2 =兰德(Nx、N + 1 M + 1);
ntests = 10000;
%方法1
抽搐
2 = 1:ntests
j = 1: Nx
j_n_m = f_n_m (:,:, j);
结束
结束
toc
%的方法2
抽搐
2 = 1:ntests
j = 1: Nx
j_n_m_2 = f_n_m_2 (j,:,);
结束
结束
toc
% 1是更快的方法
表明,方法1更快。我应该检查所有的代码和更新循环的两倍/三倍,这样循环经过列最后(我认为这是列为主是如何工作的。我明天看深入这是1:00am我需要睡眠)。
第二个评论:我同意randi rand() /()是低效的。这不是我生产代码的一部分,只是将代码创建论坛。我真正的成千上万行代码(具有多个功能)。我不通过兰德()创建数据。
第三个评论:没有必要创建系数。写作
j = 1: Nx
如果(SumType = = 1)
%这是我产品代码调用。我没有展示什么
% taylor_sum2、pade_sum2 pasde_sum2_safe做太多
%细节,将使问题“不独立”。
f (j) = taylorsum_2_coeff (f_n_m (:,:, j),每股收益,三角洲,N, M);
elseif(SumType = = 2)
f (j) = padesum2 (f_n_m (:,:, j),每股收益,三角洲,N, M);
其他的
f (j) = padesum2_safe (f_n_m (:,:, j),每股收益,三角洲,N, M);
结束
结束
更快。我将回顾在本地(和测试)改变(Nx、N + 1 M + 1)到(N + 1, M + 1, Nx)作为我的生产代码中有大量的for循环,循环类似
j = 1: Nx
n = 1: n
m = 1: m
%,evenually做一些东西
f_n_m = (j n + 1, m + 1);
结束
结束
结束
j = 1: Nx
f_n_m = (j,:,);
结束
这可能是低效的指数j应该在第三列。有趣的是注意到,在此设置
M = 20;
N = 20;
Nx = 32;
Gnm =兰德(N + 1, M + 1, Nx);
Gnm_2 =兰德(Nx、N + 1 M + 1);
ntests = 10000;
%方法1
抽搐
2 = 1:ntests
n = 0: n
m = 0: m
f_n_m = Gnm (m + 1, n + 1:);
结束
结束
结束
toc
%的方法2
抽搐
2 = 1:ntests
n = 0: n
m = 0: m
f_n_m_2 = Gnm_2 (:, n + 1, + 1);
结束
结束
结束
toc
%方法2快,尽管它的大小(Nx、N + 1 M + 1)

登录置评。

答案(1)

西蒙•陈
西蒙•陈 2021年7月23日
编辑:西蒙•陈 2021年7月23日
循环找到可以完全取代系数:
new_coeff =排列(f_n_m [2 3 1]);
注意到new_coeff大小31 x31x32和new_coeff(:,: 1)相当于你的多项式系数j = 1。

类别

找到更多的在循环和条件语句帮助中心文件交换

s manbetx 845


释放

R2020a

社区寻宝

找到宝藏在MATLAB中央,发现社区如何帮助你!

开始狩猎!