Pass by reference MatLab - matlab

I am working on a GUI in matlab and I'm using a variable called top to store everything. I have an update function that is in one area that updates other areas, but I don't like that it bleeds my topvariable into it, but I can't find a way to just pass the reference to the top variable so that it can still mutate what needs to be mutated.
Is there a pass by reference or some equivalent in matlab?
Edit:
For example I want to move this function to a place where top is inaccessible, but it needs a current top to do it's job, if I were to pass top by reference to the file that makes this I could still access top:
function update_Screens_Callback(~,~)
% Look to see if each check box is marked and if it is add it to seen.
seen = [];
for i=1:10
top.screens{i}.Visible='off';
end
for i=1:4
if(top.sets{i,1}.Value==top.sets{i,1}.Max)
seen = [seen i];
end
end
for i=1:6
if(top.sets{i,2}.Value==top.sets{i,2}.Max)
seen = [seen,i+4];
end
end
tmp = size(seen);
tmp = tmp(2);
sizes = getSizes(tmp);
for i=1:tmp
index = seen(i);
top.screens{index}.Visible = 'on';
top.screens{index}.Position = sizes{i};
end
end

Generally speaking, function calls in MATLAB pass arguments by value, but there is an exception where internal optimization effectively results in passes by reference. When a function returns an argument - e.g. a large matrix - as in
function top = updategui(top)
top(42, 42) = 42;
end
and if you assign the argument as part of the invocation as in x = updategui(x);, MATLAB will recognize that copying top is unnecessary and will pass top by reference.
However, I don't think "passing by reference" will help you solve your specific problem. Much of your question sounds more related to scope than to abstraction or passing by reference vs. by value. For example, it is common practice to share variables across GUI components via setappdata.

Such behavior can be achieved in object oriented matlab. Just create an object as subclass from handle. (Here's some documentation)
classdef myHelper < handle
properties
x
end
end
you can then use it like:
a = myHelper
a.x = important_data
and give a to all your functions.
As example:
a = myHelper
a.x = 1
b = a
b.x = 2
a.x
you will see that a was also updated.

Related

Loopin through all the structures in a workspace [duplicate]

I have 40 structures in my Workspace. I Need to write a script to calculate the directional derivatives of all the elements. Here is the code :
[dx,dy] = gradient(Structure_element_1.value);
dxlb = min(min(dx));
dxub = max(max(dx));
dylb = min(min(dy));
dyub = max(max(dy));
[ddx,ddy] = gradient(gradient(Structure_element_1.value));
ddxlb = min(min(ddx));
ddxub = max(max(ddx));
ddylb = min(min(ddy));
ddyub = max(max(ddy));
This is the code for one element. I Need to find out the same for all the 40 elements and then use it later. Can anyone help with this.
To answer your literal question, you should store the variables in a structure array or at least a cell array. If all of your structures have the same fields, you can access all of them by indexing a single array variable, say Structure_element:
for i = 1:numel(Structure_element)
field = Structure_element(i).value
% compute gradients of field
end
Now to address the issue of the actual gradient computation. The gradient function computes an approximation for , where is your matrix of data. Normally, a MATLAB function is aware of how many output arguments are requested. When you call gradient(gradient(F)), the outer gradient is called on the first output of the inner gradient call. This means that you are currently getting an approximation for .
I suspect that you are really trying to get . To do this, you have to get both outputs from the inner call to gradient, pass them separately to the
outer call, and choose the correct output:
[dx,dy] = gradient(F);
[ddx, ~] = gradient(dx);
[~, ddy] = gradient(dy);
Note the separated calls. The tilde was introduced as a way to ignore function arguments in MATLAB Release 2009b. If you have an older version, just use an actual variable named junk or something like that.

Efficient way of passing data between MATLAB functions

I am solving a very large optimization problem. The objective function and constraint function needs numerous data. Currently I am passing the data as a structure to them.
myFS(X, Dat, g_Index, f_Index) % Dat is a structure which includes many variables
Do you think it's an efficient way to reduce the elapsed time?
What better alternatives do exist?
Is this what the given answer, regarding to class definition, means?
%% First we define the class in a separate file:
classdef myDataStructure < handle
properties
NRES;
NOBJ;
NVAR;
end
methods
function obj = myDataStructure()
end
end
end
%% In another file where the main program is, we initialize the class.
Dat = myDataStructure();
%% Initialize
Dat.NRES = 1;
Dat.NOBJ = 1;
Dat.NVAR = 1;
[myF, Dat_updated] = BBB(Dat);
%% Here we define the function and use the class
function [f, CalssDat] = BBB(CalssDat)
x = CalssDat.NRES;
y = CalssDat.NOBJ;
z = CalssDat.NVAR;
f = x + y + z;
CalssDat.NOBJ = 2;
end
As far as I know, MATLAB does not actually copy the content of the data you pass to a function until the point when you modify it in the function itself - in which case it makes a local copy and that takes some CPU time.
Therefore, as long as Dat doesn't change inside myFS(), what you are doing now does not add any CPU overhead. In case you do change the values of Dat inside myFS() and want to return it, I can think of two ways to optimise it:
You can declare myFS() as: function [Dat, anythingElse] = myFs(X,Dat,g_Index, f_Index), which should prevent matlab from making a local copy.
Another approach is to use a class that derives from handle and have Dat be a member of that. This way, whenever you pass the object containing Dat, you only pass the object handle and not a copy of the object itself.
Example of the second approach:
classdef myDataStructure < handle
properties
p1FromDat;
p2FromDat;
% .
% .
% .
pNFromDat;
end
methods
function obj = myDataStructure()
% Add initialization code here if you want. Otherwise p1FromDat
% ... pNFromDat are accessible from outside
end
end
end
Than, in your code:
Dat = myDataStructure();
Dat.p1FromDat = 1;
Dat.p2FromDat = 1;
And in your myFs() you use Dat exactly the same way as you used before.
Because myDataStructure derives from handle, the data inside will not be copied when you pass Dat around.
Do be careful with this, because when you change Dat in myFS(), the values will be changed outside the scope of myFS() as well.

How to pass parameter by reference in Matlab

I am a beginner in matlab and learn about the following question online and was having trouble solving it. I have a 1 x 20 matrix called current_load that I need to update periodically. This matrix resides in the main workspace of Matlab (as shown in the code bellow).
current_loads = zeros(1, 20);
for col=1:20
current_loads(1,col)=10; %// Initially give all nodes a current value of 10
end
Object = HandleObject(current_load);%To pass by reference
recursive_remove(Object, 0);
In order to pass current_load by reference, I have created the following class HandleObject.m
classdef HandleObject < handle
properties
Object=[];
end
methods
function obj=HandleObject(receivedObject)
obj.Object=receivedObject;
end
end
end
This matrix will be passed to a function call recursive_remove (shown bellow).
function recursive_remove( current_load, val )
current_load.object = new matrix;
if(val<10)
current_load.object(1,3) = 2+val; %Not the correct way of using current_load ??
end
recursive_remove( current_load, current_load.object (1,3) )
end
Intention here is to modify current_load variable in this function and later I can see these same changes from the main. But This code doesn't work since I don't know how to pass by reference. I need to pass by reference since I am calling this recursively without returning to the main to make it overwrite its variable at the caller. Please show with an example if possible.
If you really need this feature, you can look into turning your HandleObject class into a Singleton like this:
classdef HandleObject < handle
properties
Object=[];
end
methods(Static)
function obj = Instance(receivedObject)
persistent uniqueInstance
try
if isempty(uniqueInstance)
obj = HandleObject(receivedObject);
uniqueInstance = obj;
else
obj = uniqueInstance;
end
catch ME
disp(ME.getReport);
end
end
end
methods
function obj=HandleObject(receivedObject)
obj.Object=receivedObject;
end
end
end
Your recursive function would become a bit simpler then:
function recursive_remove(val )
current_load = HandleObject.Instance();
current_load.object = new matrix;
if(val<10)
current_load.object(1,3) = 2+val;
end
recursive_remove(current_load.object (1,3) )
end
And to create an instance of your HandleObject class, you do something like:
Object = HandleObject.Instance(current_load);
Hope this helps you further.

passing a variable by ref in matlab

Can I pass a variable by ref to a function in Matlab?
I want to do something such as this:
function change(x)
x=x+1;
end
and call it like this:
x=1;
change(x)
% x should be 2 now.
The usual style for doing this is to have the same name appear in both the input and output parameter lists:
function [x] = change(x)
x=x+1;
end
x = 1;
x = change(x);
% now 2
For example, the standard function setfield works this way.
In addition, handle objects (e.g. graphic handles) are effectively passed by reference -- the handle numeric value is passed by value, so you can't substitute a different object, but any changes made to the handle object in the function will be visible to the caller.
Since you do not describe your usecase I cannot estimate whether it is worth to define your own handle class but there are situations where you may benefit from the object oriented way.
Your basic example would look something like this:
Define your handle class in a separate file called cnt.m (make sure you inherit from the handle class):
classdef cnt < handle
properties (SetAccess = private)
% a private member variable.
c = 0;
end
methods
function h = cnt(c_init)
% CNT constructs a cnt handle
% CNT()
% CNT(INIT)
if nargin > 0
h.c = c_init;
end
end
function change(h)
% CHANGE increment by one
h.c = h.c+1
end
end
end
Then you can do something like this:
x = cnt();
x.change();
and you can also do something like this:
function change2(cnt_obj)
cnt_obj.change()
and call this function then like so:
change2(x)
which will then do what you are asking for.
The later is the reason why you should inherit from handle. If you create an ordinary value class the call to change2 would create a copy of the actual input object.
Please note that for the simple use case you describe doing something like this is STUPID OVERHEAD. Use this only in case you have good reason to.

Matlab - how to create a subclass of dataset class keeping the dataset parameter constructor

dataset allows us to do:
x = rand(10, 1);
y = rand(10, 1);
d = dataset(x, y);
d will have 2 variables with name 'x' and 'y' and content x and y - variable names are obtained from the workspace. The dataset() call above is equivalent to:
d = dataset({'x', x}, {'y', y});
when the names are specified.
Now if I have a subclass of dataset:
classdef mydataset < dataset
properties
end
methods
function spec = mydataset(varargin)
spec = spec#dataset(varargin{:});
% Add some more things to this subclass because that's the reason I need a subclass
end
end
end
The problem is, if I call:
d = mydataset(x);
d will have the variable x but the name is just 'var1'. The workspace name 'x' is not recognized. Unless I call:
d = mydataset({'x', x});
I will not get the same effect.
Any solution?
Note that I do not want to lose other argument parsing abilities of dataset(). It can process really complicated arguments, and I do want to preserve that.
http://www.mathworks.com/help/toolbox/stats/dataset.html
A = dataset(varspec,'ParamName',Value)
A = dataset('File',filename,'ParamName',Value)
A = dataset('XLSFile',filename,'ParamName',Value)
A = dataset('XPTFile',xptfilename,'ParamName',Value)
The example in this question with mydataset(x) is the a simple and commonly encountered situation that mydataset() can't pass things to dataset() and obtain the same results. Thus it's an important situation. But to do just that and lose other capabilities of dataset() is not worth it.
One option is to capture the argument names yourself and build a cell that you then pass in to the dataset constructor, i.e. you build a cell that looks like
{{Var1 VarName1}, {Var2 VarName2}, ...}
A quick and dirty solution:
classdef mydataset < dataset
properties
end
methods
function self = mydataset(varargin)
for k = 1:nargin
args{k} = {varargin{k}, inputname(k)};
end
self = self#dataset(args{:});
end
end
end
Now if I call it:
>> x=1;
>> y=2;
>> mydataset(x,y)
ans =
x y
1 2
Of course, you've now lost the ability to call mydataset with the {val, valname},... syntax, but maybe that's worth giving up. If you also wanted to be able to do that, you would need to write a conditional that checks the format of your input first, and builds args differently depending on the input format.
Note that you can't do the obvious thing and put your calls to the superclass constructor inside two branches of an if statement. In Matlab, calls to the superclass have to be at the top level (i.e. you can't put them inside loops or conditionals).