Notes on miscellaneous Matlab topics

Array subscripts and ordering.

Matlab's treatment of arrays and their subscripts can be confusing. There are two issues to be aware of:

1. Order and algebraic roles of array subscripts.

Matlab arrays are indexed as follows:
A2D(row, col)
A3D(row, col, page)
A4D(row, col, page, cube)

Matlab follows standard algebra conventions in assigning the row, col, page ... roles to indexes 1, 2, 3: Wikipedia Matrix_(mathematics) This differs from other languages such as C, which use the leftmost index for the largest granularity step, and the rightmost for the smallest. (More on this below.)

Matlab provides no "1-D" data structure (vector), instead making use of 1 row x N col, or N row x 1 col arrays for that purpose. See note below on this.

2. Accessing array items using a single index

Matlab allows an N-dimensional array to be accessed using a single index as though it was a single "linear" vector of items. In that case it is important to know how rows, cols etc are mapped into the 1-D view.

In the 1D view, as the single index increments, it advances from row-to-row first (down a column), then at the end of the column it progresses to the next column, and so on. Because the row index represents the finest jump, we would say that the row index is the "minor index", and (in the case of a 2-D matrix) the column index is the "major index".

"Column Major" terminology


Sometimes Matlab's indexing arrangement is called "column major" ordering. However this terminology is ambigous:

  • For 3 or more indexes, column is no longer the major index. For N-dimensional matrices, the arrangement could be called "N-major ordering".
  • It's nor entirely clear whether the term "Column major" refers to the order of data items when accessed using a single index, or to the ordering of the indices themselves ( (row,col) vs (col,row) ).

Vector = "1-D matrix" is presented as 2-D matrix with either 1 row or 1 col

Note that there is no "1-D matrix". The smallest number of dimensions is 2. Data which is a 1-D list (often called a vector) can be stored either as 1 row by N cols, or N cols by 1 row, and one must be careful to have the appropriate arrangement for the purpose at hand. This parallels algebra's distinction between row vector and col vector.

Despite the fact that a 2-D structure is used to store vector data, as described above it can be accessed using a single index, in which case either 1xN or Nx1 arrangement will appear the same:

A = [10 20 30 40] % creates a vector of 1 row x 4 cols.
B = A' % Single quote transposes

A(2) % returns 20, same as A(1,2)
B(2) % also returns 20, same as B(2,1)

For vectors, Matlab defaults to row vectors

It's worth being aware that Matlab's choice of row as the most minor index is somewhat incongruent with the simplest syntax for creating a vector or matrix, which expects data in column-minor order:
So:
A = [1 2 3 4; 5 6 7 8]; creates a vector of 2 rows x 4 cols.

From an everyday convenience point-of-view, this is probably what you want to happen, and visually it looks right on the page or screen. But the fact that it collides conceptually with the underlying 'row-to-row-is-finest-granularity' holds to some potential for confusion.

When the above matrix is read back using a single index, using B = A(:) it produces:
B: 1 5 2 6 3 7 4 8

So although the simplest syntax creates the data by traveling across columns and then from row to row, the "underlying order" of the data is from row to row and then across the columns.

The same applies to arrays of strings, though it this case it's slightly more jarring:

A = ['abcd';'efgh']
B = A(:)
B: a e b f c g d h.

(But for general purposes, arrays of strings are not very useful -- see separate section.)

The N-D case continues this pattern

Example: A 3-D matrix's data is stored in order of row, col, page, with row-to-row being adjacent.

So given the 4 row x 3 col x 2 page array here:
A(:,:,1) =
 1 5 9
 2 6 10
 3 7 11
 4 8 12
A(:,:,2) =
 13 17 21
 14 18 22
 15 19 23
 16 20 24

A(:) will return 1 2 3 ...24 in order.

Matlab implementation of variant arrays: Cell arrays

Cell arrays provide Matlab with a kind of array whose items can be different types.

Matlab's central data object type is the array. An array specifies a number of dimension (2 to ?), a particular length for each dimension (so the array must be rectangular, not irregular), and a data type (so all items in the array must be of a uniform type).

For some applications, it's valuable to have an array whose items are of different types. That is where the Matlab "cell array" comes in. A cell is an object that looks like a single uniform type ("cell") to the array which contains it, but any type may be placed within it. It's basically an "any-type-to-single-type adapter".

Cells are not usually manipulated individually, instead you work with a cell array, using curly-braces syntax to create the cell array and access the items in the cells, in a manner parallel to the way square and round brackets are used to work with an ordinary single-type array.

Other languages may have arrays that accept any type of items by default, or can be declared to be of "variant" type when that flexibility is needed. Matlab uses the distinct cell array concept and syntax to handle the job.

Gotchas

The main gotcha with cell arrays is accidentally using normal array syntax to access them, instead of curly-braces syntax. Since a cell array is just a normal array whose items are cells, the normal array syntax will return the cell object instead of what we really want, which is the cell object's contents.

This opportunity for error is compounded by display that the the Matlab IDE command line shows for cell results: The IDE automatically shows the cell's contents, and does not make it obvious that you are looking at a cell and its contents, rather than just the contained data you expected.

List of strings: Use cell array, not array of strings.

A Matlab array of strings is really a 2-D arrays of char. It must be rectangular, so that means each 'string' (row in the 2-D array) must be the same length. This is almost never what you want, despite the Matlab docs going to some length to explain how you can pad shorter strings with spaces.

Instead, one really wants the strings to be different lengths. This is trivial in most languages, but in Matlab requires resorting to the relatively "advanced" feature called a "cell array", discussed in a separate section on this page.

To implement a list of arbitrary-lengthened strings in Matlab, one can use a 1-D cell array, each containing a string, each with its own length. Of course, you can't have 1-D arrays, you have to have 1 x N array, so to get the functionality of a 1-D array of strings you must use:

1 row x N column array of cells where each cell contains a 1 row x N col array of char.

 % Attempt to use ordinary array for list of strings...
 A = ['abcde', 'fgh'] % FAIL due to inconsistent lengths of rows.
 
 % Use cell array instead...
 A = {'abcde', 'fgh'} % creates 1 row x 2 col array where each item is a cell
                      % containing a 1 row x N col array of char, 1x5 for 'abcde',
                      % and 1x3 for 'fgh'.
 
% To access these:
 getfgh = A(1,2) % 'Succeeds', but can't be used as a string, because round
                 % parens get the cell, not the contents of the cell.
 getfgh = A{1,2} % Using curly braces, getfgh is now a 'string',
                 % i.e., a 1 row x 3 col array containing the three chars 'fgh'.
By way of completeness: if you do use ordinary parens to access a cell array (example: oops = A(1,2) ), you now have a 1 x 1 "array" whose one item is a cell object. You can retrieve the contents by using curly-braces indexing on that: (example: ahha = oops{1,1} ).

Also, since access using cell array subscripts parallels access using square brackets, you can use a single subscript to extract to access the list of strings. So in the example above, A{2} could replace A{1,2}, and in the ahha example, oops{1} could replace oops{1,1}.

More compact command window display

By default, Matlab's command window shows command results using excessive intervening blank lines. To eliminate (most?) blank lines:

File > Preferences > Command Window > Text display > Numeric display
Set this item to "compact" instead of "loose".
(I have no idea why this option is referred to as "Numeric display", that seems like a mistake.)
Equivalently, one can enter the command:
format compact;