How to achieve vector input/output with different operations using anonymous functions? - matlab

Suppose I want to create an anonymous function that does the following
f: [a, b] -> [a^2, b/2]
Since the operation is different on a and b I haven't been able to figure out how. Is this at all possible in matlab? My function will have the constraints R^2 -> R^2

Because of the specific constraints, it would have to be something like this:
f = #(x) [x(1)^2, x(2)/2];
You can't explicitly define outputs in an anonymous function any other way.

Though you already accepted PQL's answer your question actually reads like you're looking for this solution using deal:
f = #(x,y) deal( x^2, y/2 );
[u,v] = f(2,2)
returning:
u =
4
v =
1

Looking at the matlab help for anonymous functions looking at section functions with multiple inputs or outputs, I would think that you would be able to do something like the code below
Second edit Turns out if you use deal (as given by thewaywewalk) or if you dereference the anonymous function you can get the same thing.
crazyfunction=#(a,b) {(a^2),(b/2)};
[x y]=crazyfunction(a,b);
Quick and dirty test shows that this will give no syntax errors
>> f = #(x,y) {x^2, y/2};
>> f(2,2)
ans =
[4] [1]
EDIT Fired up matlab to see my original answer would actually work, doesn't look like it (see second edit you need to use {}).
You would either daisy chain two anonymous functions together in such a way that a and b are part of anonymous function c or use a struct of anonymous functions effectively as shown below
crazyfunction={#(a) (a^2); #(b) (b/2);}
[crazyfunction{1](7) crazyfunction{2}(9)]
ans =
49.0000 4.5

Related

MATLAB: Defining a function in terms of another function

If I have a function f(x,y), I want to know how to define another function (say g) where g(x) = f(x,y), where y has been defined beforehand, either explicitly or as the input of another function.
I know this is probably quite simple but my code does not seem to work and I cannot find a solution in the documentation.
You are probably looking for anonymous functions.
A very common use-case is minimiziation. You often need to minimize a function of multiple variables along a single parameter. This leaves you without the option of just passing in constants for the remaining parameters.
An anonymous definition of g would look like this:
g = #(x) f(x, y)
y would have to be a variable defined in the current workspace. The value of y is bound permanently to the function. Whether you do clear y or assign a different value to it, the value of y used in g will be whatever it was when you first created the function handle.
As another, now deleted, answer mentioned, you could use the much uglier approach of using global variables.
The disadvantages are that your code will be hard to read and maintain. The value of the variable can change in many places. Finally, there are simply better ways of doing it available in modern versions of MATLAB like nested functions, even if anonymous functions don't work for you for some reason.
The advantages are that you can make g a simple stand alone function. Unlike the anonymous version, you will get different results if you change the value of y in the base workspace, just be careful not to clear it.
The main thing to remember with globals is that each function/workspace wishing to share the value must declare the name global (before assigning to it to avoid a warning).
In the base workspace:
global y
y = ...
In g.m:
function [z] = g(x)
global y;
z = f(x, y);
I am not particularly recommending this technique, but it helps to be aware of it in case you can't express g as a single statement.
A note about warnings. Both anonymous functions and globals will warn you about assigning to a variable that already exists. That is why putting a global declaration as the first line of a function is generally good practice.
f = #(a,b) a^2 + b^2;
y = 4;
g = #(x) f(x,y);
g(2)
ans = 20

Problems using anonymous function in matlab

For function like
fun = #(x,y) x+y
Can I annotate x to 1 and generate the function equals to #(y) 1+y? Is there anyway to do that without creating a new function?
I am asking this question because I can't modify the function with part of the fixed value and apply it to functions like arrayfun
It's unclear what you mean by "do that without creating a new function" since the first part of the question asks about how to "generate" a new function. You have basically three choices, depending on what you wanted:
Just call fun(1,y) where you need the value.
Define another anonymous function g = #(y) fun(1,y).
Use the direct definition h = #(y) 1 + y.

Can I Expand "Nested" Symbolic Functions in Matlab?

I'm trying to model the effect of different filter "building blocks" on a system which is a construct based on these filters.
I would like the basic filters to be "modular", i.e. they should be "replaceable", without rewriting the construct which is based upon the basic filters.
For example, I have a system of filters G_0, G_1, which is defined in terms of some basic filters called H_0 and H_1.
I'm trying to do the following:
syms z
syms H_0(z) H_1(z)
G_0(z)=H_0(z^(4))*H_0(z^(2))*H_0(z)
G_1(z)=H_1(z^(4))*H_0(z^(2))*H_0(z)
This declares the z-domain I'd like to work in, and a construct of two filters G_0,G_1, based on the basic filters H_0,H_1.
Now, I'm trying to evaluate the construct in terms of some basic filters:
H_1(z) = 1+z^-1
H_0(z) = 1+0*z^-1
What I would like to get at this point is an expanded polynomial of z.
E.g. for the declarations above, I'd like to see that G_0(z)=1, and that G_1(z)=1+z^(-4).
I've tried stuff like "subs(G_0(z))", "formula(G_0(z))", "formula(subs(subs(G_0(z))))", but I keep getting result in terms of H_0 and H_1.
Any advice? Many thanks in advance.
Edit - some clarifications:
In reality, I have 10-20 transfer functions like G_0 and G_1, so I'm trying to avoid re-declaring all of them every time I change the basic blocks H_0 and H_1. The basic blocks H_0 and H_1 would actually be of a much higher degree than they are in the example here.
G_0 and G_1 will not change after being declared, only H_0 and H_1 will.
H_0(z^2) means using z^2 as an argument for H_0(z). So wherever z appears in the declaration of H_0, z^2 should be plugged in
The desired output is a function in terms of z, not H_0 and H_1.
A workable hack is having an m-File containing the declarations of the construct (G_0 and G_1 in this example), which is run every time H_0 and H_1 are redefined. I was wondering if there's a more elegant way of doing it, along the lines of the (non-working) code shown above.
This seems to work quite nicely, and is very easily extendable. I redefined H_0 to H_1 as an example only.
syms z
H_1(z) = 1+z^-1;
H_0(z) = 1+0*z^-1;
G_0=#(Ha,z) Ha(z^(4))*Ha(z^(2))*Ha(z);
G_1=#(Ha,Hb,z) Hb(z^(4))*Ha(z^(2))*Ha(z);
G_0(H_0,z)
G_1(H_0,H_1,z)
H_0=#(z) H_1(z);
G_0(H_0,z)
G_1(H_0,H_1,z)
This seems to be a namespace issue. You can't define a symbolic expression or function in terms of arbitrary/abstract symfuns and then later on define these symfuns explicitly and be able to use them to obtain an exploit form of the original symbolic expression or function (at least not easily). Here's an example of how a symbolic function can be replaced by name:
syms z y(z)
x(z) = y(z);
y(z) = z^2; % Redefines y(z)
subs(x,'y(z)',y)
Unfortunately, this method depends on specifying the function(s) to be substituted exactly – because strings are used, Matlab sees arbitrary/abstract symfuns with different arguments as different functions. So the following example does not work as it returns y(z^2):
syms z y(z)
x(z) = y(z^2); % Function of z^2 instead
y(z) = z^2;
subs(x,'y(z)',y)
But if the last line was changed to subs(x,'y(z^2)',y) it would work.
So one option might be to form strings for case, but that seems overly complex and inelegant. I think that it would make more sense to simply not explicitly (re)define your arbitrary/abstract H_0, H_1, etc. functions and instead use other variables. In terms of the simple example:
syms z y(z)
x(z) = y(z^2);
y_(z) = z^2; % Create new explicit symfun
subs(x,y,y_)
which returns z^4. For your code:
syms z H_0(z) H_1(z)
G_0(z) = H_0(z^4)*H_0(z^2)*H_0(z);
G_1(z) = H_1(z^4)*H_0(z^2)*H_0(z);
H_0_(z) = 1+0*z^-1;
H_1_(z) = 1+z^-1;
subs(G_0, {H_0, H_1}, {H_0_, H_1_})
subs(G_1, {H_0, H_1}, {H_0_, H_1_})
which returns
ans(z) =
1
ans(z) =
1/z^4 + 1
You can then change H_0_ and H_1_, etc. at will and use subs to evaluateG_1andG_2` again.

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.

Evaluating multivariate functions with some arguments fixed

I have an anonymous multivariate function. Is it possible to find the value of the function by fixing one of the values?
Here is what I would like to happen:
>> f = #(a, b) a + b;
>> f(1, b)
ans =
1 + b
I understand that the input I gave above is syntactically invalid, since variables must contain values. Is there a way I can accomplish this through another Matlab tool?
Thanks.
There are two ways you can accomplish this. Either, you get the symbolic toolbox, and declare b as a symbolic variable before evaluating f, or you create a new anonymous function like this:
g = #(b)f(1,b);