How to simplify this piece of code?

6 views (last 30 days)
I am working on implementing the PAC2002 Magic Formula on MATLAB, and while I was writing the code for computing all the matrices of the model, I noticed the computing time required was getting way too big. I know this is happening because of so many variables I'm using in order to compute these matrices, but I don't know how to make it simpler really. Let me show an example:
Thetax = zeros(length(sigmax),length(Bx),length(Ex));
for i = 1:1:length(sigmax)
for j = 1:1:length(Bx)
for k = 1:1:length(Ex)
Thetax(i,j,k) = Cx*atan(Bx(j,k)*sigmax(i,j)-Ex(i,j)*(Bx(j,k)*sigmax(i,j)-atan(Bx(j,k)*sigmax(i,j))));
end
end
end
where length(sigmax) = 201, length(Bx) = 10, length(Ex) = 10.
I should mention that sigmax, Bx and Ex are not just vectors, they are 2 dim matrices. But this didn't affect much the computing time. It was the last equation that really did. This equation in particular increased so much the computing time, from just a few seconds to a few minutes. Everyt time I had to compute a matrix, it would be depending on 2 variables, and so I'd use some code like this:
Svx= zeros(length(Fz),length(dfZ)):
for i = 1:1:length(Fz)
for j = 1:1:length(dfZ)
Svx(i,j) = Fz(i)*(PVX1+PVX2*dfZ(j))*LVX*LMUX;
end
end
The problem is that almost every independent variable in these equations is depending on other 2, making themselves 2nd dim matrices, and so I have lots of pieces of code in my script that look like the last equation. By the time I added the 1st equation, the computing time just went to the moon! Is there any way around this problem, that does not require calling so many fors?
Thank you.
  1 Comment
Adam
Adam on 25 Mar 2015
If you have 2d matrices I would not recommend using e.g.
length( sigmax )
You should use the size operator with an explicit dimension to avoid unwanted surprises in some cases.

Sign in to comment.

Accepted Answer

Roger Stafford
Roger Stafford on 25 Mar 2015
Edited: Roger Stafford on 25 Mar 2015
You are concentrating too much on getting rid of the for-loops. You should look for unnecessarily repeated operations, whether in for-loops or elsewhere. For example, in your second case the line
Svx(i,j) = Fz(i)*(PVX1+PVX2*dfZ(j))*LVX*LMUX;
requires five additions or multiplications for each step in the loops, a total of 5*length(Fz)*length(dfZ) operations. There is unnecessary repetition here. If you write it like
T = (PVX1+PVX2*dfZ)*(LVX*LMUX);
and then inside the loops:
for
for
Svx(i,j) = Fz(i)*T(j);
there is a total of only 3*length(dfZ) + 1*length(Fz)*length(dfZ) operations. By storing results in T, you have cut down the number of required operations.
Actually this code can be vectorized. Assuming, say, that Fz and dfZ are column vectors, you could write:
Svx = Fz*((PVX1+PVX2*dfZ)*(LVX*LMUX)).';
In the first code you might gain something by storing a temporary product:
t = Bx(j,k)*sigmax(i,j);
Thetax(i,j,k) = Cx*atan(t-Ex(i,j)*(t-atan(t)));
which cuts down the number of multiplications. However, the numerous calls on atan are what is taking the majority of execution time and I don't see a way of avoiding this.

More Answers (1)

Vicente
Vicente on 26 Mar 2015
Thank you for your prompt answer. I confess I'm a newbie on programming language. As I was reading your answer, already 2 hours after you posted it, I was thinking I would have never thought of separating the whole expression further more. The tire model's equations are already all broken down into smaller ones, and that is why I am writing here again. I had pretty much fixed all my worst long unnecessary codes, and managed to use one-dimensional matrices for most of the cases. Some cases were almost without a choice, I had to do a loop, or I wouldn't get the value correct. But anyway, I am now struggling with the last equation for this 1st part. Let me write it down:
Fxo = Dx*sin(Thetax)+Svx
It looks real simple. The problem is that Dx and Svx are now 2 1x10 vectors, while Thetax is a 10x10x201 3D matrix. Every matrix in this model depends at their very core on only 3 independent variables. But it is totally umpractical and counterproducive to try and express each of these terms as functions of these core variables, as I would need to put all broken down equations back together in one monstrous one! It would be about a third to half a page long.
So, I need 10 values in Dx, 10 values in Svx, and 20100 values in Thetax so that I can compute this little equation. I even thought of doing this:
for i = 1:1:length(Fz) % 10
for j = 1:1:length(gamma) % 10
for k = 1:1:length(Thetax(:)) % 20100
Fxo = Dx*sin(Thetax)+Svx
end
end
end
but I gave up this idea, because I actually need to know where goes what. I thought that if I did it like shown, I'd loose track of the 3 dimensions of Thetax, by clamping them all together in a very long Thetax vector. What can I do in this situation?
Thank you so much for your help.

Categories

Find more on Variable Initialization in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!