Fortunately, the speed of MATLAB can be increased significantly by careful construction of the scripts. There is one basic rule to follow when writing a MATLAB script for speed:
Let's consider a simple example. We want to find how many points in an image have a value greater than 2000. In a traditional programming language, we might take the following approach:
j=0; for i=1:16384; if (PET(i)>2000) j=j+1; end endThis takes about a second to execute under MATLAB. A vectorized approach is to use the MATLAB find function:
length(find(PET>2000));This takes about 0.07 seconds to execute, and is therefore approximately 15 times faster than the traditional approach. Now, consider the following related problem. We wish to create a mask based on the image we were just manipulating, where any point whose value is greater than 2000 is set to one, and all other points are set to zero. The traditional solution to this might look something like:
mask=zeros(16384,1); for i=1:16384; if (PET(i)>2000) mask(i)=1; end; end;This takes about 0.81 seconds to execute. A faster, vectorized approach is as follows:
mask2=zeros(16384,1); index=find(PET>2000); mask2(index)=ones(size(index));This takes about 0.05 seconds to execute, and is therefore about 16 times faster than the traditional approach. It also introduces an important technique that is useful when vectorizing routines: using a vector as an index to another vector. In the above code fragment, the variable index contains the indices of values.
One other thing to keep in mind when trying to speed up MATLAB code is that it is possible to call FORTRAN or C routines from within MATLAB. These functions are called either FMEX or CMEX functions depending on which language they are written in, and details on creating them can be found in the MATLAB External Interface Guide.
The EMMA toolbox contains several CMEX versions of popular MATLAB functions:
lookup
performs 1-D linear interpolation, similar to
MATLAB's interp1
routine.
rescale
is useful for scaling a large matrix by a
constant, or by another matrix of the same size and shape.
rescale
doesn't offer a significant speed advantage over
the .*
operator, but it performs the arithmetic in place,
so no copy is made of the target matrix. This can result in significant
memory savings.