Sunday, May 3, 2009

MATLAB: Tryin' to CODE smarter

Whenever I look at my MATLAB codes I see nothing but a hapless hierarchy of for loops and if statements. And I am pretty accustomed to the troubled look I have to see on other peoples faces when they look at my codes. The other day I examined few geeky codes and discovered that they extensively make use of the built-in functions and operators of MATLAB to downsize their code length and runtime. I never bothered much about MATLAB functions, but now it's becoming unbearable! So I have decided, I will try to learn some spells used by MATLAB wizards (quite a job for a programming squib like me!). If you are also thinking about looking little smarter with MATLAB, you are welcome to join!

Ok let's start with some basic array operations. These may not be arcane secrets, still it's always good to know.

%%%%%%%%%%%%% ADVERTISEMENT %%%%%%%%%%%%%%%%%%%%
% If you find this post too messy to comprehend, a better and improved rendition is available here: http://www.sajidmc.net/en/2009/05/efficient-matlab-coding/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

1. Accessing an entire row or column without running a loop.
  • A(i,:) = 1 => makes all the elements of row i of matrix/vector A equal to 1.
  • A(:,i) = 1 => does the same thing with column 1.
  • B = A(i,:) => stores row i in a row vector B
2. Accessing more than one rows/columns simultaneously.
  • A([i,j],:) = 1 => makes all elements of rows i and j equal to 1
  • B = A(:,[i,j])=> B is a matrix with columns i and j of A as its two columns

3. Swapping entire rows or columns. This is often required for numerical solution of simultaneous equations.
  • A([i,j],:) = A([j,i],:) => swaps the elements of rows i and j
  • A(:,[i,j]) = A(:,[j,i]) => swaps the column elements of col i and col j
4. The find( ) function. Used to find index of elements satisfying some condition.
  • find(A) returns indices of all non-zero elements
  • find(A > 5) finds indices of all elements greater than 5.
5. Diagonal Elelments. These are accessible! (what a surprise...;P)
  • B = diag(A) => stores in B the diagonal elements of A
  • B = diag(A,1) => stores in B the elements next to each diagonal element
  • B = diag(A,-1) => stores elements to the left of diagonal elements

5. Deleting a row/column of a matrix or an element of a row/column vector.
  • A(i) = [] % Deletes the i-th element of a row/column vector A
  • A(i,:) = [] % Deletes an entire row
  • A(:,i) = [] % Deletes an entire row
6. Ctrl+C. Yeah it can be a life-saver when you are running a Sisyphean (=infinite) loop intentionally or unintentionally and wanna break out of this without breaking out of MATLAB.

7. Saving MATLAB plot as an image (Love it!)
  • saveas(gcf, 'img_name', ’img_format’);
  • img_format may be png, bmp, jpg, tif, even pdf!
8. Extracting Data from a Plot. (Still found no use!)
  • p = plot(x,y); % p is the plot defined as an object
  • x = get(p, 'XData')
    y = get(p, 'YData')
*** More plotting/image tips are available *here*, here and here

9.Tony's Trick. This is a popular (and allegedly faster) trick used to form a matrix by repeating a row/column vector.
  • B = A(ones(3,1),:)
*Example:
>> A =[1 2 3] % A is a row vector


>> B = A(ones(3,1),:)
>> B =

1 2 3
1 2 3
1 2 3

>> A = [1 ; 2 ; 3] % A as a column vector

>> B = A(:,ones(3,1))

>> B =

1 1 1
2 2 2
3 3 3

And WOW! it's really faster for replication in one dimension! For matrix A given above:
Elapsed time is 0.014354 seconds. %Using repmat()function
Elapsed time is 0.000063 seconds. %Using Tony's trick

10. Last but not the least, a great book on MATLAB ARRAY MANIPULATION for the blessed ones!
http://home.online.no/~pjacklam/matlab/doc/mtt/doc/mtt.pdf

3 comments:

Anonymous said...

great tips, keep them coming...

Sabih Uddin Omar said...

Is it Sajid? Why anonymous?

Sajid Muhaimin Choudhury said...

Find the (nearly) copy/pasted version of this article at:
http://www.sajidmc.net/bn/2009/05/efficient-matlab-coding/