for-loop over Structure Array
191 views (last 30 days)
Show older comments
Hello together,
I am currently working with multiple experimental datasets containing velocitys of different fluid components and pressure losses. One of those datasets is contained in a structure with fields containing the experimental data as arrays.
My task ist to calculate the same dimensionless numbers for every dataset from the presure losses, densities, velocities, etc. I have written a loop over all structures grouped to an array, however calculations are only saved to the index (i) of the loop , not to the original structures in the array. So only the last calculation is saved. I suspect the calculations are running correctly inside the loop but don't get saved to the right output structure.
Code:
A=load('dataset1.mat'); %saved workspace with dataset1
B=load('dataset2.mat'); %saved workspace with dataset2
% and so on
A.vel1 %returns 15x1 double
A.vel2 %returns 15x1 double
B.vel1 %returns 24X1 double
B.vel2 %returns 24x1 double
A.rho=997; %additional data
B.rho=876;
%and so on
for i=[A,B]: %loop over all datasets
i.f1=i.rho*i.vel1;
%and so on
end
A.f %Error: Reference to non-existent field 'f'
B.f %Error: Reference to non-existent field 'f'
i.f %returns 24x1 double with right values B.rho*B.vel1
Can anybody exlpain to me, why this happens and how I can fix it, so that all calculations are computed and saved in A and B?
Thank you for your help!
Accepted Answer
Stephen23
on 11 Feb 2020
Edited: Stephen23
on 11 Feb 2020
"Can anybody exlpain to me, why this happens"
Because MATLAB is (as far the end-user is concerned) pass-by-value and not pass-by-reference as you are trying to use it. So when you change the structures in the loop you change the ones in the loop only... but this is totally irrelevant to A and B.
"how I can fix it"
The usual solution is to use indexing. This would be the standard, efficient MATLAB approach:
S(1) = load('dataset1.mat'); % note how indexing makes this trivial in a loop!
S(2) = load('dataset2.mat'); % note how indexing makes this trivial in a loop!
...
for k = 1:numel(S)
S(k).f1 = S(k).rho * S(k).vel1;
end
Importing into separate structures with names A, B, etc. is not recommended and is unlikely to allow efficient handling of your data. It looks like you are trying to write code based on what you know of some other language, but this is rarely a good approach to writing MATLAB code.
3 Comments
Goncalo Costa
on 12 Oct 2022
Can a for loop be created for the indexing? Something like
for x = 1:4
S(x)= load('dataset(x).mat')
end
I know this is wrong but I am trying to achieve it, and I don't know how.
Stephen23
on 12 Oct 2022
"Can a for loop be created for the indexing?"
Here are several approaches. First lets create some fake data:
X = 1;
Y = 'hello';
save file1.mat X Y
X = 22;
Y = 'happy';
save file2.mat X Y
X = 333;
Y = 'world';
save file3.mat X Y
% check files
clearvars
dir
N = 3;
% 1. Simple but not very robust, assumes S does not exist in workspace.
for k = 1:N
F = sprintf('file%u.mat',k);
S(k) = load(F);
end
display(S)
% 2. Robust if the MAT files contain different variables.
C = cell(1,N);
for k = 1:N
F = sprintf('file%u.mat',k);
C{k} = load(F);
end
S = [C{:}] % however this works only if the fields are the same.
% 4. Using DIR (note the file order might not be what you expect).
S = dir('*.mat');
for k = 1:numel(S)
T = load(S(k).name);
S(k).X = T.X;
S(k).Y = T.Y;
end
display(S)
% 4. On one line (some people like this kind of thing).
S = arrayfun(@(n)load("file"+n+".mat"), 1:N)
More Answers (0)
See Also
Categories
Find more on Function Creation 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!