How can I save the matlab workspace in a structure?

I have a program that modifies a lot of variables in the workspace in every iteration. At the end of every iteration I need to check the old as well as the updated values of some of the variables in the workspace. Is there a way for me to do this by saving the current workspace in a structure and then comparing the current workspace with the structure?

 Accepted Answer

If a struct is really what you want, you can automatically generate statements to build the struct, using STRUCTVARS ( Download ).
>> a=1, b=2, c=3
a =
1
b =
2
c =
3
>> z=[who,who].'; myStruct=struct(z{:}); structvars(myStruct,0)
ans =
myStruct.a = a;
myStruct.b = b;
myStruct.c = c;
The idea is just to copy/paste the assignment commands into your mfile and update them as needed.

9 Comments

I need to do exactly the same, but instead of myStruct.a keeping the string "a", I want myStruct.a the actual value of a, which in your example is 1.
So, instead of this:
val =
myStruct.a = a;
myStruct.b = b;
myStruct.c = c;
I need this:
val =
myStruct.a = 1;
myStruct.b = 2;
myStruct.c = 3;
Thanks for your help!
Do you need help? You can do what you said, no problem. Just hard code in the numbers like 1,2,3 instead of using variables like a,b,c - just like you did.
By the way, "a" is not a "string". It's a "variable name", and in the structure it's a "field name".
@Dani,
I'm not seeing the difference between your request and the original proposal. Since a=1, the statements
myStruct.a = a;
and
myStruct.a = 1;
have the same effect when executed.
Well, the thing is that I am running an algorithm that calls a Simulink model several times changing some parameters and I need to save in every myStruct(j) all the parameters and outputs of every simulation. If a, b and c are changing every time, I have to save the value and not the variable.
There are quite a bit of variables, so it would be very helpful if I can do it automatically. Something like this:
for j = 1:num_simulations
set_param('simulink_model\Gain','Gain',num2str(j));
sim('simulink_model.slx');
myStruct(j) = workspace_vars;
end
I tired but I cannot figure out how to do this.
Thanks for your help!
Ok, found!
Here the way to assign the values of the variables instead of their names:
names = fieldnames(myStruct);
for j=1:length(names)
myStruct.(names{j}) = eval(myStruct.(names{j}));
end
Thanks guys for your tips! Working with arrays, cells and structures can be sometimes confusing. Does anyone know a good tutorial to learn when to use them and, specially, the use of ( ), [ ], and { }?
This is what confuses me, when to use ones or others.
Cheers!
Here the way to assign the values of the variables instead of their names:
It's a highly discouraged way of doing it. EVAL is hazardous and avoiding its use is one of the main reasons that I created the structvars tool in the first place. Your loop looks wrong, too. I think you really meant to write
for j=1:length(names)
myStruct.(names{j}) = eval(names{j});
end
But the motivation for this is still very doubtful. If names{j}='a' and 'a' is the name of 'a' variable in your workspace, it means you had to undertake the manual effort of defining 'a' explicitly. Why you'd rather avoid an additional explicit statement
myStruct.a=a
is quite befuddling, especially when structvars makes it so easy.
Yes, you are right about the correction of my code.
But well, a, b, and c are the results of a Simulink simulation. I want to run the simulink model 10 times with different parameters which will be giving different a, b, and c values. So I use the structure myStruct(1:10) to save the results of all these 10 simulations.
How should I do it to save the simulation results instead? I cannot think of another way of doing it.
I don't use Simulink, but I have a hard time seeing why, if you are able to execute,
myStruct.(names{j}) = eval(names{j});
you cannot just as easily, and at the same place in your code, execute
myStruct.a=a;
The two are absolutely equivalent when names{j}='a'. Obviously, you can do the same with all of your other variables.
@Dani Tormo: you really should avoid using eval for such a trivial thing as allocating values to a variable. Structures are perfectly capable of storing your values in a loop, and Matt J has shown you exactly how to do this. If you want robust code, learn to avoid eval:

Sign in to comment.

More Answers (3)

w = whos;
for a = 1:length(w)
str.(w(a).name) = eval(w(a).name);
end

1 Comment

Matt J
Matt J on 27 Feb 2019
Edited: Matt J on 27 Feb 2019
This solution was already discussed (and discouraged) here. Although, in hindsight, this is probably one of the safer applications of eval - no risk here of being shadowed by existing function names.

Sign in to comment.

Well, the cheesy and simple way to do it is,
S=load(save(dummyFilename));
However, I am somewhat skeptical that you're going down the right path with this. If all your variables are scalars, you should really be storing them concatenated in a vector and using vectorized functions to do all the comparisons.

2 Comments

No, all the variables are matrices.
You accepted an answer, so are you still having trouble or not? I'm guessing not.
By the way, I do this all the time. I put the status of all my GUI widgets into a structure called UserSettings, and then save that when the app exits. Then when the user runs the app again, I retrieve that and set up the GUI just the way it was the last time they ran it - all the same settings.

Sign in to comment.

You can save the variables in a structure
s.var1 = var1;
s.var2 = var2;
% Save to disk if you want
save(fullFileName, 's');
You can retrieve from disk, if you need to
s = load(fullFileName);
var1prior = s.var1;
var2prior = s.var2;
You can then compare variable by variable. I don't believe there is a way to compare a whole structure at once because each field can be vastly different data types.
if var1prior ~= var1
warndlg('var1 changed!');
end
if var2prior ~= var2
warndlg('var2 changed!');
end

Products

Asked:

on 1 Feb 2015

Edited:

on 27 Feb 2019

Community Treasure Hunt

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

Start Hunting!