How to replace a "for loop" with vectorization?
Show older comments
Hi everyone, I have built in Simulink a user-defined function block for solving a set of algebraic nonlinear equations (with sine and cosine). It works alright. However, I used for loop to construct the equations, which is very slow when the system size increases. It takes up to one hour to solve a system consisting of 136 equations with a reasonable accuracy and step size. I have read that vectorizing can enormously speed up the simulation. I was not able to do so, however. Any help is greatly appreciated. This is my code (part of it):
function outt = DAE_Full01(x)
n=68;m=16;
%======= Defining the variables=====================
S=1;
for i1=1:m
Id(i1)=x(S);S=S+1;
end
for i2=1:m
Iq(i2)=x(S);S=S+1;
end
for i3=1:n
V(i3)=x(S);S=S+1;
end
for i4=1:n
TH(i4)=x(S);S=S+1;
end
%===End of defining the variables===============
%=== Construct the equations ================
for i6=1:m
SE1(i6,:)=Edp(i6)-V(i6)*sin(D(i6)-TH(i6))-Rs(i6)*Id(i6)+Xqp(i6)*Iq(i6);
SE2(i6,:)=Eqp(i6)-V(i6)*cos(D(i6)-TH(i6))-Rs(i6)*Iq(i6)-Xdp(i6)*Id(i6);
end
.
.
.
[xx ]=solve...
Where Rs, Xdp, Xqp are constant values. Id, Iq, Edp, Eqp, and D are inputs to the block (variables) with size m. x0 is a vector of initial values already defined. How one can replace the above for loop with vectorization form?
Accepted Answer
More Answers (1)
Hi,
You can find a good start to this topic in the link below.
You assign the decision variables x(1) ... x(168) in the 4 loops by increasing S successively. Instead you could omit S and take advantage of the known quantities of m and n like this:
Id(1:m)=x(1:m); % x(1) ... x(16)
Iq(1:m)=x(m+1:2*m); % x(17) ... x(32)
V(1:n)=x(2*m+1:2*m+n); % x(33) ... x(100)
TH(1:n)=x(2*m+1+n:2*m+2*n); % x(101) ... x(168))
I hope that's what you wanted to achieve in your code.
The equations below in the code should also work without the for loop:
SE1(1:m,:)=Edp(1:m)-V(1:m)*sin(D(1:m)-TH(1:m))-Rs(1:m)*Id(1:m)+Xqp(1:m)*Iq(1:m);
SE2(1:m,:)=Eqp(1:m)-V(1:m)*cos(D(1:m)-TH(1:m))-Rs(1:m)*Iq(1:m)-Xdp(1:m)*Id(1:m);
Since I could not test the code, I would be very grateful for any feedback as to whether it works. I have found that with every help that I offer here in the forum, I am learning and would be happy if you contributed with your feedback.
I would also be interested to know if you have seen an improvement in the performance of your code and how large it is.
Best regards
Stephan
10 Comments
Stephan
on 2 May 2018
Hi,
nice that i could help.
I'll think about this. But now I have to go to work. I probably will not come to this today - but I'll stick to it.
Best regards
Stephan
Ismaeel
on 2 May 2018
Hi,
i have some questions about the code, as I suspect there might be inconsistencies. Please help me to understand:
1.) sum1 & sum2 are scalars and should be scalars?
2.) after every run through the inner loop is finished your code says:
sum1(i6)=sum1
sum2(i6)=sum2
this will turn your scalar values for sum1 and sum2 into a vector which looks like this:
i6 = 1:
sum1 = [Value_of_sum1]
sum2 = [Value_of_sum2]
i6 = 2:
sum1 = [Value_of_sum1, Value_of_sum1]
sum2 = [Value_of_sum2, Value_of_sum2]
i6 = 3
sum1 = [Value_of_sum1, 0, Value_of_sum1]
sum2 = [Value_of_sum2, 0, Value_of_sum2]
i6 = 4
sum1 = [Value_of_sum1, 0, 0, Value_of_sum1]
sum2 = [Value_of_sum2, 0, 0, Value_of_sum2]
...
i6 = 16:
sum1 = [Value_of_sum1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Value_of_sum1]
sum2 = [Value_of_sum2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Value_of_sum2]
Is this what you wanted to do?
At the moment, this does not play a decisive role in the coding you are using because you also call this index in the formulas for PV1 and PV2:
PV1 (i6, :) = ... -sum1 (i6)
PV2 (i6, :) = ... -sum2 (i6)
If I understood that correctly, you calculate the scalars sum1 and sum2 over 68 loop passes in the inner loop. Repeat this procedure 16 times with the outer loop, with the summations sum1 and sum2 starting again from zero. With these scalars you go into the calculation of the values for PV1 and PV2, where each one comes out a vector that is 16x1 large.
If that was really understood by me, you could therefore consider the sums sum1 and sum2 independently of the rest of the calculation and represent the sums as two vectors, each 16x1 large and can be traversed in the calculation of PV1 and PV2 , I suspect that is also thought so. Currently this does not happen in the form - see above.
Before it makes any sense to continue thinking about the vectorization, I want to understand the whole and to eliminate possible errors that are contained.
Please try to explain it to me clearly.
Best regards
Stephan
Ismaeel
on 2 May 2018
Stephan
on 2 May 2018
Hi,
there is already progress in vectorizing your code, but I'm not quite finished yet. At the same time, the topic described by me on sum1 and sum2 as a "waste product" is also solved. I'll take a look at the files and also delete them when I do not need them anymore.
Best regards
Stephan
Stephan
on 3 May 2018
Hi,
I'm done, but I'm still not satisfied with the result. I have generated needed matrices and vectors by means of a random generator and then saved these values as a .mat file. It turns out that the vectorized code does not run faster, or even slower, to be precise. I'm amazed about that and would like to understand why that is. I am also considering whether to post these two code snippets together with my .mat file as a question here in the forum, because it can be that the very experienced power users here can solve this new unexpected problem - provided you agree. I had not expected such a result. First, I'll see if I can find a solution myself.
Best regards
Stephan
Ismaeel
on 3 May 2018
Hi,
i could find the issue... the sums sum1 and sum2 work fine now. i saved about 50% calculation time for the loops for the m=68 and n=16 dimensions. Excited to hear about the runtime behavior for larger problems.
This works for both sums, but still i have to look at the PV values.
The matrices and vectors i have made are only for comparision of the results with your formulas to eliminate possible errors that i could have made. If my calculation brings the same values as your calculation i made no errors. I guess that should work for this purpose.
I keep you updated ;-)
Best regards
Stephan
Categories
Find more on Loops and Conditional Statements in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


