How to get inputname of variable passed into function through cellfun? - matlab

I know that the custom function myfun outputs the variable names that are passed to it using the inputname command.
However, when I pass variables through a cellfun the inputname command ceases to work, as shown below (where I am passing in the variable names j, lat, and lon. Here, it just somehow outputs all the variables as 'x'.
>> cellfun(#(x)myfun(x, y), {j, lat, lon}, 'UniformOutput', false)
First calling variable is "x".
First calling variable is "x".
First calling variable is "x".
ans =
'x' 'x' 'x'
And if I try:
cellfun(#myfun, {j}, 'UniformOutput', false)
I get:
First calling variable is "".
ans =
{''}
I'm doing this because I'm creating a bunch of plots with a function, and would like all the plots auto-labeled with the variable name of the variable I'm passing into the plots.

You lose the connection between the name of the variable you pass and inputname in this scenario. The only solution I see is to send the name of the variable as an additional argument to myfun. You need to extract the names using a separate function like this:
function [values, names] = getNames(varargin)
values = varargin;
names = cell(size(varargin));
for iArg = 1:nargin
names{iArg} = inputname(iArg);
end
end
Then your code should look like this
[values, names] = getNames(j,lat,lon);
cellfun(#(x,n)myfun(x,y,n),values,names,'UniformOutput',false);
Now the third argument passed to myfun contains the name of its first argument.
Update:
This means you need to edit myfun to accept a third argument as the name of the variable instead of using inputname.

Related

Finding parameter names from anonymous function

I want to be able to find the parameter names of an anonymous function in Matlab.
I tried to see if there was any information about the parameter names in the functions() command, but to no avail.
Say I have an anonymous function f:
f = #(x, y) x^2 + y^2
I need to be able to find the parameter names 'x' and 'y' from this equation. Is there a built in method in Matlab which can do this? Or would I somehow have to parse the function to receive the parameter names?
The function field in the output of functions (or equivalently the output of func2str) gives the function definition as a string. You then use a regular expression to match each sequence of one or more non-), non-, characters that are between a #( or , and a , or ):
s = functions(f);
inputVarNames = regexp(s.function, '(?<=(,|#\())[^\)]+?(?=(,|\)))', 'match');

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"

Matlab: Call function that has no outputs from an anonymous function

I'd like to call a certain function from within an anonymous function, as in
#(){fooBar(baz)}
Trouble is, fooBar has no outputs, which makes the anonymous function complain. Is there a way around this besides making the fooBar function return a dummy output?
The problem is in your anonymous function definition. By enclosing your function foobar(baz) between the characters {...}, you are programming a function which has to :
evaluate the expression foobar(baz)
Place the result of this expression into a cell
return the cell
Obviously in step (2) Matlab cannot place the result of the expression (1) in a cell because there is no output from (1).
So simply define your function without the curly braces:
myFunction = #() fooBar(baz)
and everything should work ok.
To demonstrate with an example, let's define the function fooBar by doing something which does not produce an output (change an axe limits for example):
fooBar = #(axlim) set(gca,'XLim',axlim)
I can now call fooBar([0 20]) and the current axes will directly have its axes limits set to [0 20]
If there is an axis span which I use often ([-5 5] for example), I could be tempted to define a new function which will always call fooBar with the same (often used) parameters:
fooBarPrefered = #() fooBar([-5 5])
Now every time I call fooBarPrefered(), my axes X limits are directly set to [-5 5].
To further prove the point, since calling fooBar([-5 5]) does not produce an output, Matlab will indeed complain if I define my function with curly braces:
fooBarPrefered = #() {fooBar([-5 5])} ;
>> fooBarPrefered()
One or more output arguments not assigned during call to "set".
Error in #(axlim)set(gca,'XLim',axlim)
Error in #(){fooBar([-5,5])}
But note that this is the same error than if you were trying to assign the output of fooBar to a variable directly in the workspace:
a = fooBar([0 20])
One or more output arguments not assigned during call to "set".
Error in #(axlim)set(gca,'XLim',axlim)
Bottom line: If a function does not have an output, do not try to redirect this output to a variable or an expression.

Call a function with several properties of an object

For (MEX) function calls it would be really nice to pass several properties of one object at once. Instead of foo(myObj.propA, myObj.propB) I want something like foo(myObj.[propA,propB].
Is this even possible?
With structs it is possible to use the getfield() function to get the data from more than one field, e.g.:
getfield(myStruct, {index}, {'fieldA', 'fieldB'})
But unfortunately, the following attempt to get more than one property from an object results in an error (Index exceeds matrix dimensions):
getfield(myObj, {index}, {'propA', 'propB'})
Maybe the only possibility is to write a function which returns several output arguments:
[varargout] = getProps(object,propnames)
for p=1:numel(propnames)
varargout{p} = object.(propnames{p});
end
But if I call another function with that function as input, e.g. sum(getProps(myObj,propnames)) only the first output argument of getProps is passed and I fall into despair. Is there any other way?
For an object, you'd use get, not getfield (or dynamic access in a loop like you showed).
>> h = figure;
>> get(h,{'Position','Renderer'})
ans =
[1x4 double] 'opengl'
This doesn't work for all objects, but for MATLAB graphics objects it does work. To deal with any class, you can use your function, but with a custom cell output instead of varargout:
function C = getProps(object,propnames)
for p = 1:numel(propnames),
C{p} = object.(propnames{p});
end
Then inside whatever function you write, you can get a comma-separated list of all properties with C{:}, which will be suitable for a function that expects each property name input as a separate argument (e.g. C = getProps(myObj,propnames); x = myFun(h,C{:}).

Passing matrices from function to function in 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.