How to pass parameter by reference in Matlab - 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.

Related

Operating on Superclass Property with Subclass

To all,
I'm a novice programmer (I haven't taken a structured course) trying to pick up MATLAB. Currently, I'm trying to understand MATLAB's object-oriented programming tools. I want to cleanly divide up my project in the steps below. I would like to inherit the substantiated data and work on it in validate. I'm running into this error You cannot set the read-only property 'data' of validations.
How would I go about doing this? Would this be the appropriate way to organize myself in MATLAB?
classdef formatData.m
properties
data = []
end
methods
function formatData(data)
% This should initialize the data
end
function columnShift(data)
% Simple changes
end
end
end
classdef validateData.m < formatData
properties
error = logical(false)
end
methods
function validateData(data)
if nargin > 0
obj.data = obj#formatData;
end
end
function checkValues()
% check values on data from formatData
end
end
end
The sad new is that MATLAB often changes the object-oriented codes. The code that I have posted is referenced from the latest documents. It seems completely different with a book that I have owned for one year. 
classdef formatData
properties
data = [];
end
methods
function obj = formatData(DataIn)
%formatData This should initialize the data
obj.data = DataIn;
end
function [DataOut] = columnShift(obj)
%columnShift ? How to shift the column?
DataOut = (obj.data)';
end
end
end
classdef validateData < formatData
%validateData
properties
error = false;
end
methods
function obj = validateData(DataIn)
%validateData
obj#formatData(DataIn);
end
function [] = checkValues(obj)
%checkValues
end
end
end

Saving variables in MATLAB

I am working on a MATLAB program where I will have a class, here represented as Dummy, and a function which is supposed to create and save a set of Dummy objects, say to the current folder. How can I do this? I thought about creating a matfile containing the constructor arguments for each Dummy object, as done in the code example below. However, save expects a string, so my code doesn't work.
classdef Dummy < handle
properties
foo
end
methods
function D = Dummy(foo)
D.foo = foo;
end
end
end
function generateDummies(n)
for i = 1:n
Df = matfile(strcat('Df',int2str(i)),'Writable',true);
Df.foo = i;
save(Df); %(?)
end
end
Any help would be greatly appreciated!

How to pass matrix by reference or get the return value of function

I have a 1 x 118 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, 118);
for col=1:118
current_loads(1,col)=10; %// Initially give all nodes a current load of 10
end
recursive_remove(current_loads); %calling function
This matrix will be passed to a function call recursive_remove (shown bellow).
function updater = recursive_remove( current_load )
current_load(1,3) = 2.6; %// This update can't be seen from main ??
%this function will be called recursively later
end
But whatever updates I do to this current_load matrix from the function, it will not get updated since I don't know how to pass it by reference.
I am new to Matlab. I would greatly appreciate if you can show with an example how to handle this
EDIT: "How to pass parameter by reference in Matlab"
You can solve your problem passing your arguments by reference
You need a handle class
Handle Classes
Objects that share references with other objects
this is, create a file called HandleObject.m with this code:
classdef HandleObject < handle
properties
Object=[];
end
methods
function obj=HandleObject(receivedObject)
obj.Object=receivedObject;
end
end
end
Then you can do something like this
Object = HandleObject(your matrix)
yourFunction(Object)
And inside your function
function yourFunction(myObject)
myObject.object = new matrix;
end
With that you can achieve some kind of pass by reference and avoid getting a lot of copies trought your program.
The output of the function recursive_remove hasn't been defined and so you ouput can't be used anywhere else.
In matlab you define outputs of functions with square brackets as below.
function [ output1, output2 ] = recursive_remove( input1, input2 )
The outputs can now be passed into other MATLAB docs - functions.
When calling the function in the example above in a different function as you did in your first bit of code you would call it as shown:
current_loads = zeros(1, 118);
for col=1:118
current_loads(1,col)=10; %Initially give all nodes a current load of 10
end
[ output1, output2 ] = recursive_remove( input1, input2 ); %calling function
With this syntax you can take output1 and call it in the input of your next function recursive_remover

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.

parfor and handle classes

I have a handle class:
classdef A<handle
properties
a;
end
methods
function obj = A(a)
obj.a=a;
end
end
end
And I have a cell array of A objects:
arr={};
for i=1:3
arr{i}=A(i);
end
What I would like to do is pass that cell array to a parfor loop so that each object's value will change:
parfor i=1:3
arr{i}.a=i*5;
end
However, this code does not change arr at all. Indeed, here it states that
Changes made to handle classes on the workers during loop iterations are not automatically propagated to the client.
How can I overcome this?
An interesting question; I actually never encountered this problem. It's always good to know everything about parfor limitations, so I did some googlin' and came up with this:
I have received an answer to this issue from technical support.
Apparently the Mathworks regard it as a 'feature' that changes to
objects are not returned - though I can't see that it's a very useful
feature. Anyway, the way to get modified class properties returned
from a parfor loop is to make an explicit change which can be
recognised by parfor. Here are two examples which work for the above
example object:
parfor n = 1:num
exArray(n).data = n:n+5;
end
or
parfor n = 1:num
temp = exArray(n);
setData(temp,n:n+5);
exArray(n) = temp;
end
Actually, if you change any object property it also seems to work. So
for example this also works, if there is a second property data2 which
is set explicitly, both data and data2 are correctly returned:
parfor n = 1:num
setData(exArray(n),n:n+5);
exArray(n).data2 = n:n+5;
end
Where the example object is given by
classdef Example < handle
properties
data
end
methods
function obj = Example(data)
obj.data = data;
end
function setData(obj,data)
obj.data = data;
end
function data = getData(obj)
data = obj.data;
end
end
end
and the array is initialized simply as
% Initialise array of objects
for n = 1:num
exArray(n) = Example(zeros(1,6));
end