Are there other ways to apply a function in Matlab? - matlab

If I want to use real() or abs() on some variable or vector like x, I have to write real(x) or abs(x). In Mathematica someone can use either Re[x] or Re#x. What is the equivalent of # in Matlab?
I mean using # is a shorthand notation for [] in Mathematica. Is there such a shorthand notation in Matlab?

As the other answers states; no, there is no short-hand notation similar to the ones you find in Mathematica. However, if you use the same combinations of functions often, you can create anonymous function handles that might improve the readability.
combinedfun = #(x) myfun1(myfun2(x))
or, if you want combinations of built-in functions:
absreal = #(x) abs(real(x))
In a real project I would not use anonymous functions like these, as there is not control of input arguments etc., but it might be handy if you want to do some calculations on the fly.

You can use arrayfun which needs a function to be applied on each element in x
Something like following :
arrayfun( #(y)abs(y), x )
However for simpler function simply use it on entire vector/variable/element :
abs(x)

There is no general shorthand notation for function input. But if your input arguments are strings then you can just use space to separate the function and its input arguments. So
strcat('a', 'b')
is same as
strcat a b
It cannot be used if the arguments are store in variables.

Related

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

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.

Matlab symbolic function conversion without dot for matrix operation

When converting symbolic expression to matlabFunction, expression like
x=sym('x')
f=- x^3/6 + x
g=matlabFunction(f)
-> #(x)x-x.^3.*(1.0./6.0)
which is not what I want because x is gonna be a matrix and my application requires actual matrix multiplication such as x^3 instead of the dot product form of x.^3
The only way to get it working is to use anonymous function, i.e.
g=#(x) - x^3/6 + x
->#(x)-x^3/6+x
However, the issue with anonymous function is that I cannot use substitution but to type the entire formulation, i.e.
g=#(x) f
-> #(x)f which shows that expression substitution does not work
In short, I will need to solve either one of the technical difficulties: (1) If I use matlabFunction, how do I remove all the dot after the conversion? or (2) If I use anonymous function, how do I bypass typing the symbolic expression if I have already defined 'f' for the expression?
I am totally lost here and I hope someone familiar with matlab can give me 2 cents.
Thank you!
You can convert the sym object to a string when calculating the anonymous function:
g=#(x)eval(char(f))
Alternatively, you can use the following code
h=eval(['#(x)' char(f)])
instead of matlabFunction

How to use pcg with a function in MATLAB

I am going to solve an inverse problem, AX=b, using conjugate gradient method in MATLAB. I want to use pcg function in MATLAB and as I know instead of matrix A I can use a function.
I have a function for example afun which has some entries. In the documents, I have seen that the afun function is entered in pcg function without entries, however, when I do the same, the error not enough input arguments appears. I use a code like this:
b = afun(ent1,ent2);
x = pcg(#afun,b,tol,max_iter);
How should I use my function in pcg?
According to the documentation, the function handle should the have the signature afun(x) and return A*x.
Your function apparently takes two inputs... You need to use a anonymous function to wrap the call, something like this:
% I dont know what these ent1/ent2 represent exactly,
% so you must complete the ".." part first
fcn = #(x) afun(x, ..)
% now you can call PCG
x = pcg(fcn, b, tol, maxiter);
There is a doc page explaining how to parameterize functions to pass extra args using function handles.

How can I get Matlab to use the variable value instead of name

In my code, I have a line that looks like this:
f=#(test) bf{i}(5);
where bf is a cell array with functions from str2func() stored in it, i is a variable storing an integer, and the 5 is the argument to pass to the function. How can I get matlab to evaluate the line using the current value of i? Right now when I display f it outputs:
#(test)bf{i}(5)
Lets say i=1, I want it to output:
#(test)bf{1}(5)
Although technically the bf{1} should also be replaced with whatever function is stored in bf{1}. How can I force matlab to evaluate the variables in this statement?
When you create a function handle, the workspace variables are copied and the expression is evaluated when you call the function handle (Typically not a problem in memory consumption, matlab stores only changes).
Now the problem is, to tell Matlab when to evaluate what part of the expression.
If you are aiming for a better performance, pre-evaluate all constant parts of the function. Let's say your function is #(x)(g(3).*f(x)), in this case matlab would evaluate g(3) on every call.
Instead use:
f=#(x)(x.^2)
g_3=g(3)
h=#(x)(g_3.*f(x))
Now having the constant parts evaluated, you want to see the constants instead of the variabe name. I know two ways to achieve this.
You can use the symbolic toolbox, basically converting the function handle to a symbolic function, then to a function handle again. This not only displays the constants, but also substitutes f. This is not possible for all functions.
>> matlabFunction(h(sym('x')))
ans =
#(x)x.^2.*4.2e1
Another possibility is to use eval:
h=eval(['#(x)',sprintf('%e',g_3),'.*f(x)'])
Pre-evaluating constant parts of the expressions as I did in the first step is typically recommendable, but both solutions to get the constant visible in your function handle aren't really recommendable. The first solution using matlabFunction only applies to some functions, while the second comes with all the disadvantages of eval.

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.