MATLAB Language Getting started with MATLAB Language Anonymous functions and function handles


Example

Basics

Anonymous functions are a powerful tool of the MATLAB language. They are functions that exist locally, that is: in the current workspace. However, they do not exist on the MATLAB path like a regular function would, e.g. in an m-file. That is why they are called anonymous, although they can have a name like a variable in the workspace.

The @ operator

Use the @ operator to create anonymous functions and function handles. For example, to create a handle to the sin function (sine) and use it as f:

>> f = @sin
f = 
    @sin

Now f is a handle to the sin function. Just like (in real life) a door handle is a way to use a door, a function handle is a way to use a function. To use f, arguments are passed to it as if it were the sin function:

>> f(pi/2)
ans =
     1

f accepts any input arguments the sin function accepts. If sin would be a function that accepts zero input arguments (which it does not, but others do, e.g. the peaks function), f() would be used to call it without input arguments.

Custom anonymous functions

Anonymous functions of one variable

It is not obviously useful to create a handle to an existing function, like sin in the example above. It is kind of redundant in that example. However, it is useful to create anonymous functions that do custom things that otherwise would need to be repeated multiple times or created a separate function for. As an example of a custom anonymous function that accepts one variable as its input, sum the sine and cosine squared of a signal:

>> f = @(x) sin(x)+cos(x).^2
f = 
    @(x)sin(x)+cos(x).^2

Now f accepts one input argument called x. This was specified using parentheses (...) directly after the @ operator. f now is an anonymous function of x: f(x). It is used by passing a value of x to f:

>> f(pi)
ans =
    1.0000

A vector of values or a variable can also be passed to f, as long as they are used in a valid way within f:

>> f(1:3) % pass a vector to f
ans =
    1.1334    1.0825    1.1212
>> n = 5:7;
>> f(n) % pass n to f
ans =
   -0.8785    0.6425    1.2254

Anonymous functions of more than one variable

In the same fashion anonymous functions can be created to accept more than one variable. An example of an anonymous function that accepts three variables:

>> f = @(x,y,z) x.^2 + y.^2 - z.^2
f = 
    @(x,y,z)x.^2+y.^2-z.^2
>> f(2,3,4)
ans =
    -3

Parameterizing anonymous functions

Variables in the workspace can be used within the definition of anonymous functions. This is called parameterizing. For example, to use a constant c = 2 in an anonymous function:

>> c = 2;
>> f = @(x) c*x
f = 
    @(x)c*x
>> f(3)
ans =
     6

f(3) used the variable c as a parameter to multiply with the provided x. Note that if the value of c is set to something different at this point, then f(3) is called, the result would not be different. The value of c is the value at the time of creation of the anonymous function:

>> c = 2;
>> f = @(x) c*x;
>> f(3)
ans =
     6
>> c = 3;
>> f(3)
ans =
     6

Input arguments to an anonymous function do not refer to workspace variables

Note that using the name of variables in the workspace as one of the input arguments of an anonymous function (i.e., using @(...)) will not use those variables' values. Instead, they are treated as different variables within the scope of the anonymous function, that is: the anonymous function has its private workspace where the input variables never refer to the variables from the main workspace. The main workspace and the anonymous function's workspace do not know about each other's contents. An example to illustrate this:

>> x = 3 % x in main workspace
x =
     3
>> f = @(x) x+1; % here x refers to a private x variable
>> f(5)
ans =
     6
>> x
x =
     3

The value of x from the main workspace is not used within f. Also, in the main workspace x was left untouched. Within the scope of f, the variable names between parentheses after the @ operator are independent from the main workspace variables.

Anonymous functions are stored in variables

An anonymous function (or, more precisely, the function handle pointing at an anonymous function) is stored like any other value in the current workspace: In a variable (as we did above), in a cell array ({@(x)x.^2,@(x)x+1}), or even in a property (like h.ButtonDownFcn for interactive graphics). This means the anonymous function can be treated like any other value. When storing it in a variable, it has a name in the current workspace and can be changed and cleared just like variables holding numbers.

Put differently: A function handle (whether in the @sin form or for an anonymous function) is simply a value that can be stored in a variable, just like a numerical matrix can be.

Advanced use

Passing function handles to other functions

Since function handles are treated like variables, they can be passed to functions that accept function handles as input arguments.

An example: A function is created in an m-file that accepts a function handle and a scalar number. It then calls the function handle by passing 3 to it and then adds the scalar number to the result. The result is returned.

Contents of funHandleDemo.m:

function y = funHandleDemo(fun,x)
y = fun(3);
y = y + x;

Save it somewhere on the path, e.g. in MATLAB's current folder. Now funHandleDemo can be used as follows, for example:

>> f = @(x) x^2; % an anonymous function
>> y = funHandleDemo(f,10) % pass f and a scalar to funHandleDemo
y =
    19

The handle of another existing function can be passed to funHandleDemo:

>> y = funHandleDemo(@sin,-5)
y =
   -4.8589

Notice how @sin was a quick way to access the sin function without first storing it in a variable using f = @sin.

Using bsxfun, cellfun and similar functions with anonymous functions

MATLAB has some built-in functions that accept anonymous functions as an input. This is a way to perform many calculations with a minimal number of lines of code. For example bsxfun, which performs element-by-element binary operations, that is: it applies a function on two vectors or matrices in an element-by-element fashion. Normally, this would require use of for-loops, which often requires preallocation for speed. Using bsxfun this process is sped up. The following example illustrates this using tic and toc, two functions that can be used to time how long code takes. It calculates the difference of every matrix element from the matrix column mean.

A = rand(50); % 50-by-50 matrix of random values between 0 and 1

% method 1: slow and lots of lines of code
tic
meanA = mean(A); % mean of every matrix column: a row vector
% pre-allocate result for speed, remove this for even worse performance
result = zeros(size(A));
for j = 1:size(A,1)
    result(j,:) = A(j,:) - meanA;
end
toc
clear result % make sure method 2 creates its own result

% method 2: fast and only one line of code
tic
result = bsxfun(@minus,A,mean(A));
toc

Running the example above results in two outputs:

Elapsed time is 0.015153 seconds.
Elapsed time is 0.007884 seconds.

These lines come from the toc functions, which print the elapsed time since the last call to the tic function.

The bsxfun call applies the function in the first input argument to the other two input arguments. @minus is a long name for the same operation as the minus sign would do. A different anonymous function or handle (@) to any other function could have been specified, as long as it accepts A and mean(A) as inputs to generate a meaningful result.

Especially for large amounts of data in large matrices, bsxfun can speed up things a lot. It also makes code look cleaner, although it might be more difficult to interpret for people who don't know MATLAB or bsxfun. (Note that in MATLAB R2016a and later, many operations that previously used bsxfun no longer need them; A-mean(A) works directly and can in some cases be even faster.)