How to put the second "for" loop inside the first one?
Afficher commentaires plus anciens
Hi,
I need to combine two "for" loops.
I actually need the second loop (c and t arrays) to pass through all the results from the first one (a and b). This means a total of 4 results, because the permutations of a and b would be 4.
I have combined them, but it does not work. The output is only 2 results, while they should be 4.
First loop:
close all; clc; clear all;
a = [1 2 3 4 5];
b = [1 2 3 3 5];
for i=1:5;
for j=1:5;
for k = ((i-1)*5)+ j;
line1 = ['set m1 ' num2str(c(i)) ';'];
line2 = ['set m2 ' num2str(s(j)) ';'];
line3 = ['set case ' num2str(t(k)) ';'];
fid=fopen('MatParam8.0.tcl','w');
fprintf(fid,'%s\n',line1);
fprintf(fid,'%s\n',line2);
fprintf(fid,'%s\n',line3);
fid=fclose('all');
!OpenSees Model.tcl
end
end
end
Second loop:
fin = 'result_all.txt';
s = dlmread(fin,'');
c=[1 2 3 4 5];
t=[1 2 3 4 5];
for j = 1:400;
fidP = fopen('Pulse.acc','w+');
fidC= fopen('Case.tcl','w+');
fprintf(fidP, '%d\n%d\n%d',c(j), s(j), t(j));
fprintf(fidC, 'set case %d',j);
fclose(fidP);
fclose(fidC);
!OpenSees Model.tcl
end
The combination:
close all; clc; clear all;
a = [1 2];
b = [1 2];
for i=1:2;
for j=1:2;
for k = ((i-1)*2)+ j;
line1 = ['set m1 ' num2str(a(i)) ';'];
line2 = ['set m2 ' num2str(b(j)) ';'];
line3 = ['set case ' num2str((k)) ';'];
fid=fopen('MatParam8.0.tcl','w');
fprintf(fid,'%s\n',line1);
fprintf(fid,'%s\n',line2);
fprintf(fid,'%s\n',line3);
fid=fclose('all');
fin = 'result_all.txt';
s = dlmread(fin,'');
c=[1 2];
t=[1 2];
for m = 1:4;
fidP = fopen('Pulse.acc','w+');
fidC= fopen('Case.tcl','w+');
fprintf(fidP, '%d\n%d\n%d',c(m), s(m), t(m));
fprintf(fidC, 'set case %d',j);
fclose(fidP);
fclose(fidC);
!OpenSees Model.tcl
end
end
end
end
16 commentaires
Bob Thompson
le 25 Fév 2019
I don't mean this to be offensive in any way, but do you understand how indexing within a for loop works? I have seen a number of your questions come up lately, and while we as a community are happy to help, it seems the bigger issue is teaching you how to index a loop, rather than how to specifically solve this problem. Does that make sense?
Ismail Qeshta
le 25 Fév 2019
Modifié(e) : Ismail Qeshta
le 25 Fév 2019
Bob Thompson
le 25 Fév 2019
Not a problem, we all had to learn at some point. I just think helping you learn how to index will help you learn to solve some of these questions on your own, so you don't have to keep waiting on us to respond.
Take a look at this tutorial, and let me know if you have questions. Then we can at least establish a baseline of what you do, or do not know.
Ismail Qeshta
le 25 Fév 2019
Modifié(e) : Ismail Qeshta
le 26 Fév 2019
Bob Thompson
le 25 Fév 2019
So, it is generally possible to do what you're asking, as Ex. 3 shows, but a more common method is to create the loop with an index of integers, and then index an array which contains the specific values. This can be useful whenever you are calling multiple arrays, or when you want to know how many times your loop has completed, or other counting functions.
A = [24,18,17,23,28];
for a = 1:length(A); % Integer indexes from 1 to the number of elements in A
disp(A(a))
end
Ismail Qeshta
le 26 Fév 2019
Modifié(e) : Ismail Qeshta
le 26 Fév 2019
Bob Thompson
le 26 Fév 2019
You can definitely use the numbers rather than length(), but if you ever change the size of a or b, then you have to manually change the index range of your loops. I personally got tired of doing that and have made a habit of making loop sizes reactive.
Ismail Qeshta
le 26 Fév 2019
Bob Thompson
le 26 Fév 2019
I'm going to focus on this loop:
c=[1 2];
t=[1 2];
for m = 1:4;
fidP = fopen('Pulse.acc','w+');
fidC= fopen('Case.tcl','w+');
fprintf(fidP, '%d\n%d\n%d',c(m), s(m), t(m));
fprintf(fidC, 'set case %d',j);
fclose(fidP);
fclose(fidC);
!OpenSees Model.tcl
end
You are definitely going to receive an error when executing the last two loops (m = 3 and m = 4) because you are calling c(m), which means you are looking at elements 3 and 4 of the c array. Because they don't exist, you get an error 'Index exceeds matrix dimentions.' I don't know if that's the specific error message you're getting, as you haven't posted a specific error message on this thread.
That aside, because you are looking to loop through two separate arrays, you really need two separate loops. If you look at the first set of loops you have you will notice there is one for a, and one for b. This is the 'safest' and simplest way of looping through two separate loops, and is generally your solution here.
Ismail Qeshta
le 26 Fév 2019
Modifié(e) : Ismail Qeshta
le 26 Fév 2019
Bob Thompson
le 26 Fév 2019
for i=1:2;
for j=1:2;
for k = ((i-1)*2)+ j;
line1 = ['set fc ' num2str(a(i)) ';'];
line2 = ['set fy ' num2str(b(j)) ';'];
line3 = ['set case ' num2str((k)) ';'];
fid=fopen('MatParam8.0.tcl','w');
fprintf(fid,'%s\n',line1);
fprintf(fid,'%s\n',line2);
fprintf(fid,'%s\n',line3);
fid=fclose('all');
!OpenSees Model.tcl
end
end
end
If you look at this portion of code you will notice that there are three separate callings of the 'for' loop command. One is indexed with i, one with j, and the last with k. This is what I mean by separate loops. Instead of having you internal loop, indexed with m, run from m = 1:4, break the loop apart into two separate loops to account for the different arrays c and t.
for m = 1:length(c)
for n = 1:length(t)
fidP = fopen('Pulse.acc','w+');
fidC= fopen('Case.tcl','w+');
fprintf(fidP, '%d\n%d\n%d',c(m), s(m*n), t(n));
fprintf(fidC, 'set case %d',j);
fclose(fidP);
fclose(fidC);
!OpenSees Model.tcl
end
end
Ismail Qeshta
le 26 Fév 2019
Bob Thompson
le 26 Fév 2019
I used s(m*n) with the intention of moving through all four elements of s. Ultimately, this was erroneous because it will produce [1 2 2 4] as its indexes instead of the desired [1 2 3 4]. Feel free to correct it as needed, as I haven't looked over the structure of s in detail.
Yes, replacing j with m will only produce the last two files, because m can only ever be [1 2]. I would suggest introducing a new counter within your code to produce individual outputs for each result calculated. This will also solve the indexing of s (if you want a different value for each loop).
count = 0; % Initialize
for m ...
for n ...
count = count + 1;
...
fprintf(fidP, '%d\n%d\n%d',c(m), s(count), t(n));
fprintf(fidC, 'set case %d',count);
...
end
end
Ismail Qeshta
le 26 Fév 2019
Modifié(e) : Ismail Qeshta
le 26 Fév 2019
Bob Thompson
le 26 Fév 2019
Nested loops work in such a way that for each of the outer loop runs, the entirety of the inner loop is performed. Suppose we have two loops, with indices x and y.
for x = 1:4;
for y = 1:2;
disp([x,y])
end
end
If you run that code you will notice the output begins with both x and y as 1, but on the next output of the disp x remains as 1 while y becomes 2. The inner loop is now complete, and the exterior loop can now proceed. So x becomes 2, and y resets to 1. The fourth row shows that both x and y are two. This continues until all iterations of the outer loop have been completed.
Alternatively, if you have for loops in a series, the first loop runs fully to completion, and then the second runs fully to completion.
x = 1; y = 1;
for x = 1:4;
disp([x,y])
end
for y = 1:2;
disp([x,y])
end
This produces a series of display outputs where x and y both start at 1 again, but on the second disp x will be 2, and y still 1. On the third x becomes 3, with y unchanged, and so on until the end of the first loop. The second loop then executes, and the first pass displays x as 4 and y as 1 a second time, before the final pass of the loop displays x as 4 and y as 2.
Does that help you understand better the difference between series and nested loops?
I would suggest that you need to use nested loops because you want to run your second loop each time you run your first loop.
Also, I would suggest moving count to before the beginning of the first loop (before for i = ...).
Ismail Qeshta
le 27 Fév 2019
Modifié(e) : Ismail Qeshta
le 27 Fév 2019
Réponses (0)
Catégories
En savoir plus sur Loops and Conditional Statements dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!