Combining Anonymous Functions in MATLAB - matlab

I have a cell array of anonymous function handles, and would like to create one anonymous function that returns the vector containing the output of each function.
What I have:
ca = {#(X) f(X), #(X)g(X), ...}
What I want:
h = #(X) [ca{1}(X), ca{2}(X), ...]

Yet another way to it:
You can use cellfun to apply a function to each cell array element, which gives you a vector with the respective results. The trick is to apply a function that plugs some value into the function handle that is stored in the cell array.
ca = {#(X) X, #(X) X+1, #(X) X^2};
h=#(x) cellfun(#(y) y(x), ca);
gives
>> h(4)
ans =
4 5 16

You can use str2func to create your anonymous function without having to resort to eval:
ca = {#sin,#cos,#tan}
%# create a string, using sprintf for any number
%# of functions in ca
cc = str2func(['#(x)[',sprintf('ca{%i}(x) ',1:length(ca)),']'])
cc =
#(x)[ca{1}(x),ca{2}(x),ca{3}(x)]
cc(pi/4)
ans =
0.7071 0.7071 1.0000

I found that by naming each function, I could get them to fit into an array. I don't quite understand why this works, but it did.
f = ca{1};
g = ca{2};
h = #(X) [f(X), g(X)];
I feel like there should be an easier way to do this. Because I am dealing with an unknown number of functions, I had to use eval() to create the variables, which is a bad sign. On the other hand, calling the new function works like it is supposed to.

Related

Use a function as input for another function

Hi I am new to matlab so not familiar with its grammar.
I want to write a function to solve some functions using specific algo.
What I want to do is to write a function using another function which I want to slove as input.
For example, if I want to get the root of x^2 - 1 = 0 ,I need to plug in this function as in input.
my code is like
function [y] = brent(f, x0, x1, max_iter, tolerance)
fx0 = f(x0)
fx1 = f(x1)
......
end
f is the function I want to solve. My question is how should I write the code so the function 'brent' can use the function 'f' to calculate the values at specific points.
ex. In the second line, I need to get the value of f(x0) (x0 is a point).
Matlab talks about function handles. Those can be input parameter as anything:
Write your main function:
function a = func(f,x)
a = f(x) + 7;
Define your function to be input, and call 'normally'
>> myfun = #(x) x^2-1;
>> func(myfun,3)
ans =
15
>> func(#sin,0)
ans =
7
see:
https://se.mathworks.com/help/matlab/matlab_prog/creating-a-function-handle.html

Derivative of Anonymous Function

I have the following anonymous function:
f = #(x)x^2+2*x+1
I'm using this so that I use it in the following way:
f(0) = 1
But what if I want to find the derivative of such a function while still keeping it's anonymous function capability? I've tried doing the following but it doesn't work:
f1 = #(x)diff(f(x))
but this just returns
[]
Any thoughts on how to accomplish this?
Of course I could manually do this in 3 seconds but that's not the point...
If you have symbolic math toolbox, you can use symbolic functions to achieve the desired as follows:
syms x
myFun=x^2+2*x+1;
f=symfun(myFun,x);
f1=symfun(diff(f),x);
%Check the values
f(2)
f1(2)
You should get 9 and 6 as answers.
When you do diff of a vector of n elements it just outputs another vector of n-1 elements with the consecutive differences.. so when you put a 1 element vector you get an empty one.
A way to go would be to decide an epsilon and use the Newton's difference quotient:
epsilon = 1e-10;
f = #(x) x^2+2*x+1;
f1 = #(x) (f(x+epsilon) - f(x)) / epsilon;
or just do the math and write down the formula:
f1 = #(x) 2*x+2;
http://en.wikipedia.org/wiki/Numerical_differentiation
#jollypianoman this works to me. Actually you need to say that the symfun has to be evaluate using eval command, then you get all the features of an anonymous function. the best is to read the example below...
clear
N0=1;N1=5;
N=#(t) N0+N1*sin(t);
syms t
Ndot=symfun(diff(N(t)),t);
Ndot_t=#(t) eval(Ndot);
Ndot_t(0)
ans = 5
Ndot_t(1)
ans = 2.7015
[tstop] = fsolve(Ndot_t,pi/3)
tstop =
1.5708
cheers,
AP

arrayfun when each row of the array is an input

My situation is that I would like to map a scalar array A by a function with handle fun sending a row vector to a row vector, to acquire B, such that B(i,:) = fun(A(i,:)).
The most reasonable solution I could think of looks like:
temp = mat2cell(A,ones(1,size(A,1)),size(A,2));
B = cell2mat(cellfun(fun,temp,'UniformOutput',0));
However, the conversion to cells and back seems like overkill (and is assumably computationally expensive). It is also not clear to me why cellfun complains about non-uniform output. Does a more efficient way jump to mind?
There's another solution that employs accumarray. Although not as fancy as bsxfun, it doesn't require declaring a helper function:
subs = ndgrid(1:size(A, 1));
B = accumarray(subs(:), A(:), [], #fun); %// #fun is the function handle
You can do this without using cell arrays at all with bsxfun.
Using Marcin's example data and function:
A =[ 0.5669 0.4315 0.4515 0.7664 0.5923; ...
0.8337 0.7317 0.4898 0.2535 0.7506; ...
0.3321 0.5424 0.4585 0.8004 0.9564];
fun = #(x,y) x*2;
B= bsxfun(fun,A,1);
B =
1.1338 0.8630 0.9030 1.5328 1.1846
1.6674 1.4634 0.9796 0.5070 1.5012
0.6642 1.0848 0.9170 1.6008 1.9128
Edit:
As Eitan noted, fun above may need to be a wrapper on your 'real' anonymous function so it would be more complete to show my solution as:
fun = #(x) x *2; % Replace with actual anonymous function
fun2 = #(x,y) fun(x); % Wrapper on fun to discard unused 2nd parameter
B= bsxfun(fun2,A,1);
I know this is an old post, but in case someone else sees this, Matlab added rowfun to the 2013b release which can evaluate rows of tables and returns a column vector. Here is an example:
f = #(c) sum(c.^2);
x=[1 2;
3 4;
5 6];
z=table2array(rowfun(f,table(x)))
z=
5
25
61
I think you could do as follows, if I understand what u want to do:
A = rand(3, 5);
fun = #(x) x*2;
B = cell2mat(arrayfun(#(i) fun(A(i, :)), 1:size(A, 1), 'UniformOutput', false)');
% example results:
A =
0.5669 0.4315 0.4515 0.7664 0.5923
0.8337 0.7317 0.4898 0.2535 0.7506
0.3321 0.5424 0.4585 0.8004 0.9564
B =
1.1338 0.8630 0.9030 1.5328 1.1845
1.6675 1.4635 0.9795 0.5071 1.5013
0.6642 1.0848 0.9169 1.6008 1.9128
This will apply fun to each element of row in A. This is based on the post here. Also there u find more info and explanation what is happening or alternative ways of applying function to rows in an array.

MATLAB Function (Solving an Error)

I have one file with the following code:
function fx=ff(x)
fx=x;
I have another file with the following code:
function g = LaplaceTransform(s,N)
g = ff(x)*exp(-s*x);
a=0;
b=1;
If=0;
h=(b-a)/N;
If=If+g(a)*h/2+g(b)*h/2;
for i=1:(N-1)
If=If+g(a+h*i)*h;
end;
If
Whenever I run the second file, I get the following error:
Undefined function or variable 'x'.
What I am trying to do is integrate the function g between 0 and 1 using trapezoidal approximations. However, I am unsure how to deal with x and that is clearly causing problems as can be seen with the error.
Any help would be great. Thanks.
Looks like what you're trying to do is create a function in the variable g. That is, you want the first line to mean,
"Let g(x) be a function that is calculated like this: ff(x)*exp(-s*x)",
rather than
"calculate the value of ff(x)*exp(-s*x) and put the result in g".
Solution
You can create a subfunction for this
function result = g(x)
result = ff(x) * exp(-s * x);
end
Or you can create an anonymous function
g = #(x) ff(x) * exp(-s * x);
Then you can use g(a), g(b), etc to calculate what you want.
You can also use the TRAPZ function to perform trapezoidal numerical integration. Here is an example:
%# parameters
a = 0; b = 1;
N = 100; s = 1;
f = #(x) x;
%# integration
X = linspace(a,b,N);
Y = f(X).*exp(-s*X);
If = trapz(X,Y) %# value returned: 0.26423
%# plot
area(X,Y, 'FaceColor',[.5 .8 .9], 'EdgeColor','b', 'LineWidth',2)
grid on, set(gca, 'Layer','top', 'XLim',[a-0.5 b+0.5])
title('$\int_0^1 f(x) e^{-sx} \,dx$', 'Interpreter','latex', 'FontSize',14)
The error message here is about as self-explanatory as it gets. You aren't defining a variable called x, so when you reference it on the first line of your function, MATLAB doesn't know what to use. You need to either define it in the function before referencing it, pass it into the function, or define it somewhere further up the stack so that it will be accessible when you call LaplaceTransform.
Since you're trying to numerically integrate with respect to x, I'm guessing you want x to take on values evenly spaced on your domain [0,1]. You could accomplish this using e.g.
x = linspace(a,b,N);
EDIT: There are a couple of other problems here: first, when you define g, you need to use .* instead of * to multiply the elements in the arrays (by default MATLAB interprets multiplication as matrix multiplication). Second, your calls g(a) and g(b) are treating g as a function instead of as an array of function values. This is something that takes some getting used to in MATLAB; instead of g(a), you really want the first element of the vector g, which is given by g(1). Similarly, instead of g(b), you want the last element of g, which is given by g(length(g)) or g(end). If this doesn't make sense, I'd suggest looking at a basic MATLAB tutorial to get a handle on how vectors and functions are used.

Merging function handles in MATLAB

I'm currently coding a simulation in MATLAB and need some help in regards to an issue that I've been having.
I'm working on a problem where I have n separate anonymous function handles fi stored in cell array, each of which accepts a 1×1 numeric array xi and returns a 1×1 numeric array yi.
I'm trying to combine each of these anonymous function handles into a single anonymous function handle that accepts a single n×1 numeric array X and returns a single n×1 numeric array Y, where the i-th elements of X and Y are xi and yi = fi (xi), respectively.
As an example, let n = 2 and f_1, f_2 be two function handles that input and output 1×1 arrays and are stored in a cell array named functions:
f_1 = #(x_1) x_1^2
f_2 = #(x_2) x_2^3
functions = {f_1, f_2}
In this example, I basically need to be able to use f_1 and f_2 to construct a function handle F that inputs and outputs a 2×1 numeric array, like so:
F = #(x) [f_1(x(1,1)); f_2(x(2,1))]
The question is how to generalize this for an arbitrary number n of such functions.
It is difficult to define such a function using the inline #()-anonymous
syntax (because of the requirement for the function’s body to be
an expression).
However, it is possible to define a regular function that runs over
the items of a given vector and applies the functions from a given
cell array to those items:
function y = apply_funcs(f, x)
assert(length(f) == length(x));
y = x;
for i = 1 : length(f)
y(i) = feval(f{i}, x(i));
end
end
If it is necessary to pass this function as an argument to another
one, just reference it by taking its #-handle:
F = #apply_funcs
This can be solved using a solution I provided to a similar previous question, although there will be some differences regarding how you format the input arguments. You can achieve what you want using the functions CELLFUN and FEVAL to evaluate your anonymous functions in one line, and the function NUM2CELL to convert your input vector to a cell array to be used by CELLFUN:
f_1 = #(x_1) x_1^2; %# First anonymous function
f_2 = #(x_2) x_2^3; %# Second anonymous function
fcnArray = {f_1; f_2}; %# Cell array of function handles
F = #(x) cellfun(#feval,fcnArray(:),num2cell(x(:)));
Note that I used the name fcnArray for the cell array of function handles, since the name functions is already used for the built-in function FUNCTIONS. The colon operator (:) is used to turn fcnArray and the input argument x into column vectors if they aren't already. This ensures that the output is a column vector.
And here are a few test cases:
>> F([2;2])
ans =
4
8
>> F([1;3])
ans =
1
27
#you can try
f=#(x)[x(1)^2;x(2)^3]
>>f([1,2])
ans =
1
8
>>f([2,3])
ans =
4
27