Hello, and welcome to another episode of the Software Carpentry lecture on MATLAB. In this episode, we'll have a look at some of the ways you can index arrays. As we'll see, clever indexing allows you to avoid writing loops, which both reduces the size of your code, and makes your code more efficient.
Individual elements in an array can be accessed using a comma separated list of integer indices.
In most programming languages, the first element of an array is element 0. In MATLAB, indexes start at 1.
Arrays can be sliced by using another array as an index. In this example, we use the array 1, 2, 3, which we can create using the shorthand 1 colon 3 notation.
MATLAB programs should always use slices and other indexing operations rather than write loops over arrays. There are several advantages, including shorter code that is more easily understood, and improved runtime.
It is also possible to assign to slices. For example, we can assign zero to columns 2 and 3 in row 2 of 'block' in a single statement.
An array slice makes a copy of the underlying array, which means that the data values are copied to a new location and subsequent updates do not change the original matrix.
Slicing on both sides of the statement gives us a way to shift data along the axes. If 'vector' is a one-dimensional array as shown here, then 'vector[1:3]' selects slots 1, 2, and 3, while 'vector[2:4]' selects the values in slots 2, 3, and 4. Doing the assignment overwrites the lower three values, but it leaves the uppermost untouched).
MATLAB has a function circshift, which shifts values in an array in a circular pattern. Rather than discard the leftmost item, it is placed in the rightmost spot and all other values are shifted left.
To perform more sophisticated indexing operations, we can use an array as a set of subscripts. For example, here's our four-element vector again, and a list with three legal subscripts: 4, 2, and 3. The expression 'vector[subscript]' creates a new array, whose elements are selected from 'vector' as you'd expect.
Arrays can also be used in comparisons. When we use the result of a comparison in an index, we only get those values that satisfy the condition. Almost all arrays in MATLAB are of type double, which means they are floating point numbers. When a matrix is used in a comparison, the result is not a double: it is a matrix of integer 0s and 1s.
The difference is apparent in this example. Here, the array 'm' is the result of a comparison, and we can see that a 1 means that the corresponding element of v was less than 4. The array 'm2' is hand constructed with the same pattern as m, but the values are doubles since this is the default. Try to use m and m2 as an index. The result of the comparison 'm' can be used but 'm2' fails because indices must be integers, not doubles.
Another term for an index from a comparison is a mask, because the boolean array masks all of the elements of vector that fail the condition.
We can use Boolean masking on the left side of assignment as well, though we have to be careful about its meaning. If we use a mask directly, elements are taken in order from the source on the right and assigned to elements corresponding to True values in the mask.
Using a mask on both sides of an assignment has a different effect. Corresponding elements of the array 'fill' are assigned to 'a' if the location meets the criteria in mask. In both cases, only locations corresponding to True values in the mask are affected; it's what happens at the source that changes.
Sometimes we want to replace values in a matrix with 0s without changing the size of the result. We can use the boolean mask and element-wise multiplication to replace locations that are less than 1 with zeros.
There are two sets of logical operators in MATLAB. A single ampersand & or vertical bar | corresponds to elementwise "AND" and "OR" on an array. Double AND and double OR operate on scalars only. It is usually preferable to use the single AND or single OR since they work in both cases.
In logical expressions, zero is the only number that is false. Be careful though: very small numbers are still nonzero even if they look like zero when you print them.
To review, arrays can be sliced with vectors of indices, or masked with conditionals.
No matter what you do, if you are writing loops over array elements, you have probably missed something, or are doing something wrong.
In our next episode, we'll use the tools we have looked at so far to explore some linear algebra.