MATLAB - create anonymous function recursively - matlab

For use within the least square fitting routine lsqcurvefit, I need a function in terms of a series representation like :
F = #(D, t) F0 - D(1)*(1-exp(-t))...
- D(2)*(1-exp(-t))...
- D(3)*(1-exp(-t))...
...
- D(n)*(1-exp(-t));
However, the amount of terms in the series is to be determined by the user; so the anonymous function F needs to be created within a loop, like
F = #(D, t) F0;
for i=1:n
F = F - D(i)*(1-exp(-t));
end
Unfortunately, the above method is not working within MATLAB; is there a possibility to get it work?

Unless I'm misunderstanding something, your function is not actually recursive. You can just do:
F = #(D,t) F0 - sum(D*(1-exp(-t));
or, if you want to specify n explicitly:
F = #(D,n,t) F0 - sum(D(1:n)*(1-exp(-t));
or, if t is a vector the same size as D:
F = #(D,n,t) F0 - D(1:n)*(1-exp(-t(1:n)).';

The best way to do this is with a combination of anonymous and normal functions.
recursionDepth = 5
CoefficientList = ones(numel(recursionDepth) + 1);
functionResults = #(t) myFunction(t, CoefficientList, recursionDepth);
function F = myFunction(t, CoefficientList, Depth)
F = CoefficientList(1);
for idx = 1:Depth
F = CoefficientList(idx) * (1 - exp(-1));
end
end
What I've done here is defined the full function that contains your model with all of its parameters, and then wrapped that into an anonymous function that sets the user selectable, unchanging parameters within the anonymous function, and leaves the single adjustable parameter as the input. You'll have to adjust for your particular model, but that is your basic template.

Related

How to fix nan in anonymous function?

Suppose I have a function f(x) defined, which gives nan when it is very large, say x>100. Fortunately, when x>100, I can replace f by another function g. So I would like to define:
h = #(x)isnan(f(x)).*f(x)+isnan(f(x)).*g(x)
However, when I substitute h(1001), it gives nan. Is it possible to define h so that it gives g(1001) instead of nan? The only restriction is that I need to have anonymous function h for later use, say I would like to use it in integration, i.e., integral(h,0,inf).
Example: Suppose I have a function:
f = #(x)x.*1./x
This function is very easy and must be 1. I construct a function:
g = #(x)isnan(f(x)).*0+isnan(f(x)).*1
How to make g to be well defined so that I can still evaluate integral(g,-1,1)? For this example, I know I can evaluate it easily, but my restriction is that I need to define anonymous function g and use integral to do it.
You would need to make a regular function and wrap it with the anonymous function.
i.e.
function r = ternary(a, b, c)
if (a)
r = b;
else
r = c;
end
end
h = #(x)ternary(isnan(f(x)), g(x), f(x));
Note that this will evaluate your function twice. A less generalized solution for your particular case that won't evaluate the function twice.
function r = avoidNAN(a, b)
if (isnan(a))
r = b;
else
r = a;
end
end
There is a solution without any additional functions:
f = #(x)x.*1./x;
g = #(x)100+x;
h= #(x)getfield(struct('a',f(x),'b',g(x)),char(isnan(f(x))+'a'))

MATLAB function handles and parameters

When I type help gmres in MATLAB I get the following example:
n = 21; A = gallery('wilk',n); b = sum(A,2);
tol = 1e-12; maxit = 15;
x1 = gmres(#(x)afun(x,n),b,10,tol,maxit,#(x)mfun(x,n));
where the two functions are:
function y = afun(x,n)
y = [0; x(1:n-1)] + [((n-1)/2:-1:0)'; (1:(n-1)/2)'].*x+[x(2:n); 0];
end
and
function y = mfun(r,n)
y = r ./ [((n-1)/2:-1:1)'; 1; (1:(n-1)/2)'];
end
I tested it and it works great. My question is in both those functions what is the value for x since we never give it one?
Also shouldn't the call to gmres be written like this: (y in the #handle)
x1 = gmres(#(y)afun(x,n),b,10,tol,maxit,#(y)mfun(x,n));
Function handles are one way to parametrize functions in MATLAB. From the documentation page, we find the following example:
b = 2;
c = 3.5;
cubicpoly = #(x) x^3 + b*x + c;
x = fzero(cubicpoly,0)
which results in:
x =
-1.0945
So what's happening here? fzero is a so-called function function, that takes function handles as inputs, and performs operations on them -- in this case, finds the root of the given function. Practically, this means that fzero decides which values for the input argument x to cubicpoly to try in order to find the root. This means the user just provides a function - no need to give the inputs - and fzero will query the function with different values for x to eventually find the root.
The function you ask about, gmres, operates in a similar manner. What this means is that you merely need to provide a function that takes an appropriate number of input arguments, and gmres will take care of calling it with appropriate inputs to produce its output.
Finally, let's consider your suggestion of calling gmres as follows:
x1 = gmres(#(y)afun(x,n),b,10,tol,maxit,#(y)mfun(x,n));
This might work, or then again it might not -- it depends whether you have a variable called x in the workspace of the function eventually calling either afun or mfun. Notice that now the function handles take one input, y, but its value is nowhere used in the expression of the function defined. This means it will not have any effect on the output.
Consider the following example to illustrate what happens:
f = #(y)2*x+1; % define a function handle
f(1) % error! Undefined function or variable 'x'!
% the following this works, and g will now use x from the workspace
x = 42;
g = #(y)2*x+1; % define a function handle that knows about x
g(1)
g(2)
g(3) % ...but the result will be independent of y as it's not used.

How to define an inline function according to another inline function in Matlab?

Suppose that I have a vector of variables that I have created in this way:
A = sym('A%d',[1 , 3]);
And also an inline function which is a function of A:
f = inline(A(1)^2 + A(2)^3 - 10*A(3) , 'A');
Now, the question is how to define another function like g that has the following form:
g = f*10 or any other types of functions that depends on f.
thanks in advance
As suggested by #Daniel, you should use anonymous functions. In the documentation to inline, Mathworks warns that this will be removed in a future release, and tells you to use anonymous functions.
The syntax of anonymous functions is very easy:
f = #(A) A(1)^2 + A(2)^3 - 10*A(3)
with #(A), you define that you want one input variable, and name it A. If you have two inputs, A and B, then write #(A,B). But caution: these names A and B are only internal names inside your anonymous function. The following two functions are 100% identical:
f1 = #(x) 10*x
f2 = #(A) 10*A
You can call these anonymous functions like normal functions, e.g.
f([1, 2, 3])
f(x)
If you want to create a function g = 10*f, then you define this function as
g = #(A) 10*f(A)
Here's a small demonstration:
A = sym('A%d',[1 , 3]);
f = #(x) x(1)^2 + x(2)^3 - 10*x(3)
g = #(x) 10*f(x)
g(A)
ans =
10*A1^2 + 10*A2^3 - 100*A3

How to pass constants to a function which is used in fminbnd(#myfun,x1,x2) in a loop

I'm implementing a ML receiver for a communication channel.
For this I need to find the minimum value of the function below with respect to x in the range x = 0 to 15 (16QAM)
f = abs( rx(n) - (h'*h)*x )^2 ;
I have to iterate this in a loop (n=1:100). I found that I can do this by matlab function x = fminbnd(fun,x1,x2) where I can put the function in a separate .m-file as:
function f = myfun(x)
f = abs( rx(n) - (h'*h)*x )^2
and find the minimum for x from
x = fminbnd(#myfun,x1,x2);
My question is since constants to the function rx(n) is changing thorough the loop, how to sent it to the function myfun(x) within the loop.
You can do it by using an anonymous function to call your function in a separate file:
function mainfcnmin
h = [1;1];
rx = 1:3;
for n = 1:length(rx)
x = fminbnd(#(x)myfun(x,rx(n),h),0,15)
end
end
function f = myfun(x,rx,h)
f = abs(rx-(h'*h)*x)^2 ;
end
Or alternatively in one file by defining the function directly in the anonymous function like this:
h = [1;1];
rx = 1:3;
for n = 1:length(rx)
x = fminbnd(#(x)(abs(rx(n)-(h'*h)*x)^2),0,15)
end
You will need to make a function with rx(n) as a second parameter and then turn it into a single parameter anonymous function inside the loop.
Here is an example from the MATLAB documentation (for 'fminsearch' function):
If fun is parameterized, you can use anonymous functions to capture
the problem-dependent parameters. For example, suppose you want to
minimize the objective function myfun defined by the following
function file:
function f = myfun(x,a)
f = x(1)^2 + a*x(2)^2;`
Note that myfun has an extra parameter a, so you cannot pass it directly to > fminsearch. To optimize for a specific value of a, such as a = 1.5.
Assign the value to a
a = 1.5; % define parameter first
Call
fminsearch with a one-argument anonymous function that captures that
value of a and calls myfun with two arguments:
x = fminsearch(#(x) myfun(x,a),[0,1])
Hope that helped (sorry for bad text formatting).

Matlab Defining A Function That Has Vector As An Input

I was given a simple exercise by my professor, which is to define a cerrtain function. Here is my function
function [a,b,c] = PHUN([x,y],[z,t,w])
a = x
b = ((y+z)^2)*t
c = z/w + x
However, matlab states that I am using invalid syntax in the first line. So, I figured, perhaps there is a particular way in which vector inputs are supposed to be typed. I have attempt several searches on defining functions with vector inputs (or arguments), but have not been successful. I was wondering if someone could possibly help me.
You can pass vectors as arguments in the same way you pass variables. Then access them in the function body appropriately. Your function could be re-written as follows:
function [a,b,c] = PHUN(X,Y)
a = X(1)
b = ((X(2)+Y(1))^2)*Y(2)
c = Y(1)/Y(3) + X(1)
Or if you want to keep the original variables:
function [a,b,c] = PHUN(X,Y)
Z = num2cell([X,Y]);
[x,y,z,t,w] = Z{:};
a = x
b = ((y+z)^2)*t
c = z/w + x