Passing default arguments along function handles in Matlab - matlab

Say that I have the following function
function y = f(x,a)
if nargin < 2
a = 2;
end
y = x.^2 - a;
end
I have another function which finds the root through Newton's method. Say that this is how I call upon the method :
newton(#f,#df,x0)
If I run the newton function with the supplied arguments, then it will only run for the default value of a = 2.
I was wondering if it is possible to some how specify a default parameter for a function when sending it through a function handle. Like this for instance
newton(#f(a),#df,x0)

If you mean this newton, then it expects a univariate function. You can still use your bivariate function f, but you have to be tricky: you need to define a new, anonymous function, and use your variable a as parameter to that:
a = 3; %or any other specific value, have to be set before calling newton
newton(#(x) f(x,a),#df,x0)
If you find that more transparent, you can also do it in a separate step:
f_uni = #(x) f(x,a); %defines f_uni(x), "a" is a parameter to it
newton(f_uni,#df,x0);
Note that in this case f_uni is already a function handle, so you don't have to (and mustn't) put a # before it.

Related

How to create a function to calculate g(1,2) g(2,3) g(1,3) for equations like this g(1)+g(2)+g(1)*g(2)?

I'm trying to create Matlab code to calculate these following equations in Matlab
g(1,2)=g(1)+g(2)+g(1)g(2)
g(1,3)=g(1)+g(3)+g(1)g(3)
g(2,3)=g(2)+g(3)+g(2)g(3)
and values of g(1), g(2),g(3) are available.
Where should I start to write such Matlab code?
One problem here appears to be that you have functions of one and two variables, but you're calling them the same thing (g). Let's call the function of one variable g and the function of two variables (that you want to create) f. Assuming the function g already exists, you can create f using an anonymous function like so:
f = #(x1, x2) g(x1)+g(x2)+g(x1)*g(x2);
And calling it like this:
result = f(1, 2);
is equivalent to:
result = g(1)+g(2)+g(1)*g(2);

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.

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)

Variable or function undefined

I am trying to implement following in MATLAB,
n1 = 6;
n2 = 1;
n3=0.1;
global ps
ps=zeros(3,15);
[R,t,d]=model(n1,n2,n3);
ps=R;
[x, fval] = fmincon(#Obj,[1/3,1/3, 1/3],[],[],[],[],[],[],#cons);
function f = Obj(x)
f = x(1)^2+x(2)^3+x(3)^4;
function [c, ceq] = cons(x)
c=[];
ceq(1) = sum(ps(1,:))*x(1)+sum(ps(2,:))*x(2)+sum(ps(3,:))*x(3) - (sum(d(1,:)));
ceq(2) = sum(x) - 4;
I'm getting following error, what is wrong here?
variable or function 'ps' undefined
You don't need to and definitelty should not use global variables for this. It is a very bad habit and inefficient to boot. Any time you think about using global you should ask yourself if there is another way and search for it. It is only in the very very rare case that globals are needed/helpful (usually in large codebases such as toolboxes).
In your case, you should pass your ps variable in as a parameter by creating an anonymous function. First define your cons function like this so that it takes in a parameter argument:
function [c, ceq] = cons(x,ps)
Then create the anonymous function with one input (x) and one captured parameter (the variable ps, which needs to be defined before this):
[x, fval] = fmincon(#Obj,[1/3,1/3, 1/3],[],[],[],[],[],[],#(x)cons(x,ps));
Alternatively you can save a handle to the anonymous function and pass that in:
cfun = #(x)cons(x,ps);
[x, fval] = fmincon(#Obj,[1/3,1/3, 1/3],[],[],[],[],[],[],cfun);
Here's a blog post from The MathWorks with other bad habits.
I cannot run your lines of code, but I think you have to put
global ps
in your function cons to inform Matlab that you are referring to the global ps. More information on global variables can be found here: http://www.mathworks.de/de/help/matlab/ref/global.html
EDIT: For a cleaner design, you should take into account horchler's advice: https://stackoverflow.com/a/20721808/3060323

Defining function in matlab which uses a function as a parameter

I want to define a function like this:
function f = f1(fun,a,b,c)
f = c*fun(a+b);
Here fun is some function that I will pass when I use the function f.
How can I do this in Matlab?
Have you tried it? The best way to learn a tool like matlab is to try things!
In fact, you don't even need to create an m-file function. I'll do it using a function handle here.
fun = #(x) sin(x);
f1 = #(f,a,b,c) c*f(a+b);
f1(fun,2,3,4)
ans =
-3.8357
I could have defined f1 as an m-file function too, but that would have required I save a file. Why bother?
What you are looking for is the function handle.
You can obtain the function handle of a function (in the following case, sqrt) by placing the "at" symbol ('#') in front of the function name:
a = 1;
b = 2;
c = 3;
fun = #sqrt; % obtain the function handle of sqrt()
f = f1(fun, a,b,c); % pass the function handle of sqrt() into your function f1().
When you use fun, it will be as if you are using the sqrt function.
For more details, you may also refer to another Stackoverflow question: function handle in MATLAB