How to write an anonymous function with a variable number of output arguments? - matlab

Using deal we can write anonymous functions that have multiple output arguments, like for example
minmax = #(x)deal(min(x),max(x));
[u,v] = minmax([1,2,3,4]); % outputs u = 1, v = 4
But if you want to provide a function with its gradient to the optimization function fminunc this does not work. The function fminunc calls the input function sometimes with one and sometimes with two output arguments. (EDIT: This is not true, you just have to specify whether you actually want to use the gradient or not, using e.g. optimset('SpecifyObjectiveGradient',true). Then within one call it always asks for the same number of arguments.)
We have to provide something like
function [f,g] = myFun(x)
f = x^2; % function
g = 2*x; % gradient
which can be called with one or two output arguments.
So is there a way to do the same inline without using the function keyword?

Yes there is, it involves a technique used in this question about recursive anonymous functions. First we define a helper function
helper = #(c,n)deal(c{1:n});
which accepts a cell array c of the possible outputs as well as an integer n that says how many outputs we need. To write our actual function we just need to define the cell array and pass nargout (the number of expected output arguments) to helper:
myFun = #(x)helper({x^2,2*x,2},nargout);
This now works perfectly when calling fminunc:
x = fminunc(myFun,1);

The OP's solution is good in that it's concise and useful in many cases.
However, it has one main shortcoming, in that it's less scalable than otherwise possible. This claim is made because all functions ({x^2,2*x,2}) are evaluated, regardless of whether they're needed as outputs or not - which results in "wasted" computation time and memory consumption when less than 3 outputs are requested.
In the example of this question this is not an issue because the function and its derivatives are very easy to compute and the input x is a scalar, but under different circumstances, this can be a very real issue.
I'm providing a modified version, which although uglier, avoids the aforementioned problem and is somewhat more general:
funcs_to_apply = {#(x)x.^2, #(x)2*x, #(x)2};
unpacker = #(x)deal(x{:});
myFun = #(x)unpacker(cellfun(#(c)feval(c,x),...
funcs_to_apply(1:evalin('caller','nargout')),...
'UniformOutput',false)...
);
Notes:
The additional functions I use are cellfun, evalin and feval.
The 'UniformOutput' argument was only added so that the output of cellfun is a cell (and can be "unpacked" to a comma-separated list; we could've wrapped it in num2cell instead).
The evalin trick is required since in the myFun scope we don't know how many outputs were requested from unpacker.
While eval in its various forms (here: evalin) is usually discouraged, in this case we know exactly who the caller is and that this is a safe operation.

Related

What does this matlab statement do

I have a statement in my MATLAB program:
f = #(A)DistanceGauss(A,x_axis,Y_target,Y_initial,numOf,modus);
I understood that f is defined as the function handle to the function distancegauss which contains the parameters/arg list present inside the parentheses.
What does the variable A in #(A) do? Does it have any importance? While browsing I found that the variables within parentheses after # would be the input arguments for an anonymous function..
Can anyone explain what does that A do? Will this handle work even without that A after the # symbol ? Because it is already present as an argument to be passed after the function name.
Your code will create an anonymous function f which accepts one input A. In particular f will call the function DistanceGauss(A,x_axis,Y_target,Y_initial,numOf,modus); where the value of A is whatever you input with f(A) and the other inputs must already exist in your workspace and will be passed to the function. Note: if the other variables don't exist you should get an error when calling f.
Now a reasonable question is why would you want to do this you could just call DistanceGauss(A,x_axis,Y_target,Y_initial,numOf,modus); directly with whatever values you want, without having to worry about whether some of them exist.
There are two main reasons I can think of why you would do this (I'm sure there are others). Firstly for simplicity where your other inputs don't change and you don't want to have to keep retyping them or have users accidentally change them.
The other reason where you would want this is when optimizing/minimizing a function, for example with fminsearch. The matlab optimization functions will vary all inputs. If you want only vary some of them you can use this sort of syntax to reduce the number of input variables.
As to what A actually is in your case this will depend on what it does in DistanceGauss, which is not a standard MATLAB function so I suggest you look at the code for that.
"f(A)" or "f of A" or "The function of A" here has the handle "f"
DistanceGauss() here is another function that was defined elsewhere in your code.
You would set x_axis, Y_target, Y_initial, numOf, & modus before creating the function f. These arguments would stay the same for Function f, even if you try and set them again later.
'A' though, is different. You don't set it before you make the function. You can later operate on all values of A, such as if you plot the function or get the integral of the function. In that case, it would be performing the DistanceGauss function on every value of 'A', (though we can't see here what DistanceGauss function does. )
Anonymous function should be defined such as:
sqr = #(x) x.^2;
in which x shows the variable of the the function and there is no name for it (it is called anonymous!).
Although you can do something like this:
c = 10;
mygrid = #(x,y) ndgrid((-x:x/c:x),(-y:y/c:y));
[x,y] = mygrid(pi,2*pi);
in which you are modifying an existing function ndgrid to make a new anonymous function.
In your case also:
f = #(A)DistanceGauss(A,x_axis,Y_target,Y_initial,numOf,modus);
This is a new anonymous function by modifying the function DistanceGauss that you may want to have a single variable A.
If you remove (A) from the code, then f would be a handle to the existing function DistanceGauss:
f = #DistanceGauss;
Now you can evaluate the function simply by using the handle:
f(A,x_axis,...)

Number of outputs from constant anonymous function (anonymous function not known a priori)

This question may initially appear similar to this other question but my situation is a little bit different.
I have a function 'deriv' that takes a symbolic expression as its input, then takes the first derivative of that symbolic expression. That derivative is then converted into an anonymous function using matlabFunction(), and is then evaluated over an array of points. I also use the anonymous function later in some other code.
The problem I'm having is that sometimes the input symbolic expression happens to be linear, and thus the derivative is constant; therefore the anonymous function is also a constant. When I evaluate the anonymous function over the array of points, I only get one output instead of an array of outputs.
Here's some code showing what I'm doing. For the sake of simplicity here, let's assume that the symbolic input expressions will involve only one symbolic variable called q.
function[derivFun,derivVals] = deriv(input)
derivSym = diff(input,q);
derivFun = matlabFunction(derivSym,'vars',q);
evalPoints = [1;2;3;4;5]; %in my true application, a much larger array
derivVals = derivFun(evalPoints);
end
So if the input is q^2, then the output derivVals will be [2;4;6;8;10]. But if the input happens to be, say, 3*q, then derivVals will be 3 (just a single scalar). What I'd like is for derivVals to be [3;3;3;3;3].
That is, I'd like derivVals to be the same size as evalPoints even if the input function happens to be linear (or constant). And I don't know ahead of time what the input expression will be.
Can anyone give suggestions for a scheme that would do that? I understand that a constant anonymous function will just return a single constant scalar, regardless of the size of its input. What I'm hoping for is perhaps some way to recognize when the anonymous function is constant and then still cause derivVals to be the same size as evalPoints.
I know that I could use a for loop to evaluate derivFun for every row of evalPoints, but I'd like to avoid using such a loop if possible.
Thank you for your time and consideration.
I think that this is a slightly simpler solution. The issue is that you're using matlabFunction, which simplifies down the equations and doesn't allow much customization. However, you can create an anonymous function of an anonymous function. Just add the this line right after your matlabFunction line:
derivFun = #(evalPoints)derivFun(evalPoints)+zeros(size(evalPoints));
This only evaluates the original derivFun once. However, I do like you symvar solution (just remember that adding zeros is always better than multiplying ones).
Not 100% sure I got the problem correctly.
Would this solve your issue?:
if isscalar(derivVals)
derivVals = repmat(derivVals, size(evalPoints));
end

When using a multiple-output matlab function, do i need to callback all variables?

When using a multiple-output matlab function, do i need to callback all variables? or can I just take the first two variables? (if so..is it not recommended?)
lets say in function.m
[a, b, c] = function( )
in main.m
[var1, var2] = function;
When calling (almost) any function in matlab you can request fewer outputs than it specifies. So, yes the example you give should work perfectly fine.
There are some clever things you can do with this, such as using nargout within a function to see how many output arguments have been requested and only calculating the values that have been requested as an optimisation trick.
It depends on the definition of the function, and exactly which of the outputs you want to get.
Not all the function allow to do it, you can find all the options for each function in the beginning of the help documentation on the specific function.
If you want only the 2nd, or 3rd outputs, and you want also to save the computation-time of the results that does not interesting, you can use ~ option, like this (for versions 2009b and later):
[~, var1, var2]=function
Many functions allow for options to passed that change how the function behaves. I used/wrote various numerical solving functions a bit and one that nice amount of option, for instance is the LSMR function(s).
Otherwise, if you can manipulate the original either introduce an input(s) to do so before or at the end with an inline subroutine to generate the outputs you want.
Or if you can't it will return as either a cell array or a vector and you can pass an anonymous function to generate the desired outputs that way.
Really, can be done many ways. Very contextual.

Trick matlab into thinking gpuArray is scalar

I have following function which I would like to apply to each element:
function result = f(a, b, bs)
% Simplified code
result = a
for i=0:bs
result = dosomething(result, b(i))
end
end
% Use
arrayfun(#result, gpuArray(A), gpuArray(B), size(B));
Is there a way of 'tricking' MATLAB into thinking b is scalar for purpose of passing to function?
Unfortunately, there's currently no way to do this for two reasons: firstly, the ARRAYFUN implementation for gpuArrays always insists that inputs are either scalar or all of the same size. Secondly, the gpuArray ARRAYFUN body does not currently support either indexing or anonymous functions that refer to variables from the outer scope.
The only way to do it is to use bsxfun function:
C = bsxfun(f, A, B') % A is column vector
is more or less equivalent to
C(i,j) = f(A(i,1), B(j,1))
Other useful function is repmat.
Then the series of matrices and vectors are JITted so there is in effect no O(MN) space penalty (checked by nvidia-smi).
I'm not entirely sure what you want to do, but I suspect that you want the whole of array B to be passed into the function on each call to result. The best way of achieving this would be to use an anonymous function something like so (untested code):
arrayfun( #(a_in) result(a_in, gpuArray(B), size(B)), gpuArray(A) );
What this should do is to make an anonymous function which only takes one argument (a_in), and calls result (actually f in your function header), with the full B array, regardless of the value of a_in.
So on each iteration of arrayfun, result will be called using just one slice of A, but the whole of B.
A more syntaxically explicit way of writing the above code would be as follows:
my_anon_fun = #(a_in) result(a_in, gpuArray(B), size(B));
arrayfun( my_anon_fun , gpuArray(A) );
A disclaimer: code is untested, and I have little experience with code using gpuArray so this may not apply.

A command to catch the variable values from the workspace, inside a function

when I am doing a function in Matlab. Sometimes I have equations and every one of these have constants. Then, I have to declare these constants inside my function. I wonder if there is a way to call the values of that constants from outside of the function, if I have their values on the workspace.
I don't want to write this values as inputs of my function in the function declaration.
In addition to the solutions provided by Iterator, which are all great, I think you have some other options.
First of all, I would like to warn you about global variables (as Iterator also did): these introduce hidden dependencies and make it much more cumbersome to reuse and debug your code. If your only concern is ease of use when calling the functions, I would suggest you pass along a struct containing those constants. That has the advantage that you can easily save those constants together. Unless you know what you're doing, do yourself a favor and stay away from global variables (and functions such as eval, evalin and assignin).
Next to global, evalin and passing structs, there is another mechanism for global state: preferences. These are to be used when it concerns a nearly immutable setting of your code. These are unfit for passing around actual raw data.
If all you want is a more or less clean syntax for calling a certain function, this can be achieved in a few different ways:
You could use a variable number of parameters. This is the best option when your constants have a default value. I will explain by means of an example, e.g. a regular sine wave y = A*sin(2*pi*t/T) (A is the amplitude, T the period). In MATLAB one would implement this as:
function y = sinewave(t,A,T)
y = A*sin(2*pi*t/T);
When calling this function, we need to provide all parameters. If we extend this function to something like the following, we can omit the A and T parameters:
function y = sinewave(t,A,T)
if nargin < 3
T = 1; % default period is 1
if nargin < 2
A = 1; % default amplitude 1
end
end
y = A*sin(2*pi*t/T);
This uses the construct nargin, if you want to know more, it is worthwhile to consult the MATLAB help for nargin, varargin, varargout and nargout. However, do note that you have to provide a value for A when you want to provide the value of T. There is a more convenient way to get even better behavior:
function y = sinewave(t,A,T)
if ~exists('T','var') || isempty(T)
T = 1; % default period is 1
end
if ~exists('A','var') || isempty(A)
A = 1; % default amplitude 1
end
y = A*sin(2*pi*t/T);
This has the benefits that it is more clear what is happening and you could omit A but still specify T (the same can be done for the previous example, but that gets complicated quite easily when you have a lot of parameters). You can do such things by calling sinewave(1:10,[],4) where A will retain it's default value. If an empty input should be valid, you should use another invalid input (e.g. NaN, inf or a negative value for a parameter that is known to be positive, ...).
Using the function above, all the following calls are equivalent:
t = rand(1,10);
y1 = sinewave(t,1,1);
y2 = sinewave(t,1);
y3 = sinewave(t);
If the parameters don't have default values, you could wrap the function into a function handle which fills in those parameters. This is something you might need to do when you are using some toolboxes that impose constraints onto the functions that are to be used. This is the case in the Optimization Toolbox.
I will consider the sinewave function again, but this time I use the first definition (i.e. without a variable number of parameters). Then you could work with a function handle:
f = #(x)(sinewave(x,1,1));
You can work with f as you would with an other function:
e.g. f(10) will evaluate sinewave(10,1,1).
That way you can write a general function (i.e. sinewave that is as general and simple as possible) but you create a function (handle) on the fly with the constants substituted. This allows you to work with that function, but also prevents global storage of data.
You can of course combine different solutions: e.g. create function handle to a function with a variable number of parameters that sets a certain global variable.
The easiest way to address this is via global variable:
http://www.mathworks.com/help/techdoc/ref/global.html
You can also get the values in other workspaces, including the base or parent workspace, but this is ill-advised, as you do not necessarily know what wraps a given function.
If you want to go that route, take a look at the evalin function:
http://www.mathworks.com/help/techdoc/ref/evalin.html
Still, the standard method is to pass all of the variables you need. You can put these into a struct, if you wish, and only pass the one struct.