I am trying to write a variable into a structure and read it from another existing structure:
struct1.vector = struct2.matrix(:,1);
when I run this line in my script it will create a double variable struct1. Thats why I will get the error:
Unable to perform assignment because dot indexing is not supported for variables of this type.
When I just run the same line in my Command Window it will create a struct variable struct1 just as I want to. Also there are multiple lines, where I try to write into struct1 and some times the first 4 lines work and the 5th doesn't.
I don't understand why the script is creating a double, can anybody help me with this?
Help is much appreciated, thank you.
That probably means that you already have a variable named struct1 in your workspace, either leftover from some previous activity, or assigned earlier in the script.
You can make sure you have a fresh workspace by calling clear before running your script. Better yet, turn your script into a function, and it will have its own workspace.
You can also replace the whole struct1 variable with a new empty struct, to make sure it's of the right type, before assigning to its fields.
struct1 = struct;
struct1.vector = struct2.matrix(:,1);
Related
I have a project consisting of multiple nested functions.
For debugging purpose I want to save all internal variables in one way or another, in order to display figures, replay parts of code etc...
I also want to keep this as transparent as possible regarding calculation time.
My first thought was to create a global variable, and store programmatically at the end of each function the inputs and outputs inside the variable as a structure :
globalVariable.nameOfParentfunction_NameOfFunction.nameInput1 = valueInput1;
globalVariable.nameOfParentfunction_NameOfFunction.nameInput2 = valueInput2;
...
globalVariable.nameOfParentfunction_NameOfFunction.nameOutput1 = valueOutput1;
...
Is it possible to use some kind of reflection to get the name and value of inputs/outputs without necessarily parse the file where the function is written?
I found a good but maybe outdated topic about parsing
How do I collect internal signals?
The simple solution is to use save, which will save all variables in the current workspace (the function’s context) to file.
If you want to keep the values in memory, not in a file, you can use names = who to get a list of all variables defined in the current workspace, then use val = eval(names{i}) to get the value of the variable called name{i}.
I would recommend putting all of that in a separate function, which you can call from any other function to store its variables, to avoid repeating code. This function would use evalin('caller',…) to get names and values of variables in the workspace of the calling function.
Note that using eval or evalin prevents MATLAB from optimizing code using its JIT. They also are dangerous to use, since they can execute arbitrary code, however in this case you control what is being executed so that is no a concern.
I have a a workspace called "parameters.mat", which contains many variables (really, constants) used by several methods throughout my simulation. The reason that I want these in one workspace is to have them in a handy place for the user to change.
I want to access these variables within class methods. I've found two ways of doing this, and I'd like to know which one is considered better (or perhaps if there's an even better way):
Load the workspace before anything else, as the base workspace, and whenever I want to use a variable from it within a method, I call evalin('base', 'variable_name') first.
Load the workspace within the method whenever I need it. This works,
but it gives me a warning when I use an undefined variable name in
the rest of the method (because MATLAB doesn't know it will be
loaded from a workspace). Is there a clean way to remove this warning?
Probably the cleanest way to do this is to use a wrapper function. Building on my comment, assuming your parameter constants are in a file parameters.mat:
function value = param(name)
s = load('parameters.mat');
value = getfield(s, name);
Now you can use a syntax like
var = param('name');
wherever you need the value of this variable. This way to do it is easily understandable to humans, and transparent to Matlab's code checker. You can also use param('name') directly in your computations, without assigning the value to a local variable.
If the parameter file contains more than just a few numbers, and loading it time after time slows down things, you can cache the data in a persistent variable:
function value = param(name)
persistent s
if isempty(s)
s = load('parameters.mat');
end
value = getfield(s, name);
Now the mat-file is read only on the first call to param(). The persistent variable s remains until the next clear all (or similar, see clear) or the end of the Matlab session. A drawback of this is that if you changed the mat-file, you have to clear all in order to make param() re-read it.
If on the other hand your mat-file does only consist of a few numbers, maybe a mat-file is not even necessary:
function value = param(name)
s.x0 = 1;
s.epsilon = 1;
s.dt = 0.01;
value = getfield(s, name);
With this approach the function param() is no longer a wrapper, but a central location where you store parameter values instead of a mat-file.
Is there a way to access data generated in one .m file from another. What I am trying to do is I have one .m call it A.m where I have loaded a large amount of data from a .txt file and broken it up into a structure with various fields. Since this takes up a large amount of space in the script I would like to create another .m file call it B.m, in which I can access the structure created in A.m and plot and perform calculations in B.m. So, basically I want to access a structure created in A.m from B.m. Is this possible?
-Thanks
There are some things to think of here. First, to limit scope, do not use scripts: use functions instead. Calling a script from another script mainly add code to the first script and have nothing to do with scope. However, by using this method, your code becomes hard to read and understand. If you want that all code to be in the same scope I would recommend you keep all the code in the same m-file.
A function however have a function scope and unless a variable is declared global it can only be passed into this scope by using function input arguments. Also, the only way to return values is to use function output arguments.
function [out1, out2,...] = myFun(in1,in2,...)
out1 = in1*in2;
out2 = in2.^2;
...
Now to the tricky part. The variable passed into the function is passed as "copy on write", meaning that the variables are always passed as a reference unless they are modified inside the script. When using structs, only the field that is modified is copied. This can have consequences for your program as well. Since you say your data is large, changing too many fields in the struct in the same function may cause memory overflow.
Anyway, if you only uses script you do not need to pass any data, since the scope is not affected. However, I recommend you to use functions and pass the struct as an input argument. If this was not what you asked for, please comment on this answer.
I have multiple vectors (+100) that have been loaded into MATLAB workspace, I would like to write a script that can plot and save them all, but for that I need their name, my question is: is there a way to automatically get the name vectors saved in the workspace.
thanks in advance.
Step one: whoever gave you a *.mat file with 100+ named variables in it, [censored for strong language and scenes some viewers may find upsetting]. I am only partly joking here; if you find yourself in this sort of situation normally it is because something has gone terribly wrong upstream. We can work around it, though.
Step two: use who with the filename to get a list of variables in that file
names = who('-file', 'all');
Step three: load the variables (or a subset of them) into a struct
data = load('all.mat');
Step four: use dynamic structure naming to extract data:
for n = 1:length(names);
plot(data.(names{n})); % or whatever you want to do with this data
end
I would probably just use the loop to dump the data in a cell array so as to make further processing simpler and avoid further use of dynamic field names or worse, eval.
You can use who, which lists all variables alphabetically in the active workspace.
I would like my Simulink Level 2 S function to sequentially run a series of test cases. Each test case populates a struct containing multiple numerical arrays.
I am currently trying to achieve the above in two steps:
Step 1: generate test cases using a M file, save to Workspace as an array of structs
Step 2: read the array of structs from the Workspace into my model, using a Level 2 M
file S function to process the test cases.
Step 2 is problematic for me, in that I cannot figure out a way to get the S-function block to accept the array-of-structs variable from the Workspace as input. I want to try avoiding the simin method (another Stackoverflow discussion, here), because it seems to require representing the entire structure as a single data column, and I would like to keep the struct intact. Also tried using a Constant block with the struct array as the variable name, but that returns an 'Invalid setting for blockname parameter Value' for the block.
Would appreciate any suggestions for getting this set up correctly. Also open to a different method of building the model, if absolutely necessary. Thanks!
EDIT: Realized that I can import the data within the S function M file itself, using load. This works for the purposes of my project. However, am still interested in knowing whether a conventional solution exists for this.
If you just want to access the workspace, I would consider using evalin(caller,'expression') inside you M-file S-function:
mystruct = evalin('base','MyStructFromWorkspace');
/* (process mystruct) */
It should also do the trick.