© Apress 2015

Michael Paluszek and Stephanie Thomas, MATLAB Recipes, 10.1007/978-1-4842-0559-4_1

1. Coding Handbook

Michael Paluszek and Stephanie Thomas2

(1)Princeton, New Jersey, USA

(2)Princeton Junction, New Jersey, USA

Electronic supplementary material: The online version of this chapter (doi: 10.​1007/​978-1-4842-0559-4_​1) contains supplementary material, which is available to authorized users.

The purpose of this chapter is to provide an overview of MATLAB syntax and programming, highlighting features that may be underutilized by many users and noting important differences between MATLAB and other programming languages and integrated development environments (IDEs). You should also become familiar with the very detailed documentation that is available from MathWorks in the help browser. The “Language Fundamentals” section of the MathWorks web site describes entering commands, operators, and data types.

Over the last two decades, MATLAB has matured a lot from its origins as a linear algebra package. Originally, all variables were double-precision matrices. Today, MATLAB provides different variable types, such as integers, data structures, object-oriented programming and classes, and integration with Java. The MATLAB application is a full IDE with an integrated editor, debugger, command history, and code analyzer, and offering report capabilities. Engineers who have worked with MATLAB for many years may find that they are not taking advantage of the full range of capabilities now offered. In this text, we hope to highlight the more useful new features.

The first part of this chapter provides an overview of the most commonly used MATLAB types and constructs. We’ll then provide some recipes that make use of these constructs to show you some practical applications of modern MATLAB.

MATLAB Language Primer

A Brief Introduction to MATLAB

MATLAB is both an application and a programming language. It was developed primarily for numerical computing and it is widely used in academia and industry. MATLAB was originally developed by a college professor in the 1970s to provide easy access to linear algebra libraries. MathWorks was founded in 1984 to continue the development of the product. The name is derived from MATrix LABoratory . Today, MATLAB uses the LAPACK (Linear Algebra Package) libraries for the underlying matrix manipulations. Many toolboxes are available for different engineering disciplines; this book focuses on features available only in the base MATLAB application.

The MATLAB application is a rich development environment for the MATLAB language. It provides an editor, command terminal, debugger, plotting capabilities, creation of graphical user interfaces, and more recently, the ability to install third-party apps. MATLAB can interface with other languages, including Fortran, C, C++, Java, and Python. A code analyzer and profiler are built in. Extensive online communities provide forums for sharing code and asking questions.

The following are the main components of the MATLAB application:

  • Command Window The terminal for entering commands and operating on variables in the base workspace. The MATLAB prompt is > >.

  • Command History A list of previously executed commands.

  • Workspace display Lists the variables and their values in the current workspace (application memory). Variables remain in memory once created until you explicitly clear them or close MATLAB.

  • Current Folder The file browser displaying the contents of the current folder and providing file system navigation. Recent versions of MATLAB can also display the SVN status on configuration managed files.

  • File Details A panel displaying information on the file selected in the Current Folder panel.

  • Editor The editor for m-files with syntax coloring and a built-in debugger. It can also display any type of text file, and recognizes and appropriately colors other languages, including Java, C/C++, and XML/HTML.

  • Variables editor A spreadsheet-like graphical editor for variables in the workspace.

  • GUIDE The graphical interface development window.

  • Help browser A searchable help documentation on all MATLAB products and third-party products you have installed.

  • Profiler A tool for timing code as it runs.

These components can be docked in various configurations. The default layout of the main application window or desktop contains the first five components listed and is shown in Figure 1-1. The Command Window is in the center. The upper-left panel shows a file browser with the contents of the Current Folder. Under this is a file information display. On the right-hand side are the workspace display and the Command History panel. The base workspace is all the variables currently in application memory. Commands from the history can be double-clicked or dragged onto the command line to be executed. The extensive toolbar includes buttons for running the code analyzer, opening the code profiler, and the Help window, as well as typical file and data operations. Note the PLOTS and APPS tabs above the toolbar. The PLOTS tab allows the graphical creation and management of plots from data selected in the workspace browser. The APPS tab allows you to access and manage the third-party apps that you install.

A335353_1_En_1_Fig1_HTML.jpg
Figure 1-1. MATLAB desktop with the Command Window

The Editor with the default syntax coloring is shown in Figure 1-2 (you can see a file from this chapter). The horizontal lines show the division of the code into “cells” using a double-percent sign, which can be used for sequential execution of code and for creating sections of text when publishing. The cell titles are bolded in the editor. MATLAB keywords are highlighted in blue, comments in green, and strings in pink. The toolbar includes buttons for commenting code, indenting, and running or debugging the code. The Go To pop-up menu gives access to subfunctions within a large file. Note the PUBLISH and VIEW tabs with additional features on publishing (covered in the next chapter) and options for the editor view.

A335353_1_En_1_Fig2_HTML.jpg
Figure 1-2. MATLAB File Editor

The Help browser is shown in Figure 1-3. MATLAB offers extensive help, including examples and links to online videos and tutorials. Third-party toolboxes can also install help in this browser. Like any browser, you can open multiple tabs; there is a search utility; and you can mark favorite topics. Topics available in the help browser are referred to throughout this book.

A335353_1_En_1_Fig3_HTML.jpg
Figure 1-3. MATLAB Help Window

Everything Is a Matrix

By default, all variables in MATLAB are double-precision matrices. You do not need to declare a type for these variables. Matrices can be multidimensional and are accessed using 1-based indices via parentheses. You can address elements of a matrix using a single index, taken columnwise, or one index per dimension. To create a matrix variable, simply assign a value to it, like this 2 × 2 matrix a:

>> a = [1 2; 3 4];

>> a(1,1)

1

>> a(3)

2

You can simply add, subtract, multiply, and divide matrices with no special syntax. The matrices must be the correct size for the linear algebra operation requested. A transpose is indicated using a single quote suffix, ', and the matrix power uses the operator ^.

>> b = a'*a;

>> c = a^2;

>> d = b + c;

By default, every variable is a numerical variable. You can initialize matrices to a given size using the zeros, ones, eye, or rand functions, which produce zeros, ones, identity matrices (ones on the diagonal), and random numbers, respectively. Use isnumeric to identify numeric variables. Table 1-1 shows a selection of key matrix functions.

Table 1-1. Key Functions for Matrices

Function

Purpose

zeros

Initialize a matrix to zeros

ones

Initialize a matrix to ones

eye

Initialize an identity matrix

rand, randn

Initialize a matrix of random numbers

isnumeric

Identify a matrix or scalar numeric value

isscalar

Identify a scalar value (a 1 × 1 matrix)

size

Return the size of the matrix

Strings Are Simple

String and character variables are defined using single quotes. They can be concatenated using the same syntax as matrices, namely, square brackets. They are indexed the same way as matrices. Here is a short example of string manipulation:

>> s = 'Hello⊔World' ;

>> msg = [s 'more⊔string'];

>> hello = msg(1:5)

hello =

Hello

Use ischar to identify string variables. Also note that isempty returns true for an empty string; that is, ''.

For a description of string syntax, type help strings at the MATLAB command line, and for a comprehensive list of string functions, type help strfun. Table 1-2 shows a selection of key string functions.

Table 1-2. Key Functions for Strings

Function

Purpose

ischar

Identify a character string

char

Convert integer codes or cell array to character string

sprintf

Write formatted data to a string

strcmp, strncmp

Compare strings

strfind

Find one string within another

num2str, mat2str

Convert a number or matrix to a string

lower

Convert a string to lowercase

Use Strict Data Structures

Data structures in MATLAB are highly flexible, leaving it up to the user to enforce consistency in fields and types. You are not required to initialize a data structure before assigning fields to it, but it is a good idea to do so, especially in scripts, to avoid variable conflicts.

Replace

d.fieldName = 0;

with

d = struct;

d.fieldName = 0;

In fact, we have found that it is generally a good idea to create a special function to initialize larger structures that are used throughout a set of functions. This is similar to creating a class definition. Generating your data structure from a function, instead of typing out the fields in a script, means that you always start with the correct fields. Having an initialization function also allows you to specify the types of variables and provide sample or default data. Remember, since MATLAB does not require you to declare variable types, doing so yourself with default data makes your code that much clearer.

Tip Create an initialization function for data structures.

You make a data structure into an array simply by assigning an additional copy. The fields must be in the same order, which is yet another reason to use a function to initialize your structure. You can nest data structures with no limit on depth.

d = MyStruct;

d(2) = MyStruct;

function d = MyStruct

d = struct;

d.a = 1.0;

d.b = 'string';

MATLAB now allows dynamic field namesusing variables; for example, structName.(dynamicExpression). This provides improved performance over getfield, where the field name is passed as a string. This allows all sorts of inventive structure programming. Take our data structure array in the previous code snippet to get the values of field a using a dynamic field name; the values are returned in a cell array.

>> field = 'a';

>> values = {d.(field)}

values =

[1] [1]

Use isstruct to identify structure variables and isfield to check for the existence of fields. Note that isempty will return false for a struct initialized with struct, even if it has no fields. Table 1-3 shows a selection of key struct functions.

Table 1-3. Key Functions for Structs

Function

Purpose

struct

Initialize a structure with or without fields

isstruct

Identify a structure

isfield

Determine if a field exists in a structure

fieldnames

Get the fields of a structure in a cell array

rmfield

Remove a field from a structure

deal

Set fields in a structure to a value

Cell Arrays Hold Anything and Everything

One variable type unique to MATLAB is cell arrays. This is really a list container, and you can store variables of any type in elements of a cell array. Cell arrays can be multidimensional, just like matrices, and are useful in many contexts.

Cell arrays are indicated by curly braces, {}. They can be of any dimension and contain any data, including string, structures, and objects. You can initialize them using the cell function, recursively display the contents using celldisp, and access subsets using parentheses, just like with a matrix. The following is a short example.

>> c = cell(3,1);

>> c{1} = 'string';

>> c{2} = false;

>> c{3} = [1 2; 3 4];

>> b = c(1:2);

>> celldisp(b)

b{1} =

string

b{2} =

0

Using curly braces for access gives you the element data as the underlying type. When you access elements of a cell array using parentheses, the contents are returned as another cell array, rather than the cell contents. MATLAB help has a special “Comma-Separated Lists” section, which highlights the use of cell arrays as lists. The code analyzer also suggests efficient ways to use cell arrays. Take the following, for instance.

Replace

a = {b{:} c};

with

a = [b {c}];

Cell arrays are especially useful for sets of strings, with many of MATLAB’s string search functions optimized for cell arrays, such as strcmp.

Use iscell to identify cell array variables. Use deal to manipulate structure array and cell array contents. Table 1-4 shows a selection of key cell array functions.

Table 1-4. Key Functions for Cell Arrays

Function

Purpose

cell

Initialize a cell array

cellstr

Create cell array from a character array

iscell

Identify a cell array

iscellstr

Identify a cell array containing only strings

celldisp

Recursively display the contents of a cell array

Optimize Your Code with Logical Arrays

A logical array is composed of only ones and zeros. You can initialize logical matrices using the true and false functions, and there is an islogical function to test if a matrix is logical. Logical arrays are outputs of numerous built-in functions, like isnan, and are often recommended by the code analyzer as a faster alternative to manipulating array indices. For example, you may need to set any negative values in your array to zero.

Replace

k = find (x<0);

x(k) = 0;

with

x(x<0) = 0;

where x<0 produces a logical array with 1, where the values of x are negative and 0 elsewhere.

MATLAB provides both traditional relational operators, such as && for AND and || for OR, as well as unique element-wise operators. These element-wise operators, such as single & and |, compare matrices of the same size and return logical arrays.

Use Persistent and Global Scope to Minimize Data Passing

In general, variables defined in a function have a local scope and are only available within that function. Variables defined in a script are available in the workspace and, therefore, from the command line.

MATLAB has a global scope, which is the same as any other language, applying to the base workspace and maintaining the variable’s value throughout the MATLAB session. Global variables are empty once declared, until initialized. The clear and clearvars functions each have flags for removing only the global variables.

>> global MY_GLOBAL_VAR; % variable is empty

>> MY_GLOBAL_VAR = 1.0;

>> whos

Name Size Bytes Class Attributes

MY_GLOBAL_VAR 1x1 8 double global

>> clearvars -GLOBAL

Table 1-5 shows some key functions for logical operations.

Table 1-5. Key Functions for Logical Operations

Function

Purpose

logical

Convert numeric values to logical

islogical

Identify a logical array (composed of 1 s and 0 s)

true

Return a true value (1) or array (M,N)

false

Return a false value (0) or array (M,N)

any

Return true if any value in the array is a nonzero number

all

Return true if none of the values in the array is 0

and, or

Functional forms of element-wise operators & and |

isnan, isinf, isfinite

Values testing functions returning logical arrays

MATLAB has a unique scope that pertains to a single function, persistent. This is useful for initializing a function that requires a lot of data or computation, and then saving that data for use in later calls. The variable can be reset using the clear command on the function, such as clear functionName. This can also be a source of bugs, thus it is important to note the use of persistent variables in a function’s help comments so that you don’t get unexpected results when you switch models.

Tip Use a persistent variable to store initialization data for subsequent function calls.

Variables can also be in scope for multiple functions defined in a single file, if the end keyword is used appropriately. In general, you can omit a final end for functions, but if you use it to wrap the inner functions, the functions become nested and can access variables defined in the parent function. This allows subroutines to share data without passing large numbers of arguments. The editor highlights the variables that are so defined.

In the following example, the constant variable is available to the nested function inside the parent function.

NESTED FUNCTION

function y = parentFunction( x )

constant = 3.0;

y = nestedFunction( x );

function z = nestedFunction( x )

z = constant *x;

end

end

Table 1-6 shows a selection of scope functions.

Table 1-6. Key Functions for Scope Operations

Function

Purpose

persistent

Specify the persistent scope for a variable in a function

global

Specify the global scope for a variable

clear

Clear a function or variable

who, whos

List the variables in a workspace

mlock, munlock

Lock (and unlock) a function or MEX file that prevents it from being cleared

Understanding Unique MATLAB Operators and Keywords

Some common operators have special features in MATLAB, which we call attention to here.

Colon

The colon operator for creating a list of indices in an array is unique to MATLAB. A single colon used by itself addresses all elements in that given dimension; a colon used between a pair of integers creates a list.

>> a(1,1:2)

ans =

1 2

>> a(:,1)

ans =

1

3

The colon operator applies to all variable types when accessing elements of an array: cell arrays, strings, and data structure arrays.

The colon operator can also be used to create an array using an interval, as a shorthand for linspace. The interval and the endpoints can be doubles. Using it for matrix indices is really an edge case using a default interval of 1. For example, 0.1:0.2:0.5 produces 0.1 0.3 0.5.

>> a = 0.1:0.2:0.5

a =

0.1 0.3 0.5

Tilde

The tilde () is the logical NOT operator in MATLAB. The output is a logical matrix of the same size as the input, with values of 1 if the input value is zero and a value of 0 otherwise.

>> a = [0 -1; 1 0];

>> ∼a

ans =

1 0

0 1

In newer versions, it also can be used to ignore an input or output to a function; this is suggested often in the code analyzer as preferable to the use of a dummy variable.

[∼,b] = MyFunction(x,y);

Dot

By dot, we mean using a period with standard arithmetic operators, like .* or . or .^. This is special syntax in MATLAB used to apply an operator on an element per element basis over the matrices, instead of performing the linear algebra operation otherwise implied. This is also termed an array operation as opposed to a matrix operation. Since the matrix and array operations are the same for addition and subtraction, the dot is not required.

y = a.*b;

MATLAB is optimized for array operations. Using this syntax is a key way to reduce for loops in your MATLAB code and make it run faster. Consider the traditional alternative code.

a = rand (1,1000);

b = rand (1,1000);

y = zeros (1,1000);

for k = 1:1000

y(k) = a(k)*b(k);

end

Even this simple example takes two to three times as long to run as the vectorized version shown.

end

The end keyword serves multiple purposes in MATLAB. It is used to terminate for, while, switch, try, and if statements, rather than using braces, as in other languages. It is also used to serve as the last index of a variable in a given dimension. Using end appropriately can make your code more robust to future changes in the size of your data.

>> a = [1 2 3; 4 5 6; 7 8 9];

>> b = a(1: end-1,2: end)

b =

2 3

5 6

Harnessing the Power of Multiple Inputs and Outputs

Uniquely, MATLAB functions can have multiple outputs. They are specified in a comma-separated list, just like the inputs. Additionally, you do not need to specify the data types of the inputs or outputs, and you can silently override the output types by assigning any data you want to the variables. Thus, a function can have an infinite number of syntaxes defined within a single file. Outputs must be assigned the names given in the signature; you cannot pass a variable to the return keyword.

MATLAB provides helper functions for specifying a variable number of inputs or outputs, namely, varargin and varargout. These variables are cell arrays, and you access and assign elements using curly braces. Here is an example function definition:

function [y,varargout] = varargFunction(x,varargin)

y = varargin{1};

varargout{1} = size (x,1);

varargout{2} = size (x,2);

The following example demonstrates that the outputs were correctly assigned.

USING VARARGOUT AND VARARGIN

>> [y,a,b] = varargFunction( rand(3,2),1.0)

y =

1

a =

3

b =

2

This allows you to accept unlimited arguments or parameter pairs in your function. It is up to you to create consistent forms for your function and document them clearly in the help comments.

You can also count the input and output arguments for a given call to your function using nargin and nargout, and use this with logical statements or a switch statement to handle multiple cases.

If you need very complex input handling, MATLAB now provides an inputParser class, which allows you to parse and validate an input scheme. You can define functions to validate the inputs, optional arguments, and predefine parameter pairs.

Use Function Handles for Efficiency

Function handles are pointers to functions. They are closely related to anonymous functions, which allow you to define a short function inline, and return the function handle. When you create a handle, you can change the input scheme and give values for certain inputs, such as parameters. Using handles as inputs to integrators and similar routines is much faster than passing in a string variable of the function name.

In the following snippet, we created an anonymous function handle to myFunction with a different signature and a specific value for a. Note the use of the ampersand, which designates a function handle. The handle can be evaluated with inputs, just like a regular function.

function y = myFunction(a, b, c)

...

a = 2;

h = @(c,b) myFunction(a,b,c);

y = h(c,b);

The handle h can be passed to a function such as an integrator that is expecting a signature with only two variables. You will also commonly use function handles to specify an events function for integrators or similar tools, as well as output functions that are called between major steps. Output functions can print information to the screen or a figure; for example, odeplot and odeprint.

In order to test if a variable is a function handle, you need to use the function handle class name with isa, for example:

isa(f,'function_handle')

ishandle works only for graphics handles. For more information, see the help documentation for function_handle. Table 1-7 provides the few key functions for dealing with function handles.

Table 1-7. Key Functions for Handles

Function

Purpose

feval

Execute a function from a handle or string

func2str

Construct a string from a function handle

str2func

Construct a handle from a function name string

isa

Test for a function handle

Advanced Data Types

The data types discussed so far are all that are needed for most engineering programming. However, for specialized applications, there are additional options for data types, including the following.

  • Classes Classes, with properties and methods, can be defined using the classdef keyword in an m-file similar to writing a function. See also the properties, methods, and events keywords.

  • Tables Tables are new to release R2013 of MATLAB and allow tabular data to be stored with metadata in one variable. It is an effective way to store and interact with data that one might put in a spreadsheet. The table columns can be named, assigned units and descriptions, and accessed as one would fields in a data structure, such as T.DataName. See the function readtable on creating a table from a file.

  • Categorical Arrays Arrays of data from a discrete set of categories (an enumeration) can be stored in this special type, which provides more efficient searching than elements of a cell array. See categorical and categories.

  • Time Series The timeseries object and the related tscollection object provide methods for associating data samples with timestamps. Plotting a timeseries object uses the stored time vector automatically.

  • Map Containers The map container allows you to store and look up data using a key that may be nonnumeric. This is an object instantiated via containers.Map.

The MATLAB documentation is thorough, should you find these data types advantageous to your application.

Primer Recipes

The next part of this chapter provides recipes for some common tasks in modern MATLAB, like adding help to your functions, loading binary data, writing to a text file, creating a MEX file, and parsing functions into “pcode.”

1.1 Creating Function Help

Problem

You need to document your functions so that others may use them and so that you remember how they work.

Solution

MATLAB provides a mechanism for providing command-line access to documentation about your function or script using the help command, if you put the documentation in the right place.

How It Works

The comments you provide at the top of your function file, called a header, become the function help. The help can be printed at the command line by typing help MyFunction. Whereas the style and format of these comments are covered in the next chapter, your attention is drawn to the functionality here.

The help comments can go either above or below the declarative line of your function. If you include the words “see also” in your comments, followed by the names of additional functions, MATLAB helpfully supplies links to those functions’ help. All comments are printed until the first blank line is reached.

Consider the help for a function that calculates a dot product. The first line should be a single sentence description of the function, which is utilized by lookfor. If you insert your function name in all capital letters, MATLAB automatically replaces it with the true case version when printing the help. Your comments might look like this:

function d = Dot( w, y )

%% DOT Dot product of two arrays.

%% Forms

% d = Dot( w, y )

% d = Dot( w )

%

%% Description

% Dot product with support for arrays. The number of columns of w and y can be:

%

% * Both > 1 and equal

% * One can have one column and the other any number of columns

%

% If there is only one input the dot product will be taken with itself.

%

%% See also

% Cross

When printed to the command line, MATLAB removes the percent signs and just displays the text, like this:

>> help Dot

Dot Dot product of two arrays.

% Forms

d = Dot ( w, y )

d = Dot ( w )

% Description

Dot product with support for arrays. The number of columns of w and y can be:

* Both > 1 and equal

* One can have one column and the other any number of columns

If there is only one input the dot product will be taken with itself.

% See also

Cross

You can link to additional help documentation attached to subfunctions in your file. This can be handy for providing more detailed examples or descriptions of algorithms. In order to do so, you have to embed an HTML link in your help comments. For example:

% More detailed help is in the <a href="matlab: help foo>extended_help">extended help

</a>.

function extended_help

%EXTENDED_HELP Additional technical details and examples

%

% Describe additional details of your algorithms or provide examples.

error ('Thisisaplaceholderfunctionjustforhelptext');

This type sets in the Command Window as

More detailed information is in the extended help.

MATLAB also provides the capability for you to create HTML help for your functions that will appear in the help browser. This requires the creation of XML files to provide the contents hierarchy. See the MATLAB help topic “Display Custom Documentation” and the related recipe in the next chapter.

You can also run help reports to identify functions that are missing help or missing certain sections of help, such as a copyright notice. To learn how to launch this report on your operating system, see the MathWorks “Check Which Programs Have Help” help topic.

1.2 Locating Directories for Data Storage

Problem

A variety of demos and functions in your toolbox generate data files and they end up all over your file system. You can’t use an absolute path on your computer because the code is shared among multiple engineers.

Solution

Use mfilename to save files in the same location as the generating file or to locate a dedicated data directory that is relative to your file location.

How It Works

It’s easy to sprinkle save commands throughout your scripts, or print figures to image files, and end up with files spread all over your file system. MATLAB provides a handy function, mfilename, which can provide the path to the folder of the executing m-file. You can use this to locate a data folder dedicated to either input files or output files for your routine. This uses the MATLAB functions fileparts and fullfile.

For example, to save an output mat-file in the same location as your function or script:

thisPath = mfilename('fullpath');

thisDir = fileparts(thisPath);

save ( fullfile(thisDir,'fileName'),x,y);

To save output to a dedicated directory, you only need an additional call to fileparts. In this case, the directory is called DataDir.

thisPath = mfilename('fullpath');

prevDir = fileparts(fileparts(thisPath));

dataDir = fullfile(prevDir,'DataDir','fileName');

save ( fullfile(dataDir,'fileName'),x,y);

If you are printing images, you can either use the functional form of print, as with save, or change the path to the directory you want. You should save the current directory and return there when your script is complete.

thisPath = mfilename('fullpath');

cd0 = cd;

cd ( fileparts(thisPath));

print -dpng MyFigure

cd (cd0)

Table 1-8 shows key functions for path operations.

Table 1-8. Key Functions for Path Operations

Function

Purpose

mfilename

The name, and optionally, the full path to the currently executing m-file

fileparts

Divide a path into parts (directory, file name, extension)

fullfile

Create a system-dependent file name from parts

cd

The current directory

path

The current MATLAB path

1.3 Loading Binary Data from a File

Problem

You need to store data in a binary file, perhaps for input to another software program.

Solution

MATLAB provides low-level utilities for creating and writing to binary files, including specifying the endianness.

How It Works

Reading and writing binary data introduces some complexities beyond text files. Let’s start with MATLAB’s example of creating a binary file of a magic square. This demonstrates fopen, fwrite, and fread. The options for precision are specified in the help for fread. For example, a 32-bit integer can be specified with the MATLAB-style string 'int32' or the C-style string 'integer*4'.

>> magic(4)

ans =

16 2 3 13

5 11 10 8

9 7 6 12

4 14 15 1

>> fid = fopen('magic4.bin','wb');

>> fwrite(fid,magic(4),'integer*4');

>> fclose(fid);

Now, let’s try to read this data file back in. Since the data was stored as 32-bit integers, you have to specify this precision to get the data back.

>> fid = fopen('magic4.bin','rb');

>> c = fread(fid,inf,'integer*4')

c =

16

5

9

4

2

11

7

14

3

10

6

15

13

8

12

1

The shape of the matrix was not preserved, but you can see that the data was printed to the file in columnwise order. To fully re-create the data, you need to reshape the matrix.

>> data = reshape(c,5,5)

data =

16 2 3 13

5 11 10 8

9 7 6 12

4 14 15 1

If you need to specify the endianness of the data, you can so do in both fopen and fread. The local machine format is used by default, but you can specify the IEEE floating point with a little endian byte ordering, the same with big ending ordering, and both with 64-bit long data type. This may be important if you are using binary data from an online source or using data on embedded processors.

For example, to write the same data in a big endian format, simply add the 'ieee-be' parameter.

>> fid = fopen('magic5.bin','wb','ieee-be');

>> fwrite(fid,magic(5),'integer*4');

>> fclose(fid);

Table 1-9 lists key functions for interacting with binary data.

Table 1-9. Key Functions for Binary Data

Function

Purpose

fopen

Open a file in text or binary mode

fwrite

Write to a file

fread

Read the contents of a file

fclose

Close the file

1.4 Command-Line File Interaction

Problem

You have some unexpected behavior when you try to run a MATLAB script and you suspect a function conflict among different toolboxes.

Solution

MATLAB provides functions for locating and managing files and paths from the command line.

How It Works

MATLAB has a file browser built in to the command window, but it is still helpful to be familiar with the commands for locating and managing files from the command line. In particular, if you have a lot of toolboxes and files in your path, you may need to identify name conflicts.

For example, if you get the wrong behavior or a strange error from a function and you recently changed your path, you may have a file shadowing it in your path. To check for duplicate copies of a function name, use which with the -all switch. Shadowed versions of the function are marked. which can take a partial pathname.

>> which DemoPSS –all

/Users/.../Toolboxes/Missions/Demos/DemoPSS.m

/Users/.../Toolboxes/Math/Demos/DemoPSS.m % Shadowed

/Users/.../Toolboxes/Imaging/Demos/DemoPSS.m % Shadowed

/Users/.../Toolboxes/Common/Demos/DemoPSS.m % Shadowed

To display the contents of a file at the command line, which is helpful if you need to see something in the file but don’t need to open the file for editing, use type, as in Unix.

To list the contents of a directory, use what. A partial path can be used if there are multiple directories with the same name on your path. Specifying an output returns the results in a data structure array. MATLAB identifies which files are code, mat-files, p-files, and so forth. what is recursive and returns all directories with the given name anywhere in the path—useful if you use the same name of a directory for functions and demos, as follows.

>> what Database

MATLAB Code files in folder /Users/Shared/svn/Toolboxes/SourceCode/Core/Common/Demos/

Database

Contents TConstant

MATLAB Code files in folder /Users/Shared/svn/Toolboxes/SourceCode/Core/Common/

Database

BuildConstant Contents MergeConstantDB

Constant Database

Use exist to determine if a function or variable exists in the path or workspace. The code analyzer will prompt you to use the syntax with a second argument specifying the desired type, such as 'var', 'file', or 'dir'. The output is a numerical code indicating the type of file or variable found.

Open a file in the editor from the command line using edit.

Load a mat-file or ASCII file using load. Give an output to store the data in a variable, or else it will be loaded directly into the workspace. For mat-files, you can also specify particular variables to load.

d = load ('MyMatFile','var1','var2');

The final command-line function introduced is lookfor. This function searches for a keyword through all help available on the MATLAB path. The keyword must appear in the first line of the help, such as the one-line help comment or H1 line. The printed result looks like a Contents file and includes links to the help for the found functions. Here is an example for the keyword integration.

>> lookfor integration

IntegrationAccuracyDemo - Integration Accuracy for PropagateOrbitPlugin.

PropagatorComparison - Integration accuracy study comparing RK4, RK45, and ode113.

lotkademo - Numerical Integration of Differential Equations

cumtrapz - Cumulative trapezoidal numerical integration.

trapz - Trapezoidal numerical integration.

Table 1-10 lists key functions to use at the command line.

Table 1-10. Key Functions for Command-Line Interaction

Function

Purpose

which

The location of a function in the path

what

List the MATLAB-specific files in directory

type

Display the contents of a file

dbtype

Display the contents of a file with line numbers

exist

Determine if a function or variable exists

edit

Open a file in the editor

load

Load a mat-file into the workspace

lookfor

Search help comments in the path for a keyword

1.5 Using a MEX File to Link to an External Library

Problem

There is an external C++ library that you need to use for an application. You would like to perform the analysis in MATLAB.

Solution

You can write and compile a special function in MATLAB using the C/C++ matrix API that allows you to call the external library functions via a MATLAB function. This is called a MEX file.

How It Works

A mex function is actually a shared library compiled from C/C++ or Fortran source code, and is callable from MATLAB. It can be used to link to external libraries such as GLPK, BLAS, and LAPACK. When writing a mex function, you provide a gateway routine mexFunction in your code, and use MATLAB’s C/C++ Matrix Library API. You must have a MATLAB-supported compiler installed on your machine.

#include "mex.h"

void mexFunction ( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

You can see that, as with regular MATLAB functions, you can provide multiple inputs and multiple outputs. mxArray is a C language type, actually the fundamental data type for all matrices in MATLAB, provided by the MATLAB API.

You use the mex function to compile your C, C++, for Fortran function into a binary. Passing the verbose flag, -v, provides verbose output familiar to C programmers. An extension such as 'mexmaci64', as determined on your system by mexext, is appended and you can then call the function from MATLAB like any other m-file. For example, on the Mac, MATLAB detects and uses Xcode automatically when compiling one of the built-in examples, yprime.c. This function solves simple three-body orbit problems. First, you need to copy the example into a local working directory.

>> copyfile(fullfile( matlabroot ,'extern','examples','mex','yprime.c'),'.','f');

The following are excerpts from the verbose compile.

>> mex -v -compatibleArrayDims yprime.c

Verbose mode is on.

No MEX options file identified; looking for an implicit selection.

... Looking for compiler 'XcodewithClang' ...

... Looking for environment variable 'DEVELOPER_DIR' ...No.

... Executing command 'xcode-select-print-path' ...Yes ('/Applications/Xcode.app/

Contents/Developer').

... Looking for folder '/Applications/Xcode.app/Contents/Developer' ...Yes.

... Executing command 'whichxcrun' ...Yes ('/usr/bin/xcrun').

... Looking for folder '/usr/bin' ...Yes.

...

Found installed compiler 'Xcode withClang'.

--------------------------------------------------------

Compiler location: /Applications/Xcode.app/Contents/Developer

Options file: /Applications/MATLAB_R2014b.app/bin/maci64/mexopts/clang_maci64.xml

CC : /usr/bin/xcrun -sdk macosx10.9 clang

DEFINES : -DMX_COMPAT_32 -DMATLAB_MEX_FILE

MATLABMEX : -DMATLAB_MEX_FILE

CFLAGS : -fno-common -arch x86_64 -mmacosx- version-min =10.9 -fexceptions -

isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.

platform/Developer/SDKs/MacOSX10.9.sdk

INCLUDE : -I"/Applications/MATLAB_R2014b.app/extern/include" -I"/Applications/

MATLAB_R2014b.app/simulink/include"

COPTIMFLAGS : -O2 –DNDEBUG

LD : /usr/bin/xcrun -sdk macosx10.9 clang

LDFLAGS : -Wl,-twolevel_namespace -undefined error -arch x86_64 -mmacosx-

version-min =10.9 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer

/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -bundle -Wl,-

exported_symbols_list,"/Applications/MATLAB_R2014b.app/extern/lib/maci64/

mexFunction .map"

LDBUNDLE : -bundle

LINKEXPORT : -Wl,-exported_symbols_list,"/Applications/MATLAB_R2014b.app/

extern/lib/maci64/ mexFunction .map"

LINKLIBS : -L"/Applications/MATLAB_R2014b.app/bin/maci64" -lmx -lmex -lmat -

lstdc++

OBJEXT : .o

LDEXT : .mexmaci64

----------------------------------------------------

Building with 'XcodewithClang'.

/usr/bin/xcrun -sdk macosx10.9 clang -c -DMX_COMPAT_32 -DMATLAB_MEX_FILE -I"/

Applications/MATLAB_R2014b.app/extern/include" -I"/Applications/MATLAB_R2014b.app/

simulink/include" -fno-common -arch x86_64 -mmacosx- version-min =10.9 -fexceptions -

isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/

Developer/SDKs/MacOSX10.9.sdk -O2 -DNDEBUG /Users/Shared/svn/Manuals/

MATLABCookbook/MATLAB/yprime.c -o /var/folders/22/l715021s5rnghdtkxsy_cbk40000gp/T//

mex_47653762085718_983/yprime.o

/usr/bin/xcrun -sdk macosx10.9 clang -Wl,-twolevel_namespace -undefined error -arch

x86_64 -mmacosx- version-min =10.9 -Wl,-syslibroot,/Applications/Xcode.app/Contents/

Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -bundle -Wl,-

exported_symbols_list,"/Applications/MATLAB_R2014b.app/extern/lib/maci64/

mexFunction .map" /var/folders/22/l715021s5rnghdtkxsy_cbk40000gp/T//

mex_47653762085718_983/yprime.o -O -Wl,-exported_symbols_list,"/Applications/

MATLAB_R2014b.app/extern/lib/maci64/ mexFunction .map" -L"/Applications/

MATLAB_R2014b.app/bin/maci64" -lmx -lmex -lmat -lstdc++ -o yprime.mexmaci64

rm -f /var/folders/22/l715021s5rnghdtkxsy_cbk40000gp/T//mex_47653762085718_983/yprime.o

MEX completed successfully.

Now, assuming that you copied the source into an empty directory, if you now print the contents, you will see something like the following:

>> dir

. .. yprime.c yprime.mexmaci64

And you can run a test of the compiled library.

>> T = 0;

>> Y = rand (1,4);

>> yprime(T,Y)

Writing MEX files is not for the faint of heart and requires substantial programming knowledge in the base language. In the preceding printout, you can see that the standard C++ library is included, but you need to provide links and includes explicitly to other libraries that you want to use. Note that your MEX file will not have any function help, so it is a good idea to provide a companion m-file that supplies the help comments and calls your mex function internally.

Tip

Provide a separate m-file with your MEX file that contains help comments, and optionally, calls the MEX file.

See the help articles, including “Components of MEX File” in MATLAB, as well as the many examples for help writing MEX files. In the case of GLPK (GNU Linear Programming Kit), an excellent MEX file is available under the GNU public license. It was written by Nicolo Giorgetti and is maintained by Niels Klitgord. It is now available on SourceForge at http://glpkmex.sourceforge.net .

1.6 Protect Your IP with Parsed Files

Problem

You want to share files with customers or collaborators without compromising your intellectual property in the source code.

Solution

Create protected versions of your functions using MATLAB’s pcode function. Create a separate file with the help comments so that users have access to the documentation.

How It Works

The pcode function provides a capability to parse m-files into executable files with the content obscured. This can be used to distribute your software while protecting your intellectual property. A pcoded file on your path with a “p” extension, takes precedence over an m-file of the same name. Parsing an m-file is simple:

>> pcode Dot

The only argument available is the -INPLACE flag to store the p-file in the same directory as the source m-file; otherwise, it is saved to the current directory.

One difficulty you may encounter is that once you have parsed your functions and moved them into a new folder, you no longer have access to the function help you created. The command-line help is not implemented for pcoded files and typing “help MyFunction” no longer works. You have to create a separate m-file with the help comments, as with MEX files. You can write a function to extract the header from an m-file and save it. You will use fprintf for this, so it’s important that the header not contain any special characters like backslashes.

function ParseAndSaveHeader( readFromFile, writeToFile )

filePath = which (readFromFile);

[pathStr,name,ext] = fileparts(filePath);

copyfile (filePath, fullfile(pathStr,[name,'_orig',ext]));

fid = fopen (filePath,'rt');

t = fgetl (fid);

hlp = ";

while ( ˜ isempty (t) && strcmp (t(1),'%') )

if length (t)>1 && strcmp (t(2),'%')

t = ['%' t];

end

hlp = [hlp,' %',t];

t = fgetl (fid);

if ( ˜ischar(t) )

break ;

end

end

hlp = [hlp,' %% %%Thisfunctionwasparsedon', date ,' '];

fclose (fid);

if ischar(writeToFile)

fid = fopen (writeToFile,'wt');

else

fid = writeToFile;

end

fprintf (fid,hlp);

if ischar(writeToFile)

fclose (fid);

end

pcode(filePath);

You save a copy of the m-file with the _orig suffix to prevent unpleasant mistakes with deleted files. Note that you add a final comment at the end with the date that the function was parsed.

1.7 Writing to a Text File

Problem

You need to write some information from MATLAB to a text file. One example is creating a template for new functions following a preferred format.

Solution

You use fopen, fprintf, and fclose to open a new text file, print desired lines to it, and then close it. The input function is used to allow the user to enter a one-line summary of the function.

How It Works

MATLAB has a full set of functions for input and output, including writing to files. See help iofun for a detailed listing. You can write to text files, spreadsheets, binary files, XML, images, or zip files.

One useful example is creating a template for new functions for your company, following your preferred header format. This requires using fopen and fclose, and fprintf to print the lines to the file. The first input is the desired name of the new function. Note that fprintf prints to the command line if given a file ID of 1. You are provided an option to do so with the second input, which is a boolean flag. You use the date function to get the current year for the copyright notice, which returns a string in the format ‘dd-mmm-yyyy’; you use the string function strsplit to break the string into tokens. Using string indices would be an alternative. In addition, this demonstrates using input to prompt the user for a string, namely, a one-line description of the new function.

%% NEWBOOKFILE Create a new function with the default header style.

% Pass in a file name and the header template will be printed to that file

% in the current directory. You will be asked to enter a one-line summary.

%% Forms:

% NewBookFile( fName, outputIsFile )

%% Input

% fName (1,1) File name

% outputIsFile (1,1) True if a file is created, otherwise header is

% printed to the command line.

%% Output

% None.

function NewBookFile( fName, outputIsFile )

if ( nargin < 2)

outputIsFile = false;

end

if ( nargin == 0 || isempty (fName))

fName = input ('Functionname:','s');

end

% Check if the filename is valid and if such a function already exists.

if (˜isvarname(fName))

error ('Book:error','invalid name');

end

if (outputIsFile && exist (fName,'file'))

error ('Book:error','file%salreadyexists',fName);

end

% Get a one-line description (H1 line) from the user.

comment = input ('One-linedescription:','s');

% Open the file or specify command line output.

if (outputIsFile)

fid = fopen ([fName '.m'],'wt');

c = onCleanup(@() fclose (fid));

else

fid = 1;

fprintf (fid,' ');

end

% Write the header to the file. Use the current year for the copyright

% notice.

fprintf (fid,'%%%%%s%s ', upper (fName),comment);

fprintf (fid,'%%Description. ');

fprintf (fid,'%%%%Forms ');

fprintf (fid,'%%⊔⊔y⊔=⊔%s(x) ',fName);

fprintf (fid,'%%%%Input ');

fprintf (fid,'%%⊔⊔⊔x⊔⊔⊔(1,1)⊔⊔⊔⊔Description %% ');

fprintf (fid,'%%%%Output ');

fprintf (fid,'%%⊔⊔⊔y⊔⊔⊔(1,1)⊔⊔⊔⊔Description %% ');

fprintf (fid,'%%%%Reference ');

fprintf (fid,'%%Insertthereference. ');

fprintf (fid,'%%%%Seealso ');

fprintf (fid,'%%Listpertinentfunctions. ');

today = strsplit(date ,'-');

year = today{ end };

fprintf (fid,'%%%% Copyright ');

fprintf (fid,'%%Copyright⊔⊔(c)%s PrincetonSatelliteSystems,Inc. %%Allrights

reserved. ',year);

fprintf (fid,' functiony⊔=⊔%s(x) ',fName);

if outputIsFile

edit (fName);

end

Note that this function checks for two errors: a bad function name and a function with the same name already exists on the path. You use the two-input form of error where the first input is a message identifier. The message identifier is useful if an error is returned from a catch block. The message identifier can be verified using lasterr. For instance, if you fail to enter a valid function name when prompted, you can see the results of the first error.

>> NewBookFile([])

Function name:

Error using NewBookFile (line 29)

invalid name

>> [LASTMSG, LASTID] = lasterr

LASTMSG =

Error using NewBookFile (line 29)

invalid name

LASTID =

Book:error

The function includes the ability to print the header to the command window, instead of creating a file, which is useful for testing, or if you went ahead and started with a blank file and need to add a header after the fact. This is accomplished by using 1 for the file identifier. This is what the header looks like:

>> NewBookFile('Test')

One-line description: This is a test function.

%% TEST This is a test function.

% Description.

%% Forms

% y = Test( x )

%% Input

% x (1,1) Description

%

%% Output

% y (1,1) Description

%

%% Reference

% Insert the reference.

%% See also

% List pertinent functions.

%% Copyright

% Copyright (c) 2015 Princeton Satellite Systems, Inc.

% All rights reserved.

function y = Test(x)

Table 1-11 summarizes some key functions for interacting with text files.

Table 1-11. Key Functions for Interacting with Text Files

Function

Purpose

fprintf

Print formatted text to a file

strsplit

Split a string into tokens using a delimited

fgetl

Get one line of a file (until a newline character)

input

Get string input from the user via the command line

Summary

This chapter reviewed basic syntax for MATLAB programming. It highlighted differences between MATLAB and similar languages, like C and C++, in the language primer. Recipes give tips for efficient usage of key features, including writing to binary and text files. Tables at the end of each section highlight key functions you should have at your fingertips.

This chapter did not provide any information on using MATLAB’s computational tools, like integration and numerical search, as those are covered in the applications chapter. Interacting with MATLAB graphics is also covered a later chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.63.5