for-loop over Structure Array

191 views (last 30 days)
Hannes Stagge
Hannes Stagge on 11 Feb 2020
Commented: Stephen23 on 12 Oct 2022
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!
  1 Comment
KSSV
KSSV on 11 Feb 2020
You should attach your dataset files also.

Sign in to comment.

Accepted Answer

Stephen23
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
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
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
. .. file1.mat file2.mat file3.mat
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)
S = 1×3 struct array with fields:
X Y
% 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.
S = 1×3 struct array with fields:
X Y
% 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)
S = 3×1 struct array with fields:
name folder date bytes isdir datenum X Y
% 4. On one line (some people like this kind of thing).
S = arrayfun(@(n)load("file"+n+".mat"), 1:N)
S = 1×3 struct array with fields:
X Y

Sign in to comment.

More Answers (0)

Categories

Find more on Function Creation in Help Center and File Exchange

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!