Week14A: User Functions and Modular Programming in MATLAB#
Introduction#
You’ve already learned about functions and modular programming in Python, and you’ll find that MATLAB follows many of the same principles. However, MATLAB has some unique syntax and conventions that we’ll explore in this reading. By the end, you’ll understand how to write well-organized, reusable MATLAB code using user-defined functions.
Why Functions Matter#
Just as in Python, functions help us:
Break down complex problems into manageable pieces
Reuse code without copying and pasting
Test and debug smaller components independently
Collaborate more effectively by dividing work
MATLAB Function Syntax#
Basic Structure#
In Python, you defined functions within a script or module. In MATLAB, each function typically lives in its own file with the same name as the function. Here’s the basic syntax:
function [output1, output2] = functionName(input1, input2)
% FUNCTIONNAME Brief description of what the function does
% Detailed explanation of the function's purpose, inputs, and outputs.
%
% Inputs:
% input1 - description of first input
% input2 - description of second input
%
% Outputs:
% output1 - description of first output
% output2 - description of second output
% Function body goes here
output1 = ...;
output2 = ...;
end
Key differences from Python:
The
functionkeyword starts the definitionOutputs are listed in square brackets on the left side of the equals sign
The function name and filename must match (e.g.,
calculateArea.mcontainsfunction calculateArea)The
endkeyword closes the function
All MATLAB functions consist of:
The function header (first line) with:
The reserved word
functionIf the function returns values: the output argument name(s) followed by
=The function name (should match the filename)
Input arguments in parentheses (separated by commas if more than one)
Comments describing what the function does (displayed by the
helpcommand)The body with all statements, including assigning values to all output arguments
The
endkeyword
Viewing and Getting Help#
You can view a function’s code using the type command:
type calculateCircleArea
You can view a function’s help comments using the help command:
help calculateCircleArea
This displays the comment block immediately after the function header.
Single Output Functions#
When your function returns only one value, you can omit the square brackets:
function area = calculateCircleArea(radius)
% CALCULATECIRCLEAREA Calculates the area of a circle
% area = calculateCircleArea(radius) returns the area of a circle
% given its radius.
area = pi * radius^2;
end
Save this as calculateCircleArea.m.
Important: The output argument must be assigned a value somewhere in the function body. This is how the value is returned from the function.
No Output Functions#
Some functions perform actions without returning values (like printing or plotting):
function displayGreeting(name)
% DISPLAYGREETING Displays a personalized greeting
% displayGreeting(name) prints a greeting message to the console.
fprintf('Hello, %s! Welcome to MATLAB.\n', name);
end
Key points about functions with no outputs:
There are no output arguments in the function header
There is no assignment operator (=) in the header
The function call is a statement by itself—it cannot be embedded in an assignment statement or used in expressions
Correct usage:
displayGreeting('Alice'); % This works
Incorrect usage:
x = displayGreeting('Alice'); % ERROR: Too many output arguments
Multiple Outputs#
MATLAB makes it easy to return multiple values (remember unpacking in Python?):
function [mean_val, std_val, max_val] = analyzeData(data)
% ANALYZEDATA Computes statistics for a dataset
% [mean_val, std_val, max_val] = analyzeData(data) returns the mean,
% standard deviation, and maximum value of the input data.
mean_val = mean(data);
std_val = std(data);
max_val = max(data);
end
Calling functions with multiple outputs:
When calling this function, you should capture the returned values in separate variables:
[m, s, mx] = analyzeData([1, 2, 3, 4, 5]);
Or if you only need some outputs:
[m, s] = analyzeData([1, 2, 3, 4, 5]); % Only returns first two outputs
Important: If you don’t capture all the outputs, only the first value is retained:
result = analyzeData([1, 2, 3, 4, 5]); % Only the mean is stored in result
Variable Scope in MATLAB#
Local Variables#
Just like in Python, variables created inside a function are local to that function. They don’t exist outside the function and don’t interfere with variables of the same name elsewhere:
function result = addNumbers(a, b)
sum_val = a + b; % sum_val is local to this function
result = sum_val;
end
If you have a variable called sum_val in your main script, it won’t be affected by the sum_val inside the function.
Pass by Value#
MATLAB uses pass by value for function arguments. This means the function receives a copy of the data, not the original:
function modifyVector(vec)
vec(1) = 999; % Changes the local copy only
disp(vec);
end
% In your script:
myData = [1, 2, 3, 4, 5];
modifyVector(myData); % Shows [999, 2, 3, 4, 5]
disp(myData); % Still shows [1, 2, 3, 4, 5]
To get modified data out of a function, you must return it as an output:
function vec = modifyVector(vec)
vec(1) = 999;
end
myData = [1, 2, 3, 4, 5];
myData = modifyVector(myData); % Now myData is updated
Global Variables (Avoid When Possible)#
MATLAB does support global variables, but they should be avoided in favor of passing data through function arguments:
global CONSTANT_VALUE; % Declared in both the function and calling script
Best practice: Use function inputs and outputs instead of global variables.
Organizing Code with Functions#
One Function Per File (Primary Functions)#
In MATLAB, each .m file should contain one main function with the same name as the file. This is called a primary function and is the only function accessible from outside the file.
File: processTemperature.m
function [tempC, tempK] = processTemperature(tempF)
% PROCESSTEMPERATURE Converts Fahrenheit to Celsius and Kelvin
tempC = (tempF - 32) * 5/9;
tempK = tempC + 273.15;
end
Local Functions (Helper Functions)#
You can define additional local functions in the same file below the primary function. These are only accessible within that file:
File: analyzeStudentGrades.m
function report = analyzeStudentGrades(grades)
% ANALYZESTUDENTGRADES Generates a comprehensive grade report
avg = calculateAverage(grades);
letter = assignLetterGrade(avg);
report = sprintf('Average: %.2f, Grade: %s', avg, letter);
end
function avg = calculateAverage(scores)
% Local function - only accessible within this file
avg = mean(scores);
end
function letter = assignLetterGrade(numericGrade)
% Local function - only accessible within this file
if numericGrade >= 90
letter = 'A';
elseif numericGrade >= 80
letter = 'B';
elseif numericGrade >= 70
letter = 'C';
elseif numericGrade >= 60
letter = 'D';
else
letter = 'F';
end
end
This is similar to defining helper functions within a Python module.
Best Practices for Modular Design#
1. Single Responsibility Principle#
Each function should do one thing well. If you find yourself using “and” to describe what a function does, it might need to be split up.
Bad:
function processAndPlotData(data)
% Cleans data AND plots it AND saves the plot
% Too many responsibilities!
end
Good:
function cleanData = cleanData(rawData)
% Only handles data cleaning
end
function plotData(data)
% Only handles plotting
end
2. Meaningful Names#
Function names should be descriptive verbs or verb phrases:
calculateVolumeinstead ofvolconvertToRadiansinstead ofconvvalidateInputinstead ofcheck
3. Clear Documentation#
Always include a header comment explaining:
What the function does
What inputs it expects
What outputs it returns
Any assumptions or limitations
MATLAB’s help function displays these comments:
help calculateCircleArea
4. Input Validation#
Check that inputs meet your expectations:
function area = calculateRectangleArea(length, width)
% CALCULATERECTANGLEAREA Computes the area of a rectangle
% Input validation
if length <= 0 || width <= 0
error('Length and width must be positive values');
end
area = length * width;
end
5. Consistent Formatting#
Use meaningful variable names
Indent code blocks consistently (4 spaces is standard)
Add blank lines to separate logical sections
Comment complex operations
6. Testing Functions Independently#
Write functions so they can be tested on their own:
% Test script for calculateCircleArea
testRadius = 5;
expectedArea = pi * 25;
actualArea = calculateCircleArea(testRadius);
if abs(expectedArea - actualArea) < 1e-10
fprintf('Test passed!\n');
else
fprintf('Test failed!\n');
end
Example: Building a Modular Program#
Let’s say you need to analyze temperature data from a file. Here’s how you might break it down:
File: analyzeTemperatures.m (Primary function)
function summary = analyzeTemperatures(filename)
% ANALYZETEMPERATURES Reads and analyzes temperature data from a file
temps = readTemperatureFile(filename);
temps_cleaned = removeOutliers(temps);
stats = calculateStatistics(temps_cleaned);
summary = formatSummary(stats);
end
function temps = readTemperatureFile(filename)
temps = load(filename);
end
function cleaned = removeOutliers(data)
meanVal = mean(data);
stdVal = std(data);
cleaned = data(abs(data - meanVal) < 3 * stdVal);
end
function stats = calculateStatistics(data)
stats.mean = mean(data);
stats.median = median(data);
stats.std = std(data);
end
function summary = formatSummary(stats)
summary = sprintf('Mean: %.2f, Median: %.2f, Std: %.2f', ...
stats.mean, stats.median, stats.std);
end
Notice how each function has a clear, single purpose and how they work together to accomplish the larger task.
Common Pitfalls to Avoid#
Forgetting to return values: Make sure output variables are assigned before the function ends
Filename mismatch: The filename must match the primary function name exactly
Modifying inputs and expecting changes: Remember pass by value—return modified data
Overusing global variables: Pass data through function arguments instead
Functions that are too long: If a function is more than 50 lines, consider breaking it up
Summary#
MATLAB functions follow similar principles to Python functions but with different syntax:
Each primary function lives in its own file
Outputs are declared in square brackets before the function name
Variables are local by default and data is passed by value
Local functions can be used as helpers within a file
Good modular design makes code reusable, testable, and maintainable
In class, we’ll practice writing functions and building modular programs to solve real engineering problems. Come prepared with questions!
Quick Reference#
% Single output
function output = myFunction(input)
output = input * 2;
end
% Multiple outputs
function [out1, out2] = myFunction(in1, in2)
out1 = in1 + in2;
out2 = in1 - in2;
end
% No output
function myFunction(input)
disp(input);
end
% With local helper function
function result = mainFunction(data)
processed = helperFunction(data);
result = processed * 2;
end
function out = helperFunction(in)
out = in + 1;
end