我正在从事线性模型预测控制,需要为控制器计算一些矩阵,但其中一个矩阵的计算时间很长,我想问一下是否有更好的编码方式来计算它。我正在使用MATLAB,但我也了解FORTRAN。
我想计算一个矩阵(Φ),但我现在的方法计算它需要太长时间。Φ矩阵的形式如下(右边那个):MPC_matrices.
这里是我找到这张图片的书籍,如果需要参考可以看看第8页。
现在我在MATLAB中编写的代码如下:(移动到EDIT之后)
考虑到我的NS、Np和Nc变量会非常大,这个计算过程会花费很长时间。有没有更优化的方法(或者至少比我的方法更好)来加速这个计算过程呢?
这是生成的图形:
请记住,现在
结果 很明显,我的最初想法只比这里建议的稍差一点..谢谢大家!你们非常有帮助!
我想计算一个矩阵(Φ),但我现在的方法计算它需要太长时间。Φ矩阵的形式如下(右边那个):MPC_matrices.
这里是我找到这张图片的书籍,如果需要参考可以看看第8页。
现在我在MATLAB中编写的代码如下:(移动到EDIT之后)
考虑到我的NS、Np和Nc变量会非常大,这个计算过程会花费很长时间。有没有更优化的方法(或者至少比我的方法更好)来加速这个计算过程呢?
EDIT
在考虑了@Daniel和user2682877的评论后,我测试了以下内容:
clear;clc
Np = 80;
Nc = Np / 2;
m = 3;
q = 1;
Niter = 30;
MAT = zeros(Niter,5);
for I=1:Niter
NS = 10 * I;
A = rand(NS,NS);
B = rand(NS,m);
C = rand(1,NS);
tic
Phi1 = zeros(Np*q,Nc*m);
CB = C * B;
for i=1:Np
for j=1:Nc
if j<i
Phi1( (q*i-(q-1)):(q*i) , (m*j-(m-1)):(m*j) ) = C * A^(i-1-(j-1)) * B;
elseif j==i
Phi1( (q*i-(q-1)):(q*i) , (m*j-(m-1)):(m*j) ) = CB;
end
end
end
t1 = toc;
% 丹尼尔的建议
tic
Phi2=zeros(Np*q,Nc*m);
CB = C * B;
for diffij=0:Np-1
if diffij>0
F=C * A^diffij * B;
else
F=CB;
end
for i=max(1,diffij+1):min(Np,Nc+diffij)
j=i-diffij;
Phi2( (q*i-(q-1)):(q*i) , (m*j-(m-1)):(m*j) ) = F;
end
end
t2 = toc;
% user2682877 的建议
tic
Phi3=zeros(Np*q,Nc*m);
temp = B;
% 1st column
Phi3( (q*1-(q-1)):(q*1) , (m*1-(m-1)):(m*1) ) = C * B;
for i=2:Np
% reusing temp
temp = A * temp;
Phi3( (q*i-(q-1)):(q*i) , (m*1-(m-1)):(m*1) ) = C * temp;
end
% remaining columns
for j=2:Nc
for i=j:Nc
Phi3( (q*i-(q-1)):(q*i) , (m*j-(m-1)):(m*j) ) =...
Phi3( (q*(i-j+1)-(q-1)):(q*(i-j+1)) , (m*1-(m-1)):(m*1) );
end
end
t3 = toc;
MAT(I,:) = [I, NS, t1, t2 ,t3];
fprintf('I iteration = %g \n', I);
end
figure(1)
clf(1)
hold on
plot(MAT(:,2),MAT(:,3),'b')
plot(MAT(:,2),MAT(:,4),'r')
plot(MAT(:,2),MAT(:,5),'g')
hold off
legend('My <Unfortunate> Idea','Daniel`s suggestion','user2682877 suggestion')
xlabel('NS variable')
ylabel('Time, s')
这是生成的图形:
![enter image description here](https://istack.dev59.com/59lyC.webp)
NS = 300
,但当我升级我的模型(我打算在状态空间模型中包含越来越多的方程和变量)时,这些变量(主要是NS和Np)将越来越大。
关于@Daniel的第二个评论,我知道我执行的计算比我应该执行的计算多,但我的经验不足限制了我对升级的想法。
关于@durasm的评论,我不太熟悉parfor,但我会测试它。
关于答案:只要我理解了你们的建议,我会尽快测试并回复你们。结果 很明显,我的最初想法只比这里建议的稍差一点..谢谢大家!你们非常有帮助!
NS=100; m=99; A = rand(NS,NS); B = rand(NS,m); C = rand(1,NS);
但这并没有初始化所有内容。 - Danielj<i
,C * A^(i-1-(j-1)) * B
只有Np
种不同的结果,但你却大约计算了Np*Nc/2
次。 - DanielPhi
,还有一点问题是用户2682877的解决方案没有填满完整的矩阵。 - Daniel