Object Oriented Programming in Matlab

May 25, 2010 by Admin · Leave a Comment
Filed under: Code Optimization, Tutorials 
VN:F [1.8.8_1072]
Rating: +7 (from 7 votes)
VN:F [1.8.8_1072]
Rating: 10.0/10 (6 votes cast)

by Matt Dunham

One of Matlab’s best kept secrets is its comprehensive support for Object Oriented Programming, (OOP). Entire courses in computer science are devoted to extolling OOPs many virtues and we will not have space to mention them all here. Instead, we focus on the specifics of OOP in Matlab and provide enough detail to start using objects in your own programs and writing your own classes.

Contents

We make extensive reference to the online Matlab OO documentation available here: http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matlab_oop.pdf

Old vs New Syntax

Mathworks recently, (as of version 2008a) introduced an entirely new Object Oriented, (OO), framework and syntax, however, the old style is still supported. This tutorial discusses both in some depth. Topics relating only to the old style are tagged (<2008a) and are listed in the bottom third of the document. They can be safely skipped by anyone solely interested in the new design.

The converse is not necessarily true, although for the most part the sections on the old style are self contained. We suggest that the reader interested only in the old style, nevertheless, read the following sections in the top two-thirds of the tutorial: Relation to Structs , Dynamic Dispatch , Operator Overloading , Object Arrays, and Inheritance.

Relation to Structs

At a first approximation, objects in Matlab are just structs. Here are some important differences, which we will elaborate on in due course.

  • Both structs and objects store data in named fields, (called properties in objects) but objects also encapsulate the operations you can perform on them, (called methods).
% Objects in Matlab are similar to structs, discussed earlier, in that
% both allow you to consolidate and encapsulate your data. It will be
% useful to remember this similarity as we progress, and if you are not
% yet familiar with structs, you may find it useful to return to that
% section first.

Recall that structs are created by specifying field names and data to be stored in these fields. Objects also have fields that store data, called properties, which operate in a very similar way. However, unlike structs, we must predefine what properties we want an entire class of objects to have, and we do so by writing a class definition. While objects of the same class will have the same set of properties, the values of these properties will differ just as two different structs might have the same field names and yet store different data.

So far we could imagine achieving the same effect by creating, say, an array of structs all with the same fields. However, there are further differences.

Objects, unlike structs, also encapsulate the operations we want to perform on the data, called methods.

Suppose for instance that we want to use and manipulate calendar dates in our program. We could create structs with minute, hour, day, month, and year fields and store all of the information about specific dates and times in these. This would certainly be better than having separate variables for all of these values floating around unstructured. However, there are also a number of operations we we might want to perform on these dates, such as incrementing them by a day, comparing them, subtracting them, etc. We could write stand alone functions to perform all of these operations, but it would be nice to organize them together too, just as we did the data. This is precisely what an object oriented approach lets us do.

There are further differences and advantages, which we will come to in due course. We first describe how to write a class definition.

Defining a Class

If you are new to OOP, make sure you mark the distinction between classes and instances of that class, called objects. This distinction will hopefully become clearer as we see more examples. In the class definition, we create a kind of prototype, or specification for the construction of a objects of a certain class or type. From one class definition, we create many instances.

To begin, create a new m-file with the same name as the class you want to create and start the file with the classdef keyword followed by the class name. Properties and methods are defined and written below this line in designated blocks as shown below. We must include a special method, called the constructor , which is responsible for constructing new objects and it must have the same name as the class. The constructor can take any number of arguments specifying initial values for the properties for instance, and must return one argument, the constructed object. Properties can optionally be assigned default values as with the minute property below. If no default is specified and no value is assigned by the constructor, they are assigned the empty matrix, [].


  classdef date
   % write a description of the class here.
     properties
       % define the properties of the class here, (like fields of a struct)
           minute = 0;
           hour;
           day;
           month;
           year;
       end
      methods
       % methods, including the constructor are defined in this block
          function obj = date(minute,hour,day,month,year)
           % class constructor
               if(nargin > 0)
                 obj.minute = minute;
                 obj.hour   = hour;
                 obj.day    = day;
                 obj.month  = month;
                 obj.year   = year;
               end
           end
           function obj = rollDay(obj,numdays)
            obj.day = obj.day + numdays;
           end
       end
   end

Our date constructor, could have been as simple as the following.

 function obj = date()
       obj;
 end

Matlab does all of the real work of creating the object, we just have to ensure that we write a constructor by the right name and perform any desired initialization, returning a declared variable.

Now that we have written the class, we can create date objects by simply calling the constructor.

d1 = date(0,3,27,2,1998);                    % Create a new date object

It is usually good practice to write a constructor so we can optionally create objects without having to specify any parameters. As we have written the date class, we could create a date object like this as well:

d2 = date();                                 % create a new date object

However, none of the properties, (except for minute) will be set. (They will all be equal to []).

Properties

The properties defined above are, in java lingo, public, that is, accessible from outside the class just like fields of a struct. We can access and assign them using dot notation.

day = d1.day;                                 % access the day property
d1.year = 2008;                               % set the year property

It is usually a good idea, however, to restrict direct access to properties to maintain a separation between implementation and interface. That is, we want clients to be able to use our class without having to know about the details of implementation and we will want the freedom to change how we store properties, for instance, without affecting clients already using our class. Perhaps at a later point, for example, we want the freedom to only calculate the value of a property when the user asks for it, (so called lazy evaluation). Without a level of indirection, this would not be possible. The idea is then to provide access to properties but only through methods. We will discuss such methods, so called getters and setters shortly.

Matlab offers quite a lot of control over property access. There are three levels, private , protected , and public and these apply separately to read and write access. Private properties are only accessible from methods of the class, and public properties, (the default) are accessible anywhere. Protected properties are private properties that are also accessible from subclasses. We will discuss subclasses and Inheritance later in this tutorial.

To mark a group of properties as say private, we modify the attributes of a property block. We saw one such property block above, however, we can create as many as we like all with different access rights so that some properties can be public and others private for example. We specify these access rights by assigning the GetAccess and SetAccess attributes the strings ‘public’, ‘private’, or ‘protected’ as in the examples below.


  properties(GetAccess = 'public', SetAccess = 'private')
       % public read access, but private write access.
   end
   properties(GetAccess = 'private', SetAccess = 'private')
       % private read and write access
   end

There are other property attributes we can assign although they are rarely of use with the exception of ‘Constant’ and perhaps ‘Hidden’. We can specify that a block of properties are constant and thus cannot be changed anywhere as follows:


  properties(Constant = true)
       DAYS_PER_YEAR =  365;
       MONTHS_PER_YEAR = 12;
       WEEKS_PER_YEAR  = 52;
   end

Hidden properties do not show up when displaying the object. For information on additional attributes see section 6.7 of the Mathworks OO documentation. Method attributes, which we discuss shortly, are listed in section 7.4 and class attributes in section 3.5.

We can view all of the (non-hidden) properties of a class using the properties() command.

properties(date)
Properties for class date:
    minute
    hour
    day
    month
    year
    numsecs
    valid
    DAYS_PER_YEAR
    MONTHS_PER_YEAR
    WEEKS_PER_YEAR

Methods

Methods in OOP, as we mentioned, are functions, defined in a class, that operate specifically on objects of that class, (although they can certainly take objects of other classes as additional arguments). Observe the simple function, rollDay() , which we have already defined. This method adds a specified number of days to the day property. Notice that the first argument of the function definition is an object of the containing class.

There are two equivalent ways of calling methods, both shown here.

d1 = rollDay(d,3);
d1 = d.rollDay(3);

The second option is probably more familiar to java and C++ programmers. It is essentially translated into the first by placing the implicit parameter, (the object d) as the first input into rollDay. Note, the method takes 2 parameters in both cases, (i.e. nargin() will return 2 in each). There is really no particular reason to choose one over the other except perhaps that the second makes it clearer that the function is actually a method applied to object d. Pick one style and be consistent throughout your program.

We must take care to return the object when we modify any properties. Objects in Matlab are by default, passed by value not by reference, which means that a full copy of the object is passed to methods and it is this copy that is modified. If we do not pass back this copy, effectively overwriting the original, we will not observe any change in the state. We can optionally write classes whose objects are passed by reference, which we discuss in the Handle Superclass section. This point also applies to calls like d3 = d2. If d2 is the date object we created above, d3 will be an identical copy.

Private Methods

Methods, just like properties, can be private, protected, or public, (the default). Private methods are helper functions that are not intended to be part of the class interface or to be used outside the of the class methods. It is often useful, for instance, to break public methods down into a series of calls to private methods, (so call functional decomposition). Protected methods, like protected properties, are private except also accessible by subclasses.

We define access to a block of methods, by assigning the string ‘private’, ‘protected’, or ‘public’, to the Access attribute of the methods block. We are free to create as many methods blocks as we like each with different access attributes.


 methods(Access = private)
    function sec = calcSecs(obj)
      sec = obj.minute*60 + obj.hour*60*60 + obj.day*24*60*60;
    end
   function TF = isValid(obj)
        TF = obj.minute >= 0 && obj.minute <= 60;
    end
 end

Static Methods

Static methods are methods that are associated with a class as opposed to instances of that class and are defined, as you would expect, in a method block that looks like this:


 methods(Static = true)
     function printCurrentDate()
         display(datestr(now));
     end
 end

They are useful when you have methods are are thematically related to the class but which do not use any information particular to specific instances of that class. Methods that demo class functionality are also good candidates.

To call a static method, you specify the classname, followed by a dot and the static method name.

  date.printCurrentDate()
14-Sep-2008 22:37:47

Methods can also be hidden with methods(Hidden = true) hiding them from functions that display class methods such as methods() or methodsview() . We will discuss abstract and sealed methods after first introducing inheritance.

External Functions & Methods

Our class methods are free to call out to any external function on the Matlab path to perform interim calculations. Moreover, if we save our classdef m-file in a directory with the same name as the class but preceded by the @ symbol,(e.g. @date), we can write methods in their own files, store them here, and use them as we would any other method. The declaration looks just like the function declarations above and the file name is the same as the function name.

However, we cannot assign such methods any of the method attributes just discussed, (like static, hidden, or protected), they are automatically public.

To write external private methods, save them into a subdirectory called private, e.g. \@date\private\myMethod.m.

Dynamic Dispatch

An advantage of OOP is that we can create two different classes each with the same method names and Matlab will automatically call the correct method depending on the type of of the object passed. For example, a call like obj = increment(obj) will call the increment method from whatever class obj happens to belong, even if multiple classes have an increment method.

When multiple objects are passed to a method, Matlab determines which class’s method to call based on the superior-inferior relation. The most superior class’s method is invoked and if all of the classes have equal superiority, the left most object takes precedence.

We specify these relationships when creating classes, right in the classdef statements as follows:

classdef(InferiorClasses = {?class1, ?class2})

The ? marks are used to construct metaclass instances but this detail is not particularly important; class1 and class2 are instances of the inferior classes. We discuss meta classes in a later section.

Arrays of objects can be passed to methods as well but the class of an array of objects is the same as the class of the objects stored inside, (which must all be the same), and this class is used to determine precedence. See the section on Object Arrays for more information.

Set and Get

Matlab supports special kinds of setter and getter functions for assigning and accessing properties that are executed whenever an attempt to set or get the corresponding property is made. Use of these is optional; they are only called if they exist. By taking this approach, we can make properties public so that clients can use the convenient dot notation, while still maintaining a level of indirection by effectively intercepting the call.

We will add get and set methods for the public day property of the date class as an example. We write get followed by a dot and the property name, similarly for set .


 function day = get.day(obj)
     day = obj.day;              % We could execute other code as well.
 end
 function obj = set.day(obj,newday)
     obj.day = newday;
 end

We then assign and query the value as we did before using the dot notation, but the call is intercepted by these functions. We must take care as before to return the object in the setter methods, (as the objects are by default passed by value).

day = d1.day;
d1.day = 5;

Unfortunately, as of Matlab version 2008a, it was not possible to override get and set methods in subclasses, severely limiting the use value of this approach in complex projects. Furthermore, these methods are called even when properties are accessed or set from within the class, making their use for input checking a frustrating exercise. Keep this in mind when initializing variables in the constructor; these functions, if present, are invoked during construction and so must be able to deal with cases in which the variables are not yet set.

Inheritance

When writing classes, we often find that some types are really special cases of others. For instance, integers are really special cases of numbers in general. This is different than the class-object relation, such as the number 3 being a specific instance of the integer class or the Earth being a specific instance of the planet class. Planets, however, are a subclass of say celestial bodies.

Inheritance in OOP allows us to write subclasses that inherit all of the properties and methods of their superclass so that we do not have to recode all of the parent functionality. The subclass then extends or specializes this functionality.

We can think of the methods of a subclass as the union of all of its own methods with the methods of its parent superclass, and similarly for properties.

Subclasses can redefine methods inherited from parents by simply specifying a method by the same name, (the number & names of arguments do not have to be the same). The subclass version is used with objects of that class, while the superclass version is used with supeclass objects – another example of dynamic dispatch.

If you find yourself writing the same methods in two or more classes, consider creating an inheritance hierarchy in which the superclass contains the code common to all of the subclasses. This hierarchy can be as many levels deep as you like.

Be aware that classes written in the new syntax cannot inherit from those written in the old, and vice versa.

We can specify a superclass for a class we are writing by using the following syntax in the classdef statement of our class definition.

classdef classname < superclass

Matlab supports multiple inheritance, i.e. subclasses with multiple superclasses. Care must be taken that naming conflicts do not occur. See section 5.11 of the Matlab OO documentation for details on multiple inheritance conflict resolution. To inherit from multiple classes, separate the superclasses with the & symbol as in the following.

classdef classname < super1 & super2 & super3

Calling a Superclass Method

When a method has been redefined in a subclass, it is sometimes necessary to call the superclass version from the subclass. Sometimes, for example, you want the subclass version to do everything the superclass version does, and more. Rather than copy the code from the superclass, you can first call the superclass version and then execute further code.

To access superclass methods and properties use the @ operator as in

methodname@superclassname(input1,input2)

While it will not produce an error, it is not necessary to use the @ operator to access inherited methods or properties that have not been redefined. You can access them in the same way as you would a method or property written in the subclass.

Class Aliases

We can create multiple names for the same class with empty classdef declarations.

   classdef newclassname < oldclassname
   end

Sealed Classes, Methods & Properties

A sealed class cannot be subclassed and a sealed method or property cannot be redefined in a subclass. This is similar to Java’s final keyword. Classes are defined as sealed in the classdef statement and methods and properties are sealed by modifying the methods or properties block attribute.

classdef(Sealed = true) myclass
methods(Sealed = true)
properties(Sealed = true

Abstract Methods & Properties

Abstract methods, simply put, are methods that have a function header, but not a function body, (i.e. no implementation). They are used to define a common interface for all current and future subclasses. Abstract methods must be implemented by subclasses and as such their inclusion in a superclass acts as a kind of contract, enforcing interface consistency. Of course, if the implementations in all of the subclasses are going to be the same, we are better off writing a regular method in the superclass, which will be inherited by all subclasses. Abstract methods are useful when we know subclasses need to have a particular method but each subclass implementation will be slightly different.

Lets suppose we have a shape superclass with many subclasses like sphere, cube, elipsoid, pyramid, etc. We want every subclass (and future subclasses other people might dream up) to have a calculateVolume() method. The calculation will be different in each case but by creating a calculateVolume() abstract method in the shape superclass, we can rely on the fact that each subclass will have such a method. We can then write other classes or functions that depend on this fact and do not have to rewrite any code when new shape subclasses are created.

Properties can also be abstract but are of less use – they too have to be defined in subclasses.

A class with one or more abstract methods or properties is considered abstract itself and instances cannot be created from it. Any subclass that does not implement every one of the abstract methods and properties of its superclasses will itself be abstract, essentially delegating the implementation of some or all of them to further subclasses.

We define a block of methods as abstract with the Abstract attribute, and when writing the methods, we do not include a body.


   methods(Abstract = true)
       function vol = calculateVolume(obj,units);
       function area = calculateSurfaceArea(obj,units);
       function obj = doubleSize(obj);
   end

Handle Superclass

We previously mentioned that objects in Matlab are, (by default) passed by value, meaning that full copies are passed back and forth in method calls. Matlab graphics objects, however, are passed by reference, (via handles). If we subclass the built in handle class as in

classdef myclass < handle

then objects of our class will be passed by reference too, not value. Doing so has a number of benefits and consequences, which we will now discuss.

When we construct a handle object as in h = myclass(), h stores a pointer or handle to the object not the object itself. If we then execute h2 = h, we simply create another pointer to the same underlying object. For example, we could call h.prop = 3 , and then p = h2.prop and p would equal 3.

In handle method calls, there is no need to return the object because assignments occur in place, (although returning a handle to the object does no harm).

If our objects will be very large, it can be much more space efficient to use handle objects because we no longer need to copy the entire object in every method call. (Note, however, that Matlab does a lot of optimization under the surface and only actually copies objects or variables when it absolutely has to).

Only handle classes support events; we will discuss events shortly.

The major advantage, however, is that it is much easier to write data structures, (particularly recursive structures) such link lists or binary trees. We give a very simple implementation of a binary tree class now and illustrate how we can easily recurse over all of the nodes by simply following handles.


classdef bnode < handle               % subclass handle
   properties
       left;        % left  child
       right;       % right child
       data;        % data stored at the node
    end
  methods
        function obj = bnode(data)
            obj;
            if(nargin > 0)
                obj.data = data;
            end
        end
    end
end
function labelNodes(node,depth)
% recursively label the depth of the nodes
    if(isempty(node)),return,end
    node.data = depth;
    labelNodes(node.left,depth+1);
    labelNodes(node.right,depth+1);
end

It is much more complicated to create an identical copy of a handle object as we cannot simply go h2 = h1. We can use the following code, however, to create a shallow copy of any object we like. It needs full access to all of the properties and so should be added as a class method. Another approach is to use the struct() function to convert an object to a struct and then write the constructor to optionally take a struct, building a new object from its fields.


 function copy = copyobj(obj)
 % Create a shallow copy of the calling object.
     copy = eval(class(obj));
     meta = eval(['?',class(obj)]);
     for p = 1: size(meta.Properties,1)
         pname = meta.Properties{p}.Name;
         try
             eval(['copy.',pname,' = obj.',pname,';']);
         catch
             fprintf(['\nCould not copy ',pname,'.\n']);
         end
     end
 end

When there are no more handles to an object left on the stack, the object is declared invalid and the Matlab garbage collector will free the memory when it gets a chance. We can test if a handle to an object is valid with the isvalid(h) method and delete the object, causing all of its handles to become invalid with delete(h).

dynamicprops & hgsetget

Handle has two subclasses, which you can subclass instead yielding addtional functionality. By subclassing dynamicprops you get all of the benefits of subclassing handle plus the ability to dynamically attach temporary data to objects without modifying the class definition. You simply call the inherited addprop() function, as in P = obj.addprop(‘newProperty’) and you can then make calls like obj.newProperty = 3 or val = obj.newProperty. The return value of addprop() ,P, can be used to set attributes of the property, (i.e. make it hidden, etc.), or to delete the property via delete(P).

The hgsetget class, (also a subclass of handle), lets you use Matlab graphics style set and get methods as in set(h,’property’,value). See section 4.19 in the Matlab OO documentation for more details).

You can also subclass built in types like double.

Operator Overloading

Every use of a Matlab operator, such as

+ - .* * ./ .\ / \ .^ ^ < > <= >=
== ~ ~= & | && || : ' .' [] [;] () .

is actually short hand or syntactic sugar for a call to a named function like plus(), minus(), times(), power(), lt(), eq(), not(), etc. Section 7.32 of the Matlab OO documentation lists all of these operators with their corresponding function names.

We can define custom behavior for any of these operators by witting class methods by the same name. Since class methods are dynamically dispatched, our own versions of these functions will execute when we use the corresponding operators with our objects. We could write our own plus() method in the date class, for example, to add dates together and then call the function with d1 + d2. Or, we could write our own lt() function, (for less than) to compare dates, calling it with d1 < d2. Such calls get converted automatically to plus(d1,d2) and lt(d1,d2), and our own implementations of these functions are then invoked.

Operators retain their natural precedence so that * takes precedence over + in order of operations, even if one or both have been overloaded.

Another useful method to overload is display() – the function that automatically displays objects when we do not suppress the output with a semicolon. Writing our own display function allows us to display objects in any way we like.

Sometimes it is useful to simply reuse concise informative names that belong to built in functions like plot(). While plot is never automatically invoked, nor does it correspond to an operator, it is used so frequently in Matlab that reusing this name with our own objects can serve to self document their behavior extremely well, (assuming our plot function does something reasonable).

If you overload an operator or function but want to use the original implementation for some reason, use the builtin() function, which takes the string name of the function as the first input, followed by that function’s inputs.


There are two very important functions that are frequently overloaded and deserve specific mention: subsref, and subsasgn. When the dot operator, parentheses, or curly braces, . () {}, are used in indexing operations, subsasgn is called, and when they are used in assignment operations, subsasgn is called. By overloading these functions, we can create customized behavior for our classes.

Suppose we write our own data structure class, for instance, and want calls like obj(3) to retrieve the third element in our structure, we could achieve this by overloading subsref.

Here are the definitions of these functions:

  function obj = subsasgn(obj, S, value)
  function value = subsref(obj, S)
  • obj is the calling object as in obj.prop or obj(3)
  • value is the new or returned value as in obj.prop = value or value = obj.prop
  • S is a structure with two fields: type and subs
Type is one of '()' '{}' or '.' depending on the call.
 Subs is a cell array or a string of the actual subscripts used.

In complicated calls involving multiple operators like obj(5,9).prop(1:19)=value, a single call to subsasgn is made and all of the information in the call is passed to the function. In this case, S is an array of structs with the following values.

S(1).type='()'	S(2).type='.'	    S(3).type='()'
S(1).subs={5,9}	S(2).subs='prop'	S(3).subs={1:10}

Note that as of 2008a, overloaded operators do not work within the class methods, only from outside of the class, although this could, and hopefully will change in future versions. This includes any function included in the @ directory (if any) or any subdirectories. You can still call the functions by name, (i.e. plus() instead of +).

Object Arrays

Objects of the same class can be stored together in object arrays that operate just like numeric arrays. We can concatenate objects together and index into these arrays in the usual way.

d2 = date(1,4,22,3,2008);   % create another date
dates = [d1 d2];            % we can concatenate objects just like numbers
[nrows ncols] = size(dates) % and use other familiar functions
d1 = dates(1,1);            % retrieve the first entry
dates(1,1) = d1;            % assign the first entry
nrows =
     1
ncols =
     2

The type of a single date object is actually an object array of date objects, albeit of size 1-by-1. Just about everything in Matlab is an array of some sort and objects are no exception. This is quite unlike java for instance, which distinguishes in terms of class, between an object of type A and a collection of objects of type A. One consequence of this is that method calls involving an array of objects dispatch the same method as would be were only one object involved; this includes calls to subsref() and subsasgn() .

We can also store objects of multiple types in cells and structs.

Events

Matlab now has quite good support for event based programming in which objects trigger events in response to a change in state, notifying one or more other objects that have registered as listeners. This can be particularly useful when the appropriate flow of control depends upon things external to the program such as a user’s interaction with a graphical interface or environmental sensors. It can be a useful paradigm in its own right, however, particularly for simulations. Chapter 8 of the Mathworks OO documentation covers events.

To begin, all classes involved must inherit from the handle class, (or one of its subclasses). The triggering class must declare an events block in its class definition. Event blocks have attributes just like method and property blocks, defining event access control.

The ListenAccess attribute determines where you can create event listeners and NotifyAccess determines where events can be triggered. In the below example, we set ListenAccess to public so that we can register an object as a listener anywhere we like, and NotifyAccess to protected so that only methods of the date class, (or any subclasses of date) can trigger the events.

Within the block, we define the events by simply specifying a name. Here we continue with the date example and will trigger events when the date is equal to either Jan 1, 2000 or the Vancouver Olympics start date of February 12, 2010.


events(ListenAccess = 'public', NotifyAccess = 'protected')
     y2k;                            % define a couple of events
     olympicsStart;
end

Now that we have defined two events, we have to decide when to trigger them. Lets add a line to the set.day method we discussed earlier, (which is called whenever the day property is set). We will have it call a new method we will write called checkDate() , which will fire the events if the current date matches one we are looking for. We use the notify() method, (inherited from handle) to fire the event and simply pass it the name of the event we want to trigger.


   function checkDate(obj)
       if(isempty(obj.year) || isempty(obj.month) || isempty(obj.day))
           return;        % this function may be called before all fields initialized.
       end
       if(obj.year == 2000 && obj.month == 1 && obj.day == 1)
           obj.notify('y2k');
       end
       if(obj.year == 2010 && obj.month == 2 && obj.day == 12)
           obj.notify('olympicsStart');
       end
   end

Notify will send an event notification to every object that is ‘listening’. By default the event object will have the name, (as specified in the events block, e.g. ‘y2k’ or ‘olympicsStart’) and a handle to the source object itself – the object that triggered the event.

You can create customized event objects with whatever information you like by subclassing event.EventData and passing an instance along with the event name to notify(). For more information see section 8.9 of the Mathworks OO documentation.

Now that we have objects of our date class sending events, we need to add listeners – objects that will be informed when events are triggered. Note that objects of our date class will not necessarily know who is listening, unless we go out of our way to tell them, (which we will not).

There are two ways to register an object as a listener but we will only discuss one here: using the addlistener() method inherited from handle.

(The other approach involves creating an object of type event.listener – see the Matlab OO documentation for more details).

Every class that inherits from handle has an addlistener() method that takes three arguments: a handle to an object that will generate events, the name of the event to listen for, (e.g. ‘y2k’), and a handle to a function that should execute when the event is ‘heard’. This function, called a callback function, must take two arguments: src – the object that generated the event, and evnt – the event object. Here is a possible class definition for listening objects. Note, we can call addlistener() at any point, not just in the constructor as we do here.


classdef snoopingClass < handle
   properties
      snoopOn;
   end
    methods
      function obj snoopingClass(dateObj)
        % class constructor
           obj.snoopOn = dateObj;
        y2kListener = addlistener(dateObj,'y2k',@(src,evnt)fixY2Kbugs(obj,src,evnt));
           olympicsListener = addlistener(dateObj,'olympicsStart',@(src,evnt)gossip(obj,src,evnt));
        end
      function fixY2Kbugs(obj,src,evnt)
        % This will be executed when a y2k event is fired by the date object.
           display(evnt.EventName);
        end
      function gossip(obj,src,evnt)
        % This will be executed when a olympicsStart event is fired by the date object
           display(evnt.EventName);
        end
    end

The execution of a callback can be temporarily deactivated by setting the Enabled property of the listener object to false.

y2kListener.Enabled = false

Four types of events are automatically fired in response to the access or assignment of observable properties: PreSet, PostSet, PreGet, & PostGet. The ‘pre’ events are fired just before a value is changed or serviced, and the ‘post’ events are fired just after. Observable properties are those defined in a properties block with the setObservable or getObservable attributes set to true as in

properties(SetObservable = true) .

These events are not listed in the event block.

To add a listener for the PostSet event of the day property, for example, use the following syntax.

lh = addlistener(obj,’propertyName’,'PostSet’,@(src,evnt)callbackFunction(obj,src,evnt));

See section 8.14 of the Matlab OO documentation for more details on listening for property changes. Finally, note that subclasses inherit the events of their superclasses.

Meta Classes

Matlab has quite a novel feature, meta classes, which allow you to dynamically inspect the properties of a particular class. Each class, defined using the classdef syntax, has a corresponding metaclass which you can invoke using the ? operator. The resulting object stores information about the class methods, properties, events, superclasses, etc, as well as their attributes. Metaclasses can be used to write highly generic code. The viewClassTree() method, (which displays a full class hierarchy of a project) makes extensive use of metaclasses and is available here:

viewClassTree.m.

The following example function, finds all of the superclasses of a particular class, including the superclasses of its superclasses. The metaclass() function operates just like the ? operator but can be used with string names, whereas ? requires an instance of the object.


   function list = ancestors(class)
   % input is the string name of the base class
   % output is a cell array of ancestor class names
       list = {};
       meta = metaclass(class);
       parents = meta.SuperClasses;
       for p=1:numel(parents)
           list = [parents{p}.Name,ancestors(parents{p}.Name)];
       end
   end

Here is a look at the kind of data available.

metadata = ?date
metadata =
meta.class handle
package: meta
properties:
                   Name: 'date'
            Description: ''
    DetailedDescription: ''
                 Hidden: 0
                 Sealed: 0
        ConstructOnLoad: 0
        InferiorClasses: {0x1 cell}
             Properties: {11x1 cell}
                Methods: {22x1 cell}
                 Events: {3x1 cell}
           SuperClasses: {[1x1 meta.class]}
      ContainingPackage: {}

Packages

When working with large projects or when many projects exist on the Matlab path, it can be useful to organize them into packages, effectively partitioning the name space. Packages are directories beginning with the + character as in +calendar and any class or function placed inside must be accessed by first referring to the package name followed by a dot as in calendar.date. Both standalone functions and classes can be placed inside of a package. Supposing we put the date class from above into the +calendar package, we would call the printCurrentDate() static method like this:

calendar.date.printCurrentDate()

Classes and functions with the same names as other classes or functions no longer interfere with each other when placed in separate packages.

For the sake of brevity, it is sometimes desirable to import a package’s namespace into the main namespace temporarily so that we do not have to prefix every call with the package name. We can use the import() function for this as in import calendar and clear the imported namespaces with

clear import;

Packages can also be nested within each other.

Finally, individual classes and their properties can be imported and used without having to first refer to the class name. This is really only advisable when dealing with a class created to store constants because of the potential for name clashes. To do so you simply specify the fully named path as in import calendar.date.year or import calendar.date.*

Example

The date class example can be seen in full here:

@date

Writing Classes Prior to Version 2008a

We now describe how to create classes and use objects using the old OO style. This approach is still supported in 2008a and was the only OO framework available prior to this version, (although versions 2007a and 2007b do, unofficially, work with the new syntax provided a number of the more advanced features are not used). The old framework is much more limited and cumbersome but in some ways it is more consistent with the rest of the Matlab syntax. It does bridge the inherent connection with structs much more explicitly, for example.

Keep in mind that if you write classes in the old style, the following features, available in the new framework, are not supported: protected, abstract, static/constant, sealed, or hidden methods or properties; single file class definitions; events; handle classes; packages; special set. and get. methods; object.method() syntax; or meta-classes. However, you can still perform operator overloading; in fact, if anything, it plays a more prominent role.

(<2008a) Defining a Class

To begin, every method must be saved in its own file, including the constructor, and these files must be stored in a directory with the same name as the class but preceded by the @ symbol as in @date. The parent directory containing this @ directory, must be on the Matlab path.

Every class needs to have a constructor method, which constructs the objects of the class. The constructor must have the same name as the class and be saved in an m-file by the same name, (e.g. create a function called date and save it in date.m stored in the @date directory). Here is a sample definition:

function obj = date(minute, hour, day, month, year)

We define the properties of the class by creating a struct with fields by the same name and we must add one field for every property, even if we leave the data initially blank, (i.e. equal to []). We then convert the struct to an object by using the class() function.


 function obj = date(minute, hour, day, month, year)
 % constructor saved in file date.m
      obj = struct;
       obj.minute = [];                % leave blank for whatever reason
       obj.hour = hour;
       obj.day = day;
       obj.month = month;
       obj. year = year;
       obj = class(obj,'date');
 end

We can create objects by calling the constructor.

 obj = date(12,2,3,11,2008);         % create a new date object

Note that in earlier versions of Matlab, special care had to be taken to allow for objects to be saved and loaded from disk. This is no longer the case, even when using the old syntax. If you are using an older version of Matlab and run into this problem, check out the following site for a work around: http://www.cs.ubc.ca/~murphyk/Software/matlabObjects.html

When changes are made to a class definition, existing objects of that class are not automatically updated; they must be cleared and recreated. In older version of Matlab, it was necessary to use the clear classes command after making definitional changes. If you experience odd behavior, this can sometimes help. Also in older versions, date objects, for example, could not be created if @date were the current directory. Moving up one level did the trick.

(<2008a) Property Access

Technically, the creation of the constructor method in the @ directory is sufficient to create a class and objects from it, however, our date objects are not yet very useful because Matlab protects the properties from access outside of the class. They are effectively private. Only class methods can access properties in the old style, which includes any function stored inside of the @ directory.

(<2008a) Subsref & Subsasgn

As we mentioned in the section on Operator Overloading ,every use of a dot such as obj.prop, is actually shorthand for a call to either the subsasgn() or the subrsref() function just like calls involving the ‘+’ operator are shorthand for the plus() function. Subsref is called in indexing operations, (i.e. when data is requested) and subsasgn is used in assignment operations, (i.e. when data is changed). These same functions are called when parentheses are used as well, as in a = date(3,2) , or date(3,2) = 5 ,(and similarly with {} braces when dealing with structs).

One of the most powerful features of OOP in Matlab is the ability to overload such functions so that they perform customized behavior when used with objects of our class. If we create functions by these names and store them inside of the @ directory containing our class files, these functions will be executed when calls involving a . or () are made as opposed to the default implementations. We can then use these as our getter and setter methods so that users can access and set object properties with the same syntax as they would struct fields, for instance. More complicated behavior is certainly possible too.

The default behavior of these functions, for objects, is to restrict access to properties completely, but we can ‘recover’ the lax behavior we enjoyed with structs and effectively make the all of the properties public with the following simple implementations. We make use the the builtin() function to do so, which bypasses the redefined or ‘overloaded’ object versions, (versions overriden by Mathworks in this case). In general builtin() can be very useful when a function has been overloaded but you want the original behavior. Here we simply pass the inputs to the functions directly to builtin(). For more detail on these functions, (e.g. on the S arguement), see the Operator Overloading section above.


  function obj = subsasgn(obj, S, value)
     obj = builtin('subsasgn', obj, S, value);
  end
  function value = subsref(obj, S)
      value = builtin('subsref', obj, S);
  end

With these functions in place, properties of our object can then be accessed and assigned values as follows.

d1 = date(0,3,27,2,1998);        % construct a new object
min = d1.minute                  % get the minute property using . notation
d1.hour = 4;                     % set the hour property using the . notation
min =
     0

(<2008a) Displaying Objects

In the old OO style, objects are not displayed for you. You can overload the display() function so that basic info about the object is displayed in calls that do not suppress output with a semicolon. Here is a simple implementation. The struct() function when applied to an object, converts that object into a struct with fields corresponding to the properties of the object. Struct can also be used with objects created via the new OO framework.

 function display(obj)
     disp(sprintf('%s object', class(obj)))
     disp(struct(obj))
 end

The section on Operator Overloading discusses several other functions that can be overloaded.

(<2008a) Methods

To define methods, we simply create functions with definitions like the following and save them in the @ directory. The first argument should be an object of the containing class. Methods that change object properties must return the object, (because they are passed by value). We do not have the option in the old framework, as we do with the new, of writing classes whose objects can be passed by reference.


obj = rollDay(obj,3);
 function obj = rollDay(obj,numdays)
      obj.day = obj.day + numdays;
 end

Similarly, calls such as obj2 = obj, result in a copy of the object obj stored in the variable obj2.

If you choose not to overload subsasgn() and subsref() but still want to provide outside access to certain properties you will need to write java style get and set functions as in the following. This approach, while less concise, does maintain the separation between implementation and interface without necessitating complicated implementations of subasgn and subsref.


function day = getDay(obj)
    % we could change this code later without affecting users of getDay.
    day = obj.day;
 end
 function obj = setDay(obj,newDay)
     obj.day = newDay;
 end

(<2008a) Private Methods

Private methods are functions that can only be called by other methods of the class, not end users; they are not intended to act as part of the class interface. To make a method private in the old OO framework, create a sub-directory called ‘private’ in the @ directory and save it inside. You can call private methods, (from within other class methods) as you would any other method.

(<2008a) Inheritance Syntax

Inheritance in the old OO framework is quite limited and you cannot subclass built in classes like handle. Superclasses are specified as inputs to the class() function called in the constructor. You must pass in instances of the superclass objects.

 p1 = parent1(); p2 = parent2();   % create instances of the parent classes
 obj = class(obj,'date',p1,p2);    % pass these instances into the class function

Type doc class for additional calling sequences including an option to create an array of objects from an array of structs.

For more general information on inheritance, see the several related sections written regarding the new OO style.

(<2008a) Dynamic Dispatch

The old OO framework supports dynamic dispatch in much the same way as the new framework. When multiple objects of different types are passed to a method, the superior-inferior relation is used to determine which method to invoke, just as with the new OO design. However, in the old style, we must specify this relation by using the using the inferiorto() ,and superiorto() functions from within the constructor as in the following.

inferiorto('class1','class2');

Again, when the superiority of two classes is the same, the left most takes precedence.

VN:F [1.8.8_1072]
Rating: 10.0/10 (6 votes cast)
VN:F [1.8.8_1072]
Rating: +7 (from 7 votes)

Popularity: 1% [?]

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • Live
  • PDF
  • Technorati
  • Twitter
  • Yahoo! Bookmarks
  • Add to favorites
  • email
  • MySpace
  • RSS

Getting Started & The Matlab Environment

May 20, 2010 by Admin · Leave a Comment
Filed under: Tutorials, Utility 
VN:F [1.8.8_1072]
Rating: 0 (from 0 votes)
VN:F [1.8.8_1072]
Rating: 0.0/10 (0 votes cast)

by Matt Dunham

This section serves as an introduction to the Matlab environment and programming language as well as to this tutorial. It describes how to configure and start using Matlab, search for help, and how to perform file input and output.

Contents

Useful Functions

  • help, doc, type, lookfor, who, whos
  • clear, clearvars, clc, home, close
  • what, version, isvarname, namelengthmax, startup.m
  • save, load, dlmread, dlmwrite, textscan, fprintf, fopen, fclose,
  • imread, imwrite, imagesc, colormap, axis image,

What is Matlab?

Matlab is a programming environment as well as a high level, interpreted, dynamically typed language, supporting functional, object oriented, and event driven paradigms. It is well suited for numerical computation, particularly computations involving matrix operations and linear algebra.

Matlab has excellent support for data visualization and its concise and expressive syntax, as well as the plethora of predefined functions, results in a powerful environment excellent for rapid prototyping with minimal overhead.

Yet, Matlab is not just a scripting language for quick and dirty calculations. Recent versions have seen a dramatic increase for the support of large scale, highly structured code to rival C++, Java and the like. If you want the best of both worlds, Matlab’s integrated java support lets you create and manipulate instances of java classes right in your Matlab programs. You can also call out to code written in C, C++, Perl, Fortran, or execute dos or unix system commands. Furthermore, Matlab code can be exported for use in Java, C, C++, and .Net programs, or as a stand alone application, mitigating its primary disadvantage – that it is not free.

As an interpreted language, some operations are slower than in a compiled language, particularly those involving loops. This too has improved in recent versions. In many cases, however, loops can be vectorized resulting in very quick code that invokes low level, highly optimized, compiled functions from the Matlab library. When the most computationally expensive parts of your program can be written this way, the speed of Matlab code rivals that of compiled languages.

Finally, with the addition of various toolkits, e.g. for Statistics, Bioinformatics, Optimization, or Image Processing, to name just a few, the Matlab environment can be extended for more specialized requirements.

Matlab® is a product of the The Mathworks™ company; for more general information, consult their website at http://www.mathworks.com/.

Using this Guide

This tutorial so broken into several small chapters, which are themselves composed of a number of subsections. For the most part, the chapters are self contained and can be read in isolation as needed. As the code for the examples is embedded right into the document, it may be advantageous to open the tutorial in the Matlab web browser so that you can try out the examples as you read. You can execute code by highlighting it on the web page and pressing F9. The statements are processed as though they were typed one at a time in the command window. You can bring up the Matlab web browser by typing say web www.cs.ubc.ca/~mdunham at the command prompt, and can move it to whatever part of the screen you find most convenient.

Starting Matlab

To launch Matlab double click on the Matlab shortcut or type Matlab at a command prompt. There are also several command line options available to control how Matlab will run. You can modify the properties of the shortcut to add these or include them at the command prompt.

The -nojvm option loads Matlab without Java support, significantly reducing memory requirements at the cost of reduced functionality. None of the Matlab desktop windows are available in this mode, except for the command window. Here is how it looks.

You can get rid of the opening splash screen with -nospash and on unix systems bring up a Matlab command window right at the command prompt with the -nodesktop switch.

Batch Mode

Matlab can be run in batch mode, specifying commands for it to execute as soon as it begins, with the -r “command” switch. Commands are separated via semicolons and can be listed directly, or placed in a file with a .m extension and called like this: Matlab -r “myscript”. To write the output to a file, include the following switch: -logfile “logfilename”. If you want Matlab to quit when its finished executing the script, add the exit command at the end. Make sure Matlab can find the m-file you are trying to execute by placing it somewhere on the Matlab path. We discuss the Matlab search path in detail in here.

Matlab Path

Startup File

You can specify commands to execute every time Matlab starts by creating a file on the Matlab search path with the name, startup.m, and writing the commands there. In later versions of Matlab, preferences can be set under File->Preferences reducing the need for such a file, however, it can still be useful, particularly if you run Matlab in nojvm or nodesktop mode, or want to change advanced properties such as plotting defaults defined under root. Check out the following section in the plotting chapter for details.

Root Properties

Useful Preferences

You may find it useful to set the following preference to save space when the results of calculations are displayed in the command window.

  • File->Preferences->Command Window->Text Display->Numeric display->compact

Command Window

Matlab commands are either executed in scripts or functions, or directly at the command window shown below. If you do not suppress output by adding a semicolon at the end of your commands, the results are displayed here as well. It is often useful to test out commands you are adding to a script or function in the command window first to ensure you have the syntax and desired behavior right.

The last typed command can be retrieved by selecting the command window and pressing the up arrow key on your keyboard. Pressing it several times scrolls you backwards through the history of typed commands. By first typing in part of the command before pressing the up arrow, only those statements that began with the typed text are displayed.

Furthermore, you can invoke Matlab’s autocomplete feature by typing part of a command or function and pressing tab. A number of suggested options will appear. The same is true when editing files, e.g. typing edit eig followed by the tab key will list all of the m-files on the Matlab path that begin with eig.

Here are number of command window related commands.

clc                     % clear the window
home                    % move the cursor to the top of the window
diary on                % record all input and output in a file called diary
clear all               % clear all of the current variables
clearvars -except a b   % clear all of the variables except a and b
close all               % close all open figures
who                     % list all of the current variables
whos                    % same as who but with more detail
v = version             % display the current Matlab version
%what                   % display a list of the files in the current directory
v =
7.6.0.324 (R2008a)

Variables

We can create named memory locations to store data, called variables, very easily in Matlab. Here we create a number of variables, however, we go into much more detail in the section on Matrices.

The Matrix

myvar = 3
a   = 'hello'
b1  = 2 + 2
c_3 = sqrt(36)
d   = exp(4)
f   = log10(100)
g   = 2^10 - 1
myvar =
     3
a =
hello
b1 =
     4
c_3 =
     6
d =
   54.5982
f =
     2
g =
        1023

Variable names must begin with a character and can contain up to 63 characters on most systems. Type namelengthmax to see the maximum on your system. They can also contain numbers or the underscore character.

You can check that a potential variable name is valid with the isvarname command.

isvarname test-123
ans =
     0
isvarname test_123
ans =
     1

Since Matlab is a dynamically typed language, we do not predefine the type of data we will store in a particular variable and can overwrite data of one type with data of another. Notice that the variable g, currently holds the number 1023. We will now assign it the following string.

g = 'does this really work?'
g =
does this really work?

You can save all of the variables in a workspace to a file by typing save filename at the command prompt and reload them again with load filename.

Workspace

All of the current variables, as well as basic information about them, can be viewed in a convenient graphical window called the workspace. If it is not already visible, you can bring it up by typing workspace at the command prompt or by going to the desktop drop down menu. You can then drag and place it wherever it is convenient. You can set what information you want displayed by right clicking on the header bar, (with “Name Value Class Size Bytes”) in the picture below. If you double click on a variable it will open it in the variable editor where you can inspect or change its values. This is much more useful when dealing with matrices. Certain variables can also be immediately plotted from here with the plot selection button in the same window. We discuss plotting in some depth in the plotting chapter.

Plotting

Current Directory

The current directory window, unsurprisingly, displays the files in the current working directory. You can open it via the drop down menu Desktop->Current Directory if it is not already open. From here you can navigate the file system and search for files. Type F5 to force a refresh.

Userpath

Matlab automatically sets up a default directory where you can save your own Matlab files; it opens this directory, whenever its started. You can view and change this default by typing userpath or say userpath c:\Users\matt\Matlab\ at the command prompt.

Help

One of Matlab’s best features is its extensive library of help files. There are far too many built in functions to memorize and even if you remember the name, the exact syntax might allude you. You can bring up the help navigator by going to Desktop -> Help or search right from the command window. Typing help functionname at the command prompt displays that function’s documentation right there, whereas doc functionname brings this up in the help window. You can search by keyword in help or search the first line of every function’s documentation with the lookfor command, as in lookfor eigenvalue.

Editor

As we mentioned, Matlab commands are executed either at the command prompt or by running scripts or functions, which can be created and edited with the built in editor. To launch the editor, if it is not already open, type edit or edit filename. Commands can be entered here and executed as a script. They are saved with a .m extension. To run your script, type in the name at the command prompt, or press F5 or the save and run button at the top of the editor. Your own functions can be written here as well. We discuss functions in depth in a dedicated chapter.

Writing Functions

You can set break points to halt execution at certain lines for debugging, which we discuss here.

Debugging, Profiling, & Style

Comments are written by preceding the line with the % symbol. Block comments are opened with %{ and closed with %}. To have Matlab word wrap a selection of comments, right click on the highlighted text and select, Wrap Selected Text.

You can partition your code into editor cells by typing two percent signs, %%, at the beginning of the line. This can help organize your code into logical sections. You can also evaluate cells one at a time by selecting the evaluate cell button at the top of the editor. At any time, you can execute an arbitrary block of code by highlighting it and pressing F9. Cells are also used when publishing your code. This tutorial was written in Matlab and published to html by selecting the publish button at the top of the editor. This can be very useful when you want to share your code and results with others in a professional looking report.

Certain constructs like for loops and functions can be folded, hiding all but the top line from view. Select the + or – symbols appearing on the left hand side of the editor, by the line numbers.

Here is an image of the editor in action. Notice we have the open m-files listed in the center column; you can move these to the left right or bottom. We have also docked one of the figures in the top left. By default figures open in their own windows but it can sometimes be useful to work with a figure on the same screen: to do this, use the doc window arrow at the the top left of the figure.

There are many other configuration options and editor tools available; experiment by selecting the many buttons and exploring the drop down menus.

Layouts and Other Windows

Matlab gives you a lot of freedom over how you organize the windows in the environment. For instance, you can have have multiple windows take up the same screen area and toggle between them at will, or place windows at the sides where they automatically hide until you select them. Try dragging them around to different places to see the effect. There are more windows than described here available under the Desktop drop down menu.

You can save the current layout, select one of the default ones, tile all the windows, and perform many other related tasks under the Desktop drop down menu. Its worth taking the time to organize your layout effectively before you begin working.

Start Bar

Many of the tools and screens we have talked about, as well as links to various graphical wizards are available under the start bar in the bottom left hand of the environment.

Input & Output

Input and output in Matlab is relatively easy and can be done with a few useful functions. We describe these first and show examples at the bottom of this section.

The dlmread() is very useful for importing ascii delimited data into Matlab. You simply specify the filename and optionally the delimiter, although it can usually figure this out. To write data to a delimited file, use the dlmwrite() function.

You can also use the built in import wizard by typing uiimport at the command prompt. This is particularly useful when you have data stored in the windows clipboard, copied from some third party program.

If you are reading text from a file, try the textscan() function. You first have to open the file, however, with fopen() and then close it when you are done with fclose(). Here is an advanced example from the chapter on Strings.

Importing Text example

The imread() function is useful for reading image files and supports a wide range of formats. To write an image, use imwrite(). The imagesc() function can be used to view the image.

To write arbitrary data, including text, to a file, use the fprintf() function in conjunction with fopen() and fclose(): fopen() returns a file id, which you then pass as the first argument to fprintf(). If you do not specify a file id, fprintf() prints the data to the command window. We discuss the formatting options available with this function here.

Formatting Strings

For more information on, say, the textscan function type doc textscan at the command prompt.

Here a a number of examples.

A = rand(20,40);                            % create a random matrix
dlmwrite('testData.csv',A);                 % write to a file as a comma separated list
clear
B = dlmread('testData.csv');                % load it back in
C = 'We will write this string to a file';  % create some text.
fid = fopen('hello.txt','w');               % open a new file for writing
fprintf(fid,C);                             % write it to a file
fclose(fid);                                % remember to close the file
fid = fopen('hello.txt','r');               % open with read access
D = textscan(fid,'%s');                     % read it back in. %s to expect strings
D{:}                                        % show the contents of D
fclose(fid);                                % remember to close the file.
ans =
    'We'
    'will'
    'write'
    'this'
    'string'
    'to'
    'a'
    'file'
load mandrill;                              % built in image
imagesc(X);                                 % display it
axis image                                  % window dimensions appropriate for an image
map = colormap(bone);                       % a possible color scheme.

imwrite(X,map,'mandrill.jpg','jpg');        % write the image to a jpeg file
clear
X = imread('mandrill.jpg');                 % load it back in.
save example                                % save all the variables to a .mat file
clear
load example                                % load them back in
close all
clear all

Useful Functions

  • help, doc, type, lookfor, who, whos
  • clear, clearvars, clc, home, close
  • what, version, isvarname, namelengthmax, startup.m
  • save, load, dlmread, dlmwrite, textscan, fprintf, fopen, fclose,
  • imread, imwrite, imagesc, colormap, axis image,

What is Matlab?

Matlab is a programming environment as well as a high level, interpreted, dynamically typed language, supporting functional, object oriented, and event driven paradigms. It is well suited for numerical computation, particularly computations involving matrix operations and linear algebra.

Matlab has excellent support for data visualization and its concise and expressive syntax, as well as the plethora of predefined functions, results in a powerful environment excellent for rapid prototyping with minimal overhead.

Yet, Matlab is not just a scripting language for quick and dirty calculations. Recent versions have seen a dramatic increase for the support of large scale, highly structured code to rival C++, Java and the like. If you want the best of both worlds, Matlab’s integrated java support lets you create and manipulate instances of java classes right in your Matlab programs. You can also call out to code written in C, C++, Perl, Fortran, or execute dos or unix system commands. Furthermore, Matlab code can be exported for use in Java, C, C++, and .Net programs, or as a stand alone application, mitigating its primary disadvantage – that it is not free.

As an interpreted language, some operations are slower than in a compiled language, particularly those involving loops. This too has improved in recent versions. In many cases, however, loops can be vectorized resulting in very quick code that invokes low level, highly optimized, compiled functions from the Matlab library. When the most computationally expensive parts of your program can be written this way, the speed of Matlab code rivals that of compiled languages.

Finally, with the addition of various toolkits, e.g. for Statistics, Bioinformatics, Optimization, or Image Processing, to name just a few, the Matlab environment can be extended for more specialized requirements.

Matlab® is a product of the The Mathworks™ company; for more general information, consult their website at http://www.mathworks.com/.

Using this Guide

This tutorial so broken into several small chapters, which are themselves composed of a number of subsections. For the most part, the chapters are self contained and can be read in isolation as needed. As the code for the examples is embedded right into the document, it may be advantageous to open the tutorial in the Matlab web browser so that you can try out the examples as you read. You can execute code by highlighting it on the web page and pressing F9. The statements are processed as though they were typed one at a time in the command window. You can bring up the Matlab web browser by typing say web www.cs.ubc.ca/~mdunham at the command prompt, and can move it to whatever part of the screen you find most convenient.

http://www.mathworks.com/matlabcentral/fx_files/21653/3/content/tutorial/matlabTutorialBrowser.png

Starting Matlab

To launch Matlab double click on the Matlab shortcut or type Matlab at a command prompt. There are also several command line options available to control how Matlab will run. You can modify the properties of the shortcut to add these or include them at the command prompt.

The -nojvm option loads Matlab without Java support, significantly reducing memory requirements at the cost of reduced functionality. None of the Matlab desktop windows are available in this mode, except for the command window. Here is how it looks.

http://www.mathworks.com/matlabcentral/fx_files/21653/3/content/tutorial/nojvm.png

You can get rid of the opening splash screen with -nospash and on unix systems bring up a Matlab command window right at the command prompt with the -nodesktop switch.

Batch Mode

Matlab can be run in batch mode, specifying commands for it to execute as soon as it begins, with the -r “command” switch. Commands are separated via semicolons and can be listed directly, or placed in a file with a .m extension and called like this: Matlab -r “myscript”. To write the output to a file, include the following switch: -logfile “logfilename”. If you want Matlab to quit when its finished executing the script, add the exit command at the end. Make sure Matlab can find the m-file you are trying to execute by placing it somewhere on the Matlab path. We discuss the Matlab search path in detail in here.

Matlab Path

Startup File

You can specify commands to execute every time Matlab starts by creating a file on the Matlab search path with the name, startup.m, and writing the commands there. In later versions of Matlab, preferences can be set under File->Preferences reducing the need for such a file, however, it can still be useful, particularly if you run Matlab in nojvm or nodesktop mode, or want to change advanced properties such as plotting defaults defined under root. Check out the following section in the plotting chapter for details.

Root Properties

Useful Preferences

You may find it useful to set the following preference to save space when the results of calculations are displayed in the command window.

  • File->Preferences->Command Window->Text Display->Numeric display->compact

Command Window

Matlab commands are either executed in scripts or functions, or directly at the command window shown below. If you do not suppress output by adding a semicolon at the end of your commands, the results are displayed here as well. It is often useful to test out commands you are adding to a script or function in the command window first to ensure you have the syntax and desired behavior right.

The last typed command can be retrieved by selecting the command window and pressing the up arrow key on your keyboard. Pressing it several times scrolls you backwards through the history of typed commands. By first typing in part of the command before pressing the up arrow, only those statements that began with the typed text are displayed.

Furthermore, you can invoke Matlab’s autocomplete feature by typing part of a command or function and pressing tab. A number of suggested options will appear. The same is true when editing files, e.g. typing edit eig followed by the tab key will list all of the m-files on the Matlab path that begin with eig.

http://www.mathworks.com/matlabcentral/fx_files/21653/3/content/tutorial/commandWindow.png

Here are number of command window related commands.

clc % clear the window

home % move the cursor to the top of the window

diary on % record all input and output in a file called diary

clear all % clear all of the current variables

clearvars -except a b % clear all of the variables except a and b

close all % close all open figures

who % list all of the current variables

whos % same as who but with more detail

v = version % display the current Matlab version

%what % display a list of the files in the current directory

v =

7.6.0.324 (R2008a)

Variables

We can create named memory locations to store data, called variables, very easily in Matlab. Here we create a number of variables, however, we go into much more detail in the section on Matrices.

The Matrix

myvar = 3

a = ‘hello’

b1 = 2 + 2

c_3 = sqrt(36)

d = exp(4)

f = log10(100)

g = 2^10 – 1

myvar =

3

a =

hello

b1 =

4

c_3 =

6

d =

54.5982

f =

2

g =

1023

Variable names must begin with a character and can contain up to 63 characters on most systems. Type namelengthmax to see the maximum on your system. They can also contain numbers or the underscore character.

You can check that a potential variable name is valid with the isvarname command.

isvarname test-123

ans =

0

isvarname test_123

ans =

1

Since Matlab is a dynamically typed language, we do not predefine the type of data we will store in a particular variable and can overwrite data of one type with data of another. Notice that the variable g, currently holds the number 1023. We will now assign it the following string.

g = ‘does this really work?’

g =

does this really work?

You can save all of the variables in a workspace to a file by typing save filename at the command prompt and reload them again with load filename.

Workspace

All of the current variables, as well as basic information about them, can be viewed in a convenient graphical window called the workspace. If it is not already visible, you can bring it up by typing workspace at the command prompt or by going to the desktop drop down menu. You can then drag and place it wherever it is convenient. You can set what information you want displayed by right clicking on the header bar, (with “Name Value Class Size Bytes”) in the picture below. If you double click on a variable it will open it in the variable editor where you can inspect or change its values. This is much more useful when dealing with matrices. Certain variables can also be immediately plotted from here with the plot selection button in the same window. We discuss plotting in some depth in the plotting chapter.

Plotting

http://www.mathworks.com/matlabcentral/fx_files/21653/3/content/tutorial/workspace.png

Current Directory

The current directory window, unsurprisingly, displays the files in the current working directory. You can open it via the drop down menu Desktop->Current Directory if it is not already open. From here you can navigate the file system and search for files. Type F5 to force a refresh.

http://www.mathworks.com/matlabcentral/fx_files/21653/3/content/tutorial/currentdir.png

Userpath

Matlab automatically sets up a default directory where you can save your own Matlab files; it opens this directory, whenever its started. You can view and change this default by typing userpath or say userpath c:\Users\matt\Matlab\ at the command prompt.

Help

One of Matlab’s best features is its extensive library of help files. There are far too many built in functions to memorize and even if you remember the name, the exact syntax might allude you. You can bring up the help navigator by going to Desktop -> Help or search right from the command window. Typing help functionname at the command prompt displays that function’s documentation right there, whereas doc functionname brings this up in the help window. You can search by keyword in help or search the first line of every function’s documentation with the lookfor command, as in lookfor eigenvalue.

http://www.mathworks.com/matlabcentral/fx_files/21653/3/content/tutorial/helpWindow.png

Editor

As we mentioned, Matlab commands are executed either at the command prompt or by running scripts or functions, which can be created and edited with the built in editor. To launch the editor, if it is not already open, type edit or edit filename. Commands can be entered here and executed as a script. They are saved with a .m extension. To run your script, type in the name at the command prompt, or press F5 or the save and run button at the top of the editor. Your own functions can be written here as well. We discuss functions in depth in a dedicated chapter.

Writing Functions

You can set break points to halt execution at certain lines for debugging, which we discuss here.

Debugging, Profiling, & Style

Comments are written by preceding the line with the % symbol. Block comments are opened with %{ and closed with %}. To have Matlab word wrap a selection of comments, right click on the highlighted text and select, Wrap Selected Text.

You can partition your code into editor cells by typing two percent signs, %%, at the beginning of the line. This can help organize your code into logical sections. You can also evaluate cells one at a time by selecting the evaluate cell button at the top of the editor. At any time, you can execute an arbitrary block of code by highlighting it and pressing F9. Cells are also used when publishing your code. This tutorial was written in Matlab and published to html by selecting the publish button at the top of the editor. This can be very useful when you want to share your code and results with others in a professional looking report.

Certain constructs like for loops and functions can be folded, hiding all but the top line from view. Select the + or – symbols appearing on the left hand side of the editor, by the line numbers.

Here is an image of the editor in action. Notice we have the open m-files listed in the center column; you can move these to the left right or bottom. We have also docked one of the figures in the top left. By default figures open in their own windows but it can sometimes be useful to work with a figure on the same screen: to do this, use the doc window arrow at the the top left of the figure.

http://www.mathworks.com/matlabcentral/fx_files/21653/3/content/tutorial/editor.png

There are many other configuration options and editor tools available; experiment by selecting the many buttons and exploring the drop down menus.

Layouts and Other Windows

Matlab gives you a lot of freedom over how you organize the windows in the environment. For instance, you can have have multiple windows take up the same screen area and toggle between them at will, or place windows at the sides where they automatically hide until you select them. Try dragging them around to different places to see the effect. There are more windows than described here available under the Desktop drop down menu.

You can save the current layout, select one of the default ones, tile all the windows, and perform many other related tasks under the Desktop drop down menu. Its worth taking the time to organize your layout effectively before you begin working.

Start Bar

Many of the tools and screens we have talked about, as well as links to various graphical wizards are available under the start bar in the bottom left hand of the environment.

Input & Output

Input and output in Matlab is relatively easy and can be done with a few useful functions. We describe these first and show examples at the bottom of this section.

The dlmread() is very useful for importing ascii delimited data into Matlab. You simply specify the filename and optionally the delimiter, although it can usually figure this out. To write data to a delimited file, use the dlmwrite() function.

You can also use the built in import wizard by typing uiimport at the command prompt. This is particularly useful when you have data stored in the windows clipboard, copied from some third party program.

If you are reading text from a file, try the textscan() function. You first have to open the file, however, with fopen() and then close it when you are done with fclose(). Here is an advanced example from the chapter on Strings.

Importing Text example

The imread() function is useful for reading image files and supports a wide range of formats. To write an image, use imwrite(). The imagesc() function can be used to view the image.

To write arbitrary data, including text, to a file, use the fprintf() function in conjunction with fopen() and fclose(): fopen() returns a file id, which you then pass as the first argument to fprintf(). If you do not specify a file id, fprintf() prints the data to the command window. We discuss the formatting options available with this function here.

Formatting Strings

For more information on, say, the textscan function type doc textscan at the command prompt.

Here a a number of examples.

A = rand(20,40); % create a random matrix

dlmwrite(‘testData.csv’,A); % write to a file as a comma separated list

clear

B = dlmread(‘testData.csv’); % load it back in

C = ‘We will write this string to a file’; % create some text.

fid = fopen(‘hello.txt’,'w’); % open a new file for writing

fprintf(fid,C); % write it to a file

fclose(fid); % remember to close the file

fid = fopen(‘hello.txt’,'r’); % open with read access

D = textscan(fid,’%s’); % read it back in. %s to expect strings

D{:} % show the contents of D

fclose(fid); % remember to close the file.

ans =

‘We’

‘will’

‘write’

‘this’

’string’

‘to’

‘a’

‘file’

load mandrill; % built in image

imagesc(X); % display it

axis image % window dimensions appropriate for an image

map = colormap(bone); % a possible color scheme.

http://www.mathworks.com/matlabcentral/fx_files/21653/3/content/tutorial/gettingStarted_01.png

imwrite(X,map,’mandrill.jpg’,'jpg’); % write the image to a jpeg file

clear

X = imread(‘mandrill.jpg’); % load it back in.

save example % save all the variables to a .mat file

clear

load example % load them back in

close all

clear all

VN:F [1.8.8_1072]
Rating: 0.0/10 (0 votes cast)
VN:F [1.8.8_1072]
Rating: 0 (from 0 votes)

Popularity: 1% [?]

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • Live
  • PDF
  • Technorati
  • Twitter
  • Yahoo! Bookmarks
  • Add to favorites
  • email
  • MySpace
  • RSS

Writing and Using Functions in Matlab

May 12, 2010 by Admin · Leave a Comment
Filed under: Code Optimization, Tutorials 
VN:F [1.8.8_1072]
Rating: 0 (from 0 votes)
VN:F [1.8.8_1072]
Rating: 0.0/10 (0 votes cast)

by Matt Dunham

While we can perform a lot by simply writing script files or executing commands at the command prompt, there are many reasons why writing functions to perform computations and actions is advantageous. Many of these would be discussed in a wider course on programming. We simply list a few reasons here.

  • We can parameterize functions to call them multiple times with different inputs.
  • In general, its easier to reuse functional code.
  • We can compose functions together.
  • Functional code is often better organized, and easier to read and understand.
  • We can break large problems into a number of smaller problems and write functions to solve each, (i.e. functional decomposition).
  • The variable scope of a function is isolated from other functions so we can reuse variable names.
  • In Matlab at least, executing functions is faster than executing scripts.
  • In Matlab, we can pass functions as inputs to other functions.

Contents

Variable Scope

Matlab commands are executed in one of three places: the command prompt, within a script, or in a function. In the first two cases, the scope of the variables is the base stack or workspace. Functions, however, maintain their own stack, isolated from the others. This means that a variable created in one function does not affect a variable in another, (or the base workspace) even if they have the same name. (There are a couple of technical exceptions, which will not concern us: global variables and the assignin() function – use of either is not recommended).

Running Functions

Below we give some examples of executing functions. Usually we specify the function name, its inputs, and name its outputs. However, functions may return any number of outputs, including 0, and may take any number of inputs, including 0. Some functions can be executed as ‘infix’ operators like ‘+’, or with their own special syntax as with the concatenation function, [ ]. In these last two cases, the special syntax is a kind of shorthand for the execution of the underlying function: ‘a+b’ executes plus(a,b) and ‘[a b]‘ executes horzcat(a,b) .

When a function takes no arguments, the use of parentheses is optional as in version or version(). If we do not supply any names to the outputs of a function and it returns outputs, the first, and only the first, of those outputs is assigned to the ans variable. In general, if a function returns n values, we can assign 0 to n of those by supplying 0 to n variable names enclosed in square brackets as in the examples below.

A = ones(1,2)                           % call the function ones
 
B = 2+2                                 % infix call to plus
 
version;                                % use of () optional if no arguments
 
nums = [1 3 4 2 8 4 3 1 9 2 3 1 3];     % call to the horzcat function
 
unique(nums)                            % output assigned to 'ans'
 
C = unique(nums);                       % grab only the first of three outputs
 
[C,D] = unique(nums);                   % grab the first two
 
[C,D,E] = unique(nums);                 % grap all three
A =
1     1
B =
4
ans =
1     2     3     4     8     9

When a function takes only string arguments, we can call it using command syntax as in the following examples. Each input is separated by a space.

display hello                           % command syntax
 
strcat one two three four               % four inputs
hello
ans =
onetwothreefour

Creating Functions

To create your own function, open a new file in the editor and begin by creating the function header, which includes the name of the function and its inputs and outputs. When you save the m-file, you must give it exactly the same name as the function name in the header. You cannot create functions within script files, (except for anonymous functions discussed below). Make sure that the file location is on the Matlab search path, (see the section below).

function [output1 ,output2, output3] = myfunction(input1, input2)

Comments, denoted by percent signs, can occur anywhere in the file, however, only comments directly below the function header, (with no spaces in between) are included in the auto generated help entry. Only the first line of comments is searched in calls to lookfor. You can start and end a block of comments with the characters {% and %}.

%{
 
Block Comments
 
%}

Within the function, you can use the inputs as local variables and you must assign values to each of the outputs before the function terminates, (at least those that will be assigned by the caller of the function). It is customary to end the function with the end keyword but this is optional unless you have nested functions or multiple functions per file as described below.

Here is an example of a simple function. It must be saved in a file called quadform.m.

function [X1,X2] = quadform(A,B,C)
 
% Implementation of the quadratic formula.
 
tmp = sqrt(B.^2 - 4*A*C);
 
X1 = (-B + tmp)./(2*A);
 
X2 = (-B - tmp)./(2*A);
 
end

Multiple Functions Per File

You can have multiple functions per file but only the function whose name corresponds to the filename is accessible from outside the file. The other functions can be used, however, from within this main function just as they would be if they were saved elsewhere. Each function must end with the end keyword.

Nesting Functions

Relatively new to Matlab is the ability to nest functions within each other. This can be extremely useful. Nested functions operate much like the multiple-functions-per-file case above but are included before the final end statement of the main function. The principal difference is that they share their lexical scope with their parent so that variables created within the parent function are accessible in the nested function and vice versa. You can nest functions within functions, within functions as deep as you like, although more than one level is rarely necessary. Nested functions are not accessible outside of the top level function.

function C = myMainFunction(input1, input2)
 
M = 22;
 
K = innerFunction(3,2) + 1;
 
C = K + 2;
 
function B = innerFunction(D,E)
 
Z  = D + E - input1 - input2;
 
B = Z + M;
 
end
 
end

Nested functions can call other nested functions at the same level, (i.e. both contained within the same parent function), however this can sometimes obfuscate the flow of control in your program, making it difficult to read and debug, so do so with caution.

In general, however, using nested functions can make your code easier read, (and write) as you can break larger computations into smaller chunks and the name you give each inner function acts to self document its action. This is of course the same benefit you would enjoy by writing multiple functions and saving them in separate files, but it is often easier to organize your program when all of the code is within one file. Since nested functions share their lexical scope, they are very tightly coupled with the parent function. If you find yourself writing a nested function that would be useful elsewhere, not just in the current program, consider saving it as its own stand alone function.

It is often useful to parameterize nested functions even though they could just access the variables from the parent function directly. Parameterization lets you call the same nested function many times with different inputs each time. It can also make your code more readable and extensible.

Recursive Functions

Like any programming language worth its salt, Matlab supports recursive functions, that is, functions who call themselves.

function n = countNodes(tree)
 
if(isempty(tree))
 
n = 0;
 
else
 
n = countNodes(tree.left) + countNodes(tree.right) + 1
 
end
 
end

Many recursive algorithms require that you initialize certain variables before you execute the recursive loop. Nesting the recursive functions can be very handy in these cases.

Keep in mind, however, that recursive function calls in Matlab are no faster and may be slower than using loops, which are themselves quite slow. See the section on vectorization in the flowOfControl chapter.

Function Handles / Anonymous Functions

We can pass functions as inputs to other functions in Matlab by first creating a handle to the function and then passing the handle as you would any other variable. Doing so can allow you write generic code in which you predefine the circumstances under which you want a function to execute but not the precise actions that are to occur when it does; this is left up to the passed function itself. Perhaps you have code, like the above countNodes above, which iterates over every node in a tree. You could parameterize this core function so that the action performed at each node is governed by the specified function and not hard coded.

We can create handles to existing functions but can also create functions ‘on the fly’. These are called anonymous or inline functions.

To create a handle to function, we use the @ symbol followed by the name of the function, in what is essentially lambda notation. We can also optionally define the input variables following @, in parentheses. We begin by creating a handle to the exponential function and demonstrate how to use it. In the second case, we create a composition of existing functions and specify the input variables. We can create handles to our own functions as well, (even nested functions) in the same way.

h = @exp                                    % h is now a handle to exp
 
h(2)                                        % evaluate h(2) = exp(2)
h =
@exp
ans =
7.3891
g = @(x,y)sqrt(exp(x).*y.^sin(x))+x.*y      % create a more complicated inline function
 
g(3,5)                                      % evaluate g
g =
@(x,y)sqrt(exp(x).*y.^sin(x))+x.*y
ans =
20.0207

As an alternative to using function handles, we can pass the string names of functions and either convert to handles using the str2func() function or evaluate them using the feval() function. The eval() function lets you execute any string as if it were typed at the command prompt.

s = str2func(’sin’)

s(0)

feval(‘cos’,pi)

eval(‘E = 3′)

s =

@sin

ans =

0

ans =

-1

E =

3

Function Arithmetic

It can often be useful to compose two or more functions together to create a new function.

f = @(x) 2*x.^2;                                % start with functions f, g
 
g = @(x,y) log(x.*y);
 
h = @(x,y) f(x) + 2*g(x,f(y))-f(g(x,y)).*g(2,y);% create a new function, h, from f and g.

Here is a concise way to create a 100 degree polynomial.

f = @(x)0;                          % start with the constant function
 
for i=1:100
 
f = @(x)f(x) + x.^i;            % keep adding higher order terms.
 
end

Currying

Currying named after Haskel Curry. Is essentially a way of transforming a function of n variables into a function of m < n variables by specifying values for the remaining inputs. If we have a function that takes in a large number of inputs, which we will call over and over, and most of those inputs will remain the same through subsequent calls, currying can be very useful.

Create some horrendous function.

f = @(a,b,c,d,e,f,g,h,i,j,k) a*b+c-d/e-f*g.^h-i/j*k;

Suppose a through h will have fixed values for many calls. We can create a new function from the old by setting some of its values.

fcurry = @(i,j,k)f(2,4,2,0,1,2,3,2,i,j,k);
 
test = isequal(f(2,4,2,0,1,2,3,2,9,9,9),fcurry(9,9,9))
test =
1

This same technique can be useful even when the functions are not mathematical in nature but simply take a lot of parameters, (like many of the plot commands).

Variable # of Input Arguments

Matlab supports functions with a variable number of input arguments, allowing the user to to decide how many to pass in, depending on the context. There are two approaches we can take, (or a combination of the two.

  1. Create the function with the maximum number of possible input arguments and then check how many inputs were provided by the user with the nargin() function. The remaining inputs can then be assigned default values.
  2. Use the varargin construct, which ‘absorbs’ all the inputs that come its way. It must occur last in the series of inputs as in the following: function myfunc(A, B, varargin) . If the user provides 2 inputs here, varargin , (a cell array) is empty, whereas if say 10 inputs are provided, varargin will hold the remaining 8. The entries in varargin can be accessed via varargin{1} , varargin{2} , etc, with curly braces. See the section on cell arrays for more information. The narargin() function can still be used here and returns the number of inputs the user specified, (not necessarily 2 or 3).

First Approach

result = myfunc(1,2)             % user calls function with 2 inputs
 
function E = myfunc(A,B,C,D)
 
if(nargin < 4) ,D = 1,end
 
if(nargin < 3) ,C = 2,end
 
if(nargin < 2) ,B = 3,end
 
if(nargin == 0),A = 4,end
 
E = A + B + C + D;
 
end

Following the call, result will be 6 = 1+2+2+1.

Second Approach

result = mysum(1,2,3,6,2,9,7)
 
function E = mysum(varargin)
 
E  = 0;
 
for i=1:nargin
 
E = E + varargin{i};
 
end
 
end

Following this call, result will be 30 = 1+2+3+6+2+9+7

process_options

While a variable number of input arguments can be very useful, a major downside is that the order in which the inputs must be specified is fixed. A better method is to use the process_options() function written by Mark Paskin, which allows us to easily parse named parameters so that users can specify inputs in any order they like. With this approach, the values for the inputs are preceded by their names when the function is called.

A = myfunc(‘C’,2, ‘A’,3, ‘B’,1, ‘D’,5)

Inside the function, we then pass varargin to the process_options function, specify the names we are expecting, and default values should an input not be provided. Here is an example code snippet.

function myfunc(varargin)
 
[A,B,C,D,E] = process_options(varargin,'A',3,'B',1,'C',2,'D',5,'E',9);

See the included placeFigures() function for a longer example.

placeFigures

process_opttions() is available here http://www.cs.ubc.ca/~murphyk/Software/matlab/process_options.m

Redirecting Variable Inputs

Suppose you obtain a number of arguments via varargin and want to pass some or all of them directly to another function without having to parse them first. Since varargin is a cell array, we can index into it with multiple indices at once, (or all, using the : operator) and redirect the multiple return values straight into the parameter list of another function. This is equivalent to entering each entry one at a time into the parameter list, separated by commas as you would normally do.

Suppose for instance, that we call mainFunction below with 5 arguments. We can redirect these five arguments to secondFunction() , which expects 5 inputs, and the last 3 to thirdFunction() , which expects 3 inputs. You can perform this same trick with any cell array, not just varargin.

result = mainFunction(1,2,3,4,5);
 
function d = mainFunction(varargin)
 
a = varargin{1};
 
b = varargin{2};
 
c = otherFunction(varargin{:});
 
d = thridFunction(varargin{2:end}) + a + b + c;
 
end
 
function f = secondFunction(a,b,c,d,e)
 
f = a+b-c*d/e;
 
end
 
function g = thirdFunction(h,i,j)
 
g = h*i-j;
 
end

Variable # of Output Arguments

Matlab also supports variable number of output arguments using varargout() , although this is fairly uncommon. Type doc varargout for more information. The nargout() function is more useful, returning the number of outputs the caller of the function has asked for. Suppose, for instance, a function normally returns 3 outputs but all three take a long time to compute. If nargout() indicates that the user only asked for one output as in A = myfunc(2,4) as opposed to [A,B,C] = myfunc(2,4) we can bypass the expensive computation of B and C. Recall that Matlab only complains about undeclared variables when an attempt to access them is made, not before, and so this works perfectly fine. The built in Matlab hist() function operates this way. A histogram is only graphed if no outputs are specified, as in hist(data), otherwise, just the bin counts are returned.

Matlab Path and Search Order

Matlab finds the functions you call by searching the Matlab Path in the order in which the directories on the path are specified. Subdirectories of included directories are not by default added. The easiest way to add new directories or view the existing path is to use the graphical pathtool available via file->set path or by typing pathtool at the command prompt. There are many other functions related to path control, shown below. When multiple files with the same name exist on the Matlab path, Matlab silently executes the one higher up on the path. You can check which version will be executed with the which() command.

which exp                           % which implementation will be used
built-in (C:\Program Files\MATLAB\R2008a\toolbox\matlab\elfun\@double\exp)  % double method
which -all exp;                     % names of all implementations
 
allfiles = what;                    % list all of the m-files in the current directory
 
exist('writingFunctions','file');   % check if the specified file exists
built-in (C:\Program Files\MATLAB\R2008a\toolbox\matlab\elfun\@double\exp)         % double method
built-in (C:\Program Files\MATLAB\R2008a\toolbox\matlab\elfun\@single\exp)         % Shadowed single method
C:\Program Files\MATLAB\R2008a\toolbox\control\control\@lti\exp.m                  % Shadowed lti method
C:\Program Files\MATLAB\R2008a\toolbox\distcomp\parallel\elfun\@distributed\exp.m  % Shadowed distributed method
C:\Program Files\MATLAB\R2008a\toolbox\finance\ftseries\@fints\exp.m               % Shadowed fints method
C:\Program Files\MATLAB\R2008a\toolbox\mbc\mbcmodels\@xregcovariance\exp.m         % Shadowed xregcovariance method
C:\Program Files\MATLAB\R2008a\toolbox\symbolic\@sym\exp.m                         % Shadowed sym method
pathtool;                           % launch the path tool
 
addpath('c:\windows\temp');         % add this directory to the path
 
save = userpath                     % display,(or change) default save directory
 
mroot = matlabroot                  % display the root Matlab directory
save =
C:\Users\matt\Documents\MATLAB;
mroot =
C:\Program Files\MATLAB\R2008a

We can use the genpath() function to build a string containing the specified directory name and all of its subdirectories formed via recursive descent. We can then pass this string into addpath() for instance.

source = ‘c:\Windows\temp’;

d = genpath(source);

Here are a few related functions.

sfile = [source,'tmp.txt'];
 
[pathstr, name, ext, versn] = fileparts(sfile)  % parse a filename
 
f = fullfile('c:','windows','temp','myfile.tmp')% create a file path from parts
 
sep = filesep                                   % get the file separator for this OS
 
dinfo = dir;                                    % get a struct holding directory info.
pathstr =
c:\Windows
name =
temptmp
ext =
.txt
versn =
''
f =
c:\windows\temp\myfile.tmp
sep =
\

Private Functions & Packages

We will say more about private functions and packages in the object oriented programming chapter, however, they can be used in non-OO code as well. Any functions you save into a directory named private will only be accessible by functions in the containing directory one level up, (or the private directory itself). Thus, you can create functions with common names like sum or display, put them into a private directory and you will not interfere with existing implementations outside of your project.

Matlab, (as of 2008a), also supports packages, which can be used to partition the name space. Packages are directories beginning with the ‘+’ symbol. Any functions you place into these directories are then only accessible by first referring to the package name. Suppose I create a directory called ‘+lab’ and put the function ‘calc’ into this directory. I would then call it with the syntax lab.calc() . Packages can provide an easy way to organize your code and like private directories, let you reuse common function names. You can temporarily import a package, (meaning you do not have to use the . syntax) with the import command, i.e. by calling say import lab .

clear all;
VN:F [1.8.8_1072]
Rating: 0.0/10 (0 votes cast)
VN:F [1.8.8_1072]
Rating: 0 (from 0 votes)

Popularity: 1% [?]

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • Live
  • PDF
  • Technorati
  • Twitter
  • Yahoo! Bookmarks
  • Add to favorites
  • email
  • MySpace
  • RSS

Next Page »