How can I make my code repeat with out that many lines?

I'm having trouble to make some repetition structure... My English is a bit rusty but I'll try to describe it step by step... The code begins with
k = 1000;
c = 1000;
ms = 1000;
mus = 1000;
kus = 1000;
v = [30:10:120]/3.6;
Aqcar = [0 1 0 0;-k/ms -c/ms k/ms c/ms;0 0 0 1;k/mus c/mus -(k+kus)/mus -c/mus];
Bqcar = [0 0 0 kus/mus]';
Cqcar = [1 0 0 0; 0 1 0 0; 0 0 1 0;0 0 0 1];
Dqcar = 0;
qcar = ss(Aqcar,Bqcar,Cqcar,Dqcar);
So, in my code I have this step where I use the vallue 0.0254 to transform my preloaded (36x60001) randomarray measured in inches to meters.
vertical_perfs=vertical_perfs*0.0254
After that I repeat the same thing for all 36 lines making it separately, all the way to the 36th line and the problem begins here...
vertical_perf_1= vertical_perfs(1,1:60001);
vertical_perf_2= vertical_perfs(2,1:60001);
vertical_perf_3= vertical_perfs(3,1:60001);
vertical_perf_4= vertical_perfs(4,1:60001);
vertical_perf_5= vertical_perfs(5,1:60001);
vertical_perf_6= vertical_perfs(6,1:60001);
I'm doing it because there's a step further ahead where I need to find some "y" vallues.
Before I get the "y" vallues I need to make the step bellow
zroad_x1 = [0:0.0250:1500];
dx = zroad_x1(2) - zroad_x1(1) %results on 0.0250 meters
dx1 = linspace(dx,dx,length(v));
dt = dx1./v; %FEITO PELO LUCAS
temp0 = zeros(length(v),length(vertical_perf_1)) ; %(10x60001) zeros array
for j = 1:length(vertical_perf_1)
if j<=10
tempo(:,j) = 0:dt(j):(length(zroad_x1)-1)*dt(j); %(10x60001) array
else
break
end
end
All of that to find those "y" vallues... "y" is for the position that I'm gonna put the vallue in the graph later, "30" is the speed in km/h, and "p1" is the profile from "vertical_perf_1"... If I want to get the "vertical_perf_2" I would need to writhe all the 36 lines again but now the name would be "y40p1, y40p2..." al the way to y40p36.
y30p1 = lsim(qcar,vertical_perf_1,tempo(:,1),x0);
y30p2 = lsim(qcar,vertical_perf_2,tempo(:,1),x0);
y30p3 = lsim(qcar,vertical_perf_3,tempo(:,1),x0);
y30p4 = lsim(qcar,vertical_perf_4,tempo(:,1),x0);
y30p5 = lsim(qcar,vertical_perf_5,tempo(:,1),x0);
y30p6 = lsim(qcar,vertical_perf_6,tempo(:,1),x0);
I need to make the same for ALL SPEEDS, I did it but my code is now running on 455 lines because I have 36 profiles and 10 speeds, going from 30km/h, all the way to 120km/h.
How can I make this code smaller with some repetition structures???

6 Comments

Is this not what loops are designed to do?
By the way, it is a terrible idea to name dozens of variables with numbers in the names. LEARN TO USE ARRAYS!
Hi John, yes it is.
But whenever I try to make the loops the second step goes bad, I'm still learning.
zroad_x1 = [0:0.0250:1500];
dx = zroad_x1(2) - zroad_x1(1) %results on 0.0250 meters
dx = 0.0250
Why not write
dx = 0.0250; %results on 0.0250 meters
zroad_x1 = [0:dx:1500];
since you just defined what the difference between the two points will be...and this way you can just change the constant and not the code.
When you get down below, then
y30p1 = lsim(qcar,vertical_perf_1,tempo(:,1),x0);
y30p2 = lsim(qcar,vertical_perf_2,tempo(:,1),x0);
...
could be simply
[R,C]=size(vertical_perfs,1); % size of your array number rows, columns
y=zeros(R,C); % could also be zeros(size(vertical_perfs)) but need the size for the loop
for i=1:R
y(i,:)= lsim(qcar,vertical_perfs(i,:),tempo,x0);
end
" After that I repeat the same thing for all 36 lines making it separately, all the way to the 36th line and the problem begins here..."
Yes, the problem begins here. The specific problem is how you are forcing meta-data into variable names.
"I would need to writhe all the 36 lines again but now the name would be "y40p1, y40p2..." al the way to y40p36. "
Best avoided.
Fundamentally, computers are good a repeating very simple tasks in loops. So when you sit and copy-and-paste code like that you are just doing the computer's job for it.
"How can I make this code smaller with some repetition structures???"
Use arrays and indexing
  • Use the simplest data type which can reasonably hold your data, e.g. numeric vectors, matrices or ND arrays, cell arrays, structure arrays, tables, etc.
  • Don't be afraid to store your meta-data (e.g. speeds and profile numbers) in their own separate vectors.
  • Use indexing. Indexing makes it trivial to loop over array content.
  • Use operations on whole arrays (e.g. vectorized code) as much as possible.
Avoid your approach of forcing meta-data into variable names. That approach will only cause you problems.
@dpb thank you so much for the answer, I already tryed it a few months ago but every time it goes the same way...
It tells you exactly the problem -- you asked for only the row (first) dimension of the input variable but wrote the L(eft)H(and)S(ide) return expression expecting two ouputs.
Since you asked for only one output, size(x,1) sent back only one which is the incorrect number needed, which is two.
[R,C]=size(vertical_perfs);
presuming it is a 2D array.
Or, if you really do only care about the number of rows and the number of columns is immaterial here, then write
R=size(vertical_perfs);

Sign in to comment.

Answers (1)

Hi Brenno,
I understand that you are trying to avoid the repetitive operations on a large dataset. To make your code smaller and avoid repeating the same lines of code for each profile and speed, you can use loops to iterate over the profiles and speeds.
Please refer to the following code outline to proceed further,
k = 1000;
c = 1000;
ms = 1000;
mus = 1000;
kus = 1000;
v = [30:10:120]/3.6;
Aqcar = [0 1 0 0;-k/ms -c/ms k/ms c/ms;0 0 0 1;k/mus c/mus -(k+kus)/mus -c/mus];
Bqcar = [0 0 0 kus/mus]';
Cqcar = [1 0 0 0; 0 1 0 0; 0 0 1 0;0 0 0 1];
Dqcar = 0;
qcar = ss(Aqcar,Bqcar,Cqcar,Dqcar);
vertical_perfs = vertical_perfs * 0.0254;
zroad_x1 = [0:0.0250:1500];
dx = zroad_x1(2) - zroad_x1(1);
dx1 = linspace(dx, dx, length(v));
dt = dx1 ./ v;
temp0 = zeros(length(v), length(vertical_perfs));
y = cell(length(v), 1); % Cell array to store the y values
for i = 1:length(v)
tempo = zeros(length(v), length(zroad_x1));
for j = 1:length(vertical_perfs)
if j <= 10
tempo(:, j) = 0:dt(i):(length(zroad_x1)-1)*dt(i);
y{i}{j} = lsim(qcar, vertical_perfs(j, :), tempo(:, j), x0);
else
break;
end
end
end
In this modified code, I used nested loops to iterate over the profiles ('vertical_perfs') and speeds ('v'). The 'y' variable is now a cell array that stores the values for each profile and speed combination.
This approach significantly reduces the number of lines of code and avoids repeating the same lines for each profile and speed.
I hope this helps!

Categories

Find more on MATLAB in Help Center and File Exchange

Products

Release

R2023b

Asked:

on 20 Jan 2024

Answered:

on 30 Jan 2024

Community Treasure Hunt

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

Start Hunting!