Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Good Matlab programming practices

31 views
Skip to first unread message

Michael Robbins

unread,
Mar 20, 2000, 3:00:00 AM3/20/00
to
Please help me develop a list of good Matlab programming
practices. I am not a professional programmer and I'd like to
develop a standard for my team. I'll start with some things I
think I know:

1. Use structures instead of globals; pass the structures to and
from functions. This keeps the functions modular and the
variables obvious. It also helps organize the variables.

2. Use structures of arrays, not arrays of structures. Arrays of
structures are slow. Avoid DEAL, it's often slow.

3. Avoid EVAL, FEVAL, EXIST, and other self modifying code. It
may be really fun and very flexible, but its very confusing if
you're not the one debugging it.

4. Use strings and SWITCH as a proxy for enumerated types, it's
easy to use, fast and very readable:
fruit='apple';
switch(fruit)
case 'apple', fun1;
case 'banana', fun2;
end;

5. Preallocate when possible, it enhances speed.

6. Avoid MEX files when possible; KISS (Keep It Simple, Stupid).
Most of the time, vectorization is the appropriate solution and
it allows us to keep most everything in one language, open and
easily modified.

7. Use TRY, CATCH, END generously. Error checking is important.

8. Creative use of FIND, PROD, SUM, CUMSUM, NaN, REPMAT, RESHAPE,
ONES and ZEROS can really help vectorize your code, but try not
to make the code too cryptic. Readability is very important.

9. Rather than populate variables with assignments (X=1, Y=3,
etc), read in a CSV file. This allows an inexperienced user to
modify these values without having to touch the code.

10. Use long variable names with underscores; it helps me avoid a
great deal of documentation (ie. delivery_yield_using_unwind_RP)

Michael Robbins, CFA
Director, Proprietary Trading
Debt Capital Markets
Canadian Imperial Bank of Commerce, World Markets
* Sent from RemarQ http://www.remarq.com The Internet's Discussion Network *
The fastest and easiest way to search and participate in Usenet - Free!


Jordan Rosenthal

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
Michael,

I am not sure I would agree with the "avoid EVAL/FEVAL/EXIST" idea you had.
They certainly have their place for some tasks. I imagine, though, that you
had a particular task in mind for which they are not well-suited when
writing that? If so, maybe you could qualify that part with an example of
when to avoid them and provide an alternate suggestion.

One _biggie_ you are missing is about commenting your code. Always include
comments! The exact style you use for comments is a personal choice. Here
are a bunch of things I like to do. I am sure other people have their own
techniques.

I like to use this to section of code into big pieces:

%----------------------------------------------------------------------
% This section finds the blah, blah, blah
%----------------------------------------------------------------------

and sometimes this

%======================================
% This section blah, blah, blah
%======================================

These can be effectively used around case statements of a GUI implemented
switchyard style:

switch cmd
%--------------------------------------------------------------
case 'plot'
%--------------------------------------------------------------
code
code
code
%--------------------------------------------------------------
case 'update'
%--------------------------------------------------------------
code
code
%--------------------------------------------------------------
otherwise
%--------------------------------------------------------------
code
end

Before a section of code that might be confusing I like to say what it does:

%--- Reset plot properties and do something else ---%
code;
morecode;

And, of course, there is this tried-n-true style for declaring variables:

x = 5; % Input
y = 5; % Output

Let's see what else. I like to make my files readable by aligning equal
signs, spaces, and commas, but this may be a bit overboard for most people

%--------------------------------------------------------------
% Parse inputs
%--------------------------------------------------------------
if nargin<1, x = 5; end
if a<b, y = 10; end

%--- Default variables ---%
input = 5;
output_2 = 7;
output_5 = 9;


(I am not sure if this will line up correctly in the newsgroup, but the idea
was that all the equal signs lined up and the "end" statements line up).
Also, notice the empty line. Instead of just writing line after line of
code, an occasion blank line between sections of code really improves the
readability.

And, of course, NEVER write a function without the help information which
tells you how to use it! Adding the author name, email, creation date,
revision date is a common thing to do as well. If you have a revision
control program, use it.

---------------------------------
Some other ideas:
---------------------------------

Perhaps you could set down some guidelines for variable usage. For example,
I usually use certain variables for certain tasks such as k for index
vectors, etc. Occasionally, I even prefix my variables with letters that
indicate to me what the variables store

sCmd = 'a string start with an s';
cCell = {'A cell starts with a c'};

Along these same lines I like to use all-caps for global-ish variables or
variables used as flags. As an example, many of my files start with

YES = 1; NO = 0

I use this in a variety of ways. Here is an example,

CONTINUE = YES:
while CONTINUE
......
if (....)
CONTINUE = NO;
end
end

I think this is much more readable than using CONTINUE = 1 or CONTINUE = 0.

If you do decide to setup some guidelines for variable naming, I wouldn't
suggest pushing it too far. It is easy to get carried away and you get
"depreciating returns" (I thought I'd throw in a financial analogy for you
:) ). In my opinion, you'll never be able to make the variable naming
completely consistent without sacrificing readability at some point.
Although some general guidelines can improve the readability of code,
comments are MUCH more helpful then fancy variable conventions!

Good luck,

Jordan


"Michael Robbins" <michael...@us.cibc.com> wrote in message
news:14228c8c...@usw-ex0104-026.remarq.com...

Nathan Cahill

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
Michael,

In general most of these points are good. However, I think that they
can be too restricting. For instance,

> 2. Use structures of arrays, not arrays of structures. Arrays of
> structures are slow. Avoid DEAL, it's often slow.
>

Arrays of structures are very useful for containing records for a
database. For example, you may keep pertinent information about bank
customers in an array of structures. Then it is much easier to query
the info about a given customer than if your data was stored in
structures of arrays.

> 3. Avoid EVAL, FEVAL, EXIST, and other self modifying code. It
> may be really fun and very flexible, but its very confusing if
> you're not the one debugging it.
>

Perhaps you should use them sparingly, not avoid them. There are times
where using these functions is necessary, and even preferred. For
example, if you are writing a routine that allows the user to write
their own m-file to execute (think optimization toolbox), you have to
use feval. And that's not a bad thing.

>
> 6. Avoid MEX files when possible; KISS (Keep It Simple, Stupid).
> Most of the time, vectorization is the appropriate solution and
> it allows us to keep most everything in one language, open and
> easily modified.
>

> 8. Creative use of FIND, PROD, SUM, CUMSUM, NaN, REPMAT, RESHAPE,
> ONES and ZEROS can really help vectorize your code, but try not
> to make the code too cryptic. Readability is very important.
>

6 and 8 can be somewhat conflicting. In many cases, the MATLAB
programmer is solely concerned with speed of execution. If we are to
avoid MEX files, it is often true that execution time is inversely
proportional to "crypticness" (crypticity?).

> 7. Use TRY, CATCH, END generously. Error checking is important.
>

I only use this construct when debugging code, and I generally try to
avoid it in "production" code. If you are a good programmer, you should
be able to anticipate errors. It can be very costly to catch errors
after the fact.

Hope this helps,
Nathan Cahill

Matt Feinstein

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
On Mon, 20 Mar 2000 19:56:58 -0800, Michael Robbins
<michael...@us.cibc.com> wrote:

>Please help me develop a list of good Matlab programming
>practices. I am not a professional programmer and I'd like to
>develop a standard for my team. I'll start with some things I
>think I know:
>
>1. Use structures instead of globals; pass the structures to and
>from functions. This keeps the functions modular and the
>variables obvious. It also helps organize the variables.

This is good general advice, but Matlab's structures are weak because
1. there's no definition/declaration syntax, so modifying a structure
is hard.
2. the struct key has to be a string

>2. Use structures of arrays, not arrays of structures. Arrays of
>structures are slow. Avoid DEAL, it's often slow.

'deal' is hard to avoid if you use cell arrays, and cell arrays are (I
think) the only way to set up nested vectors like xx{1}(2)

>3. Avoid EVAL, FEVAL, EXIST, and other self modifying code. It
>may be really fun and very flexible, but its very confusing if
>you're not the one debugging it.

'evalin' seems to be the only way to control what workspace evaluation
takes place in. Also, I find that 'eval' gives a rather easy and
memory-efficient way saving results of multiple runs of a program in a
single .mat file; if you want to save the variable 'xx' in run k, you
do

eval([ 'xx_] num2str(k) ' = xx;']);
save('savfile',[ 'xx_' num2str(k)' ]);

>7. Use TRY, CATCH, END generously. Error checking is important.

Another use for 'eval' is for one-liner error trapping

>9. Rather than populate variables with assignments (X=1, Y=3,
>etc), read in a CSV file. This allows an inexperienced user to
>modify these values without having to touch the code.

AARGH. You've hit a sore spot here. I -WISH- that Matlab had printf
and scanf functions that worked -EXACTLY- like the functions in the
standard C library.

I would add:

Keep the sizes of functions small, and if function B is used -only- by
function A, it should be in the same file. Also, to continue in the
'graceful degradation' theme, function outputs should include an error
code, at least until Matlab gets a 'throw' statement.
--
Matt Feinstein
mf...@aplcomm.jhuapl.edu
Organizational Department of Repeated
and Unnecessary Redundancy

Lars Gregersen

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
On Mon, 20 Mar 2000 19:56:58 -0800, Michael Robbins
<michael...@us.cibc.com> wrote:

>Please help me develop a list of good Matlab programming
>practices. I am not a professional programmer and I'd like to
>develop a standard for my team. I'll start with some things I
>think I know:

Hi Michael

I mostly agree with your statements. Having a good set of rules does
not only provide a good setting for creating good programmes it also
makes it easier to maintain code for future use (possibly by others).

I have a few comments for some of the items.

>3. Avoid EVAL, FEVAL, EXIST, and other self modifying code. It
>may be really fun and very flexible, but its very confusing if
>you're not the one debugging it.

Eval is the most evil. That's clear. For some uses you really can't
escape the use of feval (optim toolbox etc.). The reason I discourage
using these functions is that they make porting Matlab coding to other
environments very difficult. Even if a port is possible, it often
makes the ported code difficult to read and/or slow.

I often use exist in functions. If I have the function
dx=fun(t,x,y,flags)
where flags are optional I would use
if ~exist('flags','var')
flags = [];
end
instead of
if nargin==3
flags = [];
end

since it makes it easier to maintain code when the number of arguments
are changed at some later point in time.

You should of course not use exist to repair faults in the programming
logic.

>5. Preallocate when possible, it enhances speed.

I also find that preallocating makes it easier to understand my
programmes. Futhermore, makes you think about the size of matrices
instead of relying on Matlab ability to grow matrices.

>7. Use TRY, CATCH, END generously. Error checking is important.

Error checking is very important, but exceptions are not used for
that.

You should extensily check for errors where possible using the "old"
built in methods: check for the right number and type of arguments to
functions, check the output of functions like fopen, eval, fzero etc.
for failure, check arguments for e.g. singularities and other
numerical problems before carrying out the calculations.

Exeptions are mostly used in GUI frameworks where the user may create
some error in some function deeply nested within other functions.

In Matlab exception handling is fairly primitive. You don't have
different types of exceptions (i.e. you can only 'throw' a string) and
the only way to throw an exception is to use the error function.


Lars

------------------------------
Lars Gregersen (l...@kt.dtu.dk)
http://www.gbar.dtu.dk/~matlg

Check out my matlab toolboxes at:
http://members.xoom.com/gregersenweb/matlab/

Lars Gregersen

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
On Tue, 21 Mar 2000 14:14:30 GMT, mf...@aplcomm.jhuapl.edu (Matt
Feinstein) wrote:

>On Mon, 20 Mar 2000 19:56:58 -0800, Michael Robbins
><michael...@us.cibc.com> wrote:
>
>>Please help me develop a list of good Matlab programming

>takes place in. Also, I find that 'eval' gives a rather easy and


>memory-efficient way saving results of multiple runs of a program in a
>single .mat file; if you want to save the variable 'xx' in run k, you
>do
>
>eval([ 'xx_] num2str(k) ' = xx;']);
>save('savfile',[ 'xx_' num2str(k)' ]);

I don't get this, sorry. Doesn't the .mat file get overwritten every
time you run the save command effectively only saving one xx_x
variable? How can it be more memory efficient to copy the array
instead of just saving the original one?

While we're talking about good programming practices: Generally it is
a bad idea to create variables using eval. It will make the code hard
to debug. Especially if the eval is inside a loop. Use cell arrays
instead.

Matt Feinstein

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
On Tue, 21 Mar 2000 15:02:05 GMT, l...@kt.dtu.dk (Lars Gregersen) wrote:

>On Tue, 21 Mar 2000 14:14:30 GMT, mf...@aplcomm.jhuapl.edu (Matt
>Feinstein) wrote:
>
>
>>takes place in. Also, I find that 'eval' gives a rather easy and
>>memory-efficient way saving results of multiple runs of a program in a
>>single .mat file; if you want to save the variable 'xx' in run k, you
>>do
>>
>>eval([ 'xx_] num2str(k) ' = xx;']);
>>save('savfile',[ 'xx_' num2str(k)' ]);
>
>I don't get this, sorry. Doesn't the .mat file get overwritten every
>time you run the save command effectively only saving one xx_x
>variable? How can it be more memory efficient to copy the array
>instead of just saving the original one?
>

sorry, should have posted something closer to actual code:

k = 1;
%do stuff
.......
%save stuff
if k == 1

eval([ 'xx_] num2str(k) ' = xx;']);
save('savfile',[ 'xx_' num2str(k)' ]);

else


eval([ 'xx_] num2str(k) ' = xx;']);

save('savfile',[ 'xx_' num2str(k)' ],'-APPEND');
end
eval( ['clear xx xx_' num2str(k)]);
k = k+1;
%now repeat do stuff

so, e.g., if xx is a large array, and you run the program 200 times,
you've saved a fair amount of memory. I agree that creating variables
with 'eval' is bad practice, but since the variables xx_k are very
temporary, they're a venial, not a mortal sin, IMO. It is also true
that when you want to look at the variables you've saved, you've
generally got to use 'eval' again after loading savfile.

duaneh

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
>
>sorry, should have posted something closer to actual code:
>
>k = 1;
>%do stuff
>........

>%save stuff
>if k == 1
> eval([ 'xx_] num2str(k) ' = xx;']);
> save('savfile',[ 'xx_' num2str(k)' ]);
>else
> eval([ 'xx_] num2str(k) ' = xx;']);
> save('savfile',[ 'xx_' num2str(k)' ],'-APPEND');
>end
>eval( ['clear xx xx_' num2str(k)]);
>k = k+1;
>%now repeat do stuff
>

I'd like to add that usage of num2str and int2str is relatively
slow and often detracts from readability. It is often faster and
easier to read eval strings using sprintf directly. For example
the line

eval( ['clear xx xx_' num2str(k)]);

can be rewritten as

eval(sprintf('clear xx xx_%d',k))

The clarity of using sprintf increases as one forms even more
complicated expressions that otherwise call num2str or int2str.

What's interesting is that num2str and int2str both call sprintf
themselves.

So I would add using sprintf rather than using num2str or
int2str when converting numerical values to strings for use in
labeling plots and constructing eval strings.

Joe Deasy

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
Hello Michael,

Interesting discussion you started.

--I too find long descriptive variable names to be essential to
debugging and reducing the
re-start cost in reusing the code elsewhere.

--I too find that naming conventions add clarity
('locality'/'proximity') when reading code:
xV is a vector
MaskM is a matrix
PatientS is a string
GoF is a flag (though I like the use of Yes and No someone posted--I'm
switching to that)
CellC is a cell array
But what about structures? I am trying StructureSt, but aagh!
Someone suggested prepending small letter to describe the type. hmm...

--Use of 'case' when appropriate (though darn it all Mathworks should
allow expressions as parameters
on the switch command,
i.e. switch _expr_)

--I normally only use 'eval' for I/O constructions.

--I try to write variable assignments explicitly before a function call:

i.e.
xV = ones(1,Num)
yV = ones(1,Num)
rV = GetRho(xV,yV), instead of
GetRho(ones(1,Num),ones(1,Num))
(Oh yah, I like to use Getx as the name of the function which gets x)

--For goodness sake, isolate all parameter settings at the top of the
function,
or better yet write a function which does not need parameter settings
(derive
them from the input data).

--I like the idea of passing an error condition, a la the Nag libraries
ifail returned parameter.

--If a function expects a vector, then do xV(:) to assure the shape no
matter what the shape of the input.

--when reading a file, read the whole thing into a cell array first,
then operate on that.

--Perhaps most importantly, offload any 'generic' code into a
well-named, well-tested routine.

I like really descriptive headers on files. For example I use the
template:

function [StructMaskUA,InfoC] = GetRTOGDir(ArchiveDirS)
%======================================================
%
%function [] = GetRTOGDir('ArchiveDirS')
%
%DESCRIPTION:
%Extract structures from RTOG archives. Structures are
%returned in the form of a single, combined, uint32
%(unsigned integer 32-bit) 3-D matrix. The z grid of the
%matrix corresponds to the "SCAN #" referred to in the
%RTOG archive image files.
%
%
%
%INPUTS:
%ArchiveDirS is a string holding the directory of the
%RTOG format archive. The trailing slash can be included or left off.
%
%OUTPUTS:
%
%InfoC returns all the relevant information about each
%structure in the different cells. The order is the
%same as that given in the *.dir file describing the
%plan.
%
%
%
%USAGE:
%
%
%
%NOTES:
%The structure field names are translations of
%the RTOG tag notations used in the *0000 file:
%1. structure fieldnames are Upper case first letter with
% no spaces between words, e.g. 'BytesPerPixel'
%2. blanks between words are dropped
%3. '#' is everywhere replaced by 'Number'
%4. parantheses are deleted
%5. '/' is everywhere deleted
%6. '-' is everywhere deleted
%
%This is designed to work whether or not there are spaces
%in the tag names (i.e. the identifiers to the left of the ':='
%delimiters).
%
%Needs:
%File2Cell.m
%deblank2.m
%word.m
%
%GLOBALS: None.
%
%COMPUTATIONAL COMPLEXITY:
%
%STORAGE NEEDED:
%
%INTERNAL PARAMETERS:
%
%STATUS:
%Reads in:
%--Directory info
%--Structure coords
%
%HISTORY:
%1st ver.: 16-mar-0
%Last modified:
%
%TESTS:
%
%AUTHOR:
%J.O.Deasy
%
%REFERENCES:
%
%======================================================

--I'd like to use more subfunctions but have run into bugs trying to get

Matlab to recognize they are there.
(and no I don't have the time now to go into it...)

--Matlab, and all other such systems are really weak at documenting just

what was done in a given calculation and then saving the results. So I
wrote something called web-notebook for matlab to do this. It saves
all the computation results to an html file, copies figures to jpegs,
and copies all the m-files used in the calculations. I've been using it
day-in-and
day-out for about 6 months, and cant live without it. I hope to make it
available
sometime this summer. (Anyone who would like to try it in it's present
form can
email me). At any rate my hope is that something like it will be
forthcoming
from Matlab.


Michael Robbins wrote:

> Please help me develop a list of good Matlab programming

> practices. I am not a professional programmer and I'd like to
> develop a standard for my team. I'll start with some things I
> think I know:
>

> 1. Use structures instead of globals; pass the structures to and
> from functions. This keeps the functions modular and the
> variables obvious. It also helps organize the variables.
>

> 2. Use structures of arrays, not arrays of structures. Arrays of
> structures are slow. Avoid DEAL, it's often slow.
>

> 3. Avoid EVAL, FEVAL, EXIST, and other self modifying code. It
> may be really fun and very flexible, but its very confusing if
> you're not the one debugging it.
>

> 4. Use strings and SWITCH as a proxy for enumerated types, it's
> easy to use, fast and very readable:
> fruit='apple';
> switch(fruit)
> case 'apple', fun1;
> case 'banana', fun2;
> end;
>

> 5. Preallocate when possible, it enhances speed.
>

> 6. Avoid MEX files when possible; KISS (Keep It Simple, Stupid).
> Most of the time, vectorization is the appropriate solution and
> it allows us to keep most everything in one language, open and
> easily modified.
>

> 7. Use TRY, CATCH, END generously. Error checking is important.
>

> 8. Creative use of FIND, PROD, SUM, CUMSUM, NaN, REPMAT, RESHAPE,
> ONES and ZEROS can really help vectorize your code, but try not
> to make the code too cryptic. Readability is very important.
>

> 9. Rather than populate variables with assignments (X=1, Y=3,
> etc), read in a CSV file. This allows an inexperienced user to
> modify these values without having to touch the code.
>

> 10. Use long variable names with underscores; it helps me avoid a
> great deal of documentation (ie. delivery_yield_using_unwind_RP)
>
> Michael Robbins, CFA
> Director, Proprietary Trading
> Debt Capital Markets
> Canadian Imperial Bank of Commerce, World Markets

Ulrich Elsner

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
According to Michael Robbins <michael...@us.cibc.com>:

>Please help me develop a list of good Matlab programming
>practices. I am not a professional programmer and I'd like to
>develop a standard for my team.
>
>[ ... lots of nice stuff snipped ...]

>9. Rather than populate variables with assignments (X=1, Y=3,
>etc), read in a CSV file. This allows an inexperienced user to
>modify these values without having to touch the code.

If you really want the user to modify values in a file, it might be
better to write a simple parser, allowing you to insert comment etc.
in the value file. It in not very difficult to parse a file like

%% Start here
%% Another comment
% Value for Y
3

% Value for X
1

>10. Use long variable names with underscores; it helps me avoid a
>great deal of documentation (ie. delivery_yield_using_unwind_RP)

Unless you want to force a similar style on everybody, just ask for
self-explaining variable names. For example I HATE underscores and would
much rather use DeliveryYield... .

But if you want to have a common coding style for the whole team, you can
also include both layout specific things like 'indent loops with 4
spaces', 'use only one expression per line', and more general rules like
' every user callable function must do some error and validity checking on
the input data'

A comment standard is also nice; every file should include date of last
change, programmers name some explanation of what is happening (both
result and algorithm used, with some additional pointers for more obscure
algorithms.


Trying to emulate the Mathworks house style is probably not the worst
thing one can do.


Ulrich 'not always sticking to my own rules' Elsner

--
Ulrich Elsner, Fak. fuer Mathematik, TU Chemnitz, D-09107 Chemnitz, Germany

Jordan Rosenthal

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
Joe,

> --Use of 'case' when appropriate (though darn it all Mathworks should
> allow expressions as parameters
> on the switch command,
> i.e. switch _expr_)

Matlab does allow expressions in switch statements. For example,

x = 4;
switch (x+3)
case 7
disp('Yep.');
otherwise
disp('Nope.');
end

switch lower(cmd)
case 'initialize'
....
case 'plot'
....
end

Hope that helped,

Jordan

Joe Deasy

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
Sorry bout that,
my complaint is that multiple values should be allowed
for the value of the case argument. (no kidding this time, ...:-)

i.e. I would like to see,
case x | y

--joe


Jordan Rosenthal wrote:

> Joe,


>
> > --Use of 'case' when appropriate (though darn it all Mathworks
> should
> > allow expressions as parameters
> > on the switch
> command,
> > i.e. switch _expr_)
>

Jordan Rosenthal

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
Joe,

> my complaint is that multiple values should be allowed
> for the value of the case argument. (no kidding this time, ...:-)

You can do that too!! Here is an example:

x = 4;
switch x
case {1,2}
disp('Nope');
case {3,4}
disp('Yep');
end

and here is another example taken for the switch statement help file:

Example (assuming METHOD exists as a string variable):

switch lower(METHOD)
case {'linear','bilinear'}
disp('Method is linear')
case 'cubic'
disp('Method is cubic')
case 'nearest'
disp('Method is nearest')
otherwise
disp('Unknown method.')

Marco De la Cruz

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
Michael Robbins <michael...@us.cibc.com> writes:

> Please help me develop a list of good Matlab programming
> practices. I am not a professional programmer and I'd like to

> develop a standard for my team. I'll start with some things I
> think I know:

Well, for what it's worth...

> 8. Creative use of FIND, PROD, SUM, CUMSUM, NaN, REPMAT, RESHAPE,
> ONES and ZEROS can really help vectorize your code, but try not
> to make the code too cryptic. Readability is very important.

It's a speed/readability tradeoff. Make it readable
unless it's unacceptably slow (and if so, write both
versions of the code and comment out the readable one).

Other stuff (YMMV):

I keep my lines short using "...". I started doing
it since sometimes I use a vt100 terminal (about
72 columns) but I think it improves overall readability.

Make indents large, 8 spaces is good. This is a
tip from Linus Torvalds (it was likely stated
previously, but I heard it from him), who
argued that at 3am those 2-space indents are
pretty damn hard to see.

Anyway, good programming practices are clearly
laid out in:

"The Practice of Programming" by
Brian Kernighan and Rob Pike,
Addison-Wesley (1999)

The authors' credentials speak for themselves.

_________________________________
ma...@chinook.physics.utoronto.ca
Gunnm: Broken Angel
http://128.100.80.13/marco/alita.html

Lars Gregersen

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
On Tue, 21 Mar 2000 12:39:50 -0600, Joe Deasy
<deasyX...@radonc.wustl.edu> wrote:

Hi

>--If a function expects a vector, then do xV(:) to assure the shape no
>matter what the shape of the input.

You should only do this if you have actually checked that xV really is
a vector. If the user gives you a matrix they will have a hard time
debugging what is going on if you do the conversion to a vector
automatically.

Peter J. Acklam

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
Joe Deasy <deasyX...@radonc.wustl.edu> wrote:
>
> --If a function expects a vector, then do xV(:) to assure the shape
> no matter what the shape of the input.

l...@kt.dtu.dk (Lars Gregersen) writes:
>
> You should only do this if you have actually checked that xV really
> is a vector.

I usually use the following expression to see if x is a vector

sum( size(x) > 1 ) <= 1

or, if x has to be a non-empty vector

~isempty(x) & ( sum( size(x) > 1 ) <= 1 )

Peter

--
%INTROSPECTIVE Introspective/self-reproducing program (displays itself).
function f,h=fopen([mfilename,'.m']); fprintf('%s',fread(h)); fclose(h);

Bogdan Tymofienko

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to

Lars Gregersen wrote:

> Hi Michael


>
> >5. Preallocate when possible, it enhances speed.
>

> I also find that preallocating makes it easier to understand my
> programmes. Futhermore, makes you think about the size of matrices
> instead of relying on Matlab ability to grow matrices.

Not always
If You declare zero's or one's matrices (homogenuosly) MATLAB may
not improove the speed but if You use other spec. function
(uch function as rand() OR linspace, etc.) it may help


Bogdan Tymofienko

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
It's Not very IMPORTANT that
name of function was correspond to name of file of it.

:^)

Bogdan

Peter Torrione

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
Hello Michael,

>Please help me develop a list of good Matlab programming

>practices. I am not a professional programmer and I'd like to
>develop a standard for my team. I'll start with some things I
>think I know:

Here's something a lot of people take for granted:

Stick to one capitalization sheme throughout your program. On NT you can
get creative with how you call your functions since Windows doesn't check
case when it goes searching for files.

g = PoLYFiT([0:10],[0:10].^2,2);

But, if you try sending your program to a UNIX machine you will run into
problems. Or, just try compiling it. . . ;)

-pt

p...@mathworks.com

Lars Gregersen

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
On Wed, 22 Mar 2000 09:28:21 -0500, "Peter Torrione"
<torr...@mathworks.com> wrote:

>Hello Michael,
>
>>Please help me develop a list of good Matlab programming
>>practices. I am not a professional programmer and I'd like to
>>develop a standard for my team. I'll start with some things I
>>think I know:
>
>Here's something a lot of people take for granted:
>
>Stick to one capitalization sheme throughout your program. On NT you can

Yes!!! And I would add that one should do this trough all programmes.
Perhaps even across programming languages.

If possible one should use the same notation as in the literature

>get creative with how you call your functions since Windows doesn't check
>case when it goes searching for files.

As it was recently seen in the post by Daniel Diep he had a problem
since he had created a variable called path and therefore couldn't use
the path function. Mysterically enough (when you don't know the
reason) the function could be called using PATH (or any other version
with at least one capital letter). Maybe some sort of warning for this
would be nice.

Using variable names equal to function names should be a no-no.

Joe Deasy

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
Continuing our interesting discussion,
I have some other suggestions for review:

--always use length(vector) instead of size(vector,1) to build
loop indexes, to avoid assuming the orientation
of the vector.

--if certain important things are supposed to remain
true concerning function outputs or intermediate
steps, then check to make sure that they remain true
before exiting the code.
(In the spirit of Eiffel). Mathworks should consider
incorporating assertions. (A fail flag is a stop gap,
though useful). One should actually be able to turn
on and off the assertions. (I actually started writing
the code for this once...)

--if you're looking to add functionality, take a look at
decisions others have made on what functions would be useful.
E.g. --REXX by Cowlishaw for string functions
--Numerical Python docs for array functions
(most of which are already there)
--Numerical recipes F90 book for more array
utility routines.

--Using the interpreter is too easy! Serious code review/reading,
sometimes printing the routine and reading it, should
precede machine execution. This is the best defense
against that class of bugs who do not race across the
carpet in full view.

--Routinely use the debugger to follow example execution
of code. Can't emphasize this enough. Lookout for the code that
worked without having to be debugged in detail!

Lars Gregersen

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
On Wed, 22 Mar 2000 10:23:33 -0600, Joe Deasy
<deasyX...@radonc.wustl.edu> wrote:

>Continuing our interesting discussion,
>I have some other suggestions for review:
>
>--always use length(vector) instead of size(vector,1) to build
> loop indexes, to avoid assuming the orientation
> of the vector.

It can be a matter of opinion/design. I have many files where I expect
the user (i.e. myself) to supply a matrix of data where each of the
rows are some related measurements. When the user provides just a
single row the scheme above breaks.

Whenever I do something related to linear algebra I force mysels in
notation and in Matlab to use column vectors. I find it a lot easier
to debug code where the orientation of vectors follow this scheme. As
the example above shows I have a clear distinction between a vector
and data in a row.

Kevin Murphy

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
I use the following - I found Peter's code a little obscure.

function p = isvector(v)
% ISVECTOR Returns 1 if the argument is Nx1 or 1xN, for some N>=1
% p = isvector(v)

s=size(v);
p = (ndims(v)<=2) & (s(1) == 1 | s(2) == 1);


Kevin

Kevin Murphy

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
Bogdan Tymofienko wrote:
>
> It's Not very IMPORTANT that
> name of function was correspond to name of file of it.
>
> :^)
>

You'd be surprised how many people got confused using my HMM toolbox
when I renamed a file from 'mk_dhmm_obs_mat' to 'mk_dhmm_obs_lik' and
forgot to change the name of the function inside the file. Fortunately,
the new emacs matlab mode checks for consistency between the two.

Kevin

Matt Feinstein

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
On Wed, 22 Mar 2000 10:23:33 -0600, Joe Deasy
<deasyX...@radonc.wustl.edu> wrote:

>--always use length(vector) instead of size(vector,1) to build
> loop indexes, to avoid assuming the orientation
> of the vector.

This hides some useful possibilities of vectorizing 'for' loops; try

for k = v
k
end

with

v = [1 2 3]
v = [1 2 3]'

and

v = [1 2 3;4 5 6]

& you'll see what I mean.

Kevin Murphy

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
I liberally sprinkle assertions through my code, using the function
below. I always run with 'dbstop if error', so if an assertion is
violated, I get popped into the debugger, type 'dbstack' to find who
caused it, and 'dbup' to move into the offending stack frame, and start
poking around.

The way matlab lets you interactively change things in the debugger is
one of the (many) reasons I love programming in matlab so much.
Mathworks please note: It would be nice if it gave you access to
object's private members, even if a subsref or display function has not
been written. Currently I hack around it by typing 's = struct(some
object); disp(s)' or whatever.

Kevin


function assert(pred, str)
% ASSERT Raise an error if the predicate is not true.
% assert(pred, string)

if nargin<2, str = ''; end

if ~pred
s = sprintf('assertion violated: %s', str);
error(s);
end

Kevin Murphy

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
Anyone interested in summarizing/collating the best suggestions posted
to this thread? (I vaguely recall someone was writing a book on
programming in matlab - maybe that person should do it.)

Kevin

Steve Eddins

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
Joe Deasy <deasyX...@radonc.wustl.edu> writes:

[snip]

> --Using the interpreter is too easy! Serious code review/reading,
> sometimes printing the routine and reading it, should
> precede machine execution. This is the best defense
> against that class of bugs who do not race across the
> carpet in full view.
>
> --Routinely use the debugger to follow example execution
> of code. Can't emphasize this enough. Lookout for the code that
> worked without having to be debugged in detail!

These are excellent suggestions.

For several years I have followed this practice rigorously: Whenever
I have a block of new code that I'm getting ready to check in, I print
it out, grab a highlighter, and step through it in the debugger. I
highlight every code line that gets hit, and I keep using different
combinations of inputs until every code line is highlighted.

It doesn't take very long, and it's definitely worth it. There are a
large number of bugs that never made it into our products because of
this procedure.

--
Steve Eddins
The MathWorks, Inc.
edd...@mathworks.com
http://www.mathworks.com

Michael Schweisguth

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
the folks on the newsgroup enjoy posting realtime feedback---
which is *more* important and *more* useful than a canned book,
in many ways! in fact, this isa(newsgroup,'book')! you read
it, and learn from it! ;-) occasionally, some of us blow off
some steam and post a flame regarding the price of MATLAB
but, for the most part, we stay honest!

Kevin Murphy (mur...@cs.berkeley.edu) wrote:
: Anyone interested in summarizing/collating the best suggestions posted

Michael Robbins

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
While Michael Schweisguth is correct, I shall summarize this
thread when this vivacious interest dies down.

Although it was my intent to start an interesting thread, and
moreso to learn some tips on how to program more efficiently, my
primary motivation was to generate a document that summarizes
these ideas.

I hope this summary will serve as a useful guide while not
inhibiting creativity, efficiency or fun.

To make a summary easier to generate, it may be best to keep this
all in one thread.

duaneh

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
I've created a function like yours that is easy to follow. It
also optionally gives information whether the vector is a row or
column. The function follows below (note it is not currently a
part of the Mastering MATLAB Toolbox (www.eece.maine.edu/mm)

function tf=mmisvect(x,rc)
%MMISVECT(X) True for Vectors. (MM)
% MMISVECT(X) returns logical TRUE if X is a 2D array having one
% row and nonzero columns or one column and nonzero rows.
%
% MMISVECT(X,'row') returns logical TRUE if X is a 2D ROW array.
% MMISVECT(X,'col') returns logical TRUE if X is a 2D COLUMN
array.

% D.C. Hanselman, University of Maine, Orono, ME 04469
% 3/2/99, 1/17/00
% Mastering MATLAB 5, Prentice Hall, ISBN 0-13-858366-8

sx=size(x);
tf= ndims(x)==2 & prod(sx)==length(x); % is vector

if tf & nargin==2 & ischar(rc) & length(rc)>0
switch lower(rc(1))
case 'r'
tf=(sx(1)==1);
case 'c'
tf=(sx(2)==1);
otherwise
error('''Row'' or ''Col'' Required for Second Argument.')
end
end

Peter J. Acklam

unread,
Mar 22, 2000, 3:00:00 AM3/22/00
to
Peter J. Acklam <jac...@math.uio.no>

>
> I usually use the following expression to see if x is a vector
>
> sum( size(x) > 1 ) <= 1

Your does the same as mine, except that I consider, for instance, a
1-by-1-by-5 array to be a vector. Mine isn't really that obscure.
Your code says it is a vector if a 2D matrix has length 1 along at
least one dimension. Mine says that an ar array is a vector if it has
length one along no more than one dimension.

John Williams

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
Lars Gregersen wrote:

> As it was recently seen in the post by Daniel Diep he had a problem
> since he had created a variable called path and therefore couldn't use
> the path function. Mysterically enough (when you don't know the
> reason) the function could be called using PATH (or any other version
> with at least one capital letter). Maybe some sort of warning for this
> would be nice.

I think any programming language worth its salt should be case
sensitive. Allowing the programmer to use arbitrary case in refering to
language constructs and variables etc is permitting or even encouraging
sloppy programming.

If a language is case sensitive, and the programmer is silly enough to
define variables with the same name but in a different case, then leave
them to their peril.



> Using variable names equal to function names should be a no-no.

I agree.

Shifting topic slightly, I also wish there was a way to make Matlab
force variable declaration before use. Leave the default behaviour as
it is for backwards compatability, but introduce a language option to
enable it. Didn't NASA lose an interplanetary probe in the 70's or 80's
because Fortran allowed the same sloppy programming? Or is that a
computing urban legend? :)

Cheers,

John

Michael Schweisguth

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
naw... im not correct! im just happy that some of my posts die a happy
death! ;-)

Michael Robbins (michael...@us.cibc.com) wrote:
: While Michael Schweisguth is correct, I shall summarize this

David C Sterratt

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
On the subject of extensive commenting, I've been trying out the idea
of literate programming in matlab recently. For those of you who
don't know, literate programming is the idea that the program should
be more like a document that explains how the program or algorithm
works. In other words one writes the documentation and source code in
the same file and then pass the file through scripts that either `weave'
the documetation together with the code to produce a nice looking
document in HTML, LaTeX, nroff, whatever or `tangle' the code out of
the file to produce the source file.

Literate programming tools allow you to put the source code in any
order that you like in the source file by labeling each chunk of code
and then concatenating the named chunks together. Each chunk of code
can be seen as a macro. This should allow you to overcome constraints
of programming languages that make you put related information in
different bits of files, thereby allowing you to describe the
algorithm in a clearer way. It also provides an incentive for
explaining why you're doing things the way you are.

On the down side, this makes the commented source code less portable,
as the person who's editting the code has to use the same tools to
weave and tangle the program.

I've been using this technique in a switchyard-style GUI, and it seems
to work quite well, though I'm not yet convinced that the benefits
outweigh the disadvantages. I'd be interested to hear from anyone
else who has experience of literate programming in matlab -- I haven't
seen about literate programming in matlab on the web.

For anyone interested, http://www.literateprogramming.com/ has info on
literate programming and various tools, many of which are in the
public domain. The particular tool I'm using is called noweb
(http://www.eecs.harvard.edu/~nr/noweb/intro.html). This is really a
UNIX tool, though is supposed to run in Win95/98/NT (though I haven't
managed to). Its advantages are simplicity and language-independence.

David

--
David C. Sterratt | http://www.cs.stir.ac.uk/~dcs
Stirling Hearing Systems | http://www.cs.stir.ac.uk/SHS
Department of Computing Science and Mathematics, | tel: +44 1786 467422
University of Stirling, Stirling FK9 4LA, Scotland | fax: +44 1786 464551


Lars Gregersen

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
On Thu, 23 Mar 2000 14:29:07 +1000, John Williams
<ja.wi...@student.qut.edu.au> wrote:

>Lars Gregersen wrote:
>
>> As it was recently seen in the post by Daniel Diep he had a problem
>> since he had created a variable called path and therefore couldn't use
>> the path function. Mysterically enough (when you don't know the
>> reason) the function could be called using PATH (or any other version
>> with at least one capital letter). Maybe some sort of warning for this
>> would be nice.
>
>I think any programming language worth its salt should be case
>sensitive. Allowing the programmer to use arbitrary case in refering to
>language constructs and variables etc is permitting or even encouraging
>sloppy programming.

The problem is that Matlab is only case sensitive for variables, but
not for function names in Windows. This breaks the platform
independence for Matlab code!

>If a language is case sensitive, and the programmer is silly enough to
>define variables with the same name but in a different case, then leave
>them to their peril.

I often create variable names that only differ in case. I often have
something like
[I,J] = size(X);
for i=1:I
for j=1:J
do_something(X,i,j);
end
end

I don't consider this silly, but actually a good practice. But I would
never have two variables called delivery_yield_using_unwind_RP and
delivery_Yield_using_unwind_RP.

Steve Eddins

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
l...@kt.dtu.dk (Lars Gregersen) writes:

> >If a language is case sensitive, and the programmer is silly enough to
> >define variables with the same name but in a different case, then leave
> >them to their peril.
>
> I often create variable names that only differ in case. I often have
> something like
> [I,J] = size(X);
> for i=1:I
> for j=1:J
> do_something(X,i,j);
> end
> end
>
> I don't consider this silly, but actually a good practice. But I would
> never have two variables called delivery_yield_using_unwind_RP and
> delivery_Yield_using_unwind_RP.

I agree with Lars.

The MATLAB language is often used to represent mathematical
expressions, and such expressions often use the same letter in both
upper and lower case forms. I often write something like this:

H = fft(h);

I believe this is readable and useful because it mimics commonplace
mathematical notation for similar operations. I also regularly use n
and N in a manner similar to what Lars wrote above.

Most of the time I use long descriptive variable names, and I wouldn't
use two such names that differed only in case, but for mathematical
expressions I prefer copying standard mathematical notation (to the
extent that ASCII allows).

Steve

Michael Robbins

unread,
Mar 23, 2000, 3:00:00 AM3/23/00
to
It is often useful to designate certain types of variables by
case, ie. globals:

varname=VARNAME;

varname=someoperation(varname);

VARNAME=varname;

Michael Robbins, CFA
Director, Proprietary Trading
Debt Capital Markets
Canadian Imperial Bank of Commerce, World Markets

John Williams

unread,
Mar 24, 2000, 3:00:00 AM3/24/00
to
Lars Gregersen wrote:
>
[SNIP]

>
> >If a language is case sensitive, and the programmer is silly enough to
> >define variables with the same name but in a different case, then leave
> >them to their peril.
>
> I often create variable names that only differ in case. I often have
> something like
> [I,J] = size(X);
> for i=1:I
> for j=1:J
> do_something(X,i,j);
> end
> end

Good counterexample!

>
> I don't consider this silly, but actually a good practice. But I would
> never have two variables called delivery_yield_using_unwind_RP and
> delivery_Yield_using_unwind_RP.

Indeed. This is more the case I was thinking about in my original post.

John

Marco De la Cruz

unread,
Mar 24, 2000, 3:00:00 AM3/24/00
to

> Lars Gregersen wrote:

> > I often create variable names that only differ in case. I often have
> > something like
> > [I,J] = size(X);
> > for i=1:I
> > for j=1:J
> > do_something(X,i,j);
> > end
> > end

I usually work with complex numbers and I've
grown used to designating loop counters as "ii"
and "jj" instead of just "i" and "j".

On a related note care must be taken not to
use built-in matlab functions and constants
as variables in one's code. Once I saved
a parameter called "beta" (as in the gradient
of the Coriolis parameter) and when I loaded
it into another m-file chaos ensued: no errors
or warnings and just "slightly" wrong results.
This is perhaps the single most common newbie
error, making title = 'Temperature' and then
wondering why the TITLE command does not work
like in the manual (giving the scary error:
??? Unable to find subsindex function for class char
to boot).

_________________________________
ma...@chinook.physics.utoronto.ca
Gunnm: Broken Angel
http://128.100.80.13/marco/alita.html

Michael Robbins

unread,
Mar 24, 2000, 3:00:00 AM3/24/00
to
It might be nice if TMW could publish a reserved word list. If
a programmer gives his function to another customer, he could
find himself duping a function name even if he had been dilligent
enough to check his toolboxes. The recipient of the function
could have different toolboxes.

Michael Schweisguth

unread,
Mar 25, 2000, 3:00:00 AM3/25/00
to
the real solution (IMO) is for the MATLAB to have librarys!

like:

mymath.sin(x)

or:

using mymath;

y = sin(x);

basically, using mymath would make the library routines in "mymath"
superior to those resolved via the path.

from my experience, if TMW did publish such a list, i would be upset
if they added a new reserved word or a function that clashed with mine.
that is, if i knew about it! MATLAB is such a large program, that
im sure that such a task would be time consuming!

i think that the "private" directories have reduced the global namespace
considerably! ;-)

Michael Robbins (michael...@us.cibc.com) wrote:
: It might be nice if TMW could publish a reserved word list. If

Kimji

unread,
Mar 25, 2000, 3:00:00 AM3/25/00
to
In article <04cc259a...@usw-ex0104-026.remarq.com>,
Michael Robbins <michael...@us.cibc.com> wrote:

> It might be nice if TMW could publish a reserved word list. If
> a programmer gives his function to another customer, he could
> find himself duping a function name even if he had been dilligent
> enough to check his toolboxes. The recipient of the function
> could have different toolboxes.

Below is a list of basic MATLAB keywords (probably
incomplete). Function names from specialized and personal
toolboxes, of course, cannot be identified a priori...


function eval, feval, global, nargchk, break, else, elseif, end,
error, for, if, return, while, input, keyboard, menu,
pause, dbclear, dbcont, dbdown, dbquit, dbstack,
dbstatus, dbstep, dbstop, dbtype, dbup, dbmex,
case, otherwise, switch, catch, try
demo, expo, help, info, lasterr, lookfor, path, subscribe, type,
ver, version, what, whatsnew, which, clear, disp, length, load,
pack, save, size, who, whos, cd, cedit, delete, diary, dir,
getenv, hostid, ls, matlabroot, pwd, tempdir, tempname, terminal,
unix, clc, echo, format, home, more, matlabrc, quit, startup,
all, any, exist, find, isempty, ishold, isieee, isinf, peaks,
isletter, isnan, isreal, issparse, isstr, eye, gallery, linspace,
logspace, meshgrid, ones, rand, randn, zeros, ans, computer,
flops, nargin, nargout, realmax, realmin, clock, cputime, date,
etime, tic, toc, diag, fliplr, flipud, isreal, reshape, rot90,
tril, triu, compan, hadamard, hankel, hilb, invhilb, magic,
pascal, rosser, toeplitz, vander, wilkinson, abs, acos, acosh,
acot, acoth, acsc, acsch, angle, asec, asech, asin, asinh, atan,
atan2, atanh, ceil, conj, cos, cosh, cot, coth, csc, csch, exp,
fix, floor, gcd, imag, lcm, log, log10, real, rem, round, sec,
sech, sign, sin, sinh, sqrt, tan, tanh, bessel, besseli, besselj,
besselk, bessely, beta, betainc, betaln, ellipj, ellipke, erfcx,
erfinv, expint, gamma, gammainc, gammaln, legendre, log2, pow2,
rat, erf, erfc, rats, cond, det, norm, null, orth, rcond, rank,
rref, subspace, trace, chol, inv, lscov, lu, pinv, qr,
balance, cdf2rdf, eig, hess, poly, qz, rsf2csf, schur, svd, expm,
funm, logm, sqrtm, qrdelete, qrinsert, cross, dot, cumprod,
cumsum, max, mean, median, min, prod, sort, std, sum, trapz,
del2, diff, gradient, corrcoef, cov, conv, conv2, deconv, filter,
filter2, abs, angle, cplxpair, fft, fft2, fftshift, ifft, ifft2,
nextpow2, unwrap, polyder, polyeig, polyfit, polyval, polyvalm,
residue, roots, griddata, interp1, interp2, interpft,
fplot, fzero, ode23, ode45, quad, quad8, spdiags, speye,
sprandn, sprandsym, find, full, sparse, spconvert, issparse, nnz,
nonzeros, nzmax, spalloc, spfun, spones, gplot, spy, colperm,
dmperm, randperm, colmmd, symmmd, symrcm, condest, normest,
sprank, entree, spaugment, spparms, symbfact, fill, loglog, plot,
semilogx, semilogy, bar, comet, hist, polar, compass, errorbar,
feather, fplot, rose, stairs, stem, grid, gtext, legend, text,
title, xlabel, ylabel, cart2pol, pol2cart, zoom, comet3, fill3,
plot3, clabel, contour, contour3, contourc, image, imagesc,
pcolor, quiver, slice, mesh, meshc, meshz, slice, surf, surfc,
surfl, waterfall, axis, caxis, colormap, hidden, shading, view,
viewmtx, zlabel, cylinder, sphere, cart2sph, sph2cart, capture,
clf, close, figure, gcf, graymon, newplot, refresh, whitebg,
axes, cla, gca, hold, ishold, subplot, line, patch, surface,
uicontrol, uimenu, drawnow, gco, get, reset, rotate, set,
uigetfile, uiputfile, orient, print, printopt, getframe, movie,
moviein, ginput, rbbox, bone, contrast, cool, copper, flag, gray,
hsv, hot, jet, pink, prism, white, brighten, colorbar, hsv2rgb,
rgb2hsv, rgbplot, spinmap, diffuse, specular, surfnorm,
sound, auread, auwrite, lin2mu, mu2lin, wavread, wavwrite,
blanks, deblank, findstr, setstr, str2mat, string, strrep,
strtok, isletter, lower, strcmp, upper, int2str, num2str,
sprintf, sscanf, str2num, dec2hex, hex2dec, hex2num, fclose,
fopen, fread, fwrite, fgetl, fgets, fprintf, fscanf, feof,
ferror, frewind, fseek, ftell, wk1read, flat,
wk1write, kron, xor, ButtonDownFcn, Clipping, Interruptible,
Parent, Userdata, Visible, CaptureRect, CurrentFigure, Diary,
DiaryFile, Echo, Format, FormatSpacing, PointerLocation,
ScreenDepth, TerminalOneWindow, TerminalProtocol, Units,
BackingStore, Color, Colormap, CurrentAxes, CurrentObject,
InvertHardcopy, KeyPressFcn, MenuBar, MinColormap, Name,
NextPlot, NumberTitle, PaperUnits, PaperOrientation,
PaperPosition, PaperType, Pointer, Position, Resize, ShareColors,
WindowButtonDownFcn, WindowButtonMotionFcn, WindowButtonUpFcn,
Box, CLim, CLimMode, ColorOrder, DrawMode,
FontAngle, FontName, FontSize, FontWeight, GridLineStyle,
LineStyleOrder, LineWidth, NextPlot, TickLength, TickDir, Title,
View, XColor, XDir, Xform, XGrid, XLabel, XLim, XLimMode, XScale,
XTick, XTickLabel, XTickLabelMode, XTickMode, YColor, YDir,
YGrid, YLabel, YLim, YLimMode, YScale, YTick, YTickLabel,
YTickLabelMode, YTickMode, ZColor, ZDir, ZGrid, ZLabel, ZLim,
ZLimMode, ZScale, ZTick, ZTickLabel, ZTickLabelMode, ZTickMode,
CallBack, ForegroundColor, HorizontalAlignment,
Max, Min, String, Style, Value, Accelerator, Checked, Enable,
Label, Separator, EraseMode, LineStyle, LineWidth, MarkerSize,
Xdata, Ydata, Zdata, Rotation, VerticalAlignment, CData,
EdgeColor, FaceColor, MeshStyle, XData, YData, ZData, cat,
flipdim, ndgrid, ndims, permute, ipermute, reshape, shiftdim,
squeeze, sub2ind, ind2sub, cell, cell2struct, celldisp, cellplot,
num2cell, fieldnames, getfield, rmfield, setfield, struct,
struct2cell, class, isa, inferiorto, superiorto, base2dec,
bin2dec, char, dec2base, dec2bin, mat2str, strcat, strmatch,
strncmp, strvcat, iscell, isequal, isfinite, islogical,
isnumeric, isstruct, logical, addpath, assignin, edit, editpath,
evalin, fullfile, inmem, inputname, mfilename, mexext, pcode,
profile, rmpath, varargin, varargout, warning, web, airy,
besselh, condeig, condest, dblquad, mod, normest, calendar,
datenum, datestr, datetick, datevec, eomday, now, weekday,
ode113, ode23s, ode15s, odefile, odeget, odeset, cholinc, luinc,
repmat, sprand, bicg, bicgstab, cgs, eigs, gmres, pcg, qmr, svds,
bitand, bitcmp, bitget, bitmax, bitor, bitset, bitshift, bitxor,
convhull, cumtrapz, delaunay, dsearch, factor, inpolygon,
isprime, nchoosek, perms, polyarea, primes, sortrows, tsearch,
voronoi, interp3, interpn, ndgrid, intersect, ismember, setdiff,
setxor, union, unique, area, bar3, bar3h, barh, pie, pie3,
plotyy, box, datetick, quiver3, ribbon, stem3, trisurf, trimesh,
contourf, colordef, autumn, colorcube, lines, spring, summer,
winter, dialog, BusyAction, Children, CreateFcn, DeleteFcn,
HandleVisibility, Selected, SelectionHighlight, Tag,
AmbientLightColor, CameraPosition, CameraPositionMode,
CameraTarget, CameraTargetMode, CameraUpVector,
CameraUpVectorMode, CameraViewAngle, CameraViewAngleMode,
DataAspectRatio, DataAspectRatioMode, FontUnits, Layer, NextPlot,
PlotBoxAspectRatio, PlotBoxAspectRatioMode, Projection,
TickDirMode, XAxisLocation, YAxisLocation, CloseRequestFcn,
Dithermap, DithermapMode, IntegerHandle, PaperPositionMode,
PointerShapeCData, PointerShapeHotSpot, Renderer, RendererMode,
Resize, ResizeFcn, CDataMapping, EraseMode, Marker,
MarkerEdgeColor, MarkerFaceColor, AmbientStrength, CDataMapping,
DiffuseStrength, FaceLightingAlgorithm, Faces, FaceVertexCData,
NormalMode, SpecularColorReflectance, SpecularExponent,
SpecularStrength, VertexNormals, Vertices, CallbackObject,
ErrorMessage, ErrorType, ShowHiddenHandles,
TerminalHideGraphCommand, TerminalDimensions,
TerminalShowGraphCommand, ListboxTop, SliderStep, dragrect,
inputdlg, msgbox, questdlg, rbbox, selectmoveresize, uiresume,
uiwait, waitfor, scatter, scatter3, pagedlg, printdlg, cholinc,
cholupdate, ifftshift, ode23t, ode23tb, qrupdate, strcmpi,
strncmpi, mislocked, mlock, munlock, copyfile, mkdir, hdfan,
hdfdf24, hdfdfr8, hdfh, hdfhd, hdfhe, hdfml, hdfsd, hdfv, hdfvf,
hdfvh, hdfvs, camdolly, camorbit, campan, camroll, camzoom,
campos, camproj, camtarget, camup, camva, daspect, pbaspect,
xlim, ylim, zlim, camlight, lightangle, fminbnd, fminsearch,
lsgnonneg, gcbo, int8, int16, int32, double, open, textread,
dlmread, saveas, single, str2double, texlabel, complex, cellfun,
blkdiag, fminbnd, fminsearch, lsqnonneg, optimset, optimget,
evalc, symvar, loadobj, saveobj, java, profreport, findfigs,
hdfgd, hdfpt, hdfsw, histc, ezcontour, ezcontourf, ezmesh.
ezmeshc, ezplot, ezplot3, ezpolar, ezsurf, ezsurfc, coneplot,
contourslice, isocaps, isonormals, isosurface, reducepatch,
reducevolume, shrinkfaces, smooth3, stream2, stream3, streamline,
surf2patch, subvolume, rectangle, DoubleBuffer, XDisplay,
XVisual, XVisualMode, fixedwidth, FixedWidthFontName, imread,
imwrite, imfinfo

__________________________
shumir...@altavista.net
Gunnm: Broken Angel
http://fly.to/broken_angel


Sent via Deja.com http://www.deja.com/
Before you buy.

Bill Whiten

unread,
Mar 26, 2000, 3:00:00 AM3/26/00
to
Michael,

One thing that I like is to terminate each function with return:
This allows you to see that the function is complete, and that lines are
not missing from the end. Also useful when multiple functions are in the
same file.

Another item that has given problems: avoid capital letters in function names.

Regards,

In article <14228c8c...@usw-ex0104-026.remarq.com>, Michael Robbins
<michael...@us.cibc.com> wrote:

> Please help me develop a list of good Matlab programming
> practices. I am not a professional programmer and I'd like to
> develop a standard for my team. I'll start with some things I
> think I know:

-----------
Bill Whiten, W.Wh...@mailbox.uq.oz.au
Julius Kruttschnitt Mineral Research Centre,
The University Of Queensland, Tel: int +61 7 3365 5888
Isles Rd, Indooroopilly, Fax: int +61 7 3365 5999
Brisbane Qld 4068, AUSTRALIA.

Jordan Rosenthal

unread,
Mar 26, 2000, 3:00:00 AM3/26/00
to
Bill

> One thing that I like is to terminate each function with return:
> This allows you to see that the function is complete, and that lines are
> not missing from the end. Also useful when multiple functions are in the
> same file.

It's really interesting to see how different people think about things. I
almost never use the return function unless it's absolutely necessary to do
so. Although your reasoning for using the return function makes perfectly
good sense, I guess I am of the viewpoint that why bother writing it if you
don't need it. Heh...to each their own. :)

Jordan


Michael Schweisguth

unread,
Mar 26, 2000, 3:00:00 AM3/26/00
to
from my experience, i put code after the return that doesnt get
executed-- by mistake. ;-(

Jordan Rosenthal (j...@ece.gatech.edu) wrote:

: It's really interesting to see how different people think about things. I

Peter J. Acklam

unread,
Mar 27, 2000, 3:00:00 AM3/27/00
to
Michael Robbins <michael...@us.cibc.com> writes:
>
> It might be nice if TMW could publish a reserved word list.

Matlab has very few reserved words, if you by "reserved word" mean
a name that can not be assigned to.

Defining "reserved word" as a Matlab builtin function whose name
can not be used as a variable identifier (the name can not be
assigned to) and whose name also matches the reguar expression
^[A-Za-z][A-Za-z0-9_]{0,30}$, I found the following 16 words with
Matlab 5.3.0.10183 (R11)

break case catch dbcont
else elseif end for
global if otherwise persistent
return switch try while

Bert Jagers

unread,
Mar 27, 2000, 3:00:00 AM3/27/00
to
In article <wkity8p...@math.uio.no>,

jac...@math.uio.no (Peter J. Acklam) wrote:
> Michael Robbins <michael...@us.cibc.com> writes:
> >
> > It might be nice if TMW could publish a reserved word list.
>
> Matlab has very few reserved words, if you by "reserved word" mean
> a name that can not be assigned to.
>
> Defining "reserved word" as a Matlab builtin function whose name
> can not be used as a variable identifier (the name can not be
> assigned to) and whose name also matches the reguar expression
> ^[A-Za-z][A-Za-z0-9_]{0,30}$, I found the following 16 words with
> Matlab 5.3.0.10183 (R11)
>
> break case catch dbcont
> else elseif end for
> global if otherwise persistent
> return switch try while
>
> Peter

Well that's almost true, but not quite ...

One can assign values to variables with these names using the command
assignin, e.g.

assignin('base','else',1)

is perfectly acceptable. Accessing the data stored in these variables
seems to be only possible using evalin, e.g.

G=evalin('base','else')

returns 1. By this, I don't want to say that it is good programming
practice to use variables with these or any other function's name.

Note: clear works in the normal way to clear these variables, so, no
riddle in this thread :)


Bert

Michael Schweisguth

unread,
Mar 28, 2000, 3:00:00 AM3/28/00
to
i gues that when a team writes a product, than the the entire MATLAB API
is "reserved," especially since when i was working on this project, we
let our customers write "plugins."

Peter J. Acklam (jac...@math.uio.no) wrote:
: Michael Robbins <michael...@us.cibc.com> writes:
: >
: > It might be nice if TMW could publish a reserved word list.

: Matlab has very few reserved words, if you by "reserved word" mean
: a name that can not be assigned to.

: Defining "reserved word" as a Matlab builtin function whose name
: can not be used as a variable identifier (the name can not be
: assigned to) and whose name also matches the reguar expression
: ^[A-Za-z][A-Za-z0-9_]{0,30}$, I found the following 16 words with
: Matlab 5.3.0.10183 (R11)

: break case catch dbcont
: else elseif end for
: global if otherwise persistent
: return switch try while

: Peter

: --

John Williams

unread,
Mar 28, 2000, 3:00:00 AM3/28/00
to
Peter J. Acklam wrote:
>
> Michael Robbins <michael...@us.cibc.com> writes:
> >
> > It might be nice if TMW could publish a reserved word list.
>
> Matlab has very few reserved words, if you by "reserved word" mean
> a name that can not be assigned to.
>
> Defining "reserved word" as a Matlab builtin function whose name
> can not be used as a variable identifier (the name can not be
> assigned to) and whose name also matches the reguar expression
> ^[A-Za-z][A-Za-z0-9_]{0,30}$, I found the following 16 words with
> Matlab 5.3.0.10183 (R11)
>
> break case catch dbcont
> else elseif end for
> global if otherwise persistent
> return switch try while

Strictly speaking you are correct, however as kimji so graphically
pointed out there are literally hundreds of toolbox functions who's
names can be inadvertantly redefined. What if TMW introduced an
equivalent to the C/C++ directive #pragma, to flag functions which were
deliberate redefinitions. That way the matlab pcode
compiler/interpreter could issue a warning (or error, in a "strict"
mode) when a function was redefined without a preceeding #pragma
directive.

Do TMW employ specialist compiler/language designers, or is what we see
today just the evolution of a legacy command interface (which I admit
usually works very well)? It seems like a few backwards-compatible
language extensions could go a long way to improving program
correctness.

Regards

John (wearing his Matlab T-shirt to work today!)

Marc Rauw

unread,
Mar 28, 2000, 3:00:00 AM3/28/00
to
About a year ago, I discovered a very useful book about general
software construction techniques. I found many of its tips and tricks
to be suitable for Matlab programming as well.

Steve McConnell, 'Code Complete: A Practical Handbook of Software
Construction', Microsoft Press, 1993, ISBN 1-55615-484-4

-Marc

Michael Schweisguth

unread,
Mar 29, 2000, 3:00:00 AM3/29/00
to
when i was thinking about this, the politically correct thing to say
isnt "backwards-compatible," but "end-user preferences' compatibility."

visual basic is doing this in the next release.

if you want fast compiled code, you would go toward the declartive.

if you want slower, RAD code, then you would go toward the implicit.

it seems that VB is moving away from the notion of one tool for RAD
and another for speed.

sort of like the JPEG compression quality parameter-- one tool, with
a few powerful parameter.

John Williams (ja.wi...@student.qut.edu.au) wrote:

: Do TMW employ specialist compiler/language designers, or is what we see

John Williams

unread,
Mar 29, 2000, 3:00:00 AM3/29/00
to
Michael Schweisguth wrote:
>
> when i was thinking about this, the politically correct thing to say
> isnt "backwards-compatible," but "end-user preferences' compatibility."

You're joking right? I hope so :)

[SNIP]

John W.

Michael Schweisguth

unread,
Mar 30, 2000, 3:00:00 AM3/30/00
to
hee, hee! i really was trying to be politically correct!

with VB, it supposedly will default to "strick type checking," but if
you perfer, you can use "loose type checking."

or, one could say: "use the new way, or use the old way."

a poster to this news group wanted really loose checking:

if (0)
i would like to put free form comments here.
end

now, this could be added as a "user preference" rather than
a language mandate:

%#pragma loose

if (0)
i would like to put free form comments here.
end;

i remember DEC C used to actually correct my C code for me if
it thought that a semicolin was missing, etc... it was pretty
slick. but, if you thought that this introduced errors, than
you could use a compiler flag to tell the compiler: "dont do
automatic corrections." some people like myself werent horried
by the feature, others were.

John Williams (ja.wi...@student.qut.edu.au) wrote:

Michael Robbins

unread,
Apr 5, 2000, 3:00:00 AM4/5/00
to
I will try to summarize this thread soon; the markets have been a
little crazy, if you haven't noticed, so it may take me a little
while to get around to it.

BTW, let me take a few lines to thank all of you for your
responses in this thread and in the many others that you have
contributed to. Your help is greatly appreciated.

Michael Robbins

unread,
Apr 11, 2000, 3:00:00 AM4/11/00
to
I was reading 'Code Complete: A Practical Handbook of Software
Construction' (Steve McConnell, Microsoft Press, 1993, ISBN
1-55615-484-4), as recommended by Marc Rauw.

He remarks that he thinks it is detrimental to combine global
variables into one large structure and pass it back and forth as
a parameter. He writes that if you're variables need to be
global, just keep them global.

I suggest that for routines that require large, and similar,
parameter lists , a large structure could provide easy access and
organization to an otherwise obscured and motley list of
variables.

Any thoughts?

Matt Feinstein

unread,
Apr 11, 2000, 3:00:00 AM4/11/00
to
On Tue, 11 Apr 2000 06:39:40 -0700, Michael Robbins
<michael...@us.cibc.com> wrote:

>I was reading 'Code Complete: A Practical Handbook of Software
>Construction' (Steve McConnell, Microsoft Press, 1993, ISBN
>1-55615-484-4), as recommended by Marc Rauw.
>
>He remarks that he thinks it is detrimental to combine global
>variables into one large structure and pass it back and forth as
>a parameter. He writes that if you're variables need to be
>global, just keep them global.
>
>I suggest that for routines that require large, and similar,
>parameter lists , a large structure could provide easy access and
>organization to an otherwise obscured and motley list of
>variables.
>
>Any thoughts?
>

Maybe the point is that -truly- global quantities ( for example, the
minimum timestep in a simulation) are already in a well-defined set,
so there's no need to segregate them further with additional
structures. This suggests (sensibly enough) that a point of using
structures is to help control visibility, e.g., if some quantities
are needed in an initialization phase but not at other times, you
should put them into an InitData structure and pass that structure to
functions that need it.

--
Matt Feinstein
mf...@aplcomm.jhuapl.edu
Organizational Department of Repeated
and Unnecessary Redundancy

Michael Robbins

unread,
Apr 11, 2000, 3:00:00 AM4/11/00
to
This does not describe my situation. I have some data that I use
in nearly every major routine; I have fifty or so of these
routines. Rather than pass 30 or 40 variables to each routine, I
was thinking of arranging those variables into a structure, and
passing the structure. (Now I just declare these variables
global).

Pekka Kumpulainen

unread,
Apr 12, 2000, 3:00:00 AM4/12/00
to
I think structs are very handy in passing arguments to functions. I too have a
lot of functions needing similar information, which I have arranged in a struct
and pass is to functions. And now if or when I notice that I need this and that
from main program in these subroutines, I just add those things to the struct
and they are in the function, no need to rewrite argument lists.
Cells are sometimes handy when i need different arguments to functions. Nice for
example in opening database connections, where we need different number of
arguments with different drivers.
myargs =getdbinfo(Whichdrivers);
Connection = database(myargs{:});

or printing:
myargs = getprintargs(my_great_struct_of_parameters)
for "whatever"
do_stuff
print(myargs{:})
end

I have no background in programming and now that MATLAB 5 gives so many possible
ways to do things it is difficult to choose the structure for my programs.

Michael Robbins

unread,
Apr 12, 2000, 3:00:00 AM4/12/00
to
> i remember DEC C used to actually correct my C code for me if
> it thought that a semicolin was missing, etc... it was pretty
> slick.

I think the Matlab major mode for Emacs will do this for you.

Michael Robbins

unread,
Apr 12, 2000, 3:00:00 AM4/12/00
to
Good Matlab Programming Practices

(please continue adding to this thread if you want).

THANK YOU to all you that contributed, especially the usual
suspects that
contribute selflessly to this forum on a regular basis!

DISCLAIMER: I tried to summarize this thread. Please do not be
upset if
I didn't include your suggestion. I may have thought it
inappropriate for
my application; I may not have understood it; I may have missed
it.

ALSO, this is not a substitute for reading the thread, or the
forum for
that matter.

You can e-mail me for a MS Word or TXT formatted version of this
summary at michael...@us.cibc.com. The Word version has
different fonts, etc.

1. READABILITY & ORGANIZATION
1.1 Use structures instead of globals; pass the structures to
and from
functions. This keeps the functions modular and the
variables
obvious. It also helps organize the variables.
1.2 Use strings and SWITCH as a proxy for enumerated types,
it's easy
to use, fast and very readable:
fruit='apple';
switch(fruit)
case 'apple', fun1;
case 'banana', fun2;
end;
1.3 Use EVAL, FEVAL, EXIST, and other self modifying code
sparingly.
It may be really fun and very flexible, but its very
confusing
if you're not the one debugging it. Do not use EXIST to
repair
faults in programming logic.
1.4 Avoid MEX files when possible; K.I.S.S. (Keep It Simple,
Stupid).
Most of the time, vectorization is the appropriate
solution and
it allows us to keep most everything in one language, open
and
easily modified.
1.5 Use long variable names with underscores; it helps me
avoid a
great deal of documentation (ie.
delivery_yield_using_unwind_RP)
1.6 Make good use of comments! Try using headers. Avoid the
if(0)
construct, it is difficult to find, especially if you are
using an
editor that offers syntactical highlighting (ie. Medit ,
Emacs,
Xemacs, TextPad).
1.7 It's nice to line up equal signs, spaces, and commas; this
makes
it easy to spot errors in similar statements.
1.8 Adopt a guideline for variable usage and commenting style.
A
common coding style is NOT necessary, as many programs
(ie.
Emacs) can reformat style easily.
1.9 Use all capitals for global-type variables, ie. flags and
comments.
1.10 Keep functions small. They may be re-used by other
functions;
besides it makes them easier to read and helps keep you
organized.
1.11 If a function is used only by one other function, include
them in
the same file.
1.12 Use "graceful degredation;" function outputs should
include an
error code. (please continue adding to this thread if you
want).
1.13 You may want to assure the shape of a vector (provided
you know
it's a vector), by using it like this: myfun(x(:)). You
can
check if x is a vector by ~isempty(x) & ( sum(size(x)>1)
<= 1 ) .
1.14 Separate any generic code into another small function.
1.15 Keep lines short by using the continuation character
(ellipsis).
1.16 Large indents can help late at night when those 2-space
indents
are hard to see.
1.17 It is not important that the function name match the file
name,
but it makes life easier.
1.18 Stick to one capitalization scheme throughout your
program. On NT
you can get creative with how you call your functions
since windows
doesn't check case when it goes searching for files.
This brings
up platform independence problems because UNIX is case
sensitive.
2. SPEED
2.1 Use structures of arrays, not arrays of structures, unless
it is
important to your code. Arrays of structures are slow.
Avoid DEAL,
it's often slow. For example, converting data of the
form
t(1).rt_coupon=.045;
t(2).rt_coupon=.050;
t(3).rt_coupon=.060;
by typing s.coupon=[t.rt_coupon] can produce great speed
advantages
2.2 There is no need to duplicate data. Instead of using
s.coupon.TU1=[5.625 5.500 5.000] and s.coupon.FV1=[5.500
6.000],
you can do this:
s.coupon=[5.625 5.500 5.000 6.000]
TU1_index=[1 2 3];
FV1_index=[2 4];
Now you can reference s.coupon(TU1_index) and
s.coupon(FV1_index).
2.3 Preallocate when possible, it enhances speed and often
makes the
code easier to read. But note, if You declare ZEROS or
ONES
matrices (homogeneously) MATLAB may not improve the speed
but if
you use other special function (such as RAND or LINSPACE)
it may
help.
2.3 Creative use of FIND, PROD, SUM, CUMSUM, NaN, REPMAT,
RESHAPE,
ONES and ZEROS can really help vectorize your code, but
try not
to make the code too cryptic. There is a tradeoff between
execution time and readability. If your statement is
cryptic,
either include an equivalent (but slow and easy to read)
version
in a comment or write a MEX file.
3. EASE OF USE
3.1 Rather than populate variables with assignments (X=1, Y=3,
etc),
read in a CSV file. This allows an inexperienced user to
modify
these values without having to touch the code.
4. GENERAL GOOD PRACTICE
4.1 Use TRY, CATCH, END generously. Error checking is
important.
It is far better to anticipate errors, but at least your
code
won't blow up.
4.2 Using the interpreter is too easy! Serious code
review/reading,
Sometimes printing the routine and reading it should
precede
machine execution. This is the best defense against that
class
of bugs who do not race across the carpet in full view.
4.3 Routinely use the debugger to follow example execution of
code.
Can't emphasize this enough. Lookout for the code that
worked
without having to be debugged in detail!
4.4 Whenever you have a block of new code that you're getting
ready
to check in, print it out, grab a highlighter, and step
through
it in the debugger. Highlight every code line that gets
hit, and
keep using different combinations of inputs until every
code line
is highlighted. It doesn't take very long, and it's
definitely
worth it.
4.5 Check for the right number and type of arguments to
functions,
check the output of functions like FOPEN, EVAL, FZERO,
etc. for
failure (e.g. singularities and other numerical problems)
before
carrying out the calculations.

Other items:
· Variable precision arithmetic and symbolic math are wonderful
features
of Matlab (well, Maple), do not forget they exist.
· Also remember EVALIN and ASSIGNIN exist. Using them in a
program is
probably problematic :), but they are very useful for
debugging.
· "The Practice of Programming" by Brian Kernighan and Rob Pike,
Addison-Wesley (1999).
· Steve McConnell, 'Code Complete: A Practical Handbook of
Software


Construction', Microsoft Press, 1993, ISBN 1-55615-484-4

Michael Robbins

unread,
Apr 19, 2000, 3:00:00 AM4/19/00
to
Dr. Charles R. Denham has a THROW function on his (very nice)
matlab web page at
http://crusty.er.usgs.gov/~cdenham/snackbar/throw.m
0 new messages