Merging function handles in MATLAB - 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

Related

how to evaluate to multivariable function

Consider the function f(y1,y2,y3,y4,z1)=(-(z1^3)/(y3^2))(3(y2-y1+y3^(-1)-z1/10)^2+(1/5)(y2-y1+y3^(-1)-(z1)/10))-y4 with 5 variables. When I put f(1,1,1,1,1) I find the answer but when I write f(v) in which v=(1,1,1,1,1) matlab does not work. How can I do that (by the second way)?
You could write a wrapper function, that will take a vector as input argument and 'unpacks' this vector before calling your function.
f(y1,y2,y3,y4,z1) = (-(z1^3)/ ...; % your function
fv(v) = f(v(1),v(2),v(3),v(4),v(5));
Or alternatively, make f refer to elements in the input vector by using the appropriate indices:
f(v) = (-(v(5)^3)/(v(3)^2)); ... % etc.

Calculating the numeric derivative

So i'm a little confounded by how to structure my problem.
So the assignment states as following:
Type a m-file numerical_derivative.m that performs numerical derivation. Use
it to calculate f'(-3) when f(x) = 3x^2 /(ln(1-x))
In the m-file you to use h = 10^-6 and have the following mainfunction:
function y = numericalderivative (f, x)
% Calculates the numerical value in the case of f in punk x.
% --- Input ---
% f: function handle f(x)
% x: the point where the derivative is calculated
% --- output ---
% y: the numerical derivative of f on the point x
If I want to save it as a file and run the program in matlab, does't it make it redundant to use handles then?
I won't give you the answer to your homework, but perhaps a simpler example would help.
Consider the following problem
Write a function named fdiff which takes the following two arguments:
A function f represented by a function handle which takes one argument,
and a point x which can be assumed to be in the domain of the f.
Write fdiff so that it returns the value f(x) - f(x-1)
Solution (would be in the file named fdiff.m)
function result = fdiff(f, x)
result = f(x) - f(x-1);
end
Example Use Cases
>> my_function1 = #(x) 3*x^2 /(log(1-x));
>> fdiff(my_function1, -3)
ans =
-10.3477
>> my_function2 = #(x) x^2;
>> fdiff(my_function2, 5)
ans =
9
What you've created with fdiff is a function which takes another function as an input. As you can see it doesn't just work for 3*x^2 /(log(1-x)) but any function you want to define.
The purpose of your assignment is to create something very similar, except instead of computing f(x) - f(x-1), you are asked write a function which approximates f'(x). Your use-case will be nearly identical to the first example except instead of fdiff your function will be named numericalderivative.
Note
In case it's not clear, the second example defines the my_function2 as x^2. The value returned by fdiff(my_function2, 5) is therefore 5^2 - 4^2 = 9.
When you make this as a function file and run this in MATLAB without any input arguments i.e., 'f' and 'x', it will give you the error: 'not enough input arguments'. In order to run the file you have to type something like numericalderivative (3x^2 /(ln(1-x)), 5), which gives the value of the numerical derivative at x = 5.
Functions and, in MATLAB function files are a simple implementation of the DRY programming method. You're being asked to create a function that takes a handle and an x file, then return the derivative of that function handle and that x value. The point of the function file is to be able to re-use your function with either multiple function handles or multiple x values. This is useful as it simply involves passing a function handle and a numeric value to a function.
In your case your script file or command window code would look something like:
func = #(x) (3*x^2)/log(1-x);
x = -3;
num_deriv = numericalderivative(func,x);
You should write the code to make the function numericalderivative work.

Matlab: Detect number of input arguments for function handle from outside of the function

I begin with a symbolic function of one variable, calculate the symbolic derivatives of orders 1 through N, and then convert those symbolic functions into function handles and store the function handles in a cell array. I then evaluate each function handle at the same input value using a loop. The problem I have is that it is possible for one of the derivatives to be a constant (with higher order derivatives being zero, of course). As I was trying to give each function handle an input, I face the "Too many input arguments" error. I would like to be able to check, in advance, whether the function handle is a constant so I can avoid the error, but I can't figure out how to do that.
In case a small working example is helpful, I provide the following
symVar = sym('symVar');
startFunc = symVar^4 + symVar^3 + symVar^2;
derivesCell = cell(5);
for J=1:5
derivesCell(J) = {matlabFunction(diff(startFunc,symVar,J))};
end
cumSum = 0;
evalPoint = 2;
for J=1:5
cumSum = cumSum + derivesCell{J}(evalPoint);
end
Execution produces "Error using symengine>#()2.4e1
Too many input arguments."
tl;dr: You can do this with nargin:
>> nargin(derivesCell{5})
ans =
0
>> nargin(derivesCell{3})
ans =
1
Explanation:
Most people are familiar with the use of nargin as a "special variable" inside the function, but it can be used outside the context of a function definition, as a function that takes a function_handle argument, returning the number of input arguments that function handle takes. From the documentation:
NARGIN(FUN) returns the number of declared inputs for the
M-file function FUN. The number of arguments is negative if the
function has a variable number of input arguments. FUN can be
a function handle that maps to a specific function, or a string
containing the name of that function.

Matlab - how to build functions

Matlab has the function Legendre that returns to an integer m and real number r a vector of length m+1.
Now I want to define another function fun that gives me only the first component of this vector per fixed m, so I want to define a function fun(m,r) that gives me the first component of the vector legendre(m,x). The point is that fun(m,r) should also be a function, just like legendre. Does anybody know how to do this?
Define the function as follows:
function out = fun(n,x)
temp = legendre(n,x); %// store output of "legendre" in a temporary variable
out = temp(1); %// return only desired element
Of course, this should be placed in a file fun.m within Matlab's path.
Alternatively, if you are feeling hackish, you can use
getfield(legendre(n,x), {1})
to extract the first element of legendre(n,x) directly (without a temporary variable). This allows defining fun as an anonymous function as follows:
fun = #(n,x) getfield(legendre(n,x), {1});

Combining Anonymous Functions in 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.