Matlab Defining A Function That Has Vector As An Input - matlab

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

Related

MATLAB Equation as User Input to work with

I'm trying to write a simple script that request a equation as input and I like to calculate with this function more than once without always requesting user input.
My current script defined f as function handle and executed the function 2 times, so I'm always asking for a new equation, which is not desirable.
f = #(x) input('f(x) = ');
a = f(2); % requests user input
b = f(3); % requests user input again
And it should look more like this (not working).
func = input('f(x) = ');
f = #(x) func;
a = f(2);
b = f(3);
And here without user input to get an idea what I try to achieve.
f = #(x) x^2;
a = f(2);
b = f(3);
I think I found a solution with Symbolic Math Toolbox, but I do not have this addon, so I cannot use/test it.
Is there another solution?
There's no need for the Symbolic Mathematics Toolbox here. You can still use input. Bear in mind that the default method of input is to directly take the input and assign it as a variable where the input is assumed to be syntactically correct according to MATLAB rules. That's not what you want. You'll want to take the input as a string by using the 's' option as the second parameter then use str2func to convert the string into an anonymous function:
func = input('f(x) = ', 's');
f = str2func(['#(x) ' func]);
a = f(2);
b = f(3);
Take note that I had to concatenate the #(x) anonymous function string with the inputted function you provided with input.
Example Run
Let's say I want to create a function that squares every element in the input:
>> func = input('f(x) = ', 's');
f(x) = x.^2
>> f = str2func(['#(x) ' func])
f =
#(x)x.^2
>> a = f(2)
a =
4
>> b = f(3)
b =
9
Take special note that I assumed the function will element-wise square each elements in the input. The . operator in front of the exponentiation operator (i.e. ^) is very important.

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 does one pass a function with some fixed argument as an argument in MATLAB

I want to pass a function that has arguments to another function that takes the function handler (pointer) as an argument, but some of the arguments to the function handler need to be fixed. How does one do this in MATLAB?
Concretely I want to minimize a function h(eta) using fminsearch(fun,x0). One obvious issue is that if I pass all the arguments in x0 it will minimize it with respect to all the arguments but that isn't what I want to do. What I really want to do is instead:
I have tried the following and it seems to work as far as I tested it:
function [ h ] = function_returner( x )
%
t = -10000;
h = #(eta)-10*x + t + eta^2;
end
and the script to test it:
h = function_returner(0);
h(3) %-9991
[x,fval,exitflag] = fminsearch(h,[10]) %returns [0, -10000, 1]
returns the correct minimum and the correct value of x at which the minimum is obtained. The thing that I wanted to make sure is that the variables that are fixed of h indeed remain fixed after I returned the function handler. i.e. if h is passed around, how does one make sure that the variables don't change value just because they go into an environment that has the same variables names as in the function handler?
I also wrote:
x = inf;
t = inf;
eta = inf;
h = function_returner(0);
h(3) %-9991
[x,fval,exitflag] = fminsearch(h,[10]) %returns [0, -10000, 1]
and it seems to go unaffected (i.e. it works as I want it to work). But just to be on the safe side, I was hoping there was not a some weird edge condition that this doesn't work.
You are worrying unnecessarily. :-) The thing is, when you create an anonymous function, all the outer variables that are used for its definition are frozen, so you don't need to worry that the function will change behavior behind your back via modified parameters. To test this, try this script:
a = 1;
b = 2;
f = #(u,v) u*a + v*b;
x = f(1,1); %// x is 3 = 1*1 + 1*2
a = 2;
b = 3;
g = #(w) f(w,a)
y = g(1); %// y is 5 = f(1,2) = 1*1 + 2*2

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).

Optimization with Matlab

A common way to write the objective function in matlab (including the gradient vector) is the following:
[L,G] = objfun(x)
where L is the value of objective function, G is the gradient vector and x is a vector of coefficients which I want to optimize.
However, when I include another input (i.e [L,G]=objfun(x,M), where M is a matrix) or when I call another function in the function objfun, the code is not running.
How can I include any inputs and call any functions in the objfun by keeping this format of optimization?
Note that I call the optimization as follows:
[x ,fval] = fminunc(#objfun,x,options)
where
options = optimoptions(#fminunc,'Algorithm','quasinewton',...
'Display','iter','Gradobj','on','TolFun',10^-8)
There's an mathworks help article on passing extra parameters to the objective function:
You can use the #(...) operator to generate an anonymous function handle to your function that will only depend on a single parameter.
a = 4; b = 2.1; c = 4;
f = #(x)objfun(x,a,b,c)
From the original page (where your objfun is parameterfun):
Note: The parameters passed in the anonymous function are those that exist at the time the anonymous function is created. Consider the
example
a = 4; b = 2.1; c = 4;
f = #(x)parameterfun(x,a,b,c)
Suppose you subsequently change, a to 3 and run
[x,fval] = fminunc(f,x0)
You get the same answer as before, since parameterfun uses a = 4, the
value when f was created.
To change the parameters that are passed to the function, renew the
anonymous function by reentering it:
a = 3;
f = #(x)parameterfun(x,a,b,c)