Dynamic Assign Field Access in MATLAB Structures

I have a MATLAB structure called `parameters` containing various fields such as `xl`, `xu`, `error_criterion`, `Cd`, `relative_error`, and `velocity_target`. I'd like to achieve dynamic access to these field values for further processing without manually specifying each field.
Like in my function I want to reasighn the value of Cd = parameters.Cd, relative_error = parameters.relative_error and so on for every single field in the struct in a for loop. How would I be able to go throug with this?
Here's an example of what I've implemented:
function myFunction(parameters)
% Dynamically access structure field values
fieldNames = fieldnames(parameters);
for i = 1:length(fieldNames)
fieldName = fieldNames{i};
fieldValue = parameters.(fieldName);
% Further processing based on 'fieldValue'
end
% Rest of the code
end
Main Script:
function main(parameters)
% Access the variables using the field names in the structure
xl = parameters.xl;
xu = parameters.xu;
error_criterion = parameters.error_criterion;
Cd = parameters.Cd;
relative_error = parameters.relative_error;
velocity_target = parameters.velocity_target;
% Call the function with the structure as an argument
myFunction(parameters);
end
---

2 Comments

"I want to reassign the value of Cd = parameters.Cd, relative_error = parameters.relative_error and so on"
Why do you want to do that? Just leave them in the structure and use them from there.

Sign in to comment.

Answers (1)

clear
s=struct('a',1,'b',2,'c',3)
s = struct with fields:
a: 1 b: 2 c: 3
% this is a dirty command that pops the field values to the workspace
cellfun(@(f) assignin('caller',f,s.(f)), fieldnames(s));
whos
Name Size Bytes Class Attributes a 1x1 8 double b 1x1 8 double c 1x1 8 double s 1x1 528 struct
a
a = 1
b
b = 2
c
c = 3

7 Comments

Notes that Bruno Luong forgot to mention: dynamically accessing variable names like this forces you into writing slow, complex, inefficient code that is harder to debug. You should simply access the data from the structure.
@Stephen23 Hard to debug yes! Slower? actually no if you access a lot to structure fields:
s=struct('a',1,'b',2,'c',3);
t_fieldaccess = timeit(@()fieldaccess(s),1),
t_fieldaccess = 0.0646
t_pop_varaccess = timeit(@()pop_varaccess(s),1),
t_pop_varaccess = 6.1885e-04
fprintf('t_pop_varaccess is %g time faster than t_fieldaccess\n', t_fieldaccess/t_pop_varaccess)
t_pop_varaccess is 104.334 time faster than t_fieldaccess
function x = fieldaccess(s)
for k=1:1e6
x = s.a + s.b + s.c;
end
end
function x = pop_varaccess(s)
cellfun(@(f) assignin('caller',f,s.(f)), fieldnames(s));
for k=1:1e6
x = a + b + c;
end
end

Slower:

  • In actual fact the total time (runtime + debugging + documentation + asking for help on random internet forums + downtime + etc) has most likely already far exceeded the time which would be required for accessing the structure fields directly.
  • Accessing the structure fields is unlikely to be the slowest part of the code: unless the OP is distributing highly optimized code the dynamic variable name approach has already consumed more time than it could save.
  • Also note that your timing is comparing apples with oranges: I did not write that the fields need to be accessed inside a loop, that is your own inefficient design. Try extracting the fields before the loop and post the times here.
"Try extracting the fields before the loop and post the times here."
I will not. Minus the extra time to do assignin (that goes again the comparison timing result) it clearly shows accessing local variable is 100 time faster, the for-loop just amplifies the effect to avoid jitter noise, but the ratio is accurate. You shoud know it very well.
Reading Voss statement "Just leave them in the structure and use them from there" that you backup it seems you want to keep field access everywhere including inside the loop? Or do I read it wrong?
Furthermore accessing structure fields inside the loop as in my benchmark code is entirely possible usecase in production code and very likely happens. I use structure to pass parameters all the time and this usecase is not rare.
I prefer method of first manually put fields to a local variables and work directly with these local variables. Why? because it is faster and mainly because the code is shorter and one can see clearer what operations are performed instead of the dot syntax that make the code less readable.
OP wants to unbunked the fields automatically this is a legitimate request. I provide the way to achive that and clearly note that is "dirty" (myself I would never do that way).
My benchmark an edge case to show mainly accessing times (that is THE purspose of benchmark code) but completely valid and demonstrates that accessing with dot syntax is slower which is to show that the claim for the opposite is not correct. The fact is there, no need to further debate around it IMO.
The advantages or disadvantages of the programming pattern has been put forward. Do I need to to be "right" on recommending the usage of it or avoid it? I really don't care.
Each programmer is free to do whatever he/she likes. It's not my intention to to give a lesson to anyone, I give the recipe who ever wants it will cook and eat it, even if it is not entirely healty food.
“. . . that you backup it seems you want to keep field access everywhere including inside the loop? Or do I read it wrong?“_
Yes, you read it wrong: I would not use or recommend that _everywhere_. I would not assume or write code using the same paradigm in every situation: code the gets run _once_ is quite a different matter to writing code that runs millions of times in a loop. The original advice is perfectly sound, until the OP gives more context. Writing simple advice that conveys the many factors is beyond the scope of one sentence, but that is expected on any help forum: start general and get more specific as information is provided during the discussion.
“(myself I would never do that way)“
!!! Worth quoting :)
Your refusal to time the (most likely) most efficient approach is curious, given that the bulk of your comments are about timing.
"Your refusal to time the (most likely) most efficient approach is curious, given that the bulk of your comments are about timing."
Again my code is perfectly fair as I explained.
If you want to show some aspect of whatever you defense, please make a code and post it. It is not my job sorry.
I have reached a (partial) conclusion with my test code results, actually it surprises me because in the pass I remember (wrongly) that puffed varables cannot be subjected of JIT accelerator, and obviously in my test shows that it can and very well (not sure I want to go back and check with older version of MATLAB whereas this behavior has changed.)
With that in mind I might reconsider that I would use the puffed recipe assignin in the future as OP request here.
"The original advice is perfectly sound,"
IMO no, if it depends the context then one should ask the context before giving out this general advise. The fault is shared, and mostly yours. OP cannot know the appropriate advise is context dependent, you know it, and clearly did not tell it. I read it wrong because it is wrong.
s=struct('a',1,'b',2,'c',3);
timeit(@()field_access(s),1)
ans = 5.4982e-04
timeit(@()pop_varaccess(s),1)
ans = 6.1182e-04
function x = field_access(s)
a = s.a;
b = s.b;
c = s.c;
for k = 1:1e6
x = a + b + c;
end
end
function x = pop_varaccess(s)
cellfun(@(f) assignin('caller',f,s.(f)), fieldnames(s));
for k = 1:1e6
x = a + b + c;
end
end

Sign in to comment.

Categories

Asked:

on 28 Sep 2023

Commented:

on 3 Oct 2023

Community Treasure Hunt

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

Start Hunting!