I'm feeling pensive today as I participate in development activities at MathWorks for Release 2006b. We are following a 6-month release schedule and the naming convention for the twice yearly releases is year followed by first "a" and then "b". This schedule requires discipline on many fronts, including for developers. Over the years, we have encountered some truisms for us regarding code we ship; they are are not all novel in the industry and have served us and our users well.
Contents
Good Programming Practices, Some Specific to MATLAB
People develop their own best practices over time, ranging from cosmetic issues to ones affecting the behavior or viability of a program. Tools such as mlint, which I wrote about here, provide one way to audit code. You can see more examples of code metrics used on MATLAB Central's File Exchange.
At MathWorks, we have several, sometimes competing, goals with respect to our code, and especially to M-files that we ship. Here's a list of some ideas that work well for us.
- Minimize the amount of code you write.
- Minimize the complexity of the code you write.
- Avoid speculative generality.
- Avoid premature optimization.
- Use components as they were designed to be used.
- Create functions instead of scripts.
- Make the code general and document ranges and exceptions.
- Write and run tests.
MATLAB Trade-Offs
A classic trade-off in MATLAB is time versus memory. You can often vectorize code, but in doing so, you add an additional memory burden.
On the MATLAB newsgroup, we've seen discussions about avoiding repmat and we also had similar discussions in these two blog articles: Scalar Expansion and More and More on expansion: arrayfun. What's the reason? It's because, in order to fully vectorize the code, potentially really large intermediate arrays are created, used, and tossed away.
When Steve Eddins, author of Steve on Image Processing, worked on the function inpolygon, he found that he could fully vectorize the code. If he did so, though, there were plenty of realistic cases using it that caused MATLAB to run out of memory. To avoid this, Steve chunked up the code, and you can see this comment:
dbtype inpolygon 51:52
51 % Choose block_length to keep memory usage of vec_inpolygon around 52 % 10 Megabytes.
Within the 10Mb memory limits, the code is vectorized (see lines 53:83, from which the subfunction vec_inpolygon is called).
Use the MATLAB Profiler to Find Bottlenecks
I remember another case from 1988 or 1989, near the time when we introduce MEX-files. It illustrates well for me why I should not rely on my intuition, but I should instead use tools to help me measure the actual effects I am hoping to influence. Despite by best efforts to think through problems as thoroughly as I think I can, I often find that, left to my own devices, I focus on the central issues, and it's often the more tangential ones that surprisingly consume the CPU cycles. So, much better if I measure than guess.
We were trying to speed up function functions, without the benefit of the MATLAB profiler. So we did experiments, first converting one of the ode solvers to C, and then turning the actual equations into C. Using only the MEX-function for the solver bought us a factor of 2. Using only the MEX-function for the equations also bought us a factor of 2. Can you guess what using both MEX-files simultaneously bought for us? You might guess a factor of 4. That's not what we found. We found a factor of 15 instead.
MATLAB has changed a lot since version 3, so what was true then with respect to performance is not, in detail, relevant today.
What Coding Principles Matter to You?
I've barely scratched the surface of what characteristics of your code might be the most important in various situations. What's important to you? Tell me here.
Published with MATLAB® 7.2

From your principles:
Avoid speculative generality.
Make the code general and document ranges and exceptions.
What is the difference between general code and “speculative generality”? Is there a line between the two?
I think there is sometimes a gray area, actually. But there is a real difference in some cases. Here’s a couple of examples.
Extend a function that works correctly for “small” input to the rest of the real line. What is “small”? Do you check for it and error if the input doesn’t meet the criteria? If so, you are okay. If you think you might need it later for a different range, it’s best to make that clear with documentation and an error, until you upgrade it. In this case, e.g., bessel functions with large input, I would prefer to make the function work correctly from the start. Then I can always rely on it. To me, this fits more closely into Make the code general and document ranges and exceptions.
Extend a function that works for real input onto the complex plane. And spend lots of time figuring out how to do the analytic continuation and defining appropriate branch cuts so inputs can be anywhere in the complex plane. Again, either error and document carefully, or implement. Is it worth implementing? Can you imagine using it that way, or is it just cool? If you don’t really see your way clear to a definite use case, even if you won’t need it for that right away, it might not be worth the effort right now. To me, this one fits more closely into Avoid speculative generality.
This may be obvious, but I’ve always found it easiest to work in dimensionless units for as much of a program as possible.
Test driven development is one key to good software development. Write tests early and often and less problems arrive later. When coding in C under Linux/LynxOS I use “Check”
http://check.sourceforge.net.
When coding under Matlab I found no decent testing framework so I wrote my own.
One of the things I find about writing tests is not only do they provide regression error protection but they help me understand my own code and designs. I may come back to some obscure corner of an API I have written after a month and forget exactly how I intended it to be used. If I have a test case for it then more often than not it makes clear to me what I was up to.
http://xtargets.com/cms/Tutorials/Matlab-Programming/MUnit-Matlab-Unit-Testing.html
which you can download and use. It’s simple to get started with and integrates into the Matlab web browser for report generation and interactive testing.
i want some help in numerical analysis,if u can help me out with the Bessel’s central diffrence formula using MATLAB
Please see this message from Steve’s blog: http://blogs.mathworks.com/steve/category/blog-policies/
Hello!
I have a function I wrote that is very similiar to FREAD in terms of input arguements:
A = FREAD(FID,SIZE,PRECISION,SKIP,MACHINEFORMAT)
Here, SIZE and SKIP arguements are optional that is the function shows an intelligent behaviour when we type
a = fread(fid,precision,machineformat)
My function also has these optional arguements depending on the type of inputs. So, can you suggest basic methods/guidelines for distributing the input arguments properly, and a robust error checking inside the m-file?
Thank you!
Oktay
Oktay-
I recommend you look at M-files we ship with MATLAB that seem similar in the idea of the extra inputs and see how the error checking is done there. One way that’s newer is to use an inputParser object for at least part of the work. Another tool is the function assert.
–Loren