59

We have a lot of MATLAB code in my lab. The problem is there's really no way to organize it. Since all the functions have to be in the same folder to be called (or you have to add a bunch of folders to MATLAB's path environment variable), it seems that we're doomed have loads of files in the same folder, all in the global namespace. Is there a better way to organize our files and functions? I really wish there were some sort of module system...

rlbond
  • 65,341
  • 56
  • 178
  • 228

4 Answers4

76

MATLAB has a notion of packages which can be nested and include both classes and functions.

Just make a directory somewhere on your path with a + as the first character, like +mypkg. Then, if there is a class or function in that directory, it may be referred to as mypkg.mything. You can also import from a package using import mypkg.mysubpkg.*.

The one main gotcha about moving a bunch of functions into a package is that functions and classes do not automatically import the package they live in. This means that if you have a bunch of functions in different m-files that call each other, you may have to spend a while dropping imports in or qualifying function calls. Don't forget to put imports into subfunctions that call out as well. More info:

http://www.mathworks.com/help/matlab/matlab_oop/scoping-classes-with-packages.html

kenm
  • 23,127
  • 2
  • 43
  • 62
  • 9
    Oh. My. gosh. Why has nobody told me about this? Thank you! – rlbond May 01 '10 at 06:50
  • 1
    To answer the why, it's because there are a lot of people who use older versions of MATLAB and this is a feature in only the newer versions. – Joseph Lisee Jul 29 '10 at 02:18
  • 1
    what is the oldest version of matlab that has this function? – Memming Aug 02 '12 at 15:54
  • 4
    @Memming I believe it is 2008a, which is when the new-style object oriented features were added. – kenm Aug 02 '12 at 17:46
  • 1
    Um, yes. I'm just starting out with Matlab, and those scientists who teach the classes completely neglect to mention this. – chryss Sep 23 '12 at 15:46
9

Another way to organize & reuse code is using matlab's object-oriented features. Each Object is customarily in a folder that begins with an "@" and has the file(s) for that class inside. (though the newer syntax does not require this for a class defined in a single file.) Using private folders inside class folders, matlab even supports private class members. Matlab's new class notation is relatively fully-featured, but even the old syntax is useful.

BTW, my startup.m that examines a well-known location that I do my SVN checkouts into, and adds all of the subfolders onto my path automatically.

Marc
  • 3,259
  • 4
  • 30
  • 41
8

I don't see the problem with having to add some folder to Matlab's search path. I have modified startup.m so that it recursively looks for directories in my Matlab startup directory, and adds them to the path (it also runs svn update on everything). This way, if I change the directory structure, Matlab is still going to see all the functions the next time I start it.

Otherwise, you can look into object-oriented code, where you store all the methods in a @objectName folder. However, this may lead to a lot of re-writing code that can be avoided by updating the path (there is even a button add with subfolders if you add the folder to the path from the File menu) and doing a bit of moving code.

EDIT

If you would like to organize your code so that some functions are only visible to the functions that call them directly (and if you don't want to re-write in OOP), you put the calling functions in a directory, and within this directory, you create a subdirectory called private. The functions in there will only be visible to the functions in the parent directory. This is very useful if you have to overload some built-in Matlab functions for a subset of your code.

Jonas
  • 74,690
  • 10
  • 137
  • 177
  • 3
    My problem with this is that all functions are in the global namespace, i.e. there's no way to call the function `subfolder1\myFunc(1,2,3)` – rlbond May 01 '10 at 00:57
  • 2
    If you want to hide functions from the global namespace, you can use `private` folders. See edit. – Jonas May 01 '10 at 01:58
7

The package system is probably the best. I use the class system (@ClassName folder), but I actually write objects. If you're not doing that, it's silly just to write a bunch of static methods. One thing that can be helpful is to put all your matlab code into a folder that isn't on the matlab path. Then you can selectively add just the code you need to the path.

So say you have two projects, stored in "c:\matlabcode\foo" and "c"\matlabcode\bar", that both use common code stored in "c:\matlabcode\common," you might have a function "setupPaths.m" like this:

function setupPaths(projectName)
basedir = fullfile('c:', 'matlabcode');
addpath(genpath(fullfile(basedir, projectName)));
switch (projectName)
   case {'foo', 'bar'}
       addpath(genpath(fullfile(basedir, 'common')));
end

Of course you could extend this. An obvious extension would be to include a text file in each directory saying what other directories should be added to the path to use the functions in that directory.

Another useful thing if you share code is to set up a "user specific/LabMember" directory structure, where you have different lab members save code they are working on. That way you have access to their code if you need it, but don't get clobbered when they write a function with the same name as one of yours.

Marc
  • 5,315
  • 5
  • 30
  • 36