Collect internal variables of nested functions in matlab - matlab

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.

Related

Exploit Matlab copy-on-write by ensuring function arguments are read-only?

Background
I'm planning to create a large number of Matlab table objects once, so that I can quickly refer to their contents repeatedly. My understanding is that each table variable/column is treated in copy-on-write manner. That is, if a table column is not modified by a function, then a new copy is not created.
From what I recall of C++ as of 1.5 decades ago, I could ensure that the code for a function does not modify its argument's data by using constant-correctness formalism.
The specific question
I am not using C++ in these days, but I would like to achieve a similar effect of ensuring that the code for my Matlab function doesn't change the data for selected arguments, either inadvertently or otherwise. Does anyone know of a nonburensome way to do this, or just as importantly, whether this is an unrealistic expectation?
I am using R2015b.
P.S. I've web searched and came across various relevant articles, e.g.:
http://www.mathworks.com/matlabcentral/answers/359410-is-it-possible-to-avoid-copy-on-write-behavior-in-functions-yet
http://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data
(which I need clarification on to fully understand, but it isn't my priority just now)
However, I don't believe that I am prematurely optimizing. I know that I don't want to modify the tables. I just need a way to enforce that without having to go through contortions like creating a wrapper class.
I've posted this at:
* Stack Overflow
* Google groups
There is no way of making variables constants in MATLAB, except by creating a class with a constant (and static?) member variable. But even then you can do:
t = const_table_class.table;
t(1,1) = 0; % Created and modified a copy!
The reason that a function does not need to mark its inputs as const is because arguments are always passed by value. So a local modification does not modify data in the caller’s workspace. const is something that just doesn’t exist in the MATLAB language.
On the other hand, you can be certain that your data will not be modified by any of the functions you call. Thus, as long as the function that owns the tables does not modify them, they will remain constant. Any function you pass these tables to, if they attempt to modify them, they will create a local copy to be modified. This is only locally a problem. The memory used up by this copy will be freed upon function exit. It will be a bug in the function, but not affect code outside this function.
You can define a handle class that contains a table as it's preperty. Define a property set listener that triggers and generates error/warning when the value of the property changes.
classdef WarningTable < handle
properties (SetObservable)
t
end
methods
function obj = WarningTable(varargin)
obj.t = table(varargin);
addlistener(obj,'t','PreSet',...
#(a,b)warning('table changed!'));
end
end
end
This should generate warning:
mytable = WarningTable;
mytable.t(1,1) = 0;

Define a variable and use it in all sub-function on Matlab

Is there any way to define a variable in main function and use it in all sub-function.
I've tried to declare variables as global but it seems I should repeat it in all function again. I'm wonder what's the benefit of global variable at all!
use variable as global:
main program
global x
syms x
subfunc1
subfunc2
...
and
subfunc1
global x
and
subfunc2
global x
(maybe this format remind us to have global variable in function but it was better to cause error if we use same name of variable in function same as Matlab keywords)
I don't want to import the variable as all function argument and don't want to declare that variable in all function again and again.
any help would be appreciated.
If you really want to have access to the same variable, then there are only two ways I know of in Matlab:
nested functions(described by answer from #justthom8) and global variables. Other methods of getting data into functions exist, such as getappdata, guidata and (my personal favorite:) passing function arguments. However, these approaches make copies of variables.
Perhaps you should ask yourself why you want to avoid making copies of variables. If you are worried about performance, you should know that Matlab efficiently use variables as reference to data only, so you can safely send a variable in to a function (thereby copying the variable) without copying the actual data. its first after you modify the data inside of the function that the data is actually copied. All this is totally invisible to us, except as a possible drop in performance during alot of copying. This is called copy-on-write.
Global variables can be used to optimize Matlabs performance, by coding them in such a way as to avoid copying data, but that really requires knowing what you are doing, and it opens up for a whole lot of pitfalls, especially if your projects grow in size.
One thing you can do is define the other functions as subfunctions of the main function. Something like below
Both of the functions subFunc1 and subFunc2 should have access to data you define above it in mainFunc
function mainFunc()
variable1 = 'stuff';
variable2 = 5;
function subFunc1()
%do stuff
end
function subFunc2()
%do more stuff
end
end
Edit 1
Of course you can define global data in the mainFunc that gets used in the subfunctions, but I wouldn't recommend doing that since it can get changed in unexpected ways that you don't intend for to happen.

MATLAB best practice: reading variables from a saved workspace within a method

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.

MATLAB Accessing data in one .m file from another .m 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.

Good way to pass many variables to function?

When one has a function, which needs many specific variables when called, what is a good way, to pass them?
Should one always pass all variable explicitly? How about storing them in structs (or objects)? But somehow I think, this makes things a bit obscure, as these structs/objects have to be well defined to make sure, they have all the fields, when handed in to the function in question.
Also probably local variables are accessed most quickly, whereas adressing struct fields might be slow in a loop...
Or is it a good thing to run an external script where everything is defined global (but even in this case on has to make everything available to the function using the global keyword)
A good way to pass many variables to a function, is to use varargin. Use it together with nargin.
function varlist2(X,Y,varargin)
fprintf('Total number of inputs = %d\n',nargin);
nVarargs = length(varargin);
fprintf('Inputs in varargin(%d):\n',nVarargs)
for k = 1:nVarargs
fprintf(' %d\n', varargin{k})
end
Varargin can also be used for optional variables.. So it gives a lot of options...