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 function keyword starts the definition

  • Outputs are listed in square brackets on the left side of the equals sign

  • The function name and filename must match (e.g., calculateArea.m contains function calculateArea)

  • The end keyword closes the function

All MATLAB functions consist of:

  1. The function header (first line) with:

    • The reserved word function

    • If 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)

  2. Comments describing what the function does (displayed by the help command)

  3. The body with all statements, including assigning values to all output arguments

  4. The end keyword

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:

  • calculateVolume instead of vol

  • convertToRadians instead of conv

  • validateInput instead of check

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#

  1. Forgetting to return values: Make sure output variables are assigned before the function ends

  2. Filename mismatch: The filename must match the primary function name exactly

  3. Modifying inputs and expecting changes: Remember pass by value—return modified data

  4. Overusing global variables: Pass data through function arguments instead

  5. 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