Professional Documents
Culture Documents
Matlab SImulink Collate 130121
Matlab SImulink Collate 130121
==, ~=, <, >, <=, >= zeros(m,n) Create m x n matrix of zeros
Relational operators
ones(m,n) Create m x n matrix of ones
&&, ||, ~, xor Logical operations
(AND, NOT, OR, XOR) eye(n) Create a n x n identity matrix
; Suppress output display A=diag(x) Create diagonal matrix from vector
... Connect lines (with break) x=diag(A) Get diagonal elements of matrix
% Description Comment meshgrid(x,y) Create 2D and 3D grids
'Hello' Definition of a character vector rand(m,n), randi Create uniformly distributed random
"This is a string" numbers or integers
Definition of a string
randn(m,n) Create normally distributed random
str1 + str2 Append strings
numbers
mathworks.com/help/matlab
Elementary Functions Plotting
sin(x), asin Sine and inverse (argument in radians) plot(x,y,LineSpec) Plot y vs. x
Line styles: (LineSpec is optional)
sind(x), asind Sine and inverse (argument in degrees)
-, --, :, -. LineSpec is a combination of
sinh(x), asinh Hyperbolic sine and inverse (arg. in Markers: linestyle, marker, and
radians) +, o, *, ., x, s, d color as a string.
Analogous for the other trigonometric functions: Colors: Example: "-r"
cos, tan, csc, sec, and cot r, g, b, c, m, y, k, w = red solid line without markers
abs(x) Absolute value of x, complex magnitude title("Title") Add plot title
exp(x) Exponential of x legend("1st", "2nd") Add legend to axes
sqrt(x), nthroot(x,n) Square root, real nth root of real numbers x/y/zlabel("label") Add x/y/z axis label
log(x) Natural logarithm of x x/y/zticks(ticksvec) Get or set x/y/z axis ticks
log2(x), log10 Logarithm with base 2 and 10, respectively x/y/zticklabels(labels) Get or set x/y/z axis tick labels
factorial(n) Factorial of n x/y/ztickangle(angle) Rotate x/y/z axis tick labels
sign(x) Sign of x x/y/zlim Get or set x/y/z axis range
mod(x,d) Remainder after division (modulo) axis(lim), axis style Set axis limits and style
ceil(x), fix, floor Round toward +inf, 0, -inf text(x,y,"txt") Add text
round(x) Round to nearest decimal or integer grid on/off Show axis grid
hold on/off Retain the current plot when
adding new plots
Tables subplot(m,n,p), Create axes in tiled positions
table(var1,...,varN) Create table from data in variables tiledlayout(m,n)
var1, ..., varN yyaxis left/right Create second y-axis
readtable("file") Create table from file figure Create figure window
array2table(A) Convert numeric array to table gcf, gca Get current figure, get current axis
T.var Extract data from variable var clf Clear current figure
T(rows,columns), Create a new table with specified close all Close open figures
T(rows,["col1","coln"]) rows and columns from T
T.varname=data Assign data to (new) column in T Common Plot Types
T.Properties Access properties of T
categorical(A) Create a categorical array
summary(T), groupsummary Print summary of table
join(T1, T2) Join tables with common variables
mathworks.com/help/matlab
Programming Methods Numerical Methods
Functions fzero(fun,x0) Root of nonlinear function
% Save your function in a function file or at the end fminsearch(fun,x0) Find minimum of function
% of a script file. Function files must have the
fminbnd(fun,x1,x2) Find minimum of fun in [x1, x2]
% same name as the 1st function
function cavg = cumavg(x) %multiple args. possible fft(x), ifft(x) Fast Fourier transform and its inverse
cavg=cumsum(vec)./(1:length(vec));
end
Integration and Differentiation
Anonymous Functions
% defined via function handles integral(f,a,b) Numerical integration
fun = @(x) cos(x.^2)./abs(3*x); (analogous functions for 2D and 3D)
trapz(x,y) Trapezoidal numerical integration
mathworks.com/help/matlab
Matrices and Arrays Descriptive Statistics
length(A) Length of largest array dimension sum(A), prod Sum or product (along columns)
size(A) Array dimensions max(A), min, bounds Largest and smallest element
numel(A) Number of elements in array mean(A), median, mode Statistical operations
sort(A) Sort array elements std(A), var Standard deviation and variance
sortrows(A) Sort rows of array or table movsum(A,n), movprod, Moving statistical functions
movmax, movmin, n = length of moving window
flip(A) Flip order of elements in array
movmean, movmedian,
squeeze(A) Remove dimensions of length 1 movstd, movvar
reshape(A,sz) Reshape array cumsum(A), cumprod, Cumulative statistical functions
repmat(A,n) cummax, cummin
Repeat copies of array
smoothdata(A) Smooth noisy data
any(A), all Check if any/all elements are nonzero
nnz(A) histcounts(X) Calculate histogram bin counts
Number of nonzero array elements
find(A) corrcoef(A), cov Correlation coefficients, covariance
Indices and values of nonzero elements
xcorr(x,y), xcov Cross-correlation, cross-covariance
normalize(A) Normalize data
Linear Algebra
detrend(x) Remove polynomial trend
rank(A) Rank of matrix
isoutlier(A) Find outliers in data
trace(A) Sum of diagonal elements of matrix
det(A) Determinant of matrix
poly(A) Characteristic polynomial of matrix
Symbolic Math*
eig(A), eigs Eigenvalues and vectors of matrix (subset) sym x, syms x y z Declare symbolic variable
inv(A), pinv Inverse and pseudo inverse of matrix eqn = y == 2*a + b Define a symbolic equation
norm(x) Norm of vector or matrix solve(eqns,vars) Solve symbolic expression
for variable
expm(A) Matrix exponential
subs(expr,var,val) Substitute variable in expression
cross(A,B) Cross product
expand(expr) Expand symbolic expression
dot(A,B) Dot product
factor(expr) Factorize symbolic expression
kron(A,B) Kronecker tensor product
simplify(expr) Simplify symbolic expression
null(A) Null space of matrix
assume(var,assumption) Make assumption for variable
orth(A) Orthonormal basis for matrix range
assumptions(z) Show assumptions for
tril(A), triu Lower and upper triangular part of matrix
symbolic object
linsolve(A,B) Solve linear system of the form AX=B fplot(expr), fcontour, Plotting functions for
lsqminnorm(A,B) Least-squares solution to linear equation fsurf, fmesh, fimplicit symbolic expressions
qr(A), lu, chol Matrix decompositions diff(expr,var,n) Differentiate symbolic expression
svd(A) Singular value decomposition dsolve(deqn,cond) Solve differential
gsvd(A,B) Generalized SVD equation symbolically
mathworks.com/help/matlab
© 2020 The MathWorks, Inc. MATLAB and Simulink are registered trademarks of The MathWorks, Inc. See mathworks.com/trademarks for a list of additional trademarks.
Other product or brand names may be trademarks or registered trademarks of their respective holders.
Advanced Programming
Techniques in MATLAB
Loren Shure
MathWorks, Inc.
2
MATLAB and Memory
function y = foo(x,a,b)
a(1) = a(1) + 12;
y = a*x+b;
Calling foo
y = foo(1:3,2,4)
– i.e., x = 1:3, a = 2, b = 4
3
In-place Optimizations
x = 2*x + 3;
y = 2*x + 3;
4
In-place Optimizations
function testInPlace
x = randn(n,1);
x = myfunc(x); % vs. y = myfunc(x)
x = myfuncInPlace(x); % vs. y = myfuncInPlace(x)
function x = myfuncInPlace(x)
x = sin(2*x.^2+3*x+4);
function y = myfunc(x)
y = sin(2*x.^2+3*x+4);
d = [1 2] % Double array
dcell = {d} % Cell array containing
dstruct.d = d
whos
6
Container Overhead
data
field
data name
cell field
data header header
unreported
112
variable header 112 + 112 112 + 112 + 64
7
MATLAB and Memory
s.A = rand(3000,3000);
s.B = rand(3000,3000);
sNew = s;
s.A(1,1) = 17;
8
MATLAB and Memory
% each 1x3
im2(1,1).pixel = [red(1) green(1) blue(1)];
im2(2,1).pixel = [red(2) green(2) blue(2)];
...
im2(m,n).pixel = [red(m*n) green(m*n) …
blue(m*n)];
9
Tables
Built-in functionality
(merge, sort, etc.)
10
Categorical Arrays
12
MATLAB and Memory: Additional Resources
Recorded Webinar:
– Handling Large Data Sets Efficiently in MATLAB
– mathworks.com -> Recorded Webinars
13
Functions
14
A comp.soft-sys.matlab Post
Question:
With the new function types introduced in R14, I am curious as to which methods would
be preferable from a speed standpoint. We have:
1. Functions defined in separate files
2. Subfunctions
3. Inline functions
4. Anonymous functions
5. Nested functions
Other than scope, persistence, or program structure, is there some difference that
makes MATLAB work better with the type?
15
comp.soft-sys.matlab Post Answered
Cleve’s Answer
Good question, and a hard one to answer. As MATLAB evolves, the answer will
change. The function call mechanism in the current version of MATLAB is pretty
expensive, for any kind of function. One of the most important tasks facing our
Accelerator/JIT team today is to make function calls faster. This is why we have
introduced the @ notation for both function handles and anonymous functions.
Future versions of MATLAB should have improved speed for anything involving the
@ sign.
Inline functions were an experiment in the use of the overloading mechanism that
turned out to be useful. But we've always regarded them as a bit of a hack. So our
advice now is to phase out their use over time. Other than that, your choice today
among the other kinds of functions should be based on style and convenience.
16
Function Quiz
18
Advice
19
Nested Function Applications
20
Application 1:
Solving Optimization Problems
We get many posts on comp.soft-sys.matlab about
optimization. The problems fall into several catgories.
The one we will address to today is:
21
Optimization Example (unconstrained)
Objective function:
a x1^2 + b x1 x2 + c x2^2 + d abs(x2 – x1)+
e*randn
22
Application 2:
Building a Graphical User Interface for Volume
Visualization
Application: Building a
custom tool for volume
visualization
This example illustrates:
– Using function handles to
export nested functions
– Using nested functions for
object callbacks
25
Application 3 (Optional):
Creating Two-Figure GUIs
This is a frequent comp.soft-sys.matlab request
(several times each month).
Challenges:
– Managing handles
– Sharing information between figures
26
Red-Blue Exercise
27
Why Use Nested and Anonymous Functions?
29
Function Usage Advice
You can now (as of Release 14) call functions without inputs using
this notation:
y = foo();
Put all nested functions at the bottom of the enclosing function. You
may prefer to have them defined right where you will use them, but
this can become unwieldy.
30
More Function Usage Advice
Nested functions are very good when there is much large data to
share for reading and writing.
31
MATLAB Function Types: Additional
Resources
MATLAB Digest - September 2005
– Dynamic Function Creation with Anonymous and Nested Functions
– http://www.mathworks.com/company/newsletters/digest/2005/sept/dynfunctions
.html
Examples
– Anonymous functions
– http://www.mathworks.com/products/matlab/demos.html?file=/products/demos/
shipping/matlab/anondemo.html
– Nested Functions
– http://www.mathworks.com/products/matlab/demos.html?file=/products/demos/
shipping/matlab/nesteddemo.html
The Art of MATLAB Blog
– Look at Category: Function Handles
– http://blogs.mathworks.com/loren/
32
Summary
33
Advanced Programming with MATLAB
2
SH1
function y = foo(x,a,b)
a(1) = a(1) + 12;
y = a*x+b;
Calling foo
y = foo(1:3,2,4)
– i.e., x = 1:3, a = 2, b = 4
3
In-place Optimizations
x = 2*x + 3;
y = 2*x + 3;
4
In-place Optimizations
function showInPlace
xx = randn(n,1);
xx = myfunc(xx); % vs. yy = myfunc(xx)
xx = myfuncInPlace(xx); % vs. yy = myfuncInPlace(xx)
function x = myfuncInPlace(x)
x = sin(2*x.^2+3*x+4);
function y = myfunc(x)
y = sin(2*x.^2+3*x+4);
y = myfunc(x);
x = myfunc(x);
Memory
y = myfuncInPlace(x);
x = myfuncInPlace(x);
Time
6
Memory Used for Different Array Types
d = [1 2] % Double array
dcell = {d} % Cell array
dstruct.d = d % Structure
whos
7
How does MATLAB store data?
Container overhead
dstruct.d = d
8
Container Overhead
data 16 bytes
field
data name
64 bytes
cell field
data header header 112 bytes
unreported
variable header
112 bytes
9
MATLAB and Memory
n = 10000;
s.A = rand(n,n);
s.B = rand(n,n);
sNew = s;
s.A(1,1) = 17;
10
MATLAB and Memory
% each 1x3
im2(1,1).pixel = [red(1) green(1) blue(1)];
im2(2,1).pixel = [red(2) green(2) blue(2)];
...
im2(m,n).pixel = [red(m*n) green(m*n) …
blue(m*n)];
11
Tables
Built-in functionality
(merge, sort, etc.)
12
Working with Big Data Just Got Easier
Machine
Memory
Use tall arrays to manipulate and analyze
data that is too big to fit in memory e.g.
4~8GB
Data Access
Data Munging
Machine Learning
ASCII File
Database (SQL) (100’s of functions)
Spreadsheet Math Linear Model
Custom Files Statistics Logistic Regression
Missing Data Discriminant Analysis
• table Visualization K-means
• cell Date/Time PCA
• numeric String Random Data Sampling
• cellstr & string
Summary Statistics
• Date & Time
• categorical
14
Execution Environments for Tall Arrays
15
Categorical Arrays
Performance improvement
– Up to 50x faster using contains with string than strfind with cellstr
– Up to 2x memory savings using string over cellstr
17
Summary of MATLAB and Memory
18
MATLAB and Memory: Additional Resources
Recorded Webinar:
– Tackling Big Data in MATLAB
– mathworks.com -> Recorded Webinars
19
Functions
20
A comp.soft-sys.matlab Post
Question:
With the new function types introduced in R14, I am curious as to which methods would be preferable from a speed
standpoint. We have:
1. Functions defined in separate files
2. Subfunctions
3. Inline functions
4. Anonymous functions
5. Nested functions
Other than scope, persistence, or program structure, is there some difference that makes MATLAB work better with
the type?
21
comp.soft-sys.matlab Post Answered
Cleve’s Answer
Good question, and a hard one to answer. As MATLAB evolves, the answer will change. The function call
mechanism in the current version of MATLAB is pretty expensive, for any kind of function. One of the most
important tasks facing our Accelerator/JIT team today is to make function calls faster. This is why we have
introduced the @ notation for both function handles and anonymous functions. Future versions of MATLAB
should have improved speed for anything involving the @ sign.
Inline functions were an experiment in the use of the overloading mechanism that turned out to be useful. But we've
always regarded them as a bit of a hack. So our advice now is to phase out their use over time. Other than that,
your choice today among the other kinds of functions should be based on style and convenience.
22
Function Quiz
23
Function Quiz Review
24
Advice
You can use the function functions to explore details of the function
referred to by a particular function handle.
NOTE: Changing the values of the struct output from functions does NOT
alter the function handle details!
25
Nested Function Applications
26
Application 1:
Solving Optimization Problems
We get many posts on comp.soft-sys.matlab about optimization. The
problems fall into several catgories. The one we will address to today is:
27
Optimization Example (unconstrained)
Objective function:
28
Application 2:
Building a Graphical User Interface for Volume Visualization
29
Why Use Nested and Anonymous Functions?
30
Summary and Advice
Anonymous Functions
Create simple functions without creating m-files:
– fh = @(x,y) a*sin(x)*cos(y)
31
Summary and Advice
Nested Functions
Embed one function within another, with shared, persistent workspace:
– function main
– function nest
– end
– end
32
Function Usage Advice
Put all nested functions at the bottom of the enclosing function. You may prefer to have
them defined right where you will use them, but this can become unwieldy.
Place a comment next to a call to a nested function stating what workspace variables are
altered by the call (since the nested function can see the enclosing workspace).
33
More Function Usage Advice
Nested functions are good when there is significant shared information (many pieces or
large arrays).
Nested functions are very good when there is much large data to share for reading and
writing.
Local functions (or private functions) are useful when users don't need these directly.
Those who need them can see.
Data sharing inside local functions is only reading large arrays, not making copies and
changing them.
34
MATLAB Function Types: Additional Resources
35
Summary
36
Dynamic Function Creation with Anonymous and Nested Functions
When you are developing algorithms to solve technical computing problems, it is often useful to create functions on-the-fly so that you can customize them at run-time without having to define them in files
beforehand. For example:
You may want to create a function based on a user's input and then evaluate or plot it over a specific range.
You may want to define a function and then pass it as an argument to an optimization, numerical integration, or ODE solving routine (also known as a function function in MATLAB).
In curve fitting, you need to create a function that best fits some chosen data and subsequently need to evaluate it at other data points or perform further operations on it, such as integration.
Sometimes it is necessary to create a function that needs to retain dynamic state and which must be initialized the first time it is called and updated at each subsequent call.
Other uses for dynamically created functions include callbacks in MATLAB Handle Graphics, data acquisition objects and timers, and, generally, any time you need to pass a function as a parameter to
another routine.
Earlier versions of MATLAB already provided a number of features for managing functions, but there were limitations, for example:
The MATLAB language has function handles that let you pass functions as parameters to routines, but they needed to be associated with a function definition in an M-file and evaluated with
the feval command.
You can specify arbitrary functions as a string with the inline command and pass them to the function function routines, but this command is difficult to use, particularly to separate the many different
types of parameters, including the arguments to the inlined function and the function function itself.
The keyword persistent provides state in functions, but you can have only one instance of a traditional MATLAB function. Also, the function must carry out initialization the first time it is called.
Two new language features in MATLAB 7, anonymous functions and nested functions, address these issues and requirements for creating and managing functions.
The SSDK uses voltammetry, an advanced chemical analysis technique that translates chemical reactions into voltammetric “signature” outputs, enabling the detection of minute quantities of gaseous
chemicals—something that was not previously possible.
The researchers implemented gaseous voltammetry using Data Acquisition Toolbox to output precisely shaped analog waveforms, each consisting of 100 to 1,000 points of data, and to excite chemical
reactions on the microsensor. Using Data Acquisition Toolbox, they also sampled the resulting signals with an analog input channel. They then used filters from Signal Processing Toolbox to remove line
noise. The resulting signals, or voltammetric signatures, included information that identified the chemicals to which the sensor was exposed.
The researchers used Neural Network Toolbox to perform pattern recognition and identify the chemicals by comparing their signatures to those in a prestored library.
“With Neural Network Toolbox, we can take an unknown sample signature, compare it to a signature library, find the best match, and calculate a confidence factor indicating how certain the match is,” Vogt
says.
To generate the sensor signal-processing algorithms, Argonne used the Sensor Algorithm Generation Environment (ChemSAGE), a Department of Defense-funded software tool, written in MATLAB, that
helps sensor researchers code and analyze complex signals from experimental sensors.
To complete their application, researchers developed a graphical user interface in MATLAB that enables users to set voltammetry parameters and visualize the voltammetric signatures. “The application
runs easily on any notebook computer,” Vogt says.
Using MATLAB Compiler, Argonne recoded the MATLAB algorithms in C for execution on popular single-chip microcontrollers.
Argonne’s sponsors plan to develop commercial instruments based on SSDK, including intelligent fire detectors and air pollutant monitors.
Doctors Michael Vogt, Laura Skubal, Erika Shoemaker, and John Ziegler developed the SSDK. Vogt, Dan MacShane, Christopher Klaus, and Maria Poulos developed the measurement and ChemSAGE
software.
Anonymous functions let you define a function on-the-fly at the command line or in M code, without an associated file. For example, to create a polynomial function,
y(x) = 3x2 + 2x + 1
type
This returns function handle y representing a function of one variable defined by the expression on the right. The variables in parentheses following the @ symbol (in this case, only x) specify variables of
which y is a function. The function y can now be evaluated by calling it like any other function (another new feature in MATLAB 7).
y(3)
ans =
34
You could evaluate this polynomial over a range of points and plot the results together with the previously evaluated point.
x=-5:.1:5;
plot(x,y(x),'-b',4,y(4),'r*');
title('y(x) = 3*x^2 + 2*x + 1');
xlabel('x');
ylabel('y');
text(4,y(4),'y(4)');
grid
Using MathWorks tools, the researchers developed simple data acquisition code that could access a variety of data acquisition cards. “Data Acquisition Toolbox allows us to perform a one-time
configuration of the hardware,” explains Vogt. “With less than a page of code, I could perform my data acquisition on four different platforms—each one with different hardware.”
The SSDK uses voltammetry, an advanced chemical analysis technique that translates chemical reactions into voltammetric “signature” outputs, enabling the detection of minute quantities of gaseous
chemicals—something that was not previously possible.
The researchers implemented gaseous voltammetry using Data Acquisition Toolbox to output precisely shaped analog waveforms, each consisting of 100 to 1,000 points of data, and to excite chemical
reactions on the microsensor. Using Data Acquisition Toolbox, they also sampled the resulting signals with an analog input channel. They then used filters from Signal Processing Toolbox to remove line
noise. The resulting signals, or voltammetric signatures, included information that identified the chemicals to which the sensor was exposed.
The researchers used Neural Network Toolbox to perform pattern recognition and identify the chemicals by comparing their signatures to those in a prestored library.
“With Neural Network Toolbox, we can take an unknown sample signature, compare it to a signature library, find the best match, and calculate a confidence factor indicating how certain the match is,” Vogt
says.
To generate the sensor signal-processing algorithms, Argonne used the Sensor Algorithm Generation Environment (ChemSAGE), a Department of Defense-funded software tool, written in MATLAB, that
helps sensor researchers code and analyze complex signals from experimental sensors.
To complete their application, researchers developed a graphical user interface in MATLAB that enables users to set voltammetry parameters and visualize the voltammetric signatures. “The application
runs easily on any notebook computer,” Vogt says.
Using MATLAB Compiler, Argonne recoded the MATLAB algorithms in C for execution on popular single-chip microcontrollers.
Argonne’s sponsors plan to develop commercial instruments based on SSDK, including intelligent fire detectors and air pollutant monitors.
Doctors Michael Vogt, Laura Skubal, Erika Shoemaker, and John Ziegler developed the SSDK. Vogt, Dan MacShane, Christopher Klaus, and Maria Poulos developed the measurement and ChemSAGE
software.
Nested functions are functions in M-files that are nested inside other functions and which can see the parent function’s workspace. The following function taxDemo.m contains a nested function.
function y = taxDemo(income)
% Calculate the tax on income.
y = computeTax;
function y = computeTax
% This function can see the variable 'AdjustedIncome'
% in the calling function's workspace
y = 0.28 * AdjustedIncome;
end
end
The nested function computeTax can see the variables in the parent function's workspace, in this case AdjustedIncome and income. This makes sharing of data between multiple nested functions easy. We
can call the function in the usual way.
tax =
2.0720e+004
The ability of nested functions to see into their parent's workspace enables you to control the scope of your variables, letting them be accessed by multiple functions, while avoiding the side effects of us ing
a global variable. At the same time, you can reduce your memory requirements by sharing large data sets in a controlled way.
An end statement is required at the end of all nested functions, making them different from traditional local subfunctions. However, all functions in a file containing nested functions, including traditional
subfunctions, require termination with an end statement. Functions can be nested to any level.
Customizing Functions
You can create different variants or customized versions of the same function with anonymous functions or nested functions. For example, if we want to create a function like
y = ax2 + bx + c
Any variables in the function that are not listed in parentheses are taken from the calling workspace at the time of definition.
Now let's change a, b, or c and generate other customized functions. For example,
x=-5:.1:5;
plot(x, y1(x), x, y2(x));
legend('y_1(x)=3x^2+2x-10','y_2(x)=-5x^2+x+20');
xlabel('x');
ylabel('y_1 and y_2');
title('y(x) = a*x^2 + b*x + c');
grid
Using MathWorks tools, the researchers developed simple data acquisition code that could access a
variety of data acquisition cards. “Data Acquisition Toolbox allows us to perform a one-time
configuration of the hardware,” explains Vogt. “With less than a page of code, I could perform my data
acquisition on four different platforms—each one with different hardware.”
The SSDK uses voltammetry, an advanced chemical analysis technique that translates chemical
reactions into voltammetric “signature” outputs, enabling the detection of minute quantities of gaseous
chemicals—something that was not previously possible.
The researchers implemented gaseous voltammetry using Data Acquisition Toolbox to output precisely
shaped analog waveforms, each consisting of 100 to 1,000 points of data, and to excite chemical
reactions on the microsensor. Using Data Acquisition Toolbox, they also sampled the resulting signals
with an analog input channel. They then used filters from Signal Processing Toolbox to remove line
noise. The resulting signals, or voltammetric signatures, included information that identified the
chemicals to which the sensor was exposed.
The researchers used Neural Network Toolbox to perform pattern recognition and identify the chemicals
by comparing their signatures to those in a prestored library.
“With Neural Network Toolbox, we can take an unknown sample signature, compare it to a signature
library, find the best match, and calculate a confidence factor indicating how certain the match is,” Vogt
says.
To generate the sensor signal-processing algorithms, Argonne used the Sensor Algorithm Generation
Environment (ChemSAGE), a Department of Defense-funded software tool, written in MATLAB, that
helps sensor researchers code and analyze complex signals from experimental sensors.
To complete their application, researchers developed a graphical user interface in MATLAB that
enables users to set voltammetry parameters and visualize the voltammetric signatures. “The
application runs easily on any notebook computer,” Vogt says.
Using MATLAB Compiler, Argonne recoded the MATLAB algorithms in C for execution on popular
single-chip microcontrollers.
Argonne’s sponsors plan to develop commercial instruments based on SSDK, including intelligent fire
detectors and air pollutant monitors.
Doctors Michael Vogt, Laura Skubal, Erika Shoemaker, and John Ziegler developed the SSDK. Vogt,
Dan MacShane, Christopher Klaus, and Maria Poulos developed the measurement and ChemSAGE
software.
Since the definitions of y1 and y2 included the values of a, b, and c at the time the function handles are
created, they are robust to variations in the workspace such as changed or deleted values of a, b, or c.
a=100;
y1(3)
ans =
23
a=5000;
y1(3)
Let's see how we can carry out a similar task with nested functions by looking at makefcn.m, which contains a nested function.
When you call makefcn, it returns a function handle to the internal nested function, which has been customized according to the parameters passed to the parent function. For example,
f1 = makefcn(3,2,10);
f2 = makefcn(0,5,25);
f1(2)
ans =
26
f2(2)
ans =
35
In general, anonymous functions are better for quick, on-the-fly simple function creation and customization. Nested functions are more suited to more complex function customization and management.
areaunder=quad(f1,0,4)
areaunder =
120.0000
By having the integrand f1 defined beforehand, you keep its arguments (such as the polynomial coefficients) separate from those of the integrator quad (such as the limits of integration). This can eliminate
potential confusion.
We will plot f1 again together with a plot of the area just calculated.
x=-5:.1:5;
plot(x,f1(x));
hold on
x=0:.1:4;
area(x,f1(x),'Facecolor','g'); % You can evaluate f without feval
hold off
title('Area under f_1(x), between 0 and 4');
grid
Handling Dynamic Function State
If you need to create a function that retains dynamic state, you can use a nested function and store its
state in the parent's workspace. Functions with dynamic state can represent algorithms that range from
simple counters to components of a large system.
When you call makecounter, it returns a handle to its nested function getCounter. getCounter is customized by the value of initvalue, a variable it can see via nesting within the workspace of makecounter.
Let's make a couple of counter functions.
Here we have created two customized counters: one that starts at 0 and one that starts at 10. Each handle is a separate instance of the nested function and its calling workspace. Note counter1 does not
take any parameters. We need to use the parentheses to invoke the function instead of looking at the function handle variable itself.
counter1Value=counter1()
counter1Value =
1
We can call the two functions independently as there are two separate workspaces kept for the parent functions. They remain in memory while the handles to their nested functions exist. Each time the
counter functions are called, the associated variable currentCount is incremented.
counter1Value=counter1()
counter1Value =
2
counter2Value=counter2()
counter2Value =
11
% Initialize State
state=zeros(max(length(a),length(b))-1,1);
The function makeFilter returns a handle to a nested function (callFilter) that performs a filtering operation and maintains its state in the parent's workspace. The filter state is initialized when the function
handle is created, then gets updated each time the nested function is called. The nested function also has to calculate the output of the filtering operation and return it as its output argument. You can call
this function in a for-loop many times, as shown in simplesystem.m.
%% System Parameters
frameSize = 1000;
sampleTime = 1e-3;
%% Simulation Loop
for k = 1:100
signal1 = randSource(); signal2 = filter1(signal1); signal3 = filter2(signal2); scope(signal3)
end
The main for-loop in the simulation now becomes very clean and simple where the only variables passed between the functions (signal1, signal2, and signal3) are pure data, without being mixed up with
other function parameters (such as filter coefficients) and state.
The makeFilter routine could be expanded to return more than one function, such as one to return the filter state, or even one to reset the filter. These function handles could be returned as multiple output
arguments or as a structure, where each field is a function handle. The functions can then be called in a manner similar to evaluating the methods of an object.
Function Composition
You can create handles to functions of functions, allowing a very natural mathematical notation for function composition, such as
f=@(x) x.^2;
g=@(x) 3*x;
h=@(x) g(f(x)); % Equivalent to 3*(x^2)
h(3)
ans =
27
Memoization
We can store the previously computed return values of a function in a "table" for later use instead of recalculating values. This is helpful if the function is computationally intensive. Let's look at a function
that stores computed values and makes them available for reuse.
function f = memoize(F)
% One argument F, inputs testable with ==
% Scaler input to F
x = [];
y = [];
f = @inner;
function out = inner(in)
ind = find(in == x);
if isempty(ind)
out = F(in);
x(end+1) = in;
y(end+1) = out;
else
out = y(ind);
end
end
end
Here's how to use this function. First you create a "memoized" version of the function for which you want to remember the return values, for example, sin.
f = memoize(@sin)
f =
@memoize/inner
f(pi/2)
ans =
1
f(pi/4)
ans =
0.7071
f(pi/8)
ans =
0.3827
The returned values, in this case sin(pi/2), sin(pi/4), and sin(pi/8) are stored. To see how this is working, let's use the functions command to inspect the state of the function handle f.
functionInfo = functions(f)
functionInfo =
function: 'memoize/inner'
type: 'nested'
file: [1x76 char]
workspace: {[1x1 struct]}
functionInfo.workspace{1}
ans =
f: @memoize/inner
F: @sin
x: [1.5708 0.7854 0.3927]
y: [1 0.7071 0.3827]
Now if you request a previously computed result, such as for sin(pi/4), the value is taken from the table without a new value being added. Here you can see the stored workspace doesn't change.
f(pi/4)
ans =
0.7071
functionInfo = functions(f);
functionInfo.workspace{1}
ans =
f: @memoize/inner
F: @sin
x: [1.5708 0.7854 0.3927]
y: [1 0.7071 0.3827]
Data Structures
Nested functions can be used to create data structures such as lists and trees.
Published 2
Polynomial fit passing through specified points
Jiro's pick this week is polyfix by Are Mjaavatten.
Have you ever wanted to fit a polynomial to your data and have the line go through some specified points? What about specifying the slope at a certain point? Let's take a look at some options,
including Are's entry.
Contents
Polynomial fitting
Constrain to go through certain points
Constrain to have a certain derivative
polyfix
Optimization Toolbox
Comments
Polynomial fitting
The function polyfit lets you fit a polynomial to your data. We'll first create some data.
t = linspace(0,2,31)';
y = sin(pi*t)+ 0.1*randn(size(t));
plot(t,y,'o')
We'll fit a 3rd order polynomial to the data.
y ≈ x 1t 3 + x 2t 2 + x 3t + x 4
y≈x1t3+x2t2+x3t+x4
x_polyfit = polyfit(t,y,3)
y1 = polyval(x_polyfit,t);
plot(t,y,'o',t,y1)
legend('data','polyfit')
x_polyfit =
2.8843 -8.6941 6.0419 -0.2050
Constrain to go through certain points
What if you want this polynomial to go through certain points. Perhaps, you want the curve to cross (0, 0) and (2, 0). This is where Are's entry comes into play. But first, let me talk about a
different method. I found this question on MATLAB Answers. There are several ways to deal with this, and one of them is to use a function like lsqlin from Optimization
Toolbox. lsqlin solves the following least-squares curve fitting problem.
A ⋅ x ≤ b,
1
min ||C ⋅ x − d|| 22 such that { Aeq ⋅ x = beq,
x 2
lb ≤ x ≤ ub
minx12||C⋅x−d||22suchthat{A⋅x≤b,Aeq⋅x=beq,lb≤x≤ub
C = [t 3 t2 t 1] , d=y
C=[t3t2t1],d=y
For the equality constraints, we need to set the yy values at t t = 0 and t t = 2 to zero. This means
Putting these into Aeq Aeq and beqbeq, we get the following.
Aeq = [0 0 0 1 ; % t = 0
2^3 2^2 2 1]; % t = 2
beq = [0 ; % y = 0 (when t = 0)
0]; % y = 0 (when t = 2)
x_lsqlin1 = lsqlin(C,d,A,b,Aeq,beq)
Warning: The trust-region-reflective algorithm can handle bound constraints
only;
using active-set algorithm instead.
Optimization terminated.
x_lsqlin1 =
2.5524
-7.6807
5.1518
0
plot(t,y,'o',t,C*x_lsqlin1)
legend('data','lsqlin')
grid on
y ≈ x 1t 7 + x 2t 6 + x 3t 5 + x 4t 4 + x 5t 3 + x 6t 2 + x 7t + x 8
y≈x1t7+x2t6+x3t5+x4t4+x5t3+x6t2+x7t+x8
dy
≈ 7x 1 t 6 + 6x 2 t 5 + 5x 3 t 4 + 4x 4 t 3 + 3x 5 t 2 + 2x 6 t + x 7
dt
dydt≈7x1t6+6x2t5+5x3t4+4x4t3+3x5t2+2x6t+x7
For example, the constraint "the derivative at t t = 0.5 is zero" can be represented as
Aeq = [0 0 0 0 0 0 0 1 ; % t = 0
2^7 2^6 2^5 2^4 2^3 2^2 2 1 ; % t = 2
0.5^7 0.5^6 0.5^5 0.5^4 0.5^3 0.5^2 0.5 1 ; % t = 0.5
1.5^7 1.5^6 1.5^5 1.5^4 1.5^3 1.5^2 1.5 1 ; % t = 1.5
7*0.5^6 6*0.5^5 5*0.5^4 4*0.5^3 3*0.5^2 2*0.5 1 0 ; % t = 0.5 (for dy/dt)
7*1.5^6 6*1.5^5 5*1.5^4 4*1.5^3 3*1.5^2 2*1.5 1 0]; % t = 1.5 (for dy/dt)
beq = [ 0 ; % y = 0 (when t = 0)
0 ; % y = 0 (when t = 2)
1 ; % y = 1 (when t = 0.5)
-1 ; % y = -1 (when t = 1.5)
0 ; % dy/dt = 0 (when t = 0.5)
0]; % dy/dt = 0 (when t = 1.5)
x_polyfix =
Columns 1 through 7
-0.2925 2.1030 -7.8142 17.6810 -19.6794 5.7234 2.2753
Column 8
0
If we compare this result with that from lsqlin, we see that it's essentially identical.
norm(x_lsqlin2-x_polyfix')
ans =
2.1194e-10
Optimization Toolbox
Are's polyfit is great for performing polynomial fits with constraints around passing points. If you need other sophisticated constraints, you would want to check out Optimization Toolbox.
Comments
Give this a try and let us know what you think here or leave a comment for Are.
Issue Warnings and Errors
Issue Warnings
You can issue a warning to flag unexpected conditions detected when running a program. The warning function prints a warning message to the command line.
Warnings differ from errors in two significant ways:
Use the warning function in your code to generate a warning message during execution. Specify the message as the input argument to the warning function:
For example, you can insert a warning in your code to verify the software version:
function warningExample1
if ~strncmp(version, '7', 1)
warning('You are using a version other than v7')
end
Throw Errors
You can throw an error to flag fatal problems within the program. Use the error function to print error messages to the command line. After displaying the message,
MATLAB stops the execution of the current program.
For example, suppose you construct a function that returns the number of combinations of k elements from n elements. Such a function is nonsensical if k > n; you
cannot choose 8 elements if you start with just 4. You must incorporate this fact into the function to let anyone using combinations know of the problem:
If the combinations function receives invalid input, MATLAB stops execution immediately after throwing the error message:
combinations(4,8)
For example, this warning uses %s and %d to mark where to insert the values of variables arrayname and arraydims:
If you execute this command with arrayname = 'A' and arraydims = 3, MATLAB responds:
Warning: Array A has 3 dimensions.
Adding run-time parameters to your warnings and errors can clarify the problems within a program. Consider the function combinations from Throw Errors. You can
throw a much more informative error using run-time parameters:
If this function receives invalid arguments, MATLAB throws an error message and stops the program:
combinations(6,9)
Enable or disable warnings with identifiers. Use an identifying text argument with the warning function to attach a unique tag to a message:
warning(identifier_text,message_text)
For example, you can add an identifier tag to the previous MATLAB warning about which version of software is running:
minver = '7';
if ~strncmp(version,minver,1)
warning('MYTEST:VERCHK','Running a version other than v%s',minver)
end
Adding an identifier to an error message allows for negative testing. However, adding and recovering more information from errors often requires working with
MException objects.
See Also
lastwarn | MException | warndlg | warning
Related Topics
• Suppress Warnings
• Restore Warnings
• Exception Handling in a MATLAB Application
Suppress Warnings
Your program might issue warnings that do not always adversely affect execution. To avoid confusion, you can hide warning messages during execution by changing
their states from 'on' to 'off'.
To suppress specific warning messages, you must first find the warning identifier. Each warning message has a unique identifier. To find the identifier associated with
a MATLAB® warning, reproduce the warning. For example, this code reproduces a warning thrown if MATLAB attempts to remove a nonexistent folder:
rmpath('folderthatisnotonpath')
Note
If this statement does not produce a warning message, use the following code to temporarily enable the display of all warnings, and then restore the original
warning state:
w = warning ('on','all');
rmpath('folderthatisnotonpath')
warning(w)
To obtain information about the most recently issued warning, use the warning or lastwarn functions. This code uses the query state to return a data structure
containing the identifier and the current state of the last warning:
w = warning('query','last')
w =
identifier: 'MATLAB:rmpath:DirNotFound'
state: 'on'
You can save the identifier field in the variable, id:
id = w.identifier;
Note
warning('query','last') returns the last displayed warning. MATLAB only displays warning messages that have state: 'on' and a warning identifier.
Using the lastwarn function, you can retrieve the last warning message, regardless of its display state:
lastwarn
ans =
Continuing the example from the previous section, turn the warning 'MATLAB:rmpath:DirNotFound' off, and repeat the operation.
warning('off',id)
rmpath('folderthatisnotonpath')
warning('on',id)
rmpath('folderthatisnotonpath')
Tip
Turn off the most recently invoked warning with warning('off','last').
Use the identifier 'all' to represent the group of all warnings. View the state of all warnings with either syntax:
warning('query','all')
warning
To disable all warnings and verify the state, use this syntax:
warning('off','all')
warning
Related Topics
• Restore Warnings
• Change How Warnings Display
Restore Warnings
MATLAB® allows you to save the on-off warning states, modify warning states, and restore the original warning states. This is useful if you need to temporarily turn
off some warnings and later reinstate the original settings.
The following statement saves the current state of all warnings in the structure array called orig_state:
orig_state = warning;
To restore the original state after any warning modifications, use this syntax:
warning(orig_state);
You also can save the current state and toggle warnings in a single command. For example, the statement, orig_state = warning('off','all'); is equivalent
to the commands:
orig_state = warning;
warning('off','all')
warning('query','Control:parameterNotSymmetric')
orig_state = warning('off','Control:parameterNotSymmetric')
orig_state =
identifier: 'Control:parameterNotSymmetric'
state: 'on'
orig_state contains the warning state before MATLAB turns Control:parameterNotSymmetric off.
3. Query all warning states:
warning
The default warning state is 'on'. Warnings not set to the default are
State Warning Identifier
off Control:parameterNotSymmetric
MATLAB indicates that Control:parameterNotSymmetric is 'off'.
4. Restore the original state:
warning(orig_state)
warning('query','Control:parameterNotSymmetric')
w(1) = warning('off','MATLAB:rmpath:DirNotFound');
w(2) = warning('off','MATLAB:singularMatrix');
w(3) = warning('off','Control:parameterNotSymmetric');
warning
The default warning state is 'on'. Warnings not set to the default are
off Control:parameterNotSymmetric
off MATLAB:rmpath:DirNotFound
off MATLAB:singularMatrix
2. Restore the three warnings to their the original state, and query all warnings:
warning(w)
warning
Note
When temporarily disabling multiple warnings, using methods related to onCleanup might be advantageous.
Alternatively, you can save and restore all warnings.
orig_state = warning('on','all');
warning(orig_state)
See Also
onCleanup | warning
Related Topics
• Suppress Warnings
• Clean Up When Functions Complete
Change How Warnings Display
You can control how warnings appear in MATLAB® by modifying two warning modes, verbose and backtrace.
Note
The verbose and backtrace modes present some limitations:
• prev_state does not contain information about the backtrace or verbose modes in the statement, prev_state = warning('query','all').
• A mode change affects all enabled warnings.
For example, you can turn on all warnings, disable backtrace, and enable verbose warnings:
warning on all
warning off backtrace
warning on verbose
rmpath('folderthatisnotonpath')
warning on backtrace
warning off verbose
Running a command that produces an error displays a hyperlink with a line number:
Warning: "folderthatisnotonpath" not found in path.
> In rmpath at 58
try
try block...
catch
catch block...
end
If an error occurs within the try block, MATLAB® skips any remaining commands in the try block and executes the commands in the catch block. If no error
occurs within try block, MATLAB skips the entire catch block.
For example, a try/catch statement can prevent the need to throw errors. Consider the combinations function that returns the number of combinations of k
elements from n elements:
MATLAB throws an error whenever k > n. You cannot construct a set with more elements, k, than elements you possess, n. Using a try/catch statement, you can
avoid the error and execute this function regardless of the order of inputs:
C1 = robust_combine(8,4)
C2 = robust_combine(4,8)
C1 =
70
C2 =
70
Optionally, you can capture more information about errors if a variable follows your catch statement:
catch MExc
MExc is an MException class object that contains more information about the thrown error. To learn more about accessing information from MException objects, see
Exception Handling in a MATLAB Application.
See Also
MException | onCleanup | try, catch
Clean Up When Functions Complete
Overview
A good programming practice is to make sure that you leave your program environment in a clean state that does not interfere with any other program code. For
example, you might want to
MATLAB provides the onCleanup function for this purpose. This function, when used within any program, establishes a cleanup routine for that function. When the
function terminates, whether normally or in the event of an error or Ctrl+C, MATLAB automatically executes the cleanup routine.
The following statement establishes a cleanup routine cleanupFun for the currently running program:
cleanupObj = onCleanup(@cleanupFun);
When your program exits, MATLAB finds any instances of the onCleanup class and executes the associated function handles. The process of generating and
activating function cleanup involves the following steps:
1. Write one or more cleanup routines for the program under development. Assume for now that it takes only one such routine.
2. Create a function handle for the cleanup routine.
3. At some point, generally early in your program code, insert a call to the onCleanup function, passing the function handle.
4. When the program is run, the call to onCleanup constructs a cleanup object that contains a handle to the cleanup routine created in step 1.
5. When the program ends, MATLAB implicitly clears all objects that are local variables. This invokes the destructor method for each local object in your program,
including the cleanup object constructed in step 4.
6. The destructor method for this object invokes this routine if it exists. This perform the tasks needed to restore your programming environment.
You can declare any number of cleanup routines for a program file. Each call to onCleanup establishes a separate cleanup routine for each cleanup object returned.
If, for some reason, the object returned by onCleanup persists beyond the life of your program, then the cleanup routine associated with that object is not run when
your function terminates. Instead, it will run whenever the object is destroyed (e.g., by clearing the object variable).
Your cleanup routine should never rely on variables that are defined outside of that routine. For example, the nested function shown here on the left executes with no
error, whereas the very similar one on the right fails with the error, Undefined function or variable 'k'. This results from the cleanup routine's reliance on
variable k which is defined outside of the nested cleanup routine:
function testCleanup function testCleanup
k = 3; k = 3;
myFun obj = onCleanup(@myFun);
function myFun function myFun
fprintf('k is %d\n', k) fprintf('k is %d\n', k)
end end
end end
function openFileSafely(fileName)
fid = fopen(fileName, 'r');
c = onCleanup(@()fclose(fid));
s = fread(fid);
.
.
.
end
function changeFolderSafely(fileName)
currentFolder = pwd;
c = onCleanup(@()cd(currentFolder));
functionThatMayError;
end % c executes cd(currentFolder) here.
Run the function as shown here. You can verify that the path has been restored by comparing the length of the path before and after running the function:
origLen = length(path);
showImageOutsidePath('greens.jpg')
Opening the figure greens.jpg
Closing the figure
Restoring the path
currLen = length(path);
currLen == origLen
ans =
1
@()restore_env(fig1, imgpath)
The details of that handle are then contained within the object returned by the onCleanup function:
You can access these details using the task property of the cleanup object as shown here. (Modify the showImageOutsidePath function by adding the following
code just before the comment line that says, “% This is the cleanup routine.”)
Run the modified function to see the output of the functions command and the contents of one of the workspace cells:
showImageOutsidePath('greens.jpg')
function cleanupByCatch
try
pause(10);
catch
disp(' Collecting information about the error')
disp(' Executing cleanup tasks')
end
Unlike the try/catch statement, the onCleanup function responds not only to a normal exit from your program and any error that might be thrown, but also to
Ctrl+C. This next example replaces the try/catch with onCleanup:
function cleanupByFunc
obj = onCleanup(@()...
disp(' Executing cleanup tasks'));
pause(10);
onCleanup in Scripts
onCleanup does not work in scripts as it does in functions. In functions, the cleanup object is stored in the function workspace. When the function exits, this
workspace is cleared thus executing the associated cleanup routine. In scripts, the cleanup object is stored in the base workspace (that is, the workspace used in
interactive work done at the command prompt). Because exiting a script has no effect on the base workspace, the cleanup object is not cleared and the routine
associated with that object does not execute. To use this type of cleanup mechanism in a script, you would have to explicitly clear the object from the command line
or another script when the first script terminates.
Create Function Handle
You can create function handles to named and anonymous functions. You can store multiple function handles in an array, and save and load them, as you would any
other variable.
• Passing a function to another function (often called function functions). For example, passing a function to integration and optimization functions, such as
integral and fzero.
• Specifying callback functions (for example, a callback that responds to a UI event or interacts with data acquisition hardware).
• Constructing handles to functions defined inline instead of stored in a program file (anonymous functions).
• Calling local functions from outside the main function.
f = @myfunction;
You call a function using a handle the same way you call the function directly. For example, suppose that you have a function named computeSquare, defined as:
function y = computeSquare(x)
y = x.^2;
end
Create a handle and call the function to compute the square of four.
f = @computeSquare;
a = 4;
b = f(a)
b =
16
If the function does not require any inputs, then you can call the function with empty parentheses, such as
h = @ones;
a = h()
a =
1
Without the parentheses, the assignment creates another function handle.
a = h
a =
@ones
Function handles are variables that you can pass to other functions. For example, calculate the integral of x on the range [0,1].
2
q = integral(f,0,1);
Function handles store their absolute path, so when you have a valid handle, you can invoke the function from any location. You do not have to specify the path to
the function when creating the handle, only the function name.
• Name length — Each part of the function name (including package and class names) must be less than the number specified by namelengthmax. Otherwise,
MATLAB truncates the latter part of the name.
• Scope — The function must be in scope at the time you create the handle. Therefore, the function must be on the MATLAB path or in the current folder. Or, for
handles to local or nested functions, the function must be in the current file.
• Precedence — When there are multiple functions with the same name, MATLAB uses the same precedence rules to define function handles as it does to call
functions. For more information, see Function Precedence Order.
• Overloading — If the function you specify overloads a function in a class that is not a fundamental MATLAB class, the function is not associated with the function
handle at the time it is constructed. Instead, MATLAB considers the input arguments and determines which implementation to call at the time of evaluation.
Anonymous Functions
You can create handles to anonymous functions. An anonymous function is a one-line expression-based MATLAB function that does not require a program file.
Construct a handle to an anonymous function by defining the body of the function, anonymous_function, and a comma-separated list of input arguments to the
anonymous function, arglist. The syntax is:
h = @(arglist)anonymous_function
For example, create a handle, sqr, to an anonymous function that computes the square of a number, and call the anonymous function using its handle.
x =
9
For more information, see Anonymous Functions.
ans =
-1
Or use a structure array:
ans =
1
Saving and Loading Function Handles
You can save and load function handles in MATLAB, as you would any other variable. In other words, use the save and load functions. If you save a function handle,
MATLAB does not save the path information. If you load a function handle, and the function file no longer exists on the path, the handle is invalid. An invalid handle
occurs if the file location or file name has changed since you created the handle. If a handle is invalid, MATLAB might display a warning when you load the file. When
you invoke an invalid handle, MATLAB issues an error.
See Also
func2str | function_handle | functions | isa | str2func
Related Examples
• Pass Function to Another Function
More About
• Anonymous Functions
MATLAB Answers
Follow
3,849 views (last 30 days)
Summary:
Dynamically accessing variable names can negatively impact the readability of your code and can cause it to run slower by preventing MATLAB from optimizing it as well as it could if you used
alternate techniques. The most common alternative is to use simple and efficient indexing.
Explanation:
Sometimes beginners (and some self-taught professors) think it would be a good idea to dynamically create or access variable names, the variables are often named something like these:
• matrix1, matrix2, matrix3, matrix4, ...
Good reasons why dynamic variable names should be avoided (click the links to jump to the "answers" below):
• Slow
• Buggy
• Security Risk
Note that avoiding eval (and assignin, etc.) is not some esoteric MATLAB restriction, it also applies to many other programming languages as well:
• Other Languages: do not use eval!
MATLAB Documentation:
If you are not interested in reading the answers below then at least read MATLAB's own documentation on this topic Alternatives to the eval Function, which states "A frequent use of the eval
function is to create sets of variables such as A1, A2, ..., An, but this approach does not use the array processing power of MATLAB and is not recommended. The preferred method is to store
related data in a single array." Data in a single array can be accessed very efficiently using indexing.
Note that all of these problems and disadvantages also apply to functions load (without an output variable), assignin, evalin, and evalc, and the MATLAB documentation explicitly recommends to
"Avoid functions such as eval, evalc, evalin, and feval(fname)".
The official MATLAB blogs explain why eval should be avoided, the better alternatives to eval, and clearly recommend against magically creating variables. Using eval comes out at position
number one on this list of Top 10 MATLAB Code Practices That Make Me Cry. Experienced MATLAB users recommend avoiding using eval for trivial code, and have written extensively on this
topic.
7 Comments
"...being able to input the name of an existing file..."
... is really easy and does not require magically accessing variable names.
"This is pretty standard with programming languages."
Indeed many languages support string evaluation... and yet interestingly experts and experienced users of most of those languages consider this to be an extremely inefficient and insecure
practice that should be avoided. Perhaps you missed reading this thread, which gives links to some of those discussions:
https://www.mathworks.com/matlabcentral/answers/304528-tutorial-why-variables-should-not-be-named-dynamically-eval#answer_236129
"There may be reasons why MATLAB does not support this,.."
MATLAB certainly does support this. Why do you think it does not? In fact the main function that is used for this is currently mentioned 75 times on this thread (and also in the title itself),
something that readers of this thread are unlikely miss.
"...but it is not a strange or clearly crazy thing to want to do"
I totally agree: I don't think that it is a strange or crazy thing to want to do. But it is important to note that wanting to do something is not at all synonymous with something being a good way to
write code: there are certainly much simpler and more efficient methods of writing better code, which waste less time (coding time, debugging time, run time). The fact that magically accessing
variables forces beginners to write slow, complex, buggy code, and is easily avoided by better, simpler code and/or data design, is not changed by how much beginners might want to do it.
We often get questions from beginners who want to calculate all permutations of a set of numbers, or want use some other highly inefficient or numerically unstable algorithm or want to use
numerically unstable operations: just because they want to do these things does not mean that their approach is going to be efficient, or produce any sensible output, or even be tractable at all.
In these cases we would show them (if at all possible) better ways of solving their problem, just like this thread does. The reality that some code is slower, buggier on average, harder to debug,
and much less efficient is not changed by you want.
Accepted Answer
• Link
Some quotes from Steven Lord, responses to inappropriate use of eval and friends:
"DO NOT USE EVAL"
"This is why you SHOULD NOT "poof" variables into the workspace at runtime, whether via EVALIN, ASSIGNIN, EVAL, or LOAD."
"Do NOT use eval, evalc, or any other function in the eval family"
2 Comments
@Cris Lengo: you can still access that newsreader thread here:
https://groups.google.com/forum/#!searchin/comp.soft-sys.matlab/subject$3A%22behavior$20of$20assignin%22/comp.soft-sys.matlab/Y-BoQbPqqXQ/Cl7zpUyT5vIJ
The relevant text is:
MATLAB is not lying to you.
When you run your function, MATLAB needs to determine what each identifier
you use is as part of the process of parsing the function. At that time,
there's no indication in your code that debug should be a variable; however,
there is a function named debug. Therefore, MATLAB decides that the
instances of debug in the code should be calls to that function. When the
code is actually executed, a variable named debug is created, and WHICH
reflects that fact -- but at that point, it's too late for MATLAB to "change
its mind" and it tries to call the debug function on the last line. DEBUG
is a script file, though, and so you correctly receive an error.
This is why you SHOULD NOT "poof" variables into the workspace at runtime,
whether via EVALIN, ASSIGNIN, EVAL, or LOAD.
--
Steve Lord
sl...@mathworks.com
Sign in to comment.
• Link
Slow
The MATLAB documentation Alternatives to the eval Function explains that code that uses eval is slower because "MATLAB® compiles code the first time you run it to enhance performance for
future runs. However, because code in an eval statement can change at run time, it is not compiled".
MATLAB uses JIT acceleration tools that analyze code as it is being executed, and to optimize the code to run more efficiently. When eval is used the JIT optimizations are not effective, because
every string has to get compiled and run again on every single iteration! This makes loops with eval very slow. This is also why not just creating variables with dynamic variable names is slow,
but also accessing them.
https://www.mathworks.com/products/matlab/matlab-execution-engine.html
https://blogs.mathworks.com/loren/2016/02/12/run-code-faster-with-the-new-matlab-execution-engine/
https://blogs.mathworks.com/loren/2007/08/29/for-versus-while/ (in the comments)
https://www.mathworks.com/matlabcentral/answers/320839-how-bad-is-the-performance-of-run-time-introspection
https://www.mathworks.com/matlabcentral/answers/33284-processor-usage#answer_53297
https://www.mathworks.com/matlabcentral/answers/353349-how-to-make-a-2-files-mat-become-1#comment_478662
https://www.mathworks.com/matlabcentral/answers/105936-how-to-make-dynamic-variable-names-a1-a2-an-with-for-loop-using-eval-num2str#comment_598847
Even the eval hidden inside of str2num can slow down code:
https://www.mathworks.com/matlabcentral/answers/357420-how-to-convert-a-numeric-string-into-a-numeric-range
0 Comments
Sign in to comment.
• Link
MATLAB Answers
Security Risk
eval will evaluate any string at all, no matter what commands it contains. Does that sound secure to you? This string command might be malicious or simply a mistake, but it can do anything at
all to your computer. Would you run code which could do anything at all to your computer, without knowing what it was about to do?
For some beginners the surprising answer is "yes please!".
https://www.mathworks.com/matlabcentral/answers/42752-assigning-input-string-as-variable-name#answer_52582
Beginners will happily run code that could do anything at all with their computer. For example, try running this (taken from Jos' answer here):
eval(char('fkur*)Ykvj"GXCN"{qw"pgxgt"mpqy"yjcv"jcrrgpu0"Kv"eqwnf"jcxg"hqtocvvgf"{qwt"jctfftkxg"000)+'-2))
Did you really run it on your computer even though you had no idea what it would do? Every time beginners write code that gets a user input and evaluates it they give that user the ability to run
anything at all. Does that sound secure to you?
3 Comments
• Link
Difficult to Work With
Many beginners come here with questions that are basically "I have lots of numbered variables but I cannot figure out how to do this simple operation...", or "my code is very slow/complex/...":
https://www.mathworks.com/matlabcentral/answers/322696-automatically-creating-an-array-of-variables-and-assigning-to-a-function-with-changing-number-of-out
https://www.mathworks.com/matlabcentral/answers/249044-code-fails-to-run-in-function-works-in-command-window-works-in-debug-evaluate-selection
https://www.mathworks.com/matlabcentral/answers/49756-use-eval-statement-to-create-matrices-with-variables
https://www.mathworks.com/matlabcentral/answers/341708-variable-names-in-loop
https://www.mathworks.com/matlabcentral/answers/346695-how-to-save-variables-to-an-array-using-a-for-loop
https://www.mathworks.com/matlabcentral/answers/356673-operation-on-variables-whose-name-contain-a-certain-string
https://www.mathworks.com/matlabcentral/answers/460207-concatenate-structures-select-structures-only-if-not-empty#answer_373564
Even advocates of eval get confused by it, fail to make it work properly, and can't even figure out why, as these two examples clearly show:
https://www.mathworks.com/matlabcentral/answers/158412-how-to-open-txt-files-with-variable-names#answer_154956
https://www.mathworks.com/matlabcentral/answers/272454-how-do-i-iterate-through-multiple-structures#answer_213034
Why can't they figure out why it does not work?:
• Totally obfuscated code. Indirect code evaluation.
0 Comments
Sign in to comment.
MATLAB Answers
• Link
Buggy
Using eval makes it really hard to track down bugs, because it obfuscates the code and disables lots of code helper tools. Why would beginners even want to use a tool that makes it harder for
them to fix their code?
Here are some examples to illustrate how what should have been simple operations become very difficult to debug because of the choice to use eval:
https://www.mathworks.com/matlabcentral/answers/275439-help-with-code-problem
https://www.mathworks.com/matlabcentral/answers/158412-how-to-open-txt-files-with-variable-names#answer_154956
https://www.mathworks.com/matlabcentral/answers/272454-how-do-i-iterate-through-multiple-structures#answer_213034
https://www.mathworks.com/matlabcentral/answers/349843-getting-an-error-this-statement-is-incomplete
Code that generates variable names dynamically based on imported data or user inputs is also susceptible to the names reaching the name length limit:
https://www.mathworks.com/matlabcentral/answers/498489-clarification-about-using-only-the-first-namelengthmax-characters-of-the-name
This quote sums up debugging eval based code: "I've never even attempted to use it myself, but it seems it would create unreadable, undebuggable code. If you can't read it and can't fix it what
good is it?" Note that eval's equally evil siblings evalc, evalin and assignin also make code slow and buggy:
https://www.mathworks.com/matlabcentral/answers/31963-functions-vs-script#answer_40489
https://www.mathworks.com/matlabcentral/answers/372206-use-of-evalc-with-num2str#answer_295604
0 Comments
Sign in to comment.
• Link
Obfuscated Code Intent
What does this code do?:
x1 = [119,101,98,40,39,104,116,116,112,58,47,47,119,119,119];
x2 = [46,121,111,117,116,117,98,101,46,99,111,109,47,119,97];
x3 = [116,99,104,63,118,61,100,81,119,52,119,57,87,103,88];
x4 = [99,81,39,44,39,45,98,114,111,119,115,101,114,39,41];
eval(char([x1,x2,x3,x4]))
Unfortunately eval makes it easy to write code which is hard to understand: it is not clear what it does, or why. If you ran that code without knowing what it does, you should know that it could
have deleted all of your data, or sent emails to all of your contacts, or downloaded anything at all from the internet, or worse...
Because eval easily hides the intent of the code many beginners end up writing code that is very hard to follow and understand. This makes the code buggy, and also harder to debug! See
these examples:
https://www.mathworks.com/matlabcentral/answers/380551-what-is-the-function-of-sub2ind
Properly written code is clear and understandable. Clear and understandable code is easier to write, to bug-fix, and to maintain. Code is read more times than it is written, so never
underestimate the importance of writing code that is clear and understandable: write code comments, write a help section, use consistent formatting and indentation, etc.
3 Comments
• Link
Code Helper Tools do not Work
The MATLAB editor contains many tools that advanced users continuously make use of, and beginners should particularly appreciate when learning to use MATLAB (tip: learn to use them!).
However none of these tools work with code that uses eval.
• check the syntax as you type.
• shows warnings and errors on the RHS of the editor. Very very useful!
• code analyzer prints reports on the code quality: errors, warnings, suggestions on how it could be improved.
• Text search or find-and-replace. Note that with magical variable names it is not even possible to do a simple search for a variable name, because if that variable name is generated
dynamically then the name is not defined until the code is executed: how would you imagine searching for where a particular variable is used, if you cannot search for that variable? Ouch!
• text search in multiple files.
• automatically rename all instances of a variable name: very handy! MATLAB Answers
• and much more...
Note that these do not work when using eval, evalc, etc. to magically create or access variable names. Would you want to disable the tools that help you to write functioning code? Here are
examples of how eval hides code errors and makes it hard to debug code:
https://www.mathworks.com/matlabcentral/answers/158412-how-to-open-txt-files-with-variable-names#comment_242698
https://www.mathworks.com/matlabcentral/answers/322696-automatically-creating-an-array-of-variables-and-assigning-to-a-function-with-changing-number-of-out
https://www.mathworks.com/matlabcentral/answers/374023-error-using-eval-function
https://www.mathworks.com/matlabcentral/answers/51946-systematic-do-not-use-global-don-t-use-eval#comment_107637
1 Comment
• Link
Alternative: Indexing into Cell Array or ND-Array
MATLAB Answers
Oftentimes when a user wants to use eval they are trying to create numbered variables, which are effectively an index joined onto a name. So then why not simply turn that pseudo-index into a
real index: MATLAB is very fast and efficient when working with indices, and using indices will make code much much simpler than anything involving dynamic variable names:
https://www.mathworks.com/company/newsletters/articles/matrix-indexing-in-matlab.html
https://www.mathworks.com/help/matlab/math/matrix-indexing.html
Using ND-arrays is a particularly efficient way of handling data: many operations can be performed on complete arrays (known as code vectorization), and ND-arrays are easy to get data in and
out of, and reduces the chance of bugs:
https://www.mathworks.com/matlabcentral/answers/409279-on-multiple-logical-test-failing-in-if-statement#answer_327952
Or simply put the data into the cells of a cell array:
https://www.mathworks.com/help/matlab/matlab_prog/access-data-in-a-cell-array.html
https://www.mathworks.com/help/matlab/matlab_prog/multilevel-indexing-to-access-parts-of-cells.html
And some real-world examples of where indexing is much simpler than eval:
https://www.mathworks.com/matlabcentral/answers/11981-help-with-find-possibly-inside-of-eval
https://www.mathworks.com/matlabcentral/answers/160310-dynamic-variables-in-loops
0 Comments
Sign in to comment.
• Link
Alternative: Dynamic Field-Names in a Structure
dynamic fieldnames are easy to use, and do not require magically creating variables in the workspace.
https://www.mathworks.com/help/matlab/matlab_prog/access-multiple-elements-of-a-nonscalar-struct-array.html
https://blogs.mathworks.com/loren/2005/12/13/use-dynamic-field-references/
0 Comments
MATLAB Answers
Sign in to comment.
• Link
Alternative: load into a Structure, not into the Workspace
In almost all cases where data is imported programmatically (i.e. not just playing around in the command window) it is advisable to load data into an output argument (which is a structure if the
file is a .mat file):
S = load(...);
The fields of the structure can be accessed directly, e.g:
S.X
S.Y
or by using dynamic fieldnames. Note that this is the inverse of saving the fields of a scalar structure.
It is important to note that (contrary to what many beginners seem to think) it is actually much easier within a loop to save and load data when the variable names in the .mat files do not change,
as having to process different variable names in each file actually makes saving/loading the files much harder.
Summary: when using a loop, keep all variable names the same!
Here are real-world examples of loading into variables:
https://www.mathworks.com/matlabcentral/answers/429680-how-to-load-a-mat-file-and-make-all-the-variables-from-that-mat-file-to-be-global-variables
https://www.mathworks.com/matlabcentral/answers/302359-access-variables-in-several-mat-files
https://www.mathworks.com/matlabcentral/answers/335253-mat-files-not-loading-correctly#answer_262994
https://www.mathworks.com/matlabcentral/answers/297146-loading-mat-file-into-a-variable
https://www.mathworks.com/matlabcentral/answers/28676-why-use-x-load-myfile-mat#answer_37821
https://www.mathworks.com/matlabcentral/answers/134091-variable-changes-value-after-using-load
https://www.mathworks.com/matlabcentral/answers/29579-decent-way-of-loading-and-saving-variables#answer_37932
https://www.mathworks.com/matlabcentral/answers/485484-using-load-in-a-test-methods-makes-the-test-pass#answer_397441
And finally Steven Lord's comment on load-ing straight into the workspace:
https://www.mathworks.com/matlabcentral/answers/349330-odd-behavior-with-a-simulink-reserved-name-in-a-function
EDIT: No longer active: https://www.mathworks.com/matlabcentral/newsreader/view_thread/244639#628669
MATLAB Answers
0 Comments
Sign in to comment.
• Link
Alternative: Non-Scalar Structure (with Indexing)
Using a non-scalar structure is much simpler than trying to access dynamic variable names. Here are some examples:
https://www.mathworks.com/matlabcentral/answers/79281-create-a-structure-name-based-on-the-string-of-a-variable-create-fieldnames-in-this-structure
https://www.mathworks.com/matlabcentral/answers/128912-concatenating-string-variable-names-and-passing-on-values-of-a-matrix-in-a-for-loop
0 Comments
Sign in to comment.
MATLAB Answers
• Link
Other Languages: do not use eval!
In case you think that avoiding dynamic variable names is just some "weird MATLAB thing", here is the same discussion for some other programming languages, all advising "DO NOT create
dynamic variable names":
https://blogs.msdn.microsoft.com/ericlippert/2003/11/01/eval-is-evil-part-one/
https://blogs.msdn.microsoft.com/ericlippert/2003/11/04/eval-is-evil-part-two/
http://nedbatchelder.com/blog/201112/keep_data_out_of_your_variable_names.html
http://www.techrepublic.com/blog/it-security/never-use-dynamic-variable-names/
http://stackoverflow.com/questions/11118486/python-list-as-variable-name
http://www.reddit.com/r/learnpython/comments/2a9o4s/why_is_it_a_bad_idea_to_create_dynamic_variables/
http://stackoverflow.com/questions/1479490/making-a-string-the-name-of-an-instance-object/1480247#1480247
http://stackoverflow.com/questions/25076883/creating-dynamically-named-variables-in-a-function-in-python-3-understanding-e
http://perl.plover.com/varvarname.html
https://24ways.org/2005/dont-be-eval
https://softwareengineering.stackexchange.com/questions/311507/why-are-eval-like-features-considered-evil-in-contrast-to-other-possibly-harmfu/311510
https://stackoverflow.com/questions/2571401/why-exactly-is-eval-evil
Some languages might use, require, or otherwise encourage dynamic variable names. If that is how they work efficiently, then so be it. But what is efficient in one language means nothing about
the same method in other languages... if you wish to use MATLAB efficiently, make your code easier to work with, and write in a way that other MATLAB users will appreciate, then you should
learn how to use MATLAB features and tools:
https://www.mathworks.com/matlabcentral/answers/320774-looping-over-a-set-of-names-and-creating-a-set-of-variables
0 Comments
Sign in to comment.
MATLAB Answers
• Link
Confuses Data with Code
The inclusion of data and meta-data within variable names (e.g. naming a variable with the user's input, the name of a test subject, or (very commonly) adding an index onto a variable name) is
a subtle (but closely related) problem, and it should definitely be avoided.
The problem with including meta-data in variable names is that this breaks the idea of code being generalized, because it mixes the code and data together. In fact data and code should be kept
separate to keep the code generalized. Code that is written to be as general as possible is simpler, more robust, more adaptable, easier to write, and easier to fix, which in turn makes code
much less buggy. Mixing meta-data into variable names really just makes everything much more complicated, and this in turn makes code slow and buggy.
Read these discussions for an explanation of why it is a poor practice to put data and meta-data in variable names:
https://www.mathworks.com/matlabcentral/answers/56124-eval-is-evil-using-variables-created-dynamically-info-retrieval
https://www.mathworks.com/matlabcentral/answers/225435-save-variable-as-string-from-user-input
https://www.mathworks.com/matlabcentral/answers/12350-variable-name-length-exceeds-63-characters
In many cases that meta-data is just a de-facto index, i.e. a value that proscribes the order of the data. But in that case the de-facto index should be turned into a much more efficient real
numeric index:
https://www.mathworks.com/matlabcentral/answers/325569-finding-the-means-of-a-large-number-of-individual-matrices#answer_255199
https://www.mathworks.com/matlabcentral/answers/8337-creating-a-matrix-with-many-numbered-variables
https://www.mathworks.com/matlabcentral/answers/240702-is-there-a-way-to-make-matlab-create-variables-of-any-number-on-its-own#answer_191569
0 Comments
Sign in to comment.
Stephen Cobeldick on 26 Sep 2016
Edited: Stephen Cobeldick on 31 Jan 2017 MATLAB Answers •
Vote
5
• Link
Alternative: Use more Efficient Ways to Pass Variables between Workspaces (applies to evalin, assignin, etc)
Use nested functions, or pass arguments, or use any of the other efficient ways to pass data between workspaces:
https://www.mathworks.com/help/matlab/matlab_prog/share-data-between-workspaces.html
https://www.mathworks.com/help/matlab/creating_guis/share-data-among-callbacks.html
0 Comments
Sign in to comment.
• Link
Magically Making Variables Appear in a Workspace is Risky
For a start those variables will be overwritten without warning, leading to hard-to-find bugs. But there is also a more serious yet subtle problem, which is caused by the MATLAB parser finding
alternative functions/objects/... and calling those instead of using the magically-created variable: basically if the variable does not exist then the parser does it best to find something that matches
where the name is called/used later... and it might just find something! For example:
https://www.mathworks.com/matlabcentral/answers/349330-odd-behavior-with-a-simulink-reserved-name-in-a-function
https://www.mathworks.com/matlabcentral/answers/28676-why-use-x-load-myfile-mat
https://www.mathworks.com/matlabcentral/answers/120518-trouble-with-accessing-variable-in-parfor-loop
https://www.mathworks.com/matlabcentral/answers/235119-can-you-explain-this-weird-behavior
https://www.mathworks.com/matlabcentral/newsreader/view_thread/244639#628669
MATLAB Answers
https://www.mathworks.com/matlabcentral/answers/410758-function-call-doesn-t-work-in-script-works-in-command-window#answer_329197
https://www.mathworks.com/matlabcentral/answers/51946-systematic-do-not-use-global-don-t-use-eval#comment_107637
The solution is simple: do not magically "poof" variables into existence: Always load into a structure, and never create variable names dynamically.
6 Comments
• Link
PS: eval is Not Faulty:
Some beginners apparently think that eval (and friends) must be faulty and should be removed from MATLAB altogether. They ask "if eval is so broken, why has it not been removed?"... but it is
important to understand that the problem is caused by magically accessing variable names regardless of what tool or operation is used, and that eval (or assignin, or evalin, or load without an
output argument, etc.) is simply being used inappropriately because there are much better methods available ( better in the sense faster, neater, simpler, less buggy, etc). Read these
discussions for good examples of this confusion:
https://www.mathworks.com/matlabcentral/answers/364851-assignin-and-eval-functions
https://www.mathworks.com/matlabcentral/answers/352237-is-there-the-more-elegant-way-to-do-this
It is important to note that any feature of a language can be used inefficiently or in an inappropriate way, not just eval, and this is not something that can be controlled by the language itself. For
example, it is common that someone might solve something with slow loops and without preallocating the output arrays: this does not mean that for loops are "faulty" and need to be removed
from MATLAB!
It is up to the programmer to write efficient code.
0 Comments
MATLAB Answers
Sign in to comment.
• Link
Alternative: save the Fields of a Scalar Structure
The save command has an option for saving the fields of a scalar structure as separate variables in a .mat file. For example, given a scalar structure:
S.A = 1;
S.B = [2,3];
this will save variables A and B in the .mat file:
save('myfile.mat','-struct','S')
This is the inverse function of loading into a structure. Some threads showing how this can be used:
https://www.mathworks.com/matlabcentral/answers/456803-how-to-allow-a-gui-user-to-defined-a-variable-name
https://www.mathworks.com/matlabcentral/answers/44175-saving-in-loop-using-eval-or-num2str
https://www.mathworks.com/matlabcentral/answers/314554-saving-function-variables-without-evil-eval#answer_245192
0 Comments
Sign in to comment.
MATLAB Answers
• Link
Simpler way to generate a table from that .mat file:
S = load('patients.mat');
T = struct2table(S,'RowNames',S.LastName);
Sign in to comment.
• Link
You discuss at length why we shouldn't A, B or C and you also comment on how we could access certain objects.
Now, suppose we need to import a few time series -- but I can only import those series one at a time. The intention behind creating a sequence of variables inside a loop is often to store those
time series in distinct object every time. That is, you want to assign the data to a different object every time and do it considerably more than once...
What other choice do you have besides creating objects within your loop?
2 Comments
MATLAB Answers
"What other choice do you have besides creating objects within your loop?"
All of the choices that are explained above: cell arrays, structures, ND numeric arrays. And with newer MATLAB versions also tables, strings, datetime, etc. All of these allow you to "import those
series one at a time", and use indexing (or fieldnames, etc) to put that data into one variable/object. Simple.
"The intention ... is often to store those time series in distinct object every time"
And that is the bad design decision right there.
See Also
MATLAB Answers
1 Answer
Entire Website
More on eval
Blogs
tblvertcat
File Exchange
dbquit
Documentation
Categories
MATLAB > Programming > Functions > Variables
Tags
eval string evaluation dynamic variable n... naming variables evalin assignin bug buggy slow tutorial
name in loop loop variable evil make me cry load worst code practices security indexing efficiency fast
efficient anti-pattern debugging pseudo indexing de-facto indexing beginner best practice magic workspace
anti pattern
Start Hunting!
MATLAB Answers
mathworks.com
© 1994-2020 The MathWorks, Inc. MATLAB and Simulink are registered trademarks of The MathWorks, Inc. See mathworks.com/trademarks for a list of additional trademarks. Other product or brand names may be trademarks or
registered trademarks of their respective holders.
Anonymous Functions
For example, create a handle to an anonymous function that finds the square of a number:
Variable sqr is a function handle. The @ operator creates the handle, and the parentheses () immediately after the @ operator include the function input arguments.
This anonymous function accepts a single input x, and implicitly returns a single output, an array the same size as x that contains the squared values.
Find the square of a particular value (5) by passing the value to the function handle, just as you would pass an input argument to a standard function.
a = sqr(5)
a =
25
Many MATLAB® functions accept function handles as inputs so that you can evaluate functions over a range of values. You can create handles either for anonymous
functions or for functions in program files. The benefit of using anonymous functions is that you do not have to edit and maintain a file for a function that requires only
a brief definition.
For example, find the integral of the sqr function from 0 to 1 by passing the function handle to the integral function:
q = integral(sqr,0,1);
You do not need to create a variable in the workspace to store an anonymous function. Instead, you can create a temporary function handle within an expression,
such as this call to the integral function:
q = integral(@(x) x.^2,0,1);
For example, create a handle to an anonymous function that requires coefficients a, b, and c.
a = 1.3;
b = .2;
c = 30;
parabola = @(x) a*x.^2 + b*x + c;
Because a, b, and c are available at the time you create parabola, the function handle includes those values. The values persist within the function handle even if
you clear the variables:
clear a b c
x = 1;
y = parabola(x)
y =
31.5000
To supply different values for the coefficients, you must create a new function handle:
a = -3.9;
b = 52;
c = 0;
parabola = @(x) a*x.^2 + b*x + c;
x = 1;
y = parabola(1)
y =
48.1000
You can save function handles and their associated values in a MAT-file and load them in a subsequent MATLAB session using the save and load functions, such as
Use only explicit variables when constructing anonymous functions. If an anonymous function accesses any variable or nested function that is not explicitly
referenced in the argument list or body, MATLAB throws an error when you invoke the function. Implicit variables and function calls are often encountered in the
functions such as eval, evalin, assignin, and load. Avoid using these functions in the body of anonymous functions.
2. Evaluate the function from zero to one by passing the function handle to integral,
3. Supply the value for c by constructing an anonymous function for the entire equation,
The final function allows you to solve the equation for any value of c. For example:
g(2)
ans =
2.3333
Functions with No Inputs
If your function does not require any inputs, use empty parentheses when you define and call the anonymous function. For example:
t = @() datestr(now);
d = t()
d =
26-Jan-2012 15:11:47
Omitting the parentheses in the assignment statement creates another function handle, and does not execute the function:
d = t
d =
@() datestr(now)
Functions with Multiple Inputs or Outputs
Anonymous functions require that you explicitly specify the input arguments as you would for a standard function, separating
multiple inputs with commas. For example, this function accepts two inputs, x and y: Try This Example
z = 111
However, an anonymous function returns only one output. If the expression in the function returns multiple outputs, then you can request them when you invoke the
function handle.
For example, the ndgrid function can return as many outputs as the number of input vectors. This anonymous function that calls ndgrid returns only one output
(mygrid). Invoke mygrid to access the outputs returned by the ndgrid function.
c = 10;
mygrid = @(x,y) ndgrid((-x:x/c:x),(-y:y/c:y));
[x,y] = mygrid(pi,2*pi);
You can use the output from mygrid to create a mesh or surface plot:
z = sin(x) + cos(y);
mesh(x,y,z)
Arrays of Anonymous Functions
Although most MATLAB fundamental data types support multidimensional arrays, function handles must be scalars (single elements). However, you can store
multiple function handles using a cell array or structure array. The most common approach is to use a cell array, such as
f = {@(x)x.^2;
@(y)y+10;
@(x,y)x.^2+y+10};
When you create the cell array, keep in mind that MATLAB interprets spaces as column separators. Either omit spaces from expressions, as shown in the previous
code, or enclose expressions in parentheses, such as
f = {@(x) (x.^2);
@(y) (y + 10);
@(x,y) (x.^2 + y + 10)};
Access the contents of a cell using curly braces. For example, f{1} returns the first function handle. To execute the function, pass input values in parentheses after
the curly braces:
x = 1;
y = 10;
f{1}(x)
f{2}(y)
f{3}(x,y)
ans =
1
ans =
20
ans =
21
Related Topics
• Create Function Handle
• Types of Functions
Callback Definition
Defining a callback as a character vector is not recommended. The use of a function specified as function handle enables MATLAB to provide important information
to your callback function.
• The handle of the object whose callback is executing. Use this handle within your callback function to refer to the callback object.
• The event data structure, which can be empty for some callbacks or contain specific information that is described in the property description for that object.
Whenever the callback executes as a result of the specific triggering action, MATLAB calls the callback function and passes these two arguments to the function .
For example, define a callback function called lineCallback for the lines created by the plot function. With the lineCallback function on the MATLAB path, use
the @ operator to assign the function handle to the ButtonDownFcn property of each line created by plot.
plot(x,y,'ButtonDownFcn',@lineCallback)
Define the callback to accept two input arguments. Use the first argument to refer to the specific line whose callback is executing. Use this argument to set the line
Color property:
function lineCallback(src,~)
src.Color = 'red';
end
The second argument is empty for the ButtonDownFcn callback. The ~ character indicates that this argument is not used.
function lineCallback(src,evt,arg1,arg2)
src.Color = 'red';
src.LineStyle = arg1;
src.Marker = arg2;
end
Assign a cell array containing the function handle and the additional arguments to the property:
plot(x,y,'ButtonDownFcn',{@lineCallback,'--','*'})
You can use an anonymous function to pass additional arguments. For example:
plot(x,y,'ButtonDownFcn',...
@(src,eventdata)lineCallback(src,eventdata,'--','*'))
Related Information
For information on using anonymous functions, see Anonymous Functions.
For information about using class methods as callbacks, see Class Methods for Graphics Callbacks.
For information on how MATLAB resolves multiple callback execution, see the BusyAction and Interruptible properties of the objects defining callbacks.
To define a ButtonDownFcn for all line objects, set a default value on the root level.
• Use the groot function to specify the root level of the object hierarchy.
• Define a callback function that is on the MATLAB path.
• Assign a function handle referencing this function to the defaultLineButtonDownFcn.
set(groot,'defaultLineButtonDownFcn',@lineCallback)
The default value remains assigned for the MATLAB session. You can make the default value assignment in your startup.m file.
Callback Definition
Defining a callback as a character vector is not recommended. The use of a function specified as function handle enables MATLAB to provide important information
to your callback function.
• The handle of the object whose callback is executing. Use this handle within your callback function to refer to the callback object.
• The event data structure, which can be empty for some callbacks or contain specific information that is described in the property description for that object.
Whenever the callback executes as a result of the specific triggering action, MATLAB calls the callback function and passes these two arguments to the function .
For example, define a callback function called lineCallback for the lines created by the plot function. With the lineCallback function on the MATLAB path, use
the @ operator to assign the function handle to the ButtonDownFcn property of each line created by plot.
plot(x,y,'ButtonDownFcn',@lineCallback)
Define the callback to accept two input arguments. Use the first argument to refer to the specific line whose callback is executing. Use this argument to set the line
Color property:
function lineCallback(src,~)
src.Color = 'red';
end
The second argument is empty for the ButtonDownFcn callback. The ~ character indicates that this argument is not used.
function lineCallback(src,evt,arg1,arg2)
src.Color = 'red';
src.LineStyle = arg1;
src.Marker = arg2;
end
Assign a cell array containing the function handle and the additional arguments to the property:
plot(x,y,'ButtonDownFcn',{@lineCallback,'--','*'})
You can use an anonymous function to pass additional arguments. For example:
plot(x,y,'ButtonDownFcn',...
@(src,eventdata)lineCallback(src,eventdata,'--','*'))
Related Information
For information on using anonymous functions, see Anonymous Functions.
For information about using class methods as callbacks, see Class Methods for Graphics Callbacks.
For information on how MATLAB resolves multiple callback execution, see the BusyAction and Interruptible properties of the objects defining callbacks.
To define a ButtonDownFcn for all line objects, set a default value on the root level.
• Use the groot function to specify the root level of the object hierarchy.
• Define a callback function that is on the MATLAB path.
• Assign a function handle referencing this function to the defaultLineButtonDownFcn.
set(groot,'defaultLineButtonDownFcn',@lineCallback)
The default value remains assigned for the MATLAB session. You can make the default value assignment in your startup.m file.
functions
Information about function handle
Syntax
s = functions(fh)
Description
s = functions(fh) returns information about a function handle. This information includes the function name, type, and file name. example
Use the functions function for querying and debugging purposes only.
Note
Do not use functions programmatically because its behavior could change in subsequent MATLAB® releases.
fh = @cos;
s = functions(fh)
Create a function handle to an anonymous function. Display its information and values of required variables.
y = 7;
fh = @(x)x.^2+y;
z = fh(2)
z =
11
Display information about the function handle.
s = functions(fh)
s =
function: '@(x)x.^2+y'
type: 'anonymous'
file: ''
workspace: {[1x1 struct]}
within_file_path: '__base_function'
The function handle contains the required value of y.
s.workspace{1}
ans =
y: 7
Create a function that returns handles to local and nested functions. Display their information.
Create the following function in a file, functionsExample.m, in your working folder. The function returns handles to a nested and local function.
function y = nestFunction(x)
y = x + v;
end
end
function y = localFunction(z)
y = z + 1;
end
[hNest,hLocal] = functionsExample(13)
hNest =
@functionsExample/nestFunction
hLocal =
@localFunction
Display information about the handle to the nested function.
s1 = functions(hNest)
s1 =
function: 'functionsExample/nestFunction'
type: 'nested'
file: 'C:\work\functionsExample.m'
workspace: {[1x1 struct]}
Display information about the handle to the local function.
s2 = functions(hLocal)
s2 =
function: 'localFunction'
type: 'scopedfunction'
file: 'C:\work\functionsExample.m'
parentage: {'localFunction' 'functionsExample'}
fh — Handle to query
function handle
Information about a function handle, returned as a structure. The structure contains the following fields.
function Function name. If the function associated with the handle is a nested function, the function name takes the form
main_function/nested_function.
The structure has additional fields depending on the type of function associated with the handle. For example, a local function has a parentage field, and an
anonymous function has a workspace field. Use the information in s for querying and debugging purposes only.
See Also
func2str | str2func
Topics
Create Function Handle
Compare Function Handles
Syntax
tf = isa(A,dataType)
tf = isa(A,typeCategory)
Description
tf = isa(A,dataType) returns 1 (true) if A has the data type specified by dataType. Otherwise, it returns 0 (false). The input argument A can example
have any data type.
If A is an object, then isa returns 1 if dataType is either the class of A or a superclass of A.
example
tf = isa(A,typeCategory) returns 1 (true) if the data type of A belongs to the category specified by typeCategory. Otherwise, it returns 0
(false).
If A is an object, then isa returns 1 if the class of A, or any superclass of A, belongs to the specified category.
A = 3.1416;
tf = isa(A,'double')
tf = logical
1
Create an array of 32-bit integers and determine if its data type is int32.
A = int32([0 2 4 6 8])
A = 1x5 int32 row vector
0 2 4 6 8
tf = isa(A,'int32')
tf = logical
1
tf = isa(A,'char')
tf = logical
0
Create an array whose data type is uint8. Determine if the array has a data type that belongs to the integer category.
Try This Example
A = uint8([0 2 4 6 8])
0 2 4 6 8
tf = isa(A,'integer')
tf = logical
1
tf = isa(A,'float')
tf = logical
0
A — Input array
array
Input array.
Data type, specified as a character vector or string scalar. dataType can be the name of:
The table shows the names of many commonly used MATLAB data types.
'char' Character
'table' Table
Data type category, specified as 'numeric', 'float', or 'integer'. These values represent categories of numeric types, as shown in the table.
'float' Single- or double-precision floating-point array, having either of these data types:
• double
• single
'integer' Signed or unsigned integer array, having one of these data types:
• int8
• int16
• int32
• int64
• uint8
• uint16
• uint32
• uint64
Tips
• To test whether the input array is sparse, use the issparse function.
• To test whether the input array has any imaginary or complex elements, use ~isreal(A).
Extended Capabilities
See Also
class | exist | is* | isenum | isfloat | isinteger | isnumeric
Topics
Fundamental MATLAB Classes
Valid Combinations of Unlike Classes
Syntax
warning(msg)
warning(msg,A1,...,An)
warning(warnID, ___ )
warning(state)
warning(state,warnID)
warning
warnStruct = warning
warning(warnStruct)
warning(state,mode)
warnStruct = warning(state,mode)
Description
warning(msg) displays the warning message and sets the warning state for the lastwarn function. If msg is empty, warning resets the warning state example
for lastwarn, but does not display any text.
warning(msg,A1,...,An) displays a message that contains formatting conversion characters, such as those used with the MATLAB® sprintf
function. Each conversion character in msg is converted to one of the values A1,...,An.
warning(warnID, ___ ) attaches a warning identifier to the warning message. You can include any of the input arguments in the previous syntaxes.
The identifier enables you to distinguish warnings and to control what happens when MATLAB encounters the warnings.
warnStruct = warning returns a structure or array of structures that contains information about which warnings are enabled and disabled. example
warnStruct includes an identifier field with a warnID or 'all', and a state field that indicates the state of the corresponding warning.
warning(warnStruct) sets the current warning settings as indicated in the structure array, warnStruct.
warning(state,mode) controls whether MATLAB displays the stack trace or additional information about the warning. example
warnStruct = warning(state,mode) returns a structure with an identifier field containing the mode and a state field containing the current
state of mode. If you pass the output structure, warnStruct, into the warning function, you set the state of the mode, not which warnings are enabled
or disabled.
n = 7;
if ~ischar(n)
warning('Input must be a character vector')
end
if ~ischar(n)
warning('Input must be a character vector, not a %s',class(n))
end
if ~ischar(n)
warning('MyComponent:incorrectType',...
'Input must be a character vector, not a %s',class(n))
end
warning('off')
warning('on')
warning('off','MATLAB:singularMatrix')
warning
The default warning state is 'on'. Warnings not set to the default are
off MATLAB:singularMatrix
Re-enable the singular matrix warning.
warning('on','MATLAB:singularMatrix')
Enable all warnings, and then disable the singular matrix warning.
warning('on')
warning('off','MATLAB:singularMatrix')
s = warning
s =
identifier
state
Examine the two structures.
s(1)
ans =
identifier: 'all'
state: 'on'
s(2)
ans =
identifier: 'MATLAB:singularMatrix'
state: 'off'
All warnings are enabled except for 'MATLAB:singularMatrix'.
warning('off')
warning('query')
warning(s)
warning('query')
The default warning state is 'on'. Warnings not set to the default are
off MATLAB:singularMatrix
warning('off','verbose')
warning('on','backtrace')
Turn on all warnings, and remove a folder that does not exist on the MATLAB path.
warning('on')
rmpath('nosuchfolder')
Warning: "nosuchfolder" not found in path.
> In rmpath at 57
Enable verbosity to display an extended warning message.
warning('on','verbose')
rmpath('nosuchfolder')
> In rmpath at 57
Disable display of the stack trace.
warning('off','backtrace')
rmpath('nosuchfolder')
A = eye(2);
B = [3 6; 4 8];
C = B\A;
[msgStr,warnId] = lastwarn;
warnStruct = warning('off',warnId);
C = B\A;
warning(warnStruct);
C = B\A;
Information about the cause of the warning and how you might correct it, specified as a character vector or string scalar. To format the message, use escape
sequences, such as \t or \n. You also can use any format specifiers supported by the sprintf function, such as %s or %d. Specify values for the conversion
specifiers via the A1,...,An input arguments. For more information, see Formatting Text.
Note
You must specify more than one input argument with warning if you want MATLAB to convert special characters (such as \t, \n, %s, and %d) in the
warning message.
A1,...,An — Values
character vector | string scalar | numeric scalar
Values that replace the conversion specifiers in msg, specified as a character vector, string scalar, or numeric scalar.
Identifier for the warning, specified as a character vector, string scalar, 'all', or 'last'. Use the warning identifier to help identify the source of the warning or
to control a selected subset of the warnings in your program.
The warning identifier includes one or more component fields and a mnemonic field. Fields must be separated with colon. For example, a warning identifier with
a component field component and a mnemonic field mnemonic is specified as 'component:mnemonic'. The component and mnemonic fields must each begin
with a letter. The remaining characters can be alphanumerics (A–Z, a–z, 0–9) and underscores. No white-space characters can appear anywhere in warnID.
For information on creating identifiers, see MException.
When you set the state of a warning, warnID can have a value of 'all' or 'last'. Use 'all' to set the state of all warnings, and use 'last' to set the state
of the last issued warning.
Example: 'MATLAB:singularMatrix'
Example: 'MATLAB:narginchk:notEnoughInputs'
Warning control indicator specified as 'on', 'off', or 'query'. Use 'on' or 'off' to control whether MATLAB issues a warning. Use 'query' to query the
current state of the warning.
Warning settings, specified as a structure or array of structures that contains information about which warnings are enabled and which are disabled.
warnStruct includes an identifier field with a warnID or 'all', and state field indicating the state of the corresponding warning.
Verbosity and the stack trace display of settings, specified by 'backtrace' or 'verbose'. By default, the state of verbosity is set to 'off' and the state of
stack trace display is set to 'on'.
Extended Capabilities
GPU Arrays
Accelerate code by running on a graphics processing unit (GPU) using Parallel Computing Toolbox™.
See Also
dbstop | disp | error | errordlg | lasterror | lastwarn | sprintf | warndlg
Topics
Issue Warnings and Errors
Suppress Warnings
Restore Warnings
Change How Warnings Display
Syntax
error(msg)
error(msg,A1,...,An)
error(errID, ___ )
error(errorStruct)
error(correction, ___ )
Description
error(msg) throws an error and displays an error message. example
error(msg,A1,...,An) displays an error message that contains formatting conversion characters, such as those used with the MATLAB® sprintf
function. Each conversion character in msg is converted to one of the values A1,...,An.
error(errID, ___ ) includes an error identifier on the exception. The identifier enables you to distinguish errors and to control what happens when
MATLAB encounters the errors. You can include any of the input arguments in the previous syntaxes.
error(correction, ___ ) provides a suggested fix for the exception. You can include any of the input arguments in the previous syntaxes. example
Throw Error
Error occurred.
n = 7;
if ~ischar(n)
error('Error. \nInput must be a char, not a %s.',class(n))
end
Error.
Input must be a char, not a double.
If you only use one input argument with error, then MATLAB does not convert \n to a line break.
if ~ischar(n)
error('Error. \nInput must be a char.')
end
if ~ischar(n)
error('MyComponent:incorrectType',...
'Error. \nInput must be a char, not a %s.',class(n))
end
Error.
Input must be a char, not a double.
Use the MException.last to view the last uncaught exception.
exception = MException.last
exception =
identifier: 'MyComponent:incorrectType'
message: 'Error.
Input must be a char, not a double.'
cause: {0x1 cell}
stack: [0x1 struct]
Throw Error Using Structure
Create structure with message and identifier fields. To keep the example simple, do not use the stack field.
errorStruct =
error(errorStruct)
Create a function hello that requires one input argument. Add a suggested input argument "world" to the error message.
function hello(audience)
if nargin < 1
aac = matlab.lang.correction.AppendArgumentsCorrection('"world"');
error(aac, 'MATLAB:notEnoughInputs', 'Not enough input arguments.')
end
fprintf("Hello, %s!\n", audience)
end
hello
Information about the error, specified as a character vector or string scalar. This message displays as the error message. To format the message, use escape
sequences, such as \t or \n. You also can use any format specifiers supported by the sprintf function, such as %s or %d. Specify values for the conversion
specifiers via the A1,...,An input arguments. For more information, see Formatting Text.
Note
You must specify more than one input argument with error if you want MATLAB to convert special characters (such as \t, \n, %s, and %d) in the error
message.
Identifier for the error, specified as a character vector or string scalar. Use the error identifier to help identify the source of the error or to control a selected
subset of the errors in your program.
The error identifier includes one or more component fields and a mnemonic field. Fields must be separated with colon. For example, an error identifier with a
component field component and a mnemonic field mnemonic is specified as 'component:mnemonic'. The component and mnemonic fields must each begin
with a letter. The remaining characters can be alphanumerics (A–Z, a–z, 0–9) and underscores. No white-space characters can appear anywhere in errID. For
more information, see MException.
Example: 'MATLAB:singularMatrix'
Example: 'MATLAB:narginchk:notEnoughInputs'
A1,...,An — Values
character vector | string scalar | numeric scalar
Values that replace the conversion specifiers in msg, specified as a character vector, string scalar, or numeric scalar.
errorStruct — Error reporting information
scalar structure
Error reporting information, specified as a scalar structure. The structure must contain at least one of these fields.
stack Stack field for the error. When errorStruct includes a stack field, error uses it to set the stack field of the error. When you specify
stack, use the absolute file name and the entire sequence of functions that nests the function in the stack frame. This character
vector is the same as the one returned by dbstack('-completenames').
Tips
• When you throw an error, MATLAB captures information about it and stores it in a data structure that is an object of the MException class. You can access
information in the exception object by using try/catch. Or, if your program terminates because of an exception and returns control to the Command Prompt, you
can use MException.last.
• MATLAB does not cease execution of a program if an error occurs within a try block. In this case, MATLAB passes control to the catch block.
• If all inputs to error are empty, MATLAB does not throw an error.
Extended Capabilities
GPU Arrays
Accelerate code by running on a graphics processing unit (GPU) using Parallel Computing Toolbox™.
See Also
assert | dbstack | errordlg | MException | MException.last | try | warning
Topics
Throw an Exception
Respond to an Exception
Syntax
msg = lastwarn
[msg,warnID] = lastwarn
[ ___ ] = lastwarn(newMsg,newID)
Description
msg = lastwarn returns the last warning message generated by MATLAB®, regardless of the display state of the warning. example
example
[msg,warnID] = lastwarn also returns the warning identifier associated with msg.
[ ___ ] = lastwarn(newMsg,newID) sets the last warning message and the last warning identifier. Subsequent calls to the lastwarn function return
the new warning message and, if requested, the new warning identifier. You can use this syntax with any of the output arguments of the previous
syntaxes.
warning('Message 1.')
Warning: Message 1.
Call the lastwarn function to display the last warning message.
msg = lastwarn
msg =
'Message 1.'
Save the current warning settings, and then disable all warnings.
origState = warning;
warning('off')
Call the warning function with a different message. The warning is not displayed.
warning('Message 2.')
Call the lastwarn function. MATLAB returns the last warning message, even though it was not displayed.
msg = lastwarn
msg =
'Message 2.'
Restore the saved warning state.
warning(origState)
The warning identifier is often used to suppress warnings. To find the identifier, use the lastwarn function.
A = eye(2);
B = [3 6; 4 8];
C = B\A;
[msg,warnID] = lastwarn;
msg =
warnID =
'MATLAB:singularMatrix'
Save the current warning state, and disable the specific warning. Perform the original calculation again. This time the warning does not display.
warnStruct = warning('off',warnID);
C = B\A;
warning(warnStruct);
New message for last warning, specified as a character vector or string scalar. Subsequent calls to the lastwarn function return the new warning message.
You can set the new message to an empty character vector ('') or string scalar ("").
New identifier for the last warning, specified as a character vector or string scalar. Use the warning identifier to help identify the source of the warning or to
control a selected subset of the warnings in your program.
A warning identifier includes one or more component fields and a mnemonic field. Fields must be separated with colon. For example, a warning identifier with a
component field component and a mnemonic field mnemonic is specified as 'component:mnemonic'. The component and mnemonic fields must each begin
with a letter. The remaining characters can be alphanumerics (A–Z, a–z, 0–9) and underscores. No white-space characters can appear anywhere in the
warning identifier. For more information on creating identifiers, see MException.
Example: 'MATLAB:singularMatrix'
Example: 'MyProject:myFunction:notEnoughInputs'
Output Arguments
collapse all
msg — Last warning message
character vector
Last warning message generated by MATLAB, regardless of the display state of the warning, returned as a character vector.
Last warning identifier, returned as a character vector. If the warning was not defined with an identifier, lastwarn returns an empty character vector for warnID.
See Also
error | warning
Topics
Suppress Warnings
Restore Warnings
Syntax
assert(cond)
assert(cond,msg)
assert(cond,msg,A1,...,An)
assert(cond,errID,msg)
assert(cond,errID,msg,A1,...,An)
Description
assert(cond) throws an error if cond is false. example
assert(cond,msg) throws an error and displays the error message, msg, if cond is false. example
assert(cond,msg,A1,...,An) displays an error message that contains formatting conversion characters, such as those used with the MATLAB®
sprintf function, if cond is false. Each conversion character in msg is converted to one of the values A1,...,An.
assert(cond,errID,msg) throws an error, displays the error message, msg, and includes an error identifier on the exception, if cond is false. The example
identifier enables you to distinguish errors and to control what happens when MATLAB encounters the errors.
assert(cond,errID,msg,A1,...,An) includes an error identifier on the exception and displays a formatted error message.
minVal = 7;
x = 26;
assert(minVal < x)
maxVal = 13;
Assertion failed.
The expression evaluates as false. The assertion fails and MATLAB throws an error.
a = 13;
b = single(42);
c = a*b;
Use the assert function to test for conditions that should not happen in normal code execution. If the coefficients are numeric, the computed roots should be
numeric. A quadratic equation using the specified coefficients and computed roots should be zero.
function x = quadraticSolver(C)
validateattributes(C,{'numeric'},{'size',[1 3]})
a = C(1);
b = C(2);
c = C(3);
x(1) = (-b+sqrt(b^2-4*a*c))/(2*a);
x(2) = (-b-sqrt(b^2-4*a*c))/(2*a);
assert(isnumeric(x),'quadraticSolver:nonnumericRoots',...
'Computed roots are not numeric')
y1 = a*x(1)^2+b*x(1)+c;
y2 = a*x(2)^2+b*x(2)+c;
assert(y1 == 0,'quadraticSolver:root1Error','Error in first root')
assert(isequal(y2,0),'quadraticSolver:root2Error','Error in second root')
end
Condition to assert, specified as a valid MATLAB expression. This expression must be logical or convertible to a logical. If cond is false, the assert function
throws an error. cond can include relational operators (such as < or ==) and logical operators (such as &&, ||, or ~). Use the logical operators and and or to
create compound expressions. MATLAB evaluates compound expressions from left to right, adhering to operator precedence rules.
Example: a<0
Example: exist('myfunction.m','file')
Information about the assertion failure, specified as a character vector or string scalar. This message displays as the error message. To format the message,
use escape sequences, such as \t or \n. You also can use any format specifiers supported by the sprintf function, such as %s or %d. Specify values for the
conversion specifiers via the A1,...,An input arguments. For more information, see Formatting Text.
Note
You must specify more than one input argument with assert if you want MATLAB to convert special characters (such as \t, \n, %s, and %d) in the
error message.
Numeric, character, or string arrays. This input argument provides the values that correspond to and replace the conversion specifiers in msg.
Identifier for the assertion failure, specified as a character vector or string scalar. Use the identifier to help identify the source of the error or to control a selected
subset of the errors in your program.
The error identifier includes one or more component fields and a mnemonic field. Fields must be separated with colon. For example, an error identifier with a
component field component and a mnemonic field mnemonic is specified as 'component:mnemonic'. The component and mnemonic fields must each begin
with a letter. The remaining characters can be alphanumerics (A–Z, a–z, 0–9) and underscores. No white-space characters can appear anywhere in errID. For
more information, see MException.
Example: 'MATLAB:singularMatrix'
Example: 'MATLAB:narginchk:notEnoughInputs'
Tips
• When you issue an error, MATLAB captures information about it and stores it in a data structure that is an object of the MException class. You can access
information in the exception object by using try/catch. Or, if your program terminates because of an exception and returns control to the Command Prompt, you
can use MException.last.
• If an assertion failure occurs within a try block, MATLAB does not cease execution of the program. In this case, MATLAB passes control to the catch block.
Extended Capabilities
C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.
GPU Arrays
Accelerate code by running on a graphics processing unit (GPU) using Parallel Computing Toolbox™.
See Also
error | MException
Introduced in R2007a
onCleanup
Cleanup tasks upon function completion
Syntax
cleanupObj = onCleanup(cleanupFun)
Description
cleanupObj = onCleanup(cleanupFun) creates an object that, when destroyed, executes the function cleanupFun. MATLAB® implicitly clears all example
local variables at the termination of a function, whether by normal completion, or a forced exit, such as an error, or Ctrl+C.
If you reference or pass cleanupObj outside your function, then cleanupFun does not run when that function terminates. Instead, it runs whenever
MATLAB destroys the object.
Save the following code in action.m and type action in the Command Window.
function action
disp('Display Figure')
f = figure;
cleanup = onCleanup(@()myCleanupFun(f));
pause(1)
end
function myCleanupFun(f)
disp('Close Figure')
close(f)
end
Display Figure
Close Figure
cd(tempdir)
disp('You are now in the temporary folder')
Save the following code in youraction.m and type youraction in the Command Window.
function youraction
cleanup = onCleanup(@cleanup);
disp('Execute Code')
end
Execute Code
You are now in the temporary folder
You can declare any number of onCleanup objects in a program file. However, if the cleanup tasks depend on the order of execution, then you should define
only one object that calls a script or function, containing the relevant cleanup commands.
You should use an anonymous function handle to call your cleanup task. This allows you to pass arguments to your cleanup function.
Example: @()fclose('file.m')
Example: @user_script
Tips
• Avoid using nested functions during cleanup. MATLAB can clear variables used in nested functions before the cleanup function tries to read from them.
• If your program contains multiple cleanup objects, MATLAB does not guarantee the order that it destroys these objects. If the order of your cleanup functions
matters, define one onCleanup object for all the tasks.
• If you save an onCleanup object, MATLAB displays a warning and does not save the cleanupFun cleanup task.
Extended Capabilities
See Also
clear | clearvars
Topics
Clean Up When Functions Complete
Object Lifecycle
Function Handles
What Are Anonymous Functions?
Introduced in R2008a
Alternatives to the eval Function
• MATLAB® compiles code the first time you run it to enhance performance for future runs. However, because code in an eval statement can change at run time, it
is not compiled.
• Code within an eval statement can unexpectedly create or assign to a variable already in the current workspace, overwriting existing data.
• Concatenated character vectors within an eval statement are often difficult to read. Other language constructs can simplify the syntax in your code.
For many common uses of eval, there are preferred alternate approaches, as shown in the following examples.
For example, create a cell array that contains 10 elements, where each element is a numeric array:
numArrays = 10;
A = cell(numArrays,1);
for n = 1:numArrays
A{n} = magic(n);
end
Access the data in the cell array by indexing with curly braces. For example, display the fifth element of A:
A{5}
ans =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
The assignment statement A{n} = magic(n) is more elegant and efficient than this call to eval:
The best practice is to use function syntax, which allows you to pass variables as inputs. For example:
currentFile = 'myfile1.mat';
save(currentFile)
You can construct file names within a loop using the sprintf function (which is usually more efficient than int2str), and then call the save function without eval.
This code creates 10 files in the current folder:
numFiles = 10;
for n = 1:numFiles
randomData = rand(n);
currentFile = sprintf('myfile%d.mat',n);
save(currentFile,'randomData')
end
• Create function handles with the @ symbol or with the str2func function. For example, run a function from a list stored in a cell array:
examples = {@odedemo,@sunspots,@fitdemo};
n = input('Select an example (1, 2, or 3): ');
examples{n}()
• Use the feval function. For example, call a plot function (such as plot, bar, or pie) with data that you specify at run time:
If you enter weight at the input prompt, then you can find the minimum weight value with the following command.
min(dataToUse)
ans =
90
For an additional example, see Generate Field Names from Variables.
Error Handling
The preferred method for error handling in MATLAB is to use a try, catch statement. For example:
try
B = A;
catch exception
disp('A is undefined')
end
If your workspace does not contain variable A, then this code returns:
A is undefined
Previous versions of the documentation for the eval function include the syntax eval(expression,catch_expr). If evaluating the expression input returns an
error, then eval evaluates catch_expr. However, an explicit try/catch is significantly clearer than an implicit catch in an eval statement. Using the implicit catch is
not recommended.
Nested Functions
For example, this function named parent contains a nested function named nestedfx:
function parent
disp('This is the parent function')
nestedfx
function nestedfx
disp('This is the nested function')
end
end
The primary difference between nested functions and other types of functions is that they can access and modify variables that are defined in their parent functions.
As a result:
• Nested functions can use variables that are not explicitly passed as input arguments.
• In a parent function, you can create a handle to a nested function that contains the data necessary to run the nested function.
This means that both a nested function and a function that contains it can modify the same variable without passing that variable as an argument. For example, in
each of these functions, main1 and main2, both the main function and the nested function can access variable x:
function main1 function main2
x = 5; nestfun2
nestfun1
function nestfun2
function nestfun1 x = 5;
x = x + 1; end
end
x = x + 1;
end end
When parent functions do not use a given variable, the variable remains local to the nested function. For example, in this function named main, the two nested
functions have their own versions of x that cannot interact with each other:
function main
nestedfun1
nestedfun2
function nestedfun1
x = 1;
end
function nestedfun2
x = 2;
end
end
Functions that return output arguments have variables for the outputs in their workspace. However, parent functions only have variables for the output of nested
functions if they explicitly request them. For example, this function parentfun does not have variable y in its workspace:
function parentfun
x = 5;
nestfun;
function y = nestfun
y = x + 1;
end
end
function parentfun
x = 5;
z = nestfun;
function y = nestfun
y = x + 1;
end
end
• Input arguments
• Variables defined within the nested function
• Variables defined in a parent function, also called externally scoped variables
When you create a function handle for a nested function, that handle stores not only the name of the function, but also the values of externally scoped variables.
For example, create a function in a file named makeParabola.m. This function accepts several polynomial coefficients, and returns a handle to a nested function that
calculates the value of that polynomial.
function p = makeParabola(a,b,c)
p = @parabola;
function y = parabola(x)
y = a*x.^2 + b*x + c;
end
end
The makeParabola function returns a handle to the parabola function that includes values for coefficients a, b, and c.
At the command line, call the makeParabola function with coefficient values of 1.3, .2, and 30. Use the returned function handle p to evaluate the polynomial at a
particular point:
p = makeParabola(1.3,.2,30);
X = 25;
Y = p(X)
Y =
847.5000
Many MATLAB functions accept function handle inputs to evaluate functions over a range of values. For example, plot the parabolic equation from -25 to +25:
fplot(p,[-25,25])
You can create multiple handles to the parabola function that each use different polynomial coefficients:
firstp = makeParabola(0.8,1.6,32);
secondp = makeParabola(3,4,50);
range = [-25,25];
figure
hold on
fplot(firstp,range)
fplot(secondp,range,'r:')
hold off
Visibility of Nested Functions
Every function has a certain scope, that is, a set of other functions to which it is visible. A nested function is available:
• From the level immediately above it. (In the following code, function A can call B or D, but not C or E.)
• From a function nested at the same level within the same parent function. (Function B can call D, and D can call B.)
• From a function at any lower level. (Function C can call B or D, but not E.)
The easiest way to extend the scope of a nested function is to create a function handle and return it as an output argument, as shown in Using Handles to Store
Function Parameters. Only functions that can call a nested function can create a handle to it.
Related Topics
• Variables in Nested and Anonymous Functions
• Create Function Handle
• Argument Checking in Nested Functions
• Types of Functions
Share Data Between Workspaces
Introduction
This topic shows how to share variables between workspaces or allow them to persist between function executions.
In most cases, variables created within a function are local variables known only within that function. Local variables are not available at the command line or to any
other function. However, there are several ways to share data between functions or workspaces.
For example, create two functions, update1 and update2, that share and modify an input value. update2 can be a local function in the file update1.m, or can be a
function in its own file, update2.m.
function y1 = update1(x1)
y1 = 1 + update2(x1);
function y2 = update2(x2)
y2 = 2 * x2;
Call the update1 function from the command line and assign to variable Y in the base workspace:
X = [1,2,3];
Y = update1(X)
Y =
3 5 7
Nested Functions
A nested function has access to the workspaces of all functions in which it is nested. So, for example, a nested function can use a variable (in this case, x) that is
defined in its parent function:
function primaryFx
x = 1;
nestedFx
function nestedFx
x = x + 1;
end
end
When parent functions do not use a given variable, the variable remains local to the nested function. For example, in this version of primaryFx, the two nested
functions have their own versions of x that cannot interact with each other.
function primaryFx
nestedFx1
nestedFx2
function nestedFx1
x = 1;
end
function nestedFx2
x = 2;
end
end
Persistent Variables
When you declare a variable within a function as persistent, the variable retains its value from one function call to the next. Other local variables retain their value
only during the current execution of a function. Persistent variables are equivalent to static variables in other programming languages.
Declare variables using the persistent keyword before you use them. MATLAB® initializes persistent variables to an empty matrix, [].
For example, define a function in a file named findSum.m that initializes a sum to 0, and then adds to the value on each iteration.
function findSum(inputvalue)
persistent SUM_X
if isempty(SUM_X)
SUM_X = 0;
end
SUM_X = SUM_X + inputvalue;
When you call the function, the value of SUM_X persists between subsequent executions.
• clear all
• clear functionname
• Editing the function file
To prevent clearing persistent variables, lock the function file using mlock.
Global Variables
Global variables are variables that you can access from functions or from the command line. They have their own workspace, which is separate from the base and
function workspaces.
• Any function can access and update a global variable. Other functions that use the variable might return unexpected results.
• If you unintentionally give a “new” global variable the same name as an existing global variable, one function can overwrite the values expected by another. This
error is difficult to diagnose.
If you use global variables, declare them using the global keyword before you access them within any particular location (function or command line). For example,
create a function in a file called falling.m:
function h = falling(t)
global GRAVITY
h = 1/2*GRAVITY*t.^2;
global GRAVITY
GRAVITY = 32;
y = falling((0:.1:5)');
The two global statements make the value assigned to GRAVITY at the command prompt available inside the function. However, as a more robust alternative,
redefine the function to accept the value as an input:
function h = falling(t,gravity)
h = 1/2*gravity*t.^2;
GRAVITY = 32;
y = falling((0:.1:5)',GRAVITY);
Like global variables, these functions carry risks of overwriting existing data. Use them sparingly.
evalin and assignin are sometimes useful for callback functions in graphical user interfaces to evaluate against the base workspace. For example, create a list box
of variable names from the base workspace:
function listBox
figure
lb = uicontrol('Style','listbox','Position',[10 10 100 100],...
'Callback',@update_listBox);
update_listBox(lb)
function update_listBox(src,~)
vars = evalin('base','who');
src.String = vars;
For other programming applications, consider argument passing and the techniques described in Alternatives to the eval Function.
Related Topics
• Base and Function Workspaces
Modeling Cyber-Physical Systems
Cyber-physical systems combine computer and physical systems to achieve design goals. Simulation of cyber-physical systems
requires a combination of modeling techniques such as continuous-time, discrete-time, discrete-event, and finite state modeling. View MATLAB Command
Simulink® and its companion products provide functionality to apply a wide range of modeling techniques and seamlessly integrate
them in one simulation environment, which is ideal for modeling cyber-physical systems.
This example shows how continuous-time, discrete-event, and finite-state modeling techniques combine to simulate the behavior of a variable speed conveyor belt
system. In SimEvents®, entities are discrete items of interest in a discrete-event simulation. Because passengers are discrete individuals, they are modeled by
SimEvents® entities, created by the Entity Generator block. A Stateflow® chart models the operational modes and motor dynamics of the variable speed conveyor
belt. Finally, the Entity Transport Delay block models passenger throughput as a function of conveyor belt dynamics, providing a bridge between the discrete-event
and continuous-time domains.
Note: The example uses blocks from SimEvents® and Stateflow®. If you do not have a SimEvents or Stateflow license, you can open and simulate the model but
only make basic changes such as modifying block parameters.
Model Structure
The model includes these key components:
• Passengers — Models the arrival of passengers as a Poisson process. The output is a sequence of SimEvents® entities corresponding to the passengers who
step on the conveyor belt. The distribution of inter-arrival time ( ) of a Poisson process is , where is the arrival rate. is modeled by a
MATLAB action in the Entity Generator block for rush hour, normal hour, and free hour. The passenger arrival rate changes with time as:
• Entity Transport Delay — Holds the passengers on the conveyor belt until they arrive at the other terminal, based on the time delay calculated by the Stateflow
chart.
• Dynamics of conveyor belt — Models the operation of a variable speed conveyor belt. See the Conveyor Belt Dynamics section for more details.
• Dashboard — Shows the runtime status of the conveyor belt. The color of the Mode Lamp indicates the mode of the conveyor belt.
• OnDemand — This is the normal operating mode, which maintains the optimal velocity for passenger comfort and throughput. The power will proportionally
increase with the weight of the load. The Mode Lamp is green in this mode.
• Max — Maximum power mode. The weight of the load is too large for the conveyor belt to maintain the optimal velocity. The conveyor belt operates at the
maximum possible velocity that does not exceed the maximum power. The Mode Lamp is red in this mode.
Results
The Scope and blocks in the DashBoard show the simulation results.
Simulation results: 1. Number of passengers versus simulation time. 2. Velocity (blue) and power (red) versus simulation time.
Three operation cycles are observed within a time span of 900. Each cycle has a period of 300, which aligns with the period of the arrival rate. The top plot shows the
number of passengers on the conveyor belt over time, and the bottom plot shows the velocity and power of the conveyor belt. The velocity and power are normalized
for better visualization.
The first two thirds of each period correspond to rush hour, and the number of passengers on the conveyor belt increases dramatically. Consequently, the conveyor
belt enters into the Max mode quickly, which is characterized by the maximum output power with a velocity that is inversely proportional to the number of passengers.
In the last third of each period, the airport is in the normal hour followed by the free hour. Therefore, the number of passengers on the conveyor belt drops and even
becomes zero for some time.
The conveyor belt then operates in OnDemand and Idle modes accordingly. In OnDemand mode, the velocity is locked to a default value, and the power is
proportional to the number of passengers. In Idle mode, both the velocity and power are maintained at low values to reduce energy consumption. Overall, the
conveyor belt operates according to the load of the airport.
Power Window Control Project
This example shows how you can use MathWorks® software and the Model-Based Development process to go from concept to
implementation for a power window system for an automobile. This example uses Simulink®, Simulink® Coverage™, DSP System View MATLAB Command
Toolbox™, Simscape™ Multibody™, Fixed-Point Designer™, Simscape™ Electrical™, Simscape™, and Simulink® Real-Time™.
When the model detects such an object, it must lower the window by about 10 centimeters.
slexPowerWindowStart
Exploring the Project
Upon visual inspection of the project, you can see features used to organize the example. These features are:
• Folders
• File Classification
• Shortcuts
Folders
• configureModel - MATLAB® files controlling the main system model variant configuration
• data - Images required by the project
• hmi - Files that animate the power window response
• model - Main system model, controller model, models for testing the controller, and libraries which support these models
• task - MATLAB files that simulate the model for the different model configurations and generate coverage reports for the controller
• utilities - MATLAB files to initialize the model, to generate spreadsheet input, to add data to the generated spreadsheet and to manage the project environment at
startup and shutdown
File Classification
Files in Projects have different classifications visible in Labels pane. Each label describes the specific role a file contributes to the body of the project. In this project,
new classifications were added, including:
Shortcuts
Project shortcuts are used to obtain quick access to project files that are used most often. Some shortcuts contain general tasks such as adding the project to the
path at startup and removing it at shutdown. In addition, project shortcut groups help organize the shortcuts. The new shortcut groups are
In this example under the model folder, the main system model is slexPowerWindowExample. This model consists of the driver and passenger switch blocks, which
generate the inputs to the system. The inputs then go through the control system model, which validates the states of the passenger and driver inputs. The control
system block also determines if there is an obstacle blocking the window's path. The referenced controller produces the window motion command signals sent to the
active variant of the window system. The window system output is the feedback to the control system block.
To visualize the results of simulation, Simulation Data Inspector (SDI) logs the output data and Simulink 3D Animation™ animates the window's motion.
Model Variants
The main system model in this project uses the Variant Subsystem block to allow for multiple implementations of within a subsystem. The active implementation
can be programmatically changed prior to simulation. In the main model, there are four Variant Subsystem blocks each with variant choices that can be
programmatically modified. Those four variant subsystems are:
• slexPowerWindowExample/driver_switch
• slexPowerWindowExample/passenger_switch
• slexPowerWindowExample/window_system
• slexPowerWindowExample/power_window_control_system/detect_obstacle_endstop
Each variant choice is associated with a variant control. The variant choice is active when its variant control evaluates to true.
Since there are four programmatically modifiable Variant Subsystem blocks in the main model, there are MATLAB files to control the combinations of variant choices
to create model variant configurations which are found under the DesignConfig classification. Available model variant configurations are
This model variant uses Stateflow® and Simulink to model both discrete event reactive behavior and continuous time behavior. It uses a low order plant model to
validate the roll-up and roll-down behavior. You can simulate this variant configuration using the SimHybridPlantLowOrder shortcut. This shortcut activates only the
variant subsystem corresponding to this model configuration. Since this model does not take into account power effects, the only output logged is position. Simulation
Data Inspector (SDI) displays the logged position data.
This model variant shows a more detailed plant model that includes power effects in the electrical and mechanical domains is used to validate that the force exerted
by the window on a trapped object never exceeds 100 N. This model variant requires Simscape™ Multibody™ and Simscape Power Systems™ products to be
installed. You can simulate this variant configuration using the SimHybridPlantPowerEffects shortcut. Unlike the previous variant model, this variant configuration
takes into account the power effects. SDI displays the logged data from armature current, position, and force exerted by the power window.
This model variant shows the use of a CAN to communicate the commands to control window movement. The switches that may be located in the center console of
the vehicle and that produce the commands are included in this model variant. This model variant requires Simscape Multibody, Simscape Power Systems, DSP
System Toolbox, and Fixed-Point Designer products to be installed. You can simulate this variant configuration on a machine running windows OS using
the|SimCANCommunication| shortcut.
To test the state machine that controls the power window, you can run the project shortcuts for testing. Available model shortcuts for testing the controller are
• InteractiveExample
• CoverageExample
• IncreaseCoverageExample
InteractiveExample
This model shortcut opens the model, slexPowerWindowCntlInteract. This model contains the power window controller which is a state machine. This model also
contains inputs to the controller which are selected with manual switch blocks.
• Passenger Input
• Driver Input
• Window Frame Endstops
• Obstacle Present
Passenger Input
Driver Input
Obstacle Present
You can interactively test the controller by simulating the model and selecting the desired combination of inputs via the manual switch blocks. After making the
selection of inputs, you can verify the internal controller state and controller output against the desired result for this specific set of inputs.
CoverageExample
This model shortcut opens the model, slexPowerWindowCntlCoverage. This model contains the power window controller which is a state machine. This model also
contains inputs to the controller which are repeating sequence blocks.
You can use the Simulink Coverage (TM) Model Coverage tool to validate the discrete event control of the window. The Model Coverage tool helps determine the
extent to which a model test case exercises the conditional branches of the controller. It also helps evaluate whether all transitions in the discrete event control are
taken given the test case we run. It also evaluates whether all clauses in a condition that enables a particular transition have become true. One transition may be
enabled by multiple clauses, e.g., the transition from emergency back to neutral occurs when either 100 ticks have occurred or when the endstop is reached.
IncreaseCoverageExample
This model shortcut opens the model, slexPowerWindowCntlCoverageIncrease. This model contains the power window controller that is a state machine. This model
also contains a From Spreadsheet block that provides multiple sets of inputs to the controller. These input sets combine with the one from the CoverageExample
model to exercise more of the logic in the power window controller.
The model coverage shortcut, GenerateIncreasedCoverage, uses the multiple input sets with the Simulink Coverage Model Coverage tool to validate the discrete
event control of the window and generate a coverage report for the multiple input sets. The Model Coverage tool helps determine the extent to which a model test
case exercises the conditional branches of the controller. It also helps evaluate if all transitions in the discrete event control have been taken into account given the
input sets we run.
Related Topics
• Power Window
• Project Management
Model an Ethernet Communication Network with CSMA/CD Protocol
Step 3 of 3 in Modeling Message Communication Patterns with SimEvents This example uses:
SimEvents
Stateflow
Simulink
This example shows how to model an Ethernet communication network with CSMA/CD protocol using Simulink® messages and SimEvents®. In the example, there
are three computers that communicate through an Ethernet communication network. Each computer has a software component that generates data and an Ethernet
interface for communication. Each computer attempts to send the data to another computer with a unique MAC address. An Ethernet interface controls a computer's
interaction with the network by using a CSMA/CD communication protocol. The protocol is used to respond to collisions that occur when multiple computers send
data simultaneously. The Ethernet component represents the network and the connection between the computers.
Software Components
In the model, each software component generates data (payload) and combines the data, its size, and its destination into a message. Then, the message is sent to
the Ethernet interface for communication.
• A MATLAB Function block generates data with a size between 46 and 1500 bytes [ 1 ].
• A Bus Creator block converts the Data, PayloadSize, and DestAddress signals to a nonvirtual bus object called dataPacket.
• An Outport block sends the message to the Ethernet interface for communication.
Each computer generates data with a different rate. You can change the data generation rate from the MATLAB Function block's sample time.
To learn the basics of creating message send and receive interfaces, see Establish Message Send and Receive Interfaces Between Software Components.
Ethernet Interface
Double-click Ethernet Interface 1. Observe that you can specify the Station ID and Transmission buffer capacity.
• A SimEvents® Entity Replicator block labeled Copy Message copies an incoming message. The original message is forwarded to a SimEvents® Entity Generator
block labeled Assemble MAC Frame. Because the Entity Generator block Generation method parameter is set to Event-based, it immediately produces an
entity when the original message arrives at the block. A copy of the message is forwarded to a Simulink Function block with the initPacket() function. The
terms message and entity are used interchangeably between Simulink® and SimEvents®.
• The Simulink Function block transfers the data, its size, and its destination address to the Assemble MAC Frame block for frame assembly.
• The Assemble MAC Frame block generates the Ethernet frames that carry both Ethernet-specific attributes and values transferred from the Simulink Function
block.
Assemble MAC Frame block calls the initPacket() function as an action that is invoked by each frame generation event.
These are the attributes of the generated Ethernet frame:
• entity.TxAddress is StationID.
• entity.RxAddress, entity.Data, and entity.PayloadSize are assigned the values from the Simulink Function block.
• entity.TxDelay is the transmission delay. It is defined by the payload size and the bitrate. The Bitrate parameter is specified by an initialization function in the
Model Properties.
Transmission Buffer
The transmission buffer stores entities before transmission by using a first-in-first-out (FIFO) policy. The buffer is modeled by a Queue block.
The capacity of the queue is determined by the Transmission buffer capacity parameter.
• An Entity Gate block labeled Admit 1 Frame is configured as an enabled gate with two input ports. One input port allows frames from the Transmission Buffer
block. The other input port is called the control port, which accepts messages from the CSMA/CD block. The block allows one frame to advance when it receives
a message with a positive value from CSMA/CD block.
• An Entity Input Switch block labeled Merge merges two paths. One input port accepts new frames admitted by the Admit 1 frame block and the other input port
accepts frames for retransmission that are sent by the CSMA/CD block.
• An Entity Server block labeled Wait for Channel models the back off time of a frame before its retransmission through the channel.
• Another Entity Gate block labeled Send to Channel opens the gate to accept frames when the channel is idle. The channel status is communicated by the
CSMA/CD chart.
• An Entity Replicator block labeled Copy Transmitted Frame generates a copy of the frame. One frame is forwarded to the Ethernet network, and the other is
forwarded to the CSMA/CD chart.
• A Discrete-Event Chart block labeled CSMA/CD represents the state machine that models the CSMA/CD protocol.
CSMA/CD Protocol
The CSMA/CD protocol [ 2 ] is modeled by a Discrete-Event Chart block that has two inputs:
• IsIdle — Opens the Send to Channel gate to accept frames when the value is 1, and closes the gate when the value is 0.
• TxRe — Retransmitted frame that is forwarded to the Merge block if there is a collision detected during its transmission.
• TxNext — Opens the Admit 1 Frame gate to accept new frames when the value is 1.
If the transmission is successful, the block sets TxNext.data to 1 to allow a new message into the channel and resets to the Standby state.
If there is a collision, the block resends the message after delaying it for a random back off time. n is the counter for retransmissions. The block retransmits a
message a maximum of 16 times. If all of the retransmission attempts are unsuccessful, then the block terminates the message and allows the entry of a new
message. Then it resets to StandBy.
Similarly, the block can receive messages from other computers. If there is no error, the messages are successfully received and the block outputs the received data
and its size.
Ethernet Hub
The Ethernet component represents the communication network and the cabled connections of the computers to the network.
• Connected stations — These values are assigned to Stations, which is a vector with the station IDs as elements.
• Length of cables (m) — These values are assigned to CableLength and represent the length of the cables, in meters, for each computer connected to the hub.
• Packet error rate (PER) — These values are assigned to PER and represent the rate of error in message transmission for each computer.
• Processing time (s) — These values are assigned to ProcessingTime and it represents the channel transmission delay.
Three SimEvents® blocks are used to model the Ethernet network. The three computer connections are merged by using an Entity Input Switch block. An Entity
Server block is used to model the channel transmission delay based on the cable length. An Entity Replicator block copies the transmitted message and forwards it
to the three computers.
• Copy an existing computer and assign a new ID by double-clicking the Ethernet Interface block. In this example, new computer has ID 4.
• Double-click the Ethernet block and add a station ID, cable length, and packet error rate for the new computer.
References
1. Ethernet frame - Wikipedia (https://en.wikipedia.org/wiki/Ethernet_frame)
2. Carrier-sense multiple access with collision detection - Wikipedia (https://en.wikipedia.org/wiki/Carrier-sense_multiple_access_with_collision_detection)
See Also
Queue | Receive | Send | Discrete-Event Chart (SimEvents) | Entity Gate (SimEvents) | Entity Generator (SimEvents) | Entity Input Switch (SimEvents) | Entity
Replicator (SimEvents)
Related Topics
• Simulink Messages Overview
• Discrete-Event Simulation in Simulink Models (SimEvents)
• Build a Shared Communication Channel with Multiple Senders and Receivers
sldemo_slproject_airframe;
This loads the upgrade advisor checks and runs a dependency analysis on your project to ensure the project hierarchy is handled correctly.
Click Upgrade to run all upgrade checks on all models, libraries and MATLAB code in your project. If any check fails and there is a fix available, the project
automatically applies the fix and runs the relevant checks again to ensure they now pass.
Model Upgrades
When working on a large model, you can separate it into multiple files so that team members can develop different model components at the same time. You can
reuse these components multiple times in a model and in other models.
Model, library, and subsystem files provide a single source for multiple instances of the same model component. To learn when you should use each of these
componentization methods, see Component-Based Modeling Guidelines.
Subsystems
Model ex_modeling_component_reuse references the contents of subsystem file ex_modeling_mechanical_system.slx twice to represent identical mechanical
subsystems.
While you can define a subsystem for reuse in either a library or subsystem file, subsystem files allow for easier editing. When you edit a referenced subsystem, the
changes apply to the subsystem file and all instances of the referenced subsystem.
Models
Model ex_modeling_component_reuse references the contents of model file ex_modeling_controller.slx. Controller code is often deployed on embedded
systems, so having a standalone controller model is useful.
An embedded processor might not support default properties for the controller. Since a controller model might be used to generate code for an embedded processor,
these constraints apply to the referenced controller model and the interface with its parent model:
• Fixed Signal Attributes — To require that buses at model interfaces share the same signal attributes, bus objects specify signal attributes at the three sets of input
and output ports.
• Discrete Sample Time — To specify a discrete sample time, model ex_modeling_controller specifies a discrete execution domain and script
ex_modeling_data_controller.m specifies discrete PID controller values.
• Fixed Data Type — To apply the single-precision data type required by the embedded processor, Data Type Conversion blocks convert the bus element data
types before they reach the model interface.
Related Topics
• Component-Based Modeling Guidelines
• Create a Custom Library
• Model Reference Basics
Observe that in this example if you change the 'Time domain' on the mask dialog box, the block within the Subsystem is replaced
accordingly. For example, if you select the 'Time domain' as 'Discrete', the continuous integrator block is replaced with a discrete integrator block and vise-versa.
This dynamic change in the structure of the self-modifiable linked block is controlled using the MATLAB code that is added in the Initialization pane of the Mask
Editor.
The structural changes take place only if the option 'Allow library block to modify its contents' available on the Initialization pane is selected.
open_system('self_modifiable_mask_example');
Artificial Algebraic Loops
An artificial algebraic loop occurs when an atomic subsystem or Model block causes Simulink to detect an algebraic loop, even
though the contents of the subsystem do not contain a direct feedthrough from the input to the output. When you create an atomic
subsystem, all Inport blocks are direct feedthrough, resulting in an algebraic loop.
Start with the included model, which represents a simple proportional control of the plant described by
The system has neither algebraic variables nor direct feedthrough and does not contain an algebraic loop.
When simulating this model, an algebraic loop occurs because the subsystem is direct feedthrough, even though the path within the atomic subsystem is not direct
feedthrough. Simulation stops with an algebraic loop error.