Department of Engineering

IT Services

Matlab - higher dimensions

Introduction

Matlab supports the use of 1D vectors and 2D matrices. It also copes with higher dimensioned matrices ("N-D arrays"), though there are a few surprises. Just as a vector with 4 elements is often described as a 4x1, so a 4x3 matrix could be described as a 4x3x1 (a slice of a 4x3xn block) or even a 4x3x1x1. These single-thickness dimensions are called "singleton dimensions".

The ndims command returns how many dimensions a matrix has. It never returns less than 2. After

   m=ones(4,1)

ndims(m) return 2. After

   m=ones(4,2,3)

(which creates a 4x2x3 matrix full of 1s) ndims(m) returns 3, though after

   m=ones(4,1,1)

ndims(m) returns 2 because it ignores trailing singleton dimensions. If you create m in the following way

   m=ones(1,1,4)

m is essentially the same shape as before, but this time ndims(m) returns 3. You can do

   m=squeeze(m) 

which removes singleton dimensions after which ndims(m) returns 2.

Another complication is that

   m=ones(4,0)

is legal - it means that m is empty along one dimension.

Creating N-D arrays

We've already seen how ones can be used to create N-D arrays. zeros and randn can be used in the same way. Also

  • If you have a 2D matrix you can add dimensions to it.
       A=randn(3,4)
       A(:,:,2) = 5; 
    
    makes A (a 3x4 matrix) into a 3D matrix whose 1st layer is the same as the original A and whose 2nd layer is full of 5s.
  • repmat can replicate through several dimensions. The following creates 24 copies of a 2x2 matrix spread through 3 dimensions.
       m=repmat([1 2;3 4], [2, 3, 4])
    
  • The cat command ("cat" stands for "concatenate") joins a list of arrays along a specified dimension. So
       A=randn(3,4)
       B=cat(3,A,A)
    
    creates a 3D matrix with 2 layers each holding a copy of A.
  • ndgrid - does in N dimensions what meshgrid does in 2 dimensions. It's useful in combination with interpn

Manipulating N-D arrays

There are some new commands to manipulate N-D arrays. Often they're generalisations of commands to deal with 2-D arrays.

Changing the shape

reshape works with N-D arrays. Also

  • shiftdim shifts dimensions, so that (for example) the 1st dimension becomes the 2nd and so on. For example
       newm=shiftdim(m,1)
    
    shifts the dimensions to the left and wraps the dimensions round so that the first becomes the last, and
       newm=shiftdim(m,-1)
    
    shifts the dimensions to the right, this time padding with singletons.
  • permute rearranges the dimensions as specified by the vector provided -
       newm=permute(m,[3 2 1 4])
    
    You can use this to transpose matrices.
  • shiftdata (there's an inverse, unshiftdata) shifts data so that it's in the right dimension for certain functions.

Changing the contents

  • circshift circularly shifts the values in the array. so
       v=[1:4;5:8]
       newv=circshift(v,1)
    
    shifts the values along the 1st dimension. Different dimensions can be selectively shifted
       v=[1:4;5:8]
       newv=circshift(v,[1 2])
    
    shifts the values down 1 and right 2. The following would shift data in the first 3 dimensions of m by 0, -1 and 2 respectively.
       newm=circshift(m,[0,-1,2])
    
  • flipdim is a generalisation of flipup and fliplr. flipdim(m,1) is equivalent to flipup(m), and flipdim(m,2) is equivalent to fliplr(m).

Taking slices

If you want to take 2-D slices from a 3-D matrix A you can use something like A(:,:,1).

Processing N-D arrays

Some old commands have been rewritten to cope with N-D arrays. For example, sum by default sums along the first non-singleton dimension. You can make it sum along other dimensions. So

   A=randn(3,4,2)
   sum(A,3)

sums along the 3rd dimension (i.e. "depth") giving 12 values.

Note that you can't have sparse N-D arrays.

An example

Suppose you wanted to calculate the possible outcomes of rolling 2 dice (a red one and a green one, say). You could use

   for red=1:6
      for green=1:6
         outcomes(red,green)=red+green;
      end
   end

To add another (blue) die, you could do

   oldoutcomes=outcomes;
   for blue=1:6
      outcomes(:,:,blue)=oldoutcomes(:,:)+blue;
   end

We can now try some simple commands just to check that all is as expected

   ndims(outcomes)  
   size(outcomes)
   numel(outcomes)
   min (outcomes(:))
   max (outcomes(:))
   lessthansix=outcomes<6
   sum(lessthansix(:))/numel(outcomes) % the chance of getting <6
   % Now find the dice values corresponding to these throws.
   % Note that for N-D arrays you need to use ind2sub as well
   lessthansixindices=find(outcomes<6)
   [red,green,blue]=ind2sub(size(outcomes),lessthansixindices)
   % Plot them
   scatter3(red,green,blue)

See also Mathworks' Multidimensional Arrays and volume visualization pages.