Passing matrices from function to function in MATLAB - matlab

I'm pretty new to MATLAB and I have a simple question. What if I have the following structured functions:
function[A] = test(A)
test1(A);
test2(A);
end
function test1(A)
#% do something with A
end
function test2(A)
#% do something else with the newly modified A
end
How do I pass around A from function to function keeping it's modified nature? (Suppose A is a matrix)
EDIT: let's make the situation a little simpler. Suppose my main function is:
function[a]=test(a)
test1(a);
#%test2(a);
end
and test1() is defined as:
function[a] = test1(a)
a=5;
end
Then, I call the function test with test(3), and I want it to report ans = 5, yet it still reports ans = 3.
Thanks!

Variables in MATLAB are passed using "call by value" (with some exceptions), so any value that you pass to a function and modify has to be returned from the function and either placed in a new variable or the old variable overwritten. Returning the value of a variable from a function is simple: you just place the variable name in the output argument list for the function.
For your example, you would do this:
function A = test(A)
A = test1(A); %# Overwrite A with value returned from test1
A = test2(A); %# Overwrite A with value returned from test2
end
function A = test1(A) %# Pass in A and return a modified A
#% Modify A
end
function A = test2(A) %# Pass in A and return a modified A
#% Modify A
end
One thing to be aware of is variable scope. Every function has its own workspace to store its own local variables, so there are actually 3 unique A variables in the above example: one in the workspace of test, one in the workspace of test1, and one in the workspace of test2. Just because they are named the same doesn't mean they all share the same value.
For example, when you call test1 from test, the value stored in the variable A in test is copied to the variable A in test1. When test1 modifies its local copy of A, the value of A in test is unchanged. To update the value of A in test, the return value from test1 has to be copied to it.

Return the object from the function and then pass it on to the next function.

Related

Matlab functions not 'posting' variables to workspace

I'm using some user generated functions in MatLab. It'll be quicker if I don't post my actual code here so I'll summarize.
I have two functions. Each of them exist in their own files saved under their proper names. They can be called and work correctly. Lets say function1 is:
function [Output1] function1=(a,b)
Output1=a+b
end
function [Output2] function2=(a,Output1)
Output2=a+Output1
end
new script file
a=2;
b=3;
function1(a,b);
function2(a,Output1);
This doesn't work, because function1 isn't posting Output1 into the workspace. How do I make it do that?
Check this tutorial. This is how you are supposed to write a function.
function Output1 = function1(a, b)
Output1 = a + b;
end
Then your second function will get the input like this.
function Output2 = function2(a, Output1)
Output2 = a + Output1;
end
Of course you need to store answers of functions into variables to have them stored in the workspace.
aa=2;
bb=3;
Output11 = function1(aa,bb);
Output22 = function2(aa,Output11);
If you don't use Output11 and Output22, functions will store their result into ans variable in the workspace. And obviously, apart from the fact that you cannot pass the variable to the second function as Output1, second function will overwrite the ans.

Will returned array be copied by value or returned as reference in MATLAB?

I wanted to ask how values in MATLAB are returned? Are they copied or passed by reference?
take a look at this example with matrix A:
function main
A = foo(10);
return;
end
function [resultMatrix] = foo(count)
resultMatrix = zeros(count, count);
return;
end
Does the copy operation take place when function returns matrix and assigns it to variable A ?
MATLAB uses a system known as copy-on-write in which a copy of the data is only made when it is necessary (i.e. when the data is modified). When returning a variable from a function, it is not modified between when it was created inside of the function and when it was stored in a different variable by the calling function. So in your case, you can think of the variable as being passed by reference. Once the data is modified, however, a copy will be made
You can check this behavior using format debug which will actually tell us the memory location of the data (detailed more in this post)
So if we modify your code slightly so that we print the memory location of each variable we can track when a copy is made
function main()
A = foo(10);
% Print the address of the variable A
fprintf('Address of A in calling function: %s\n', address(A));
% Modify A
B = A + 1;
% Print the address of the variable B
fprintf('Address of B in calling function: %s\n', address(B));
end
function result = foo(count)
result = zeros(count);
% Print the address of the variable inside of the function
fprintf('Address of result in foo: %s\n', address(result));
end
function loc = address(x)
% Store the current display format
fmt = get(0, 'format');
% Turn on debugging display and parse it
format debug
loc = regexp(evalc('disp(x)'), '(?<=pr\s*=\s*)[a-z0-9]*', 'match', 'once');
% Revert the display format to what it was
format(fmt);
end
And this yields the following (or similar) output
Address of result in foo: 7f96d9d591c0
Address of A in calling function: 7f96d9d591c0
Address of B in calling function: 7f96d9c74400
As a side-note, you don't need to explicitly use return in your case since the function will naturally return when it encounters the end. return is only necessary when you need to use it to alter the flow of your program and exit a function pre-maturely.

Save values that are calculated in a function for each iteration of fminsearch

I want to find the Minimum of a function using
[x,fval] = fminsearch(#(param) esm6(param,identi),result(k,1:end-1),options)
now for each Iteration step i want some values that the function 'esm6' calculates to be saved in an Array. I tried the following:
In the first line of the function i wrote
identi.sim.i_optiIter = identi.sim.i_optiIter + 1;
to have an iteration-variable counting the iteration steps of fminsearch. And later to catch the values that I need I used
identi.sim.guete_werte.gew(identi.sim.i_optiIter,:,:) = y_sim;
identi.sim.guete_werte.ungew(identi.sim.i_optiIter,:,:) = y_sim_ungew;
and to make sure that I use the new values of the identi-struct for the next function call, I wrote this at the end of the function:
assignin('base','identi',identi);
Now unfortunatly it doesn't do what I wanted it to do. Can anyone help me with this?
EDIT:
I made another attempt on it, using an Output function. I extendend my Options like this:
options = optimset('Display','iter','MaxIter',3,'OutputFcn',#outfun);
But now the Problem is that i cannot figure out where to put this outfun. The outfun Looks like this:
function stop = outfun(x,optimvalues,state,iteration,y_sim,y_sim_ungew)
stop = false;
if state == 'iter'
guete_werte.gew(iteration,:,:) = y_sim;
guete_werte.ungew(iteration,:,:) = y_sim_ungew;
end
end
Now the Problem with it is, that i can not put it in the file, where i call the fminsearch, because that is a script. If i put the outputfunction into a separate .m-function file, it is not able to Access the variables of the esm6 function. And if I add it to the esm6-function file, matlab can't find the function and says
??? Error using ==> feval Undefined function or method 'outfun' for
input arguments of type 'struct'.

Retrieve name of output arguments within a function

It is possible to use the function inputname to retrieve the workspace variable name passed in the call to the currently executing function. However, is there any equivalent function to obtain the name of the output arguments specified in the call to the currently executing function?
Imagine I have the following function:
function [a,b,c] = test(x)
disp([ouputname(1),ouputname(2),ouputname(3)])
end
When running this function:
[my,name,is] = test(x)
The expected result should be:
mynameis
Simply: no there isn't.
Complicated: Matlab code is "compiled" on run-time, and there is no way, that it knows [my,name,is] before it returns the result of test(x).
Workaround: if you want to ensure, that the strings used within the function are equal to the variables returned to the workspace, you can do the following using assignin:
function test(x, varnames)
a = 1;
outputname{1} = varnames{1};
assigin('base', outputname{1}, a)
...
c = 3;
outputname{3} = varnames{3};
assigin('base', outputname{3}, c)
disp([outputname{:}])
end
and call your function like:
text(x,{'my','name','is'})
and you will have exactly this variables in your workspace afterwards and your function output:
"mynameis"

Assigning to variables using dynamic naming

I am creating a function with two inputs, and would like to know how I can name the output accorinding to the name of the inputs.
E.g.
function [padded_*input_name*] = padstruct(S, F)
later in code...
else
padded_*input_name* = padarray(toPad, (longest - size(toPad,1)), NaN('double'), 'post');
So if I enter a struct (labelled as S in the input arguments) called my_struct, I would like to get an output called padded_my_struct. But this should be free to change according to the name of the input struct. I want to do this because I have a lot of structs to run through this function and I want to explicitly know from the output name, which is which.
I am a beginner with Matlab and so would appreciate any exaplanation or references to literature.
I don't quite give you what you want. Instead, I have a function that, given the inputs Account and F, produces in the base workspace a variable "padded_Account", and returns the name of the variable it creates.
function padded_Sname_str=padstruct(Sin,F)
%get the name of the structure used in the function call here
Sname=inputname(1);
%do stuff to Sin here
Sin.pad=F; %this is just my test operation
%create the name of the new variable you want
padded_Sname_str=['padded_',Sname];
%this creates it in the base workspace, since passing back as an
%output argument doesn't preserve the name
assignin('base',padded_Sname_str,Sin)
return
Hope this is helpful. Cheers!
Try this -
function [padded_*input_name*] = padstruct(S, F)
%// .. later on in code
else
value = padarray(toPad, (longest - size(toPad,1)), NaN('double'), 'post');
evalc(['padded_' inputname(1) '= value']);
Let us know if it works for you!