Anonym
Function Handlers
This section is optional. You will be able to write your code without knowing this material. However, function handlers allow you to create a cleaner and less cumbersome code. Anonymous functions reduce the number of small functions that you can lose track of and, thus, reduce the number of places where you can make a mistake. All objects in MATLAB have its handlers, i.e. variables that allow MATLAB to distinguish one such object from another and refer to it if needed. You are using them if you want to open a file for writing or reading:
fn=fopen('text.txt','w');
fprintf(fn,'This is a test\n');
You can use them for creating and manipulating figures:
f1=figure;
f2=figure;
figure(f1)
title('This is figure 1')
figure(f2)
title('This is figure 2')
Functions also have their own handlers. Function handlers have @
in front of them. In fact, you are using them in fminunc
:
fminunc(@my_obj,theta0)
Using function handlers you can rename functions without creating your own function files:
mymean=@mean;
c=1:10;
mymean(c)
ans =
5.5000
and make fun of a person who’ll try to read your code:
max=@mean;
c=1:10;
...
...
max(c)
ans =
5.5000
Function handlers are stored in a workspace. Therefore, they can be saved and loaded using standard mat files, can be passed to a function as an input, and returned from a function as an output. For example, you can create a structure with function handlers and pass it as a parameter to optimization routine. This might be quite useful once your estimation results depend on the form of the objective function, and its first and second derivative. For example, minimization of non-linear least squares/normal MLE/t-student MLE; GMM/Empirical Likelihood/Exponential Tilting can be also implemented in this way.
Anonymous Functions
There are many cases when you would like to have a function with one output that can be squeezed in one line. For example, consider a trivial case when you would like to compute a mean along the third dimension of your multidimensional array. You can do it by creating a function file:
function out=mymean(in)
out=mean(in,3);
end
Alternatively, you can do it by creating an anonymous function:
mymean=@(x)(mean(x,3));
mean
by default computes an average along the second dimension, while mymean
computes an average along the third. There are less trivial examples:
Changing the order of function inputs and/or hiding all other inputs (might be needed for
fminunc, fmincon
, etc)%assume that there is a function that you would like to minimize is myfunc(theta,data1,data2,data3) myfunc1=@(theta)(myfunc(theta,data1,data2,data3)); theta=fminunc(myfunc1,theta0);%Note! since myfunc1 IS a handler, you don't need to put @ in front of it %compare with theta=fminunc(@myfunct,theta0,[],data1,data2,data3);
Important:
Since anonymous function can return only one output, to provide an analytical gradient and hessian you have to use the following syntax:
theta=fminunc({myfunc1, grad, hess},theta0);%grad and hess are anonymous functions that provide gradient and hessian of myfunc1
Short example:
x2=@(x)x^2+5*x; gx=@(x)2*x+5; hx=@(x)2; >> fminunc({x2,gx,hx},5) ans = -2.5000
Hiding all irrelevant inputs (it is necessary for various functions that compute integrals, see for example
integral
)For double optimization, when you are minimizing with respect to one vector of inputs, while maximizing with respect to another. It allows you to use the same objective function many times
%assume that we have a function EL(beta,lambda,data), and we would like to minimize with respect to beta, while maximizing with respect to lambda: ELmin=@(beta)(EL(beta,lambda,data)); ... ... ELmax=@(lambda)(-EL(beta,lambda,data));%we put a minus here, since fminunc minimizes, not maximizes the function
Important:
Anonymous function can have only one output (it can be anything, but just one variable name)
All variables that are not specified as inputs are copied from the workspace at the moment of creating the anonymous function. If you would like to update the values of these variables, you have to recreate your anonymous function:
a=2; xplusa=@(x)(x+a); >> xplusa(3) ans = 5 a=0; >> xplusa(3) ans = 5 xplusa=@(x)(x+a); ans = 3
Anonymous functions are somewhat slower than standard functions.