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.
The Anatomy of a Modern Function
Section titled “The Anatomy of a Modern Function”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 functionKey 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. argumentsblock: (R2019b+) A declarative way to define input arguments, their types, sizes, and default values. It replaces older, manual parsing withnarginandinputParser.
Types of Functions
Section titled “Types of Functions”Anonymous Functions
Section titled “Anonymous Functions”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 functionpowerFunc = @(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 1quadratic = @(x) x.^2;area = integral(quadratic, 0, 1);Local Functions
Section titled “Local Functions”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;endSince R2016b, you can also define local functions within a script file, which is very convenient for self-contained examples and tasks.
Nested Functions
Section titled “Nested Functions”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.
Private Functions
Section titled “Private Functions”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.
A Warning on Global Variables
Section titled “A Warning on Global Variables”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.
Best Practices for Function Development
Section titled “Best Practices for Function Development”- One Task, One Function: Each function should have a single, well-defined purpose.
- Use the
argumentsBlock: For any function written in R2019b or later, use theargumentsblock 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. (
buildtestcommand or Test Browser UI). - Organize with Projects: For larger applications, use MATLAB Projects (
.prjfiles) to manage files, paths, and dependencies in a structured way.