← MATLAB EnglishChapter 10 of 13

Programming Patterns

## Learning Objectives - Apply MATLAB programming patterns - Debug code effectively - Handle errors properly - Write maintainable code ## Code Organization ### Scripts vs Functions ```matlab % Script: commands in sequence % Use for: data processing, quick analysis % Variables persist in workspace a = 10; b = 20; c = a + b; disp(c); % Function: reusable, isolated scope % Use for: reusable code, algorithms function result = add(a, b) result = a + b; end ``` ### Project Organization ```text myproject/ main.m % Entry point functions/ processData.m % Data processing visualize.m % Plotting functions utils/ helper.m % Utility functions config/ settings.m % Configuration ``` ## Debugging ### Debug Mode ```matlab % Set breakpoints % Click line number or use: dbstop in functionName at lineNumber % Run in debug mode myFunction(input) % Step through dbstep % Execute next line dbstep in % Step into function dbstep out % Step out of function % Inspect variables whos % List workspace variables disp(variable) % Display value % Resume and quit dbcont % Continue execution dbquit % Exit debug mode ``` ### dbstop Options ```matlab dbstop in functionName % Stop at function entry dbstop in functionName at line % Stop at specific line dbstop if error % Stop on error dbstop if warning % Stop on warning dbstop if naninf % Stop on NaN or Inf ``` ### Print Debugging ```matlab % Display variable values x = 10; fprintf('x = %d\n', x); % Conditional debug output DEBUG = true; if DEBUG disp('Debug: entering loop'); end % Using keyboard function process() % ... keyboard; % Pauses execution, returns to prompt % Type 'return' to continue % Type 'dbquit' to exit end ``` ## Error Handling ### try-catch ```matlab try result = riskyOperation(); catch ME disp('Error occurred:'); disp(ME.message); end ``` ### Detailed Error Information ```matlab try x = 10 / 0; catch ME disp(['Identifier: ', ME.identifier]); disp(['Message: ', ME.message]); disp(['Line: ', num2str(ME.stack(1).line)]); disp(['Function: ', ME.stack(1).name]); end ``` ### Rethrowing ```matlab try x = notAFunction(); catch ME disp('Custom error handling'); rethrow(ME); % Re-throw with original info end ``` ### Lastwarn and lasterr ```matlab % Capture warnings lastwarn(''); % Clear x = sqrt(-1); [msg, id] = lastwarn; % Capture errors lasterr % Last error message ``` ## Conditional Execution ### Checking Inputs ```matlab function result = processData(data, varargin) % Validate required input if ~isnumeric(data) error('Data must be numeric'); end % Parse optional parameters p = inputParser; p.addOptional('verbose', false, @islogical); p.addOptional('maxIter', 100, @isnumeric); p.parse(varargin{:}); opts = p.Results; end ``` ### Input Validation ```matlab function y = compute(x) % Validate type validateattributes(x, {'numeric'}, {'finite'}); % Multiple conditions validateattributes(x, {'numeric'}, {'positive', 'finite', 'nonnan'}); % Custom validation if x < 0 error('x must be non-negative'); end end ``` ## Code Quality ### Naming Conventions ```matlab % Variables: lowercase with underscores (optional) iteration_count = 0; totalSum = 0; % Constants: UPPERCASE MAX_ITERATIONS = 100; PI = 3.14159; % Functions: camelCase or snake_case function output = calculateArea(radius) output = pi * radius^2; end % Classes: PascalCase (if using OOP) classdef MyClass properties Data end end ``` ### Comments ```matlab %{ Multi-line comment block for longer explanations %} % Single line comments for: % - Function headers % - Complex calculations % - TODO items % TODO: Add error handling % FIXME: Handle negative values % NOTE: This algorithm is O(n^2) ``` ## Vectorization Patterns ### Replace Loops with Vector Ops ```matlab % Slow: Loop result = zeros(1, 1000); for i = 1:1000 result(i) = sin(i) * cos(i); end % Fast: Vectorized x = 1:1000; result = sin(x) .* cos(x); ``` ### Logical Indexing ```matlab % Find and replace A = [1, 2, 3, 4, 5]; A(A > 3) = 10; % A = [1, 2, 3, 10, 10] % Conditional assignment B = zeros(size(A)); B(A > 2 & A < 5) = A(A > 2 & A < 5); ``` ### Accumarray ```matlab % Group and aggregate id = [1, 1, 2, 2, 2, 3]; val = [10, 20, 30, 40, 50, 60]; result = accumarray(id(:), val(:), [], @sum); % result = [30; 120; 60] ``` ## Performance Tips ### Preallocation ```matlab % Bad: Growing array result = []; for i = 1:1000 result = [result, i^2]; % Slow! end % Good: Preallocate result = zeros(1, 1000); for i = 1:1000 result(i) = i^2; end ``` ### Memory Efficiency ```matlab % Use appropriate types a = int8(10); % 1 byte vs 8 bytes for double % Clear large variables when done largeArray = rand(10000); clear largeArray; % Reuse memory x = zeros(1000); % Preallocate x(:) = newData; % Fill without new allocation ``` ### Profiling ```matlab % Profile code execution profile on % ... your code ... profile viewer % Check timing tic % ... code ... elapsed = toc; % Use timeit for function timing f = @() myFunction(data); t = timeit(f); ``` ## Unit Testing ### Simple Test Framework ```matlab function testResults = runTests() tests = { @testAdd, @testMultiply, @testDivide }; passed = 0; failed = 0; for i = 1:numel(tests) try tests{i}(); passed = passed + 1; fprintf('PASS: %s\n', func2str(tests{i})); catch ME failed = failed + 1; fprintf('FAIL: %s - %s\n', func2str(tests{i}), ME.message); end end fprintf('\nResults: %d passed, %d failed\n', passed, failed); end ``` ### Test Assertions ```matlab function testAdd() result = add(2, 3); assert(result == 5, 'Expected 2+3=5'); end function assert(condition, msg) if ~condition error(msg); end end ``` ## Logging ### Simple Logging ```matlab function logMessage(level, msg) fprintf('[%s] %s: %s\n', datestr(now), level, msg); end logMessage('INFO', 'Processing started'); logMessage('WARN', 'Low memory'); logMessage('ERROR', 'File not found'); ``` ### Debug Flag ```matlab function myFunction(data, debug) if nargin < 2 debug = false; end if debug fprintf('Input size: %d x %d\n', size(data)); end % Main logic... if debug fprintf('Output size: %d x %d\n', size(result)); end end ``` ## Summary - Use scripts for sequences, functions for reusable code - Set breakpoints with `dbstop`, use `dbstep` to navigate - Wrap risky code in `try-catch` blocks - Validate inputs with `validateattributes` - Vectorize loops for performance - Preallocate arrays before filling - Use `profile` and `tic/toc` for optimization - Write tests to verify correctness

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →