Vectorization of matrix multiplication with scalar (Scalar is value of other matrix at index i) and expm() operation
1 次查看(过去 30 天)
显示 更早的评论
Hi,
I can't seem wrap my head on vectorizing a for loop in my MATLAB code. Basically, I have this code:
% Let that:
%Tp = scalar
%N, = scalar (Say 1000)
%Ac, = 4x4 matrix
%pre = 1x4 matrix
%post = 4x2 matrix
%wy1 = N+1x1 matrix (so it would be 1001*1)
%wy2 = N+1x1 matrix (so it would be 1001*1)
% preallocate
delta_ksi=Tp/N;
AcT =Ac';
sum_matrix=zeros(4,1);
Fl=zeros(4,1);
% calculate the sum
for i=1:N
Fl=delta_ksi*expm(AcT*delta_ksi*i)*post*[wy1(1,i); wy2(1,i);];
sum_matrix= sum_matrix+Fl;
end
%value I need
delta_f_des_ff= pre*sum_matrix;
What I have in mind is to construct a 3D matrix Fl_3D (4 x 1x 1000) and then do array multiplication with i = 1:1000, but I kept getting incompatible dimension error when multiplying with [wy1(1,i); wy2(1,i)] which also use the index i.
Any clue on what is the best approach to do this? Is vectorization still possible? Thanks!
Background:
- I am trying to troubleshoot a bottleneck code in a Simulink project. Code Profiling shows that the above function hogging most of the runtime.
- I am hoping vectorizing could solve the performance issue. I also just found out the bottleneck comes from expm() operation.
Any suggestion are welcomed!
0 个评论
采纳的回答
Robert
2016-8-10
I don't think this problem is well suited for vectorization since you are already doing matrix multiplication at each iteration of the loop; however, you can get a very nice speedup by taking the expm call outside of the loop.
Using the property e^(aX) = (e^X)^a you can refactor your code to calculate
E = expm(AcT*delta_ksi);
before the loop and use
E^i
in place of
expm(AcT*delta_ksi*i)
in your loop.
Since you are calculating consecutive exponents, why not do the multiplication yourself for an extra speedup?
E0 = expm(AcT*delta_ksi);
E1 = eye(4);
% calculate the sum
for ii = 1:N
E1 = E0*E1;
Fl = E1*post*[wy1(1,ii); wy2(1,ii);];
sum_matrix = sum_matrix+Fl;
end
Bonus suggestion, ii makes a good loop variable name when you want something short because it doesn't conflict with the complex variable i.
2 个评论
Robert
2016-8-15
编辑:Robert
2016-8-15
I should have been more clear about that. I am using eye(4) as the zero-th value of E1. That way, when I multiply E1 (the Identity Matrix) by E0 for the first time, I get the value of E0 back.
In this way, E1 always equals E0^ii.
ii E1
__ _____
0* eye(4)
1 E0*eye(4)
2 E0*E0*eye(4)
3 E0*E0*E0*eye(4)
4 E0*E0*E0*E0*eye(4)
...
n E0^ii
* before the loop
Now that I think about it, using 1 would probably be more clear and even easier. We just need some initial value for E1 that won't affect the results inside the loop.
So now it looks like:
E0 = expm(AcT*delta_ksi);
E1 = 1; % a dummy initial value
% calculate the sum
for ii = 1:N
E1 = E0*E1; % E1 = E0^ii
Fl = E1*post*[wy1(1,ii); wy2(1,ii);];
sum_matrix = sum_matrix+Fl;
end
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Arithmetic Operations 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!