Stuart’s MATLAB Videos

Watch and Learn

Top 10 MATLAB code practices that make me cry 83

Posted by Doug Hull,

I was chatting with the Application Support Engineers here at MathWorks about what kind of coding practices cause avoidable pain for MATLAB users.

Without further ado: The top ten and quick ways to not do them:

10.) Not using left hand zeros

Certain things must be learned the hard way. I learned this one bleary eyed evening as an undergraduate. Well into the night working on a MATLAB homework assignment that would “take ten minutes, fifteen if you type slow.” (yes, Dr. P, 13 years later I still remember that one! -smile-)

It is really easy to mistake a .5 for a 5. That is why I always use a left hand zero like 0.5.

9.) Plotting enormous amounts of data

My computer monitor has 2.3 million pixels, total. If I try to plot datasets with huge amounts of data in them, they will very often just look like a blob and slow the machine down in the process.

There is very often a better visualization available. Here is an example of changing the visualization to make it clearer and less taxing on memory.

8.) GUIs with garish color schemes

In an effort to emphasize certain buttons on their GUI, people will change the colors of them. Very quickly they end up with several different colored buttons, a non-standard background color, extra big buttons, etc…

Sticking with the default colors is a good move. Most professionally produced software sticks with the defaults, it ends up looking better.

7.) Using ans, or any other MATLAB function as a variable name or function.

When you do this, MATLAB will call whichever one is higher on the path. Some strange behavior can occur when you redefine a function like that. Unfortunately, MATLAB does not catch you doing this for the most part.

I try to avoid using variables and function names that are common terms like, mean, filter, etc… If there is any doubt, use the which command to find out if a function exists of a given name.

6.) Not using white space to good effect in code.

Even though you can put several commands on one line if separated by a semicolon, these lines can often be hard to notice. Not putting blank lines between sections of code can also make it harder to read.

White space is free, use it to make your code look good.

5.) Bad variable names

Variable names are often the only commenting that gets added to people’s code. Meaningful variable names are a great opportunity to make the meaning of your code more clear and to some degree, self-documenting.

Avoid using variable names like temp, aaa, r247899921. These just do not convey as much information to people that have to read your code as flagPassedInspection, centroidX, fidCurrentFile.

4.) Hard coding data into the MATLAB code file

Some people like to put some of their variables directly into the MATLAB code. That makes sense for small variables (I will let you define what small means for you). For instance, I would feel fine putting a 3×3 matrix into my code. I would think twice about a 10×10, and I would start using one of our file readers for a 100 x 100.

The worst instance I ever saw of this was some MATLAB code where the .M file was 4 GIG (not a mistake) long. All but a small amount of that was data written out in ASCII. This makes your code hard to read, maintain and understand.

3.) Exceptionally long files

Even if not hard coding data into a MATLAB code file, it is easy to just add on “just a few more lines of code” until you have thousands of lines of code in a single script. This makes your code hard to understand.

I try to use the rule that I should be able to see an entire script or function in one screen. This is not entirely practical, so I will at least break the code into logical sections that do fit on screen all at once.

2.) Globals

I have never seen MATLAB code where globals were the right thing to do. Exception: functions TIC and TOC use them quite nicely. Most of the time I have seen globals being used it was a situation where the code author did not understand scoping of variables. Rather than pass variables from one function to another, they were just being made global.

Why are people cautioned against using global variables? I will leave that to the consensus on Wikipedia.

1.) Eval

EVAL is right up there with globals. MATLAB user will often string together MATLAB commands to get sequential variable names s1, s2, s3… only to then have to use another EVAL statement to work with the sequential variable names! Very often, a cell array indexed with s{1}, s{2}, s{3}… would work much better.

I will also find that people use EVAL to get at certain fields in a structure (for example data.alpha) when they do not know at the time of writing the code what field they will want. Now the “.parens” notation makes that easier.

The other most common place to see people use EVAL when it is not needed is when they are trying to load a file or some other function like that. Very often they are trying to EVAL a string like “load filename.mat” not realizing that there is a functional form where you can use fileNameString = ‘filename.mat’; load(fileNameString)

Follow @stuartmcgarrity on Twitter to be notified of new posts.

83 CommentsOldest to Newest

matt fig replied on : 1 of 83
Given some of your previous writings, I am surprised that you left out premature and/or unnecessary optimization. You know, where a person spends 3 hours to vectorize a code that is intended to only run once or twice at 2 seconds per shot. Number 11?
dhull replied on : 2 of 83
@Matt, There was that and eight others that did not make the list. Premature optimization is often indistinguishable from just hard to read code! I don't always recognize it as an optimization! :) I was hoping to hear from people to see what theirs were. Top 19 did just not have the same ring to it! I guess if I think of one more, I can have the "top ten that make me cringe (instead of cry)" :)
Ryan Gray replied on : 3 of 83
6. Whitespace - YES! So much code I see seems to be from when a blank line meant a blank (wasted) card, spaces in the line meant your code took more cards to print, and more cards were a burden to carry and keep ordered. For a younger generation, it seems to be from when you only had 80x25 character screens, and whitespace meant you couldn't see much code at once. Let go of the old habits because you don't have those constraints. Let your code breathe, and be amazed at how many errors you can spot now.
Ryan Gray replied on : 4 of 83
5. Bad variable names - I often see bad variable names with copious accompanying comments that are having to explain what each variable's purpose is.
Ryan Gray replied on : 5 of 83
One common thread to many of these things is feature discovery. It's natural that you start to learn a new language's basic parts. With that small kernel you can usually cobble together anything you need to do, given enough time and dwelling on doing it rather than taking a time to see if there's another way to do it, knowing it will save you time over-and-over later rather than now. MATLAB's active M-Lint in the editor helps with some discovery. Good examples and cross-referencing in the documentation also help.
Matt Whitaker replied on : 6 of 83
Great Topic: My personal peeves: 1) People who ignore mlint messages. Repeat after me : mlint is your friend, mlint is your friend. 2) Untidy code and crummy variable names: a simple ctrl-A, ctrl-I will clean up 99% of the code that gets messy as you edit. And for the love of all that is holy do not give me variable names that start with 'my' anything. 3) Hard coding just about any non-trivial data (and some seemingly trivial) in the code will bite you down the line.
Petter replied on : 8 of 83
Using i in a loop is fine to me. I would say the opposite: always use the notation "1+1i" when writing complex numbers.
Jayveer Thakoor replied on : 9 of 83
i disagree with not using globals. Global variables are very practical when you have large data sets that are being modified within a function. The moment you change a variable inside a function, matlab makes a copy which implies using a lot more memory. that's a big problem when you have 800MB sized variables! In such cases, global is extremely convenient - preallocate and update the same one all the time using logical indexing. Far more memory efficient, wouldn't you agree?
dhull replied on : 10 of 83
@Jayveer, That is an excellent point. That is one of the good uses of globals. I have heard of people using them that way, but I have never seen it! I think it is one of those situations where 99% of all global variables give the other 1% a bad name! Doug
StephenLL replied on : 11 of 83
Just an fyi... Rather then use globals I created a handle class with dynamic properties. This way you can pass the class around of big variables. classdef dynoclss < dynamicprops end Then you can do this: x = dynoclss; x.addprop('foo'),1); pass x to your functions and go crazy. Stephen
Petros Mpogiatzis replied on : 12 of 83
I needed to store the arrival times of wavefronts and I used variable (2D array) with the name "times". Well, in Matlab "times" is the name of a function for multiplication... I accidentally figured out the mistake
Doug replied on : 13 of 83
@Stephen Nice! @Petros The reason all (except global) are on here is because I made ALL of these mistakes in the past. Experience is a great teacher! Doug
Matt Whitaker replied on : 14 of 83
@Stephen Very Nice! In the pre classdef days one trick I used was storing large common data in the root's appdata. bigData = rand(1e7,1); setappdata(0,'CommonData',bigData); then when you need it bigData = getappdata(0,'CommonData'); Had to build some framework for managing it but all in all worked pretty well. Matt
OysterEngineer replied on : 15 of 83
Matt Whitaker is correct. When a code module is complete, the M-Lint should be silent.
OysterEngineer replied on : 16 of 83
@Doug, Many of these items are already covered in some of the various MatLab coding style guides. Maybe you could reference your favorite ones.
Ken Garrard replied on : 17 of 83
Nice list. I would add two items which are practices of omission, i.e., not doing the right thing. 11. Not validating function arguments and return values. 12. Inadequate comments, especially if the variable names are not descriptive (#5). For example (without my comments),
t1F = @(b,a) b+a;
t2F = @(b,a) asin(N1/N2*sin(t1F(b,a)));
t3F = @(b,a) t2F(b,a)-a;
t4F = @(b,a) asin(N2/N3*sin(t3F(b,a)));
y1F = @(x,y,b,a) y(1);
y2F = @(x,y,b,a) y1F(x,y,b,a) + (x(2)-x(1))*tan(b);
y3F = @(x,y,b,a) y2F(x,y,b,a) + (x(3)-x(2))*tan(t3F(b,a));
y4F = @(x,y,b,a) y3F(x,y,b,a) + (x(4)-x(3))*tan(t4F(b,a));
It was obvious what the function y4F did when I wrote this 3 years ago and isn't too hard to figure out now. But why figure it out again? Perhaps nested anonymous function calls should be added to the list. Also to two of eval's cousins, str2num and feval, can be very useful and safe. I frequently use str2num, which of course calls eval in a try-catch block, to allow a user to enter parameters such as plot scaling factors as a expressions. Why make someone pull out a calculator when there's a great big one (MATLAB) behind that GUI you wrote for them? Ken
Doug replied on : 18 of 83
@ken Eval's cousins. Yes, they are safer. It is kind of like they are a lawnmower where EVAL is a lawnmower you pick up and use to trim your hedges! Doug
Steve L replied on : 20 of 83
@Ken, Nested anonymous functions aren't a bad coding practice ... as long as it's clear why you've nested them and what each contributes. In your case, I would argue the problem occurs not in the nesting of the functions but in the names of the variables in which you store them. Therefore I'd expand item 5 on the list -- it's not just bad _variable names_ that can cause problems, but bad _identifiers_, which includes things like variable names, function names, struct array field names, and even MAT-file (or other data file) names. Will you remember what's stored in mat123.mat six months from now? How about what's stored in financialDataQ1Y2010.mat?
Markus replied on : 21 of 83
Hi, I don't like the use of some relatively new features of Matlab: 1. The use of anonymous functions, see the list of Ken Gerrard for some horribly unreadable examples. 2. The use of nested functions, they are confusing regarding variable scope. 3. The use of functions like bsxfun without very detailed comments describing what happens. Too bad that the far better understandable for-loops are still soooo slow in Matlab... Markus
Torsten Pietrek replied on : 22 of 83
There is also a use of classes for avoiding global constants: Use constant properties of classes. They are initialized at first time use of the class, so you can make them dependent on a config file, elaborate one time calculations etc. You can group the constants by meaningful class names, use the meta information in the class for validation purposes etc.
Luigi replied on : 23 of 83
I like this post, Why don't you open a wiki page dedicated to MATLAB, I guess the mathworks will find interesting things in there. I agree with most of the things you wrote, These are the things that cause a lot of pain to me: - lack of MACROS, why not include #define operator like in c++ ? - huge overhead time in function calls, especially nested ones. - I would like to pass arrays to function as reference. - globals: why not leaving a dedicated space in the header for globals? wouldn't that be easier? - can not build an arrays of structure, only structure of arrays. If you know how to do it please tell me. - the rotate command in figures is not arc-balled! it only rotates on the centroid. You can spend most of your time rotating the figure like a dog trying to bite his tail, no way to focus what you want to see. - there is no built-in library for data structure like stl containers. This can be very painful when you need it. - HELP MEMORY ERROR: in my opinion it occurs for too small arrays. If I remember something else I will add it later Luigi
Arthur replied on : 24 of 83
Regarding #7, the reuse of MATLAB-defined identifiers, the chief problem with this is that you can't know what functions are defined by MATLAB. I may be working with bare MATLAB at one computer, while another computer may have Simulink and a whole slew of additional toolboxes. From the bare installation, I have no way to know what other functions are floating around out there without checking the website. Fortunately, MATLAB's name resolution rules work in the programmer's favor such that mystery functions you've never heard of in super-awesome-toolbox usually do not cause problems. I've also had the misfortune of needing this behavior to suppress calls to "keyboard" in code I inherited for testing. Add that to the list of things that will make you cry -- using keyboard() instead of assert() or error(). That really messes things up when trying to write automated tests. The converse of #7 is that it is difficult to figure out what toolboxes a piece of code actually uses.
Benjamin Kraus replied on : 25 of 83
One of my personal annoyances is to see an m-file script with the following at the top:
close all; clear all;
This is especially bad when you send your code to other people, who may not realize that your script will wipe out anything they may currently be working on. - Ben
Jason replied on : 26 of 83
I hate when people hard code inputs that are meant to be changed each time, especially file names! Why not just use inputdlg or input functions? They're just as fast to code, especially if you're not doing any error checking on the hard-coded file name anyway. I even see times where multiple lines contain the different file names and commenting and uncommenting occurs. Quite often, the person goes through the trouble of using Windows Explorer to find the file name, copy it, and paste it, save the file, then run the script. At that point, just use uigetfile and be done with it!
Mikhail replied on : 27 of 83
@Luigi My impression is that you try to code Matlab with C++ techniques. - lack of MACROS, why not include #define operator like in c++ ? >> You do not need it in Matlab (also not in Python, not in Ruby, not in Java, not in C#). - huge overhead time in function calls, especially nested ones. >> Agree! That's the cost of using a dynamically typed interpreted language, do not ever try to compare it to C++. But Matlab and C++ have completely different purposes. And with all ultra-efficient build-in Matlab functions your Matlab code programmed properly can be made very fast. - I would like to pass arrays to function as reference. >> Just do it. - globals: why not leaving a dedicated space in the header for globals? wouldn’t that be easier? >> I think this is a very minor point. - can not build an arrays of structure, only structure of arrays. If you know how to do it please tell me. >> What do you want??? - the rotate command in figures is not arc-balled! it only rotates on the centroid. You can spend most of your time rotating the figure like a dog trying to bite his tail, no way to focus what you want to see. >> You are probably right. - there is no built-in library for data structure like stl containers. This can be very painful when you need it. >> Why? You do not need it in Matlab. Newer Matlab Versions have even Hash tables. - HELP MEMORY ERROR: in my opinion it occurs for too small arrays. >> It is also about memory fragmentation.
John replied on : 28 of 83
Fun list. My pet peeves are: -Hyper-dense lines of code. My coworker likes to do this, packing fifteen different function calls into one line. I'm impressed, OK, but I can't read it. -Haphazard indentation. As mentioned above it's so easy to do this right. -Repeating giant chunks of code, but changing one little thing. It's called a "for" loop -- use it!
Jim Maneval replied on : 29 of 83
"One of my personal annoyances is to see an m-file script with the following at the top:

close all; clear all;

This is especially bad when you send your code to other people, who may not realize that your script will wipe out anything they may currently be working on." Very true if you are not expecting the commands. Unless your script is supposed to be working on the problem that is contained in the (assumed base) workspace, I think that all scripts aimed at answering a particular question should start with at least the "clear" command. So many errors can occur when there is some dependency on workspace contents (whether by design or not) for a script to run correctly. Starting from scratch ensures repeatable results wherever the code is run.
Andrew Janke replied on : 30 of 83
My pet peeve is try/catch blocks used for normal control flow. For example, testing whether a struct has a certain field by trying to dereference it and catching the "no such field" error instead of first using a non-erroring test like isfield(). Bad in any language with exceptions, but particularly bad for Matlab because "dbstop if all error" is so useful, and try/catch in the normal control flow will hobble it by triggering spurious error breakpoints.
Kay-Uwe replied on : 31 of 83
Regarding #7: I agree with Arthur, it is difficult to assure not overriding MATLAB functions (I don't really like typing "which" all the time, when coding). That is why I usually put all my code in its own namespace, e.g. work.myfun(..) or for the lazy guys: w.myfun(), so I am at least save in using the function names I like. The additional typing is not an issue to me, thanks to TAB completition.
OysterEngineer replied on : 32 of 83
@Doug, Although it is some 7.5 years old now, I've used Richard Johnson's Style Guidelines to good profit. It is available on the MathWorks File Exchange: I've found that style guides written for other languages have some application to MatLab. Your item #6 on white space fall into this category.
Doug replied on : 33 of 83
Wow, you all had a lot to say while I was on vacation! Some of this does come down to "religious issues". I personally advocate putting clear close all clc at the top of every script because I want things reproducible. I am never worried about clearing out the workspace since everything I do is in a script or function, so I should be able to get back to that point easily.
J.R.! replied on : 34 of 83
I'm gree with Doug on #33! and overall I find very important that things must be reproducible. Another point is the difference between 'clear all' and his good cousin 'clear', because the first one clear also the breakpoints on ALL the functions and scripts you have opened on the M-Editor. but I disagree with 'clc', because with it you clear past error messages, there is enough memory for this.
dhull replied on : 35 of 83
@J.R. It is funny, I use clc specifically because I want to clear the old error messages. I am running the code for a second time specifically to see if my changes fixed the errors. I would not want to confuse myself by thinking that the old error message corresponds to the new code! Doug
P replied on : 36 of 83
Re eval: How would you treat conversion w/o eval? For instance: c=class(a); ... a=double(a);% to perform some arithmetic on a do something to a ... a=eval([c '(a);']); --P
dhull replied on : 37 of 83
@P I did not know, but Loren did!
>> a = uint8(1)

a =


>> className = class(a)

className =


>> a = double(a)

a =


>> a = cast(a,className)

a =

Matt Fig replied on : 38 of 83
I mostly agree with Doug's list, although there are a few exceptions. One that comes to mind is hard-coding the Gauss points and weights into an M-File for integration. I have seen this done and it made sense to do it. Here are some of my pet peeves. - clear all,clc at the start of a function M-File. I do sometimes use HOME instead of CLC. - Use of i or j as a loop index. I always (and only) use double letters as a loop index. For example, ii or jj or kk. That way there is no overwriting of built-ins, and these variables always are known as a loop index. - Many blank spaces between lines in a M-File. - Massive IF-ELSEIF chains instead of a SWITCH. - Not pre-allocating arrays which then grow in a loop. - Recursion. I know, it has it's place, I just can't bring myself to like it. - No help in a function M-File - Dumping intermediate results to the command window. I see this one often. - Programming as if we have infinite precision. Yikes!
dhull replied on : 39 of 83
@Matt, I like the idea of HOME instead of CLC. I will have to try that for a while. ii, jj, kk. That is a nice little convention. Mush like I use vi (Valid Indices) as the output from a find operation. I always know what means. After many goofed up indices with i in a loop, out of frustration, I made up GAPLI (Generic All Purpose Looping Index) I wish I understood recursion better, it often confuses me! I might have to make up a follow up post to this one "ten more MATLAB coding practices that make blog commenters cry!" Thanks! Doug
Benjamin Kraus replied on : 40 of 83
@Matt, @Doug, and @J.R., Regarding 'close all' and 'clear all' at the top of scripts, it sounds like Matt (comment #38) has the same coding practice as I do. In order to make things reproducible I almost always write functions instead of m-file scripts. This way I always know exactly what I'm passing in and what I'm passing out, and I know that the function is starting from a clean workspace of it's own (and I refuse to use 'global' variables). While I'm writing/debugging I may put a "keyboard" as the last line of code, so I can see what's happening before that workspace gets cleared. Once I'm satisfied the function works as desired, I just remove the "keyboard" line. My big reason for *not* wanting "clear all" is that I keep the data I'm working with in structs in the workspace. The data sets tend to be rather large and take a non-negligible amount of time to load from the .mat file I store them in (at least 10-30 seconds to load, if not longer). If the meat of the function only takes 1-2 seconds, it's a lot of overhead to clear the struct then reload it again every time. - Ben
Ross Hatton replied on : 41 of 83
I am very much in agreement with Ben. I work almost exclusively in functions instead of scripts, and often have scratch data in my workspace or extensive state in my open figures. Running a script that has "close all; clear all" at the beginning (or, even worse, buried inside it) nukes all of this state without warning. -Ross
Jonathan replied on : 42 of 83
Put me in the "no clear or close all" camp. I usually have lots of figures open and things in the base workspace and scripts that clear those without warning are no fun. When I start coding something new, I usually test some things at the command line first. If that works out, I put it into a .m function file and continue working. I usually put a debugger breakpoint at the last line so I can inspect the results, and if I want to, I dump relevant variables to the base workspace using assignin('base',....). I reuse the figure numbers each time I run the script. (I usually turn off most figure creation when things look right, but keep a switch so I can use them for diagnostics.) I created a "number increment function", next_function, for this purpose, that works in the following way: next = next_function(10); % generate the increment function next, that will start at 10 figure(next()); clf; % creates and clears figure(10) plot stuff figure(next()); clf; % creates and clears figure(11) plot more stuff etc. In that way, I can easily put new figures in between others, and still keep the figure numbers in order following the order they appear in the code.
Alan B replied on : 43 of 83
I just wanted to mention that I totally agree with Luigi regarding the problem with the 3D rotate command. Another problem for me is that the elevation angle rotation is constrained to (-90 90]. I don't see any reason for this - the azimuth angle is not limited in this way, so why limit the elevation? Also, I can not reach elevation = -90; -88 works, -89 works, but when I reach what should be -90, the plot snaps back to +90, which can be pretty frustrating. I'm stuck with 2007a, so maybe these have been addressed recently, I wouldn't know.
Steve L (MathWorks) replied on : 44 of 83
Luigi asked: "- can not build an arrays of structure, only structure of arrays. If you know how to do it please tell me." It's easy to build either a structure whose fields are arrays:
b = struct('Name', 'Steve', 'BowlingScores', [90 103 86 117]);
or to build an array of structures. Two ways to do so:
s1(1) = struct('Name', 'Steve L', 'Blogger', false);
s1(2) = struct('Name', 'Loren', 'Blogger', true);
s1(3) = struct('Name', 'Doug', 'Blogger', true);
s2 = struct('Name', {'Steve L', 'Loren', 'Doug'}, 'Blogger', {false true true});
isequal(s1, s2) % returns true
Note that while I've used STRUCT to construct these struct arrays, you can do so using normal subscripting.
s3.Name = 'Steve L'; s3.Blogger = false;
s3(2).Name = 'Loren'; s3(2).Blogger = true;
s3(3).Name = 'Doug'; s3(3).Blogger = true;
isequal(s1, s3) % also returns true
Juliette replied on : 47 of 83
Hello Doug, Regarding not using global variables. What is your opinion about using global variables to prevent this type of thing:
function a=myFunction(b,c,d,physicalParameters)
I don't like REDEFINING the mass and the density and all that because it takes up so much extra space. Is it dangerous to have mass and density and all those as global variables ?
dhull replied on : 48 of 83
@Juliette, Are these huge variables? Are you running out of memory? I doubt they are. Making them global is not a recommended practice, it can cause debugging problems later and takes away on of the reasons for using functions- scoping of variables. Doug
Bill Cheatham replied on : 49 of 83
I use globals for debugging and plotting switches. Usually, I'll have one called 'debugYN' and one called 'plotYN'. By changing these booleans at the global level, I can change is my programs will or will not plot, or deliver debugging info. Other options include changing the level of verbosity etc.
Caitlyn replied on : 50 of 83
Doug, I have to agree that using global is horrible, but I have a hard time getting around it most of the time. Currently I'm working on a GUI which requires three script files to run. I'm dealing with 60+ variables that must be passed from one script to the next. From my perspective, it doesn't seem practical to use a function that requires more than 60 inputs. It drives me crazy to see lines of code that extend off to the right of the editor. So is there a way to pass that many varibles without using global? It just seems way more convenient...But I hate using them, so if you have any insight, that'd be great! Caitlyn
doug replied on : 51 of 83
When you say script, I think you mean function as you do not pass variables to a script. If these are all related variables, would it be better to save them into a structure? Then you can pass around a few structures. This has the added advantage of being able to keep the same function signature yet add more fields to the structure as you need more data sent to those functions. Doug
Christine replied on : 52 of 83
Hi Doug, I am working on a GUI right now, that contains a huge number of buttons and panels etc. and all the callback functions are in the .m file. Even if for every callback I write a separate function, that is called by the callback, the .m file is still huge and confusing. Is there a way to structure such .m files logically?
Matt Eicholtz replied on : 53 of 83
@Christine, I sometimes find that putting callbacks (and other subfunctions I may need) in separate m-files makes them more manageable. I'm not sure what you mean by "the .m file is still huge and confusing"? It should be much shorter if you remove the callbacks! Just to be clear, you don't need a callback function in the main m-file to call a separate callback function elsewhere; just make sure the separate m-file is referenced properly for the uicontrol, uipanel, etc.
Christine replied on : 54 of 83
@ Matt Thanks for your response! Can you give me an example how to reference the separate m-file properly for a uicontrol? Maybe you know some sample program, that I could have a look at. By the way, I am using guide to create the GUI.
Roger replied on : 55 of 83
How would you avoid using eval when you have to rename a variable using the string from a cell array and then have to save the new variable as a mat file? example: [pathstr name]=fileparts(Cellarray{i}); exp1=[name,'=varname']; eval(exp1); clear varname pathstr exp2=['save ',name,'.mat ',name]; eval(exp2); where Cellarray is cell array that contains only the filename.ext not the path and varname is a matrix from loop. Also function should not require user interaction other than initial function call, hence the need for eval. any suggestions would be much appreciated.
Doug replied on : 56 of 83
Roger, So the save part is easy: save(filename, name) The other bit about making a variable of a name known only as a string is more challenging. Often I would think there is just a better thing to do than that. However, you can use the command assignin to do something like this. Doug
Roger replied on : 57 of 83
Thanks Doug! After seeing what assignin did, I can see how it can replace what I wrote earlier. The modified lines are now: [ pathstr NAME ] = fileparts( Cellarray { i }); assignin ( 'base', [NAME, 'string1'], VAR) save( [NAME, 'string2', '.mat'], NAME2) clearvars -except Cellarray __ __ __ It just takes the filename.ext stored in Cellarray and then the fileparts function is used to get the name of the ith cell. Then assignin is used here to create a new variable NAME that has the same values as variable VAR. Then that new variable created called NAME2 (=[name, 'string1'] above) is saved as a .mat file. Then all variables are cleared except for Cellarray and other necessary variables shown as ___. The name of both the new variable and the .mat file can be easily changed based on string operations. But I only needed to add an extra string to the new variable name. Thanks again and hope others find this useful.
Steve L replied on : 58 of 83
Roger: Use dynamic field names (Doug's ".parens notation") in conjunction with SAVE's -struct flag. % Create a string for the "variable name" str = 'myvariable'; % Dynamic field names mydata.(str) = magic(5); % SAVE the structure save mymatfile.mat -struct mydata; % The previous step could be written using % the function form of SAVE if the MAT-file % name was stored in a variable. % % matfilename = 'mymatfile.mat'; % save(matfilename, '-struct', 'mydata'); % Check that the MAT-file contains the "variable" whos -file mymatfile.mat To avoid "poofing" the variable into the workspace when you LOAD, call LOAD with an output argument and refer to the variable using dynamic field names again. mydata = load('mymatfile.mat'); str = 'myvariable'; y = mydata.(str);
Kjas replied on : 59 of 83
To me, the worst code practice I can imagine is use of function handles. I use matlab practically every day, and it is my main tool since 1996. Matlab was always very consistent in syntax - outputs to the left of =, function name, arguments in brackets. Other operators were also very clear and math-mind oriented. That all changed to me when function handles were introduced. The idea is great, but the syntax implementation is so awful and out of line relative to the rest of matlab that to day I still don't know how to use them properly. Part of it is me refusing to learn it because I don't want to accept that monster of ill-conceived syntax as part of my coding. The @, followed by brackets with list of input variables, that don't have to be there either but could, followed by space! followed by function name (that doesn't have to be there either but could), followed by inline code or not, just horrible, and it feels like someone was trying hard to make it as far from the good old consistent matlab logic as possible.
Vassili replied on : 60 of 83
Hi Doug! Last 6 years I did not really work with ML, but please, don't cry: although my personal skill is out of date, I can still able to do something with 6 years old ML version. Could you please recommend me a person, sufficiently experienced to tell me whether the following question is known and what might be corresponding recommendations. Some 8 years ago I have submitted in FEX my UPPSALATOR. It solves numerically a boundary value integrodifferential problem in partial derivatives and a definite integral. I have tried at that time to use the calculation power of ML to possibly full extent, therefore I have replaced the whole problem by a system of many ordinary differential equations, which can be solved by different standard ODE solvers. This was achieved by a virtual Simpson integration in the relevant definite integral. The question which does bother me since those times is related to the fact that this integration has a certain error, which probably remains even after the ODE solver has formally reached its converging accuracy. I have got this impression by the fact that the high stability of the final answer (error about 1e-6) was achieved at very small spacial steps, less than 1e-3 in comparison to 1. I should appreciate any reaction, because it could save me remarkable efforts to clarify this question via numerical empirics. My email is Best regards to Cleve and whole ML team, Vassili.
pepe vilas replied on : 62 of 83
Doug, If I have a large set of parameters shared by several functions, which is the best alternative to global?. Thanks in advance!
Aslak grinsted replied on : 63 of 83
Here's a tiny tip for globals if you are concerned about naming conflicts: Always only have a *single* global variable for a given project. That can then be a struct with many fields. Often people use globals when they really just want a persistent variable. Use "persistent" for that.
Doug replied on : 64 of 83
@Pepe, I prefer passing them explicitly. One of the big dangers of globals is that variable get modified silently and you don't know who did it. Overwhelmingly, the times I see globals used is when people do not understand how the scoping of variables works. They will start out each function with


So they just copy and paste the same block of globals everywhere. It gets really ugly.

Aslak had some idea with large structures to limit the amount of variables passed. Persistent is often good too. In UIs, getappdata and setappdata are good.

David replied on : 66 of 83
I'd like to avoid globals, but I have to write callback functions and I don't have control over what the caller will pass as arguments. Any alternative?
Doug replied on : 67 of 83
@David, GetAppData and SetAppData.
brent replied on : 68 of 83
Jayveer Thakoor replied on March 9th, 2010 at 19:00 UTC : 9 of 66 ... that’s a big problem when you have 800MB sized variables! In such cases, global is extremely convenient – preallocate and update the same one all the time using logical indexing. Far more memory efficient, wouldn’t you agree?... Jayveer, That's where you would want to use a pointer.
Beth replied on : 69 of 83
If anyone can change this code into a loop for me I will be eternally grateful I am really struggling :( I think the function has something to do with ((n-1)x12)+1 >> shallow_depth=find(depth_new>=0&depth_new> deep_depth=find(depth_new>=400&depth_new<=600); shallow_mean=nanmean(NE68_EN4temp(1:5,:)); deep_mean=nanmean(NE68_EN4temp(22:24,:)); shallow_annual(1)=nanmean(shallow_mean(1:12)); shallow_annual(2)=nanmean(shallow_mean(13:24)); shallow_annual(3)=nanmean(shallow_mean(25:36)); shallow_annual(4)=nanmean(shallow_mean(37:48)); shallow_annual(5)=nanmean(shallow_mean(49:60)); shallow_annual(6)=nanmean(shallow_mean(61:72)); shallow_annual(7)=nanmean(shallow_mean(73:84)); shallow_annual(8)=nanmean(shallow_mean(85:96)); shallow_annual(9)=nanmean(shallow_mean(97:108)); shallow_annual(10)=nanmean(shallow_mean(109:120)); shallow_annual(11)=nanmean(shallow_mean(121:132)); shallow_annual(12)=nanmean(shallow_mean(133:144)); shallow_annual(13)=nanmean(shallow_mean(145:156)); shallow_annual(14)=nanmean(shallow_mean(157:162)); shallow_annual(15)=nanmean(shallow_mean(163:180)); deep_annual(1)=nanmean(deep_mean(1:12)); deep_annual(2)=nanmean(deep_mean(13:24)); deep_annual(3)=nanmean(deep_mean(25:36)); deep_annual(4)=nanmean(deep_mean(37:48)); deep_annual(5)=nanmean(deep_mean(49:60)); deep_annual(6)=nanmean(deep_mean(61:72)); deep_annual(7)=nanmean(deep_mean(73:84)); deep_annual(8)=nanmean(deep_mean(85:96)); deep_annual(9)=nanmean(deep_mean(97:108)); deep_annual(10)=nanmean(deep_mean(109:120)); deep_annual(11)=nanmean(deep_mean(121:132)); deep_annual(12)=nanmean(deep_mean(134:144)); deep_annual(13)=nanmean(deep_mean(145:156)); deep_annual(14)=nanmean(deep_mean(157:168)); deep_annual(15)=nanmean(deep_mean(169:180)); shallow_summer(1)=nanmean(shallow_mean(6:8)); shallow_summer(2)=nanmean(shallow_mean(18:20)); shallow_summer(3)=nanmean(shallow_mean(30:32)); shallow_summer(4)=nanmean(shallow_mean(42:44)); shallow_summer(5)=nanmean(shallow_mean(54:56)); shallow_summer(6)=nanmean(shallow_mean(66:68)); shallow_summer(7)=nanmean(shallow_mean(78:80)); shallow_summer(8)=nanmean(shallow_mean(90:92)); shallow_summer(9)=nanmean(shallow_mean(102:104)); shallow_summer(10)=nanmean(shallow_mean(114:116)); shallow_summer(11)=nanmean(shallow_mean(126:128)); shallow_summer(12)=nanmean(shallow_mean(138:140)); shallow_summer(13)=nanmean(shallow_mean(150:152)); shallow_summer(14)=nanmean(shallow_mean(162:164)); shallow_summer(15)=nanmean(shallow_mean(174:176)); deep_summer(1)=nanmean(deep_mean(6:8)); deep_summer(2)=nanmean(deep_mean(18:20)); deep_summer(3)=nanmean(deep_mean(30:32)); deep_summer(4)=nanmean(deep_mean(42:44)); deep_summer(5)=nanmean(deep_mean(54:56)); deep_summer(6)=nanmean(deep_mean(66:68)); deep_summer(7)=nanmean(deep_mean(78:80)); deep_summer(8)=nanmean(deep_mean(90:92)); deep_summer(9)=nanmean(deep_mean(102:104)); deep_summer(10)=nanmean(deep_mean(114:116)); deep_summer(11)=nanmean(deep_mean(126:128)); deep_summer(12)=nanmean(deep_mean(138:140)); deep_summer(13)=nanmean(deep_mean(150:152)); deep_summer(14)=nanmean(deep_mean(162:164)); deep_summer(15)=nanmean(deep_mean(174:176)); shallow_winter(1)=nanmean(shallow_mean(12:14)); shallow_winter(2)=nanmean(shallow_mean(24:26)); shallow_winter(3)=nanmean(shallow_mean(36:38)); shallow_winter(4)=nanmean(shallow_mean(48:50)); shallow_winter(5)=nanmean(shallow_mean(60:62)); shallow_winter(6)=nanmean(shallow_mean(72:74)); shallow_winter(7)=nanmean(shallow_mean(84:86)); shallow_winter(8)=nanmean(shallow_mean(96:98)); shallow_winter(9)=nanmean(shallow_mean(108:110)); shallow_winter(10)=nanmean(shallow_mean(120:122)); shallow_winter(11)=nanmean(shallow_mean(132:134)); shallow_winter(12)=nanmean(shallow_mean(144:146)); shallow_winter(13)=nanmean(shallow_mean(156:158)); shallow_winter(14)=nanmean(shallow_mean(168:170)); deep_winter(1)=nanmean(deep_mean(12:14)); deep_winter(2)=nanmean(deep_mean(24:26)); deep_winter(3)=nanmean(deep_mean(36:38)); deep_winter(4)=nanmean(deep_mean(48:50)); deep_winter(5)=nanmean(deep_mean(60:62)); deep_winter(6)=nanmean(deep_mean(72:74)); deep_winter(7)=nanmean(deep_mean(84:86)); deep_winter(8)=nanmean(deep_mean(96:98)); deep_winter(9)=nanmean(deep_mean(108:110)); deep_winter(10)=nanmean(deep_mean(120:122)); deep_winter(11)=nanmean(deep_mean(132:134)); deep_winter(12)=nanmean(deep_mean(144:146)); deep_winter(13)=nanmean(deep_mean(156:158)); deep_winter(14)=nanmean(deep_mean(168:170)); ocean_temp=[shallow_annual;shallow_summer;shallow_winter;deep_annual;deep_summer;deep_winter];ocean_temp',ans'
ask replied on : 70 of 83
I pay a visit every day some sites and blogs to read articles, except this weblog gives feature based writing.
trash cans replied on : 71 of 83
I prefer passing them explicitly. One of the big dangers of globals is that variable get modified silently and you don’t know who did it.
Adeef replied on : 72 of 83
Can any body help me in make a comparison of power in 3 MPPT method by using MATLAB/Simulink please mail me
Fiddlesticks replied on : 73 of 83
I don't see the fuss with global variables! They are a very powerful tool when defined clearly and used correctly.
Alex replied on : 74 of 83
@Beth, Try re-arranging deep_mean and shallow_mean into matrices: dm = reshape(deep_mean,12,[]); % Tells reshape to have each row as a month and determine the number of columns automatically. dm_summer would then be nanmean(dm(6:8,:)); %This tells matlab to pull out rows 6, 7, and 8 (all columns) and compute the mean from there.
Victor de Castro Morini replied on : 75 of 83
Hello, I have a doubt. What do you mean by "scoping of variables" ? Many thanks!
Hi Victor, "Scoping of variables" means limiting or controlling the region of a program in which they are defined (exist). It is best to narrow the scope of variables as much as possible, to limit unintended side effects.
Laurence Lurio replied on : 77 of 83
Regarding the question of globals, the instance where I haven't found a good alternative is when I want to integrate in one dimension over a function that exists in multiple dimensions. Suppose I want to integrate f(x,y,z) from x=x1, to x=x2 with y fixed at Y and z fixed at Z. If I use a canned integration routine it wants me to input a function of one variable, g(x). I can avoid this problem if I define Y and Z to be global and then define g(x) as f(x,Y,Z) with one input and two globals. Is there a better way to do this?
Hi Laurence, Have you tried defining g(x) as a nested function? i.e. function func=makeG Z=2; Y=3; func=@g; function result=g(x) result=x+Y+Z; end end Nested functions can access the variables in the parent.
Ankit Saxena replied on : 82 of 83
What a fantastic read on Python. This has helped me understand a lot in Python course. Please keep sharing similar write ups on Python. Guys if you are keen to know more on Python, must check this wonderful Python tutorial and i'm sure you will enjoy learning on Python training.:-