Best Practices
## Learning Objectives
- Write efficient MATLAB code
- Apply vectorization techniques
- Follow coding standards
- Optimize performance
## Code Style
### Clear Code Structure
```matlab
% Good: Clear spacing and organization
function result = calculateStatistics(data, options)
% Validate inputs
validateInputs(data);
% Process data
processed = preprocess(data, options);
% Compute statistics
result = computeStats(processed);
end
% Bad: All code crammed together
function r=c(d,o)
v(d);p=p(d,o);r=c(p);end
```
### Meaningful Names
```matlab
% Good: Descriptive names
velocityData = readData('velocity.csv');
maximumValue = max(velocityData);
% Bad: Short/unclear names
v = readData('v.csv');
m = max(v);
```
### Consistent Indentation
```matlab
% Use 4 spaces (or tab) for indentation
for i = 1:10
for j = 1:10
if i == j
matrix(i, j) = 1;
end
end
end
```
## Vectorization
### Replace Loops with Vector Operations
```matlab
% Bad: Loop
result = zeros(1, length(x));
for i = 1:length(x)
result(i) = sin(x(i)) * cos(x(i));
end
% Good: Vectorized
result = sin(x) .* cos(x);
```
### Logical Indexing
```matlab
% Find elements meeting condition
data = rand(1000, 1);
% Bad: Loop
high = [];
for i = 1:length(data)
if data(i) > 0.9
high = [high, data(i)];
end
end
% Good: Logical indexing
high = data(data > 0.9);
```
### Broadcasting
```matlab
% Add row vector to each row of matrix
A = rand(100, 10);
v = 1:10;
% Bad: Loop
B = zeros(size(A));
for i = 1:100
B(i, :) = A(i, :) + v;
end
% Good: Broadcasting
B = A + v;
```
### Array Functions
```matlab
% Instead of loops, use:
% - arrayfun: apply function to each element
% - cellfun: apply function to each cell
% - accumarray: aggregate by groups
data = 1:100;
squares = arrayfun(@(x) x^2, data);
% accumarray for grouping
id = randi(5, 100, 1);
vals = rand(100, 1);
sums = accumarray(id, vals, [], @sum);
```
## Preallocation
### Preallocate Arrays
```matlab
n = 10000;
% Bad: Growing array
result = [];
for i = 1:n
result = [result, i^2];
end
% Good: Preallocate
result = zeros(1, n);
for i = 1:n
result(i) = i^2;
end
% Best: Vectorized
result = (1:n).^2;
```
### Preallocate Cell Arrays
```matlab
% Bad
c = {};
for i = 1:100
c{end+1} = process(i);
end
% Good
c = cell(1, 100);
for i = 1:100
c{i} = process(i);
end
```
## Memory Efficiency
### Use Appropriate Types
```matlab
% Don't use double for small integers
img = uint8(imread('image.png')); % 1 byte per pixel
img = double(imread('image.png')); % 8 bytes per pixel
% Use single for large arrays if precision allows
largeArray = single(rand(10000));
```
### Clear Large Variables
```matlab
largeData = rand(10000);
clear largeData
% Or reuse variable
largeData(:) = newData;
```
### Memory-Mapped Files
```matlab
% For very large files
m = memmapfile('largefile.dat', 'Format', 'double');
m.Data(1:100)
```
## Performance Measurement
### Timing Functions
```matlab
% tic/toc for quick timing
tic
result = myFunction(data);
elapsed = toc;
% timeit for accurate function timing
f = @() myFunction(data);
t = timeit(f);
```
### Profiling
```matlab
% Start profiler
profile on
% Run code
myScript
% View results
profile viewer
% Or in command window
profview
```
### Memory Profiling
```matlab
% Check memory usage
memory
% Profile memory
profile('memory', 'on')
```
## Input Validation
### Validate Function Inputs
```matlab
function result = processData(data, varargin)
% Validate required input
if ~isnumeric(data)
error('Input must be numeric');
end
if ~isvector(data)
error('Input must be a vector');
end
% Validate using validateattributes
validateattributes(data, {'numeric'}, {'finite', 'real'});
end
```
### parseargs for Optional Parameters
```matlab
function result = func(x, varargin)
p = inputParser;
p.addOptional('alpha', 0.5, @isnumeric);
p.addOptional('maxIter', 100, @(x) x>0 && isscalar(x));
p.addParameter('verbose', false, @islogical);
p.parse(varargin{:});
opts = p.Results;
end
```
## Error Handling
### Meaningful Error Messages
```matlab
% Bad
if x < 0
error('Invalid');
end
% Good
if x < 0
error('Input x must be non-negative. Got x = %g', x);
end
```
### Use Warnings
```matlab
if x < 0
warning('x is negative, using absolute value');
x = abs(x);
end
```
## Documentation
### Function Documentation
```matlab
function result = myFunction(arg1, arg2)
%MYFUNCTION Short description
% Detailed description of what the function does.
%
% Inputs:
% arg1 - Description of first argument
% arg2 - Description of second argument
%
% Outputs:
% result - Description of return value
%
% Example:
% result = myFunction(1, 2);
%
% See also OTHERFUNCTION
% Function implementation
end
```
### Inline Comments
```matlab
% Calculate distance from origin
distance = sqrt(x^2 + y^2);
% Normalize by total (percentages)
normalized = distance / sum(distance) * 100;
```
## Testing
### Write Test Functions
```matlab
function testMyFunction
% Test basic case
assert(myFunction(2, 3) == 6);
% Test edge case
assert(myFunction(0, 5) == 0);
% Test with tolerance for floating point
assert(abs(myFunction(sqrt(2), sqrt(2)) - 2) < 1e-10);
% Test error case
try
myFunction(-1, 1);
error('Should have thrown error');
catch ME
% Expected error
end
end
```
## Version Control Integration
### Function Headers for Git
```matlab
function result = myFunction(data)
%MYFUNCTION Brief description
%
% TODO: Add parameter validation
% FIXME: Handle empty input
% DATE: 2024-01-15
% VERSION: 1.2
% Author: Your Name
% Change: Added feature X
end
```
## Common Pitfalls
### Floating Point Comparison
```matlab
% Bad
if a == b
disp('Equal');
end
% Good: Use tolerance
tol = 1e-10;
if abs(a - b) < tol
disp('Approximately equal');
end
% Or use isequaln for NaN handling
if isequaln(a, b)
disp('Equal');
end
```
### Matrix Dimensions
```matlab
% Ensure dimension compatibility
A = rand(10, 5);
B = rand(5, 1);
% Check sizes before operation
if size(A, 2) == size(B, 1)
C = A * B;
else
error('Matrix dimensions must agree');
end
```
### Avoiding Global Variables
```matlab
% Bad: Global variable
global DATA;
DATA = loadData();
% Good: Pass as argument
function result = processData(DATA)
result = analyze(DATA);
end
```
## Summary
- Use meaningful variable names and consistent formatting
- Vectorize whenever possible instead of loops
- Preallocate arrays before filling them
- Validate inputs to catch errors early
- Write clear error messages
- Document functions with help text
- Write tests to verify correctness
- Use `tic/toc` and `profile` for performance analysis
- Avoid global variables; pass data as arguments
- Use tolerances for floating point comparisons
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →