How to Simplify Passing Multiple Arguments from Structs in MATLAB Function Calls?

7 views (last 30 days)
am working on a MATLAB project where I need to pass multiple arguments from two structs (n and d) to a function called mi_decode. Currently, I am passing each field individually, which makes the code quite verbose and hard to maintain. Here is a snippet of my current code:
function results = spectral_mi(labels, data, n, d)
d.pl_ u int8
d.prr_k cell
d.is_cnrm logical = true
d.is_chk logical = true
d.is_fbk logical = true
d.is_x logical = false
d.is_pl logical = false
d.is_prr logical = false
n.cl uint16 = numel(unique(labels))
n.t uint8 = size(data{1}, 2)
n.k uint8 = numel(data)
n.trials uint8 = numel(labels)
n.f uint8 = fix(size(data{1}, 2)/2)+1
n.pl uint16
% ... other code ...
pow_per_f = cell(1, n.f);
phase_per_f = cell(1, n.f);
for f = 1:n.f
pow_per_f{f} = squeeze(power(abs(st_data(:, f, :)), 2));
phase_per_f{f} = squeeze(angle(st_data(:, f, :)));
end
[mi_, zmi_, pmi_] = mi_decode( ...
labels, pow_per_f{:}, ...
"is_x", d.is_x, ...
"t", n.t, ...
"k", n.f, ...
"pl", n.pl, ...
"is_cnrm", d.is_cnrm, ...
"is_chk", d.is_chk, ...
"is_fbk", d.is_fbk, ...
"is_pl", d.is_pl, ...
"is_prr", d.is_prr);
[phase_mi_, phase_zmi_, phase_pmi_] = mi_decode( ...
labels, phase_per_f{:}, ...
"is_x", d.is_x, ...
"t", n.t, ...
"k", n.f, ...
"pl", n.pl, ...
"is_cnrm", d.is_cnrm, ...
"is_chk", d.is_chk, ...
"is_fbk", d.is_fbk, ...
"is_pl", d.is_pl, ...
"is_prr", d.is_prr);
end
Is there a more concise way to pass all the fields from the structs n and d to the mi_decode function without listing each field individually? Any suggestions or best practices for handling this in MATLAB would be greatly appreciated.
  3 Comments
Ludwig
Ludwig on 10 Feb 2025
Edited: Ludwig on 10 Feb 2025
How would this be done in practice? @Stephen23
If I'd try to pass the whole struct:
[mi_, zmi_, pmi_] = mi_decode( ...
l_, pow_per_f{:}, "d", d, "n", n);
I get:
"Invalid argument at position 117. Value must be of type double or be convertible to double."
The whole argument list is:
arguments
l_ (:, 1) uint8
end
arguments (Repeating)
rr_k double
end
arguments
d.pl_ uint8
d.prr_k cell
d.is_cnrm logical = true
d.is_chk logical = true
d.is_fbk logical = true
d.is_x logical = false
d.is_pl logical = false
d.is_prr logical = false
n.cl uint16 = numel(unique(l_))
n.t uint8 = size(rr_k{1}, 2)
n.k uint8 = numel(rr_k)
n.trials uint8 = numel(l_)
n.f uint8 = fix(size(rr_k{1}, 2)/2)+1
n.pl uint16
end
Stephen23
Stephen23 on 10 Feb 2025
Edited: Stephen23 on 10 Feb 2025
"How would this be done in practice?"
You would have to rewrite the function to accept those scalar structures as inputs.
Note that INPUTPARSER can do this:
or you could write the function itself to accept those structures and refer to their fields, exactly like spectral_mi is.

Sign in to comment.

Answers (1)

Matt J
Matt J on 10 Feb 2025
Edited: Matt J on 11 Feb 2025
You can use namedargs2cell and comma-separated list expansion to pass multiple name-value pairs,e.g.,
function main(struct_n,struct_d)
cell_n=namedargs2cell(struct_n);
cell_d=namedargs2cell(struct_d);
someFunction(cell_n{:},cell_d{:});
end
function someFunction(n,d)
arguments
n.cl uint16
n.t uint8
n.k uint8
n.trials uint8
n.f uint8
n.pl uint16
d.pl_u int8
d.prr_k cell
d.is_cnrm logical = true
d.is_chk logical = true
d.is_fbk logical = true
d.is_x logical = false
d.is_pl logical = false
d.is_prr logical = false
end
...
end

Categories

Find more on Atomic, Molecular & Optical in Help Center and File Exchange

Products


Release

R2024b

Community Treasure Hunt

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

Start Hunting!