3

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.

Justin k
  • 1,104
  • 5
  • 22
  • 33
  • There is no call by reference for variables in Matlab. Ways to get around this is to declare a variable as `global`, or to use `evalin`, but both generally point to design problems. Are you sure you need to modify a workspace variable within a function? If yes, why? – A. Donda Apr 28 '15 at 01:14
  • Why do you want to do this? A 1-by-20 matrix of double is nothing; just return the result and have the caller overwrite its variable. – Setsu Apr 28 '15 at 01:14
  • have a look at this.. [How to pass matrix by reference or get the return value of function][1] [1]: http://stackoverflow.com/questions/29902159/how-to-pass-matrix-by-reference-or-get-the-return-value-of-function/29902298#29902298 – bilaly Apr 28 '15 at 01:15
  • @bilaly Thank you for all the comments. I have updated my question more clearly. This method show in the link provided does not work when you call the same function recursively. because it will consider the original copy sent when you call it recursively and not the updated one. – Justin k Apr 28 '15 at 02:39
  • 2
    What's wrong with `current_load = recursive_remove( current_load, val );`? – ThP Apr 28 '15 at 04:16
  • I am not sure if you can pass by reference in matlab. Matlab uses a special **"copy on write"** meaning variables are passed by reference unless modified. I may of course have missed something, but I have never seen a normal pass-by-reference in matlab. This forces you to always have a function output in case you want to change a variable, since matlab copy the variable if modified. However, I think that a `cell` always store data by reference, so if you modify one element only that is copied. Still, cells are slower than matrices this is not effective for small data. – patrik Apr 28 '15 at 06:41
  • You don't need pass-by-reference to do recursion, and your recursive method isn't doing anything (it changes one value a few times and goes into an infinite loop). If you tell us what you're actually trying to achieve, maybe we can help you. – beaker May 04 '15 at 16:28
  • Wouldn't passing a cell array with a single element be analogous to passing by reference? Even though I agree with the above comments about this being unnecessary. – dainsleif Oct 29 '15 at 05:13
  • You're on the right track. Using handle class objects you can indeed pass by reference. But your code has several typos, e.g. new matrix(?), and object instead of Object. – user664303 Dec 22 '15 at 16:43
  • Looks like there is a typo error: you property is named Object but you get object with a lowercase O. – Thierry Dalon May 09 '16 at 11:36
  • I am not sure if current_load.object(1,3) will run in one line. I assume not. Instead maybe use two steps: obj=current_load.Object; val=obj(1,3); – Thierry Dalon May 09 '16 at 11:36
  • Instead of wrapping in a handle class (quite an overload), you may want to pass a variable through appdata (see getappdata and setappdata functions). It is "cleaner" than using global variables. – Thierry Dalon May 09 '16 at 11:39

1 Answers1

0

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.

Fayssal El Mofatiche
  • 1,069
  • 1
  • 8
  • 5