I'm writing a series of MATLAB functions which communicate with a server through urlread. Each function in this package that makes this call requires an authentication username and key.
I would rather not require the user to pass in the username and key when calling every function. Instead, I prefer to have a signin(username, key) function that sets/saves these variables in such a way that each function in this package can recall.
My solution right now is for signin.m to save username and key to a temporary file and to modify finish.m to erase this temporary file when MATLAB closes. Each function in the package would load these variables from that temporary file. However, if someone force quits MATLAB, this temporary file will not be erased (right?).
Another solution was to have signin save username and key as global variables. However, if a user calls clear all, these variables will be removed the workspace and the user will need to call signin again (which is a nuisance).
Is there some way to set 'session' variables that are global and are not removed with a clear all command? Any other suggestions?
You might consider the preferences feature of MATLAB. It works with the functions setpref, addpref, rmpref, and getpref. I use these tools in a few applications, and they work nicely.
One minor problem is if you will be calling these tools frequently. Since getpref uses a read from a disk file to access the prefs, it is not as fast as it might be. So IF you must have the absolute maximum speed due to frequent calls, then a mixture of persistent variables seems to work well for me. Thus, I have a function that I use to access the preference in question. It contains the pref in a persistent variable. If this is the first time the pref is queried, then that persistent variable will be empty, so I do a getpref call to fill it. (This is a nice feature, since the pref will persist across MATLAB sessions.) When you need to change the variable, do a setpref too.
You're almost there. A few useful features:
persistent
First, you should be using persistent variables rather than global variables. They are like globals, but scoped to a single function. They're just better.
mlock
Run mlock within a function to prevent the clear or clear all command from clearing data associated with that function.
So, for example, you could define a quick function to help a username and key within a Matlab sessionb as follows:
function [name, key] = credentials(varargin)
persistent USERNAME KEY
if nargin==3 && ischar(varargin{1}) && strcmpi(varargin{1},'set')
USERNAME = varargin{2};
KEY= varargin{3};
mlock;
else
name = USERNAME;
key = KEY;
end
Then you could use it like this:
%First, set the credentials
credentials set SOMEUSERNAME SOMEKEY
% .... do some work ....
clear %As part of your work, clear all variables
% .... do some more work ....
%Get the credentials later
[name, key] = credentials;
Another alternative is the official startup.m file and the related Startup Folder. These could be used to do pretty much anything, including the other solutions provided.
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.
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;
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.
I am new to using GUIDE and using GUIs in Matlab.
I am running a script in Matlab that will accept initial inputs from the user and then proceed to open up a GUI (created with GUIDE) which will accept further inputs from the user. However, I cannot figure out a way to transfer variables and data between my script and my GUI. I am aware that script variables/data and GUI variables/data are saved in different workspaces; I just need some simple way to communicate between the two.
Thanks.
A simple way would be to use setappdata and getappdata in order to store your variables/input/whatever so that it's accessible from wherever you want.
Let's say you delcare some variable in your script that you want to retrieve in your GUI:
A = rand(100,100);
Then using setappdata like the following:
setappdata(0,'VariableName',A);
will store the data in the root directory (the 0 as the 1st input), meaning that using getappdata like this in the GUI:
A_in_GUI = getappdata(0,'VariableName');
will allow you to retrieve the value from your GUI, or from any other script as long as you use the correct variable names of course. Notice that you can use a handle to some figure/GUI where you could save your data, like this;
setappdata(handles.Something,'VariableName','A);
but if you close the figure, for instance, you might not be able to retrieve your variable.
As Tyler pointed out, a nice way to share data between different callbacks inside your GUI is to use its handles structure. More info here.
Final Note:
If you don't want to spend your time sharing many variables between scripts and GUIs, you can store all of your variables in a single large structure and use setappdata/getappdata only on this structure, which will keep all your variables updated.
For instance, you can write something like this in the script:
Variables_Structure.MyFavoriteNumber = pi;
Variables_Structure.MyFavoriteSport = 'ice hockey';
setappdata(0,'MyVariables',Variables_Structure);
and then getappdata in the GUI in which you want to use the variables:
Variables_in_GUI = getappdata(0,'MyVariables');
Is it possible to retrieve a local variable from a programme-function i've run in matlab? i.e. i want to retrieve a variable from the code, which is not appeared in the outputs.
Thanks in advance
The following describes code to add to the function itself to make the variable available outside the local scope. When you can't change the function, from the outside there is nothing to be done about changing the scope of course (which is intended, correct behaviour!!).
Dirty ways:
global variables
global t
t=2.468;
For scalars, strings, simple values: assign to variables in base workspace using evalin:
t=2.468;
evalin('base', ['var_in_base=' num2str(t) ';']);
Any other variable, use assignin:
A=magic(20);
assignin('base','A',A);
Proper way:
Inspect them during debugging
If you really want them outside the local scope, add them as output variable!!
Look at Declare function. You can access local variables if you return them as return values. If you do not, you can't access them from outside.
So in
function [mean,stdev] = stat(x)
n = length(x);
mean = sum(x)/n;
stdev = sqrt(sum((x-mean).^2/n));
You have access to mean and stdev but there is no way to access n.
I don't know matlab at all, but from programmer's logic
that seems improper and impossible without hacking the code.
That being said, through Google I saw this:
When you call a script from a function, the script uses the function workspace.
Like local functions, nested functions have their own workspaces. However, these workspaces are unique in two significant ways:
Nested functions can access and modify variables in the workspaces of the functions that contain them.
All of the variables in nested functions or the functions that contain them must be explicitly defined. That is, you cannot call a function or script that assigns values to variables unless those variables already exist in the function workspace.
Base and Function Workspace
Not sure if this helps you at all, but it may clarify some points