Skip to content

MATLAB - Functions

Writing Modern and Robust MATLAB Functions

Section titled “Writing Modern and Robust MATLAB Functions”

Functions are the building blocks of any non-trivial program. In MATLAB, they are essential for creating reusable, modular, and readable code. A function encapsulates a task, operates in its own isolated workspace, and communicates with other code via input and output arguments.

A modern MATLAB function, saved in its own .m file, should include a clear signature, help text, and robust input validation.

function [stat1, stat2] = computeStats(data, options)
%COMPUTESTATS Calculates mean and standard deviation of input data.
% [M, S] = COMPUTESTATS(DATA) calculates the mean M and standard
% deviation S of the vector DATA.
%
% [...] = COMPUTESTATS(..., 'Dimension', DIM) operates along dimension DIM.
% [...] = COMPUTESTATS(..., 'RemoveNaNs', true) removes NaN values before
% computation.
arguments
data (:,:) {mustBeNumeric, mustBeReal}
options.Dimension (1,1) {mustBeInteger} = 1
options.RemoveNaNs (1,1) {mustBeNumericOrLogical} = false
end
% Function body starts here
if options.RemoveNaNs
data = data(~isnan(data));
end
stat1 = mean(data, options.Dimension);
stat2 = std(data, 0, options.Dimension); % 0 is for default normalization
end % End of function

Key components of this modern structure include:

  • Function Signature: function [out1, ...] = functionName(in1, ...) defines inputs and outputs.
  • Help Text: The contiguous block of comments after the signature is displayed when you type help functionName. It is crucial for documentation.
  • arguments block: (R2019b+) A declarative way to define input arguments, their types, sizes, and default values. It replaces older, manual parsing with nargin and inputParser.

Anonymous functions are simple, one-line functions defined without a separate .m file. They are extremely useful for passing a function as an argument to another function (e.g., for integration or optimization).

% Syntax: fhandle = @(arglist) expression
% Example 1: A simple power function
powerFunc = @(x, n) x.^n;
result = powerFunc(5, 2) % result = 25
% Example 2: Using an anonymous function with 'integral'
% Calculate the integral of x^2 from 0 to 1
quadratic = @(x) x.^2;
area = integral(quadratic, 0, 1);

You can include multiple functions within a single .m file. The first function is the primary function (which has the same name as the file) and is callable from outside. All other functions are local functions (formerly called sub-functions), and are only visible to other functions within the same file. This is an excellent way to break down a complex task into smaller, manageable helpers.

% In a file named 'mainTask.m'
function result = mainTask(inputVal)
% This is the primary function
intermediate = helperA(inputVal);
result = helperB(intermediate);
end
function out = helperA(in)
% This is a local function, only callable by mainTask and helperB
out = in * 2;
end
function out = helperB(in)
% This is another local function
out = in + 5;
end

Since R2016b, you can also define local functions within a script file, which is very convenient for self-contained examples and tasks.

A nested function is defined completely inside another function. Its key feature is that it shares the workspace of its parent function, allowing it to access and modify the parent’s variables without passing them as arguments. This can be useful for creating functions with persistent state.

To share helper functions across multiple primary functions but not expose them globally, place them in a subfolder named private. Functions in this folder are only callable by functions in the immediate parent folder. This is a powerful tool for code encapsulation and creating libraries.

While MATLAB supports global variables that can be accessed from any function, they are strongly discouraged in modern programming. Globals make code difficult to debug, maintain, and understand, as it’s unclear where a variable is being modified. Always prefer to pass data explicitly as function arguments. If you need to manage shared state, consider using a class or a nested function structure instead.

  • One Task, One Function: Each function should have a single, well-defined purpose.
  • Use the arguments Block: For any function written in R2019b or later, use the arguments block for input validation. It’s more robust and readable.
  • Write Help Text: Your future self (and your colleagues) will thank you. Good documentation is as important as the code itself.
  • Test Your Functions: Use the MATLAB Unit Testing Framework to create automated tests for your functions. This ensures they work correctly and prevents regressions when you make changes. (buildtest command or Test Browser UI).
  • Organize with Projects: For larger applications, use MATLAB Projects (.prj files) to manage files, paths, and dependencies in a structured way.