MATLAB Answers

Translated by

このページのコンテンツは英語から自動翻訳されています。自動翻訳をオフにする場合は「<a class="turn_off_mt" href="#" onclick="window._kiq.push(['set', { 'event': 'Turn off MT' }]);">ここ</a>」をクリックしてください。

Adam
4

Pass variable by reference to function

Adam
さんによって質問されました 2012 年 9 月 28 日
最新アクティビティ Lamont Granquist さんによって 回答されました 2019 年 6 月 12 日 23:19
I have read that the only way to pass by reference with a function is if you pass a handle. Is there a matlab call to get the "handle" of a variable or structure?

  0 件のコメント

サインイン to comment.

6 件の回答

回答者: Daniel Shub
2012 年 10 月 1 日
 採用された回答

While I think IA's answer is the better way to do it. If you really want to do what you are talking about you can create a subclass of handle.
classdef myClass < handle
properties
data
end
methods
function h = myClass(data)
h.data = data ;
end
end
end
Then defining a function (which could be a method) like
function myFunction(h)
h.data = h.data+2;
end
lets you do something like
h = myClass(0);
myFunction(h);
h.data
ans =
2
of course things like h+2 will not work unless you implement a plus method.

  1 件のコメント

Alessandro 2013 年 2 月 27 日
Nice post ! Matlab should have something like this as a standard object ! The problem with this class is that it still copy the value from workspace to the class but is a good workaround.

サインイン to comment.


回答者: Image Analyst
2012 年 9 月 29 日

For all practical purposes, you can get the same effect by passing the input argument back out. For example, in the function definition:
function myVariable = ChangeMyVariable(myVariable)
myVariable = 2 * myVariable;
Then to call it, do this:
myVariable = ChangeMyVariable(myVariable);
And, obviously, myVariable could be anything, such as a structure like you mentioned. For all intents and purposes, this is the same as the code you'd use if it were pass by reference:
ChangeMyVariable(myVariable);
The net effect is you get your variable changed, it's just slightly different syntax.

  18 件のコメント

Titus Edelhofer
2015 年 1 月 8 日
Hi Lucas,
the programming pattern that Image Analyst showed, namely
function Y = someFun(x, Y, z)
Y = x + Y;
involves no copying of Y at all, provided, that you
  • call it like var = someFun(x, var, y), i.e. both the function declaration and the calling function use the same variable names for input and output
  • Your MATLAB version is not too old: this optimization was introduced somewhere around 2010.
Give it a try with a large variable. You will see in the task manager no copy is done.
Titus
Royi Avital 2015 年 2 月 22 日
Hi, I tried your trick with very large matrix. By the jump in the memory consumption I can assure you it is not working by reference.
per isakson
2015 年 2 月 22 日
I think there is a typo in the comment by Titus Edelhofer, it should read
var = someFun(x, var, y),
rather than
var = someFun(x, Var, y),
@Royi, Which release are you running?

サインイン to comment.


回答者: per isakson
2012 年 9 月 28 日
編集済み: per isakson
2012 年 9 月 28 日

No, there is no way to pass a variable by reference. See Memory Management for Functions and Variables.

  2 件のコメント

Adam
2012 年 9 月 28 日
I understand that only handles can be passed by reference. Is there a way of obtaining a handle for a variable?
per isakson
2012 年 9 月 28 日
No, not with documented Matlab. And not with http://undocumentedmatlab.com/ as far as I know.
Why do you want to pass by reference?

サインイン to comment.


回答者: James Tursa
2012 年 9 月 29 日

I will ask again what others have already asked. Why do you want the "handle" to the variable? What advice we give you will depend on the answer to that question. FYI, by default MATLAB passes a shared data copy of the arguments to the function ... i.e., there is no data copy involved. So it is already efficient in that sense. But we really need to know what you are doing with the variable inside the function in order to best answer your question, and whether passing by "reference" makes sense for your application.

  4 件のコメント

Walter Roberson
2012 年 10 月 3 日
If it is a question about code cleanliness, reuse, and good practices, then you are looking for coding advice, and IA's recommendation to use a return value is not "imposed" is an appropriate "good practices" response. Hidden modification of variables is not good practice; it is, for example, emphatically disallowed in Yourdon & Constantine's "Structured Design" (1979)
Milan Assuied 2017 年 8 月 16 日
Using pointers is not a hidden modification of a variable. It's a efficient practice widely used in any performing language.
Walter Roberson
2017 年 8 月 16 日
Once you pass in a pointer, you lose control over whether there is a modification to the original data or not. You cannot tell from a C function declaration whether it modifies the data stored at any given pointer: at best you can hope that the person who wrote the function was diligent about putting in "const" where-ever possible.
Some languages require that every parameter to a function be marked as either input only, output only, or in/out . With such languages, there is never any surprise factor. If your goal is code cleanliness, reuse, and good practices, then you should prefer to avoid languages where the default is to permit modification of any item you have a pointer to.

サインイン to comment.


回答者: Alessandro 2013 年 4 月 16 日

Hello I would say a possible solution is the following (without using classes):
%Reference to some matlab Data
function reference = globaldata()
data = [];
reference = struct('GET',@GET,'SET',@SET);
function dataout = GET()
dataout = data;
end
function SET(datain)
data =datain;
end
end
I saw something like this for making linked lists in matlab on stack overflow.

  0 件のコメント

サインイン to comment.


回答者: Lamont Granquist 2019 年 6 月 12 日 23:19

This isn't so much an answer but an example of why pass-by-reference would be useful. I want to pull an array of values out of an ode45 OutputFnc, the straightforward programming way to do this would be to create a closure over a local variable which was passed along with the function handle into ODE45 and have the OutputFnc update that. Since the original program is not the caller of the OutputFnc -- ode45 is -- it is not possible to use the output parameters.
T0a = [];
options = odeset('OutputFcn', @(t, y, flag) odethrust(t, y, flag, T0a, mf_bar, thrust_bar));
[t, y] = ode45(@(t, y) ode(t, y, tf0/2, thrust_bar, mf_bar, ve_bar), lgt, y0, options);
T0a
function dXdtau = ode(t, y, tau, thrust_bar, mf_bar, ve_bar)
r = y(1);
v = y(2);
m = y(3);
if m < mf_bar
T = 0;
else
T = thrust_bar;
end
drdt = v;
dvdt = - 1/r^2 + T / m;
dmdt = - T / ve_bar;
dXdtau = tau * [ drdt dvdt dmdt ]';
end
function status = odethrust(t,y,flag,T, mf_bar, thrust_bar)
if isempty(flag)
m = y(3);
if m < mf_bar
T = [ T 0 ];
else
T = [ T thrust_bar ];
end
end
status = 0;
end
That is a snippet out of a real program so some variables like mf_bar/ve_bar/thrust_bar/etc aren't declared. The structure of the ODE isn't terribly important other than I'm trying to access the time history of the T variable as well as the variables of integration (pretend that the simplistic way T is handled now could be arbitrarily complicated so I don't want answers that figure out the problem analytically outside of this loop -- if you can guess the problem domain, you can be sure I know that the rocket equation exists).
The important point is the way that I want to declare T0a as an empty array, and then pass that into the function handle of odethrust, which is the OutputFcn for the ode45 call.
I guarantee there's nothing wrong -- in a computer science sense -- with wanting to pass in a closure like this to accumulate state.

  0 件のコメント

サインイン to comment.



Translated by