Kahibaro
Discord Login Register

Indexing, Slicing, and Logical Indexing

Why Indexing Matters

Working with vectors, matrices, and arrays in MATLAB quickly becomes powerful once you can select and manipulate only the parts you need. Indexing is the process of telling MATLAB which elements or regions of an array you want to work with. In this chapter you will focus on how to access individual elements, ranges of elements, parts of matrices, and how to select elements using logical conditions.

You will see how indexing uses parentheses, how linear indexing works, how to index with vectors of positions, and how logical indexing lets you select data based on values instead of positions.

Basic Element Indexing

Every element in a MATLAB array has an index that starts at 1, not 0. For a vector, the single index is the position of the element inside the vector.

For example, consider a row vector:

v = [10 20 30 40 50];
third = v(3)

Here v(3) returns 30 because it is the third element of v. You can both read and write using indices. For example:

v(2) = 99;

replaces the second element of v by 99.

For a column vector, indexing works in the same way, but the vector is arranged vertically:

c = [5; 7; 9; 11];
first = c(1)

The index refers to the element in the given position regardless of row or column shape when you are dealing with a single vector.

Indexing Elements in Matrices

Matrices have two dimensions, rows and columns. To access a specific element, you provide two indices inside parentheses in the form (row, column).

For example:

A = [ 1  2  3;
      4  5  6;
      7  8  9 ];
elem = A(2,3)

Here A(2,3) is the element in the second row and third column, which is 6. As with vectors, you can assign to a particular element:

A(3,1) = 100;

Now the element in row 3, column 1 is 100.

If you try to index an element that does not exist, for example A(4,1), MATLAB will produce an error. To grow arrays deliberately you can assign to indices beyond the current size, but that is better discussed in chapters that cover array creation and modification in more detail.

Using the Colon Operator for Slicing

The colon operator : is the basic tool for slicing, which means selecting a range or block of elements. In one dimension, m:n represents all integers from m to n inclusive, provided m and n are positive integers with m <= n. For arrays, you use : inside parentheses to specify ranges of rows and columns.

For a vector, consider:

v = [10 20 30 40 50 60];
part = v(2:4)

Here v(2:4) gives a new vector [20 30 40] which contains the elements in positions 2, 3, and 4. You can also change these elements:

v(2:4) = [1 2 3];

In a matrix, the colon operator can be used separately for rows and columns. For example:

A = [ 1  2  3  4;
      5  6  7  8;
      9 10 11 12 ];
subA = A(1:2, 2:4)

The result subA is the block of A formed by rows 1 to 2 and columns 2 to 4. So subA contains:

     2   3   4
     6   7   8

You can also select all rows or all columns using a single colon in place of a range. For example:

col2 = A(:,2);     % all rows, column 2
row3 = A(3,:);     % row 3, all columns

The colon : by itself means the full range for that dimension.

Step Sizes in Ranges

Sometimes you want every second or every third element instead of all consecutive indices. In that case, you can use a step size start:step:stop.

For a vector:

v = [10 20 30 40 50 60 70 80];
evens = v(2:2:8)

The expression 2:2:8 creates the sequence 2 4 6 8, so v(2:2:8) selects the 2nd, 4th, 6th, and 8th elements of v. The result is [20 40 60 80].

For a matrix, step sizes apply to rows or columns separately. For example:

A = reshape(1:20, [4 5]);   % 4 rows, 5 columns
rows13 = A(1:2:3, :)        % rows 1 and 3, all columns
cols24 = A(:, 2:2:4)        % all rows, columns 2 and 4

This way you can create striped or subsampled views of your arrays without creating intermediate arrays of indices manually.

Linear Indexing

MATLAB arrays are stored in column major order, which means MATLAB fills columns first when it lays out the elements in memory. You can take advantage of this by using a single index with a matrix, not just with vectors. This is called linear indexing.

Consider the matrix:

A = [ 1  2  3;
      4  5  6;
      7  8  9 ];

If you write A(5) with a single index, MATLAB counts elements column by column:

Column 1: indices 1, 2, 3 correspond to 1, 4, 7.
Column 2: indices 4, 5, 6 correspond to 2, 5, 8.
Column 3: indices 7, 8, 9 correspond to 3, 6, 9.

So A(5) is 5. The order is:

$$A = [1,4,7,2,5,8,3,6,9]^\top$$

when you use a single index.

You can also use linear ranges like A(2:6). This gives a column vector that traverses the matrix down each column in turn:

B = A(2:6)

In this example B will contain elements [4 7 2 5 8] in that order.

Linear indexing is useful when you want to treat a matrix as one long vector, for example to apply a function to all elements and reshape later, or to identify positions from functions that return linear indices.

Indexing with Vectors of Indices

Instead of contiguous ranges, you can specify any list of positions using a vector of indices. This allows you to select elements in any order and to repeat positions.

For a vector:

v = [10 20 30 40 50];
idx = [5 2 5 1];
sel = v(idx)

The result sel is [50 20 50 10]. Element 5 of v comes first, then element 2, then element 5 again, and finally element 1.

For a matrix, you can use vectors of indices for rows and columns independently:

A = [ 1  2  3;
      4  5  6;
      7  8  9 ];
rows = [1 3];
cols = [3 1];
B = A(rows, cols)

Here B is composed of the combinations of the specified rows and columns:

Row 1, column 3
Row 1, column 1
Row 3, column 3
Row 3, column 1

So B is:

     3     1
     9     7

This behavior arises because MATLAB uses all combinations of row indices with column indices when you supply separate vectors for each dimension.

You can also use a vector of linear indices with matrices. For example:

idx = [1 5 9];
sel = A(idx)

Here idx refers to the first, fifth, and ninth elements in column major order, so sel becomes [1 5 9].

Logical Indexing Basics

Logical indexing selects elements based on conditions rather than position. A logical array is an array of true and false values. When you use a logical array as an index, MATLAB keeps the elements where the index is true and discards elements where it is false.

For a vector:

v = [3 8 1 12 5];
mask = v > 5;

The variable mask is a logical vector:

mask =
     0     1     0     1     0

where 1 means true and 0 means false. Now if you use it as an index:

sel = v(mask)

then sel contains only the elements of v where v > 5, which are [8 12].

You can combine conditions to create more complex selections. For example:

v = [3 8 1 12 5];
mask = (v >= 3) & (v <= 10);
sel = v(mask)

The & operator represents logical AND, so sel becomes [3 8 5].

Logical indexing is not limited to reading values. You can also assign to elements selected by a logical index:

v(v < 5) = 0;

This sets all elements of v that are less than 5 to zero.

Logical Indexing in Matrices

For matrices, logical indexing works with a logical array that has the same size as the target array, or with a logical vector that is applied to a particular dimension.

Consider:

A = [ 1  2  3;
      4  5  6;
      7  8  9 ];
mask = A > 4;

Now mask is:

     0  0  0
     0  1  1
     1  1  1

If you write:

sel = A(mask)

MATLAB returns a column vector containing all elements of A where the mask is true, in column major order. So sel is [5 7 8 6 9].

You can also use logical indexing to modify selected elements. For example:

A(A > 4) = -1;

This sets all elements greater than 4 to -1, but leaves other elements unchanged.

Sometimes you only want to select specific rows or specific columns based on conditions. There are two patterns you can use.

First, you can create a logical vector of rows or columns and use it to index that dimension. For example, to select rows where the sum is greater than 10:

rowSums = sum(A, 2);       % sum over columns, gives one value per row
rowsToKeep = rowSums > 10;
subRows = A(rowsToKeep, :)

Here rowsToKeep is a logical vector with one element per row. The index A(rowsToKeep, :) preserves all columns but keeps only those rows where rowsToKeep is true.

Similarly, to select columns based on a condition:

colSums = sum(A, 1);       % sum over rows, gives one value per column
colsToKeep = colSums > 10;
subCols = A(:, colsToKeep)

This pattern is very common in data analysis with matrices and tables.

Second, you can use a full logical matrix to select scattered elements across the matrix, as in the A > 4 example. In that case you no longer preserve the original 2D structure; the result becomes a column vector of the selected values.

Combining Logical and Positional Indexing

You are not limited to a single indexing style. You can mix logical indexing with numeric indexing to select more specific regions.

For example, suppose you have:

A = magic(5);      % 5-by-5 magic square

If you want to select elements in a particular row that satisfy a condition, you can write:

row3 = A(3, :);               % positional slice
mask = row3 > 10;             % logical condition on that row
sel = row3(mask);             % logical indexing of the row

Alternatively, you can apply the mask directly without storing the row separately:

sel = A(3, A(3,:) > 10);

Here A(3,:) > 10 creates a logical vector for the third row, and A(3, ...) uses it to select only those columns in row 3 where the condition holds.

You can apply a similar approach for columns:

col2 = A(:,2);
selCol = col2(col2 < 5);

In both examples, positional indexing first narrows down to a subset of rows or columns, and logical indexing then filters within that subset.

Using `find` with Indexing

The function find is closely related to logical indexing because it converts logical conditions into numeric indices. It is useful when you want the positions of elements that satisfy a condition rather than the values themselves.

For a vector:

v = [3 8 1 12 5];
idx = find(v > 5)

The result idx is [2 4] because the elements greater than 5 are at positions 2 and 4. You can then use idx as a numeric index:

sel = v(idx);

which is equivalent to v(v > 5).

For matrices, find returns linear indices by default:

A = [ 1  2  3;
      4  5  6;
      7  8  9 ];
idx = find(A > 4)

Here idx might be [5 8 6 9 7] based on the column major order. You can use idx directly, as in A(idx), or you can ask find to give you row and column subscripts:

[row, col] = find(A > 4);

Then row(k) and col(k) give the row and column of the kth element that satisfies A > 4. This is useful when you need the locations of elements for further processing or annotation.

Indexing to Assign and Modify Array Parts

Indexing is not only for reading data, it is also the primary way to modify specific parts of an array. You have already seen simple assignments such as A(2,3) = 10 and assignments using logical masks. Here you will look at some patterns that are useful in practice.

To replace a whole row or column, you can assign using a row or column slice:

A(2,:) = [0 0 0];       % set entire second row to zeros
A(:,1) = [1; 1; 1];     % set entire first column to ones

To replace a rectangular block, you can use slicing:

A(1:2, 2:3) = [9 9; 9 9];

The dimensions of the right hand side must match the size of the region you are assigning to.

Logical indexing also works for assignments. For example:

A(A < 0) = 0;

sets all negative values in A to zero. You do not need to know in advance where those values occur.

If you want to set all elements in a vector outside a given range to NaN, you can write:

x = [1 5 10 15 20];
mask = (x < 5) | (x > 15);
x(mask) = NaN;

The | operator represents logical OR, so the mask is true where x is less than 5 or greater than 15. Only those elements are replaced.

Common Indexing Pitfalls

New MATLAB users often run into similar problems when they start indexing. Awareness of these typical pitfalls will save time and frustration.

First, MATLAB indices start at 1. Using 0 or negative indices such as v(0) or A(-1,2) is not valid and will produce an error.

Second, : is not the same as 1:end in all contexts. While v(1:end) and v(:) both select all elements of a vector, v(:) always returns a column vector that contains all elements in column major order. On the other hand, 1:end is a vector of integer indices that preserves the original shape when used in each dimension. For example, A(:) for a matrix creates a single column with all elements, while A(1:end, :) preserves the rows and columns.

Third, the size of the right hand side of an assignment must match the number of elements on the left. For example:

v(2:4) = [1 2];   % error, 3 elements on left, 2 on right

MATLAB will complain about dimensions not agreeing. If you use a scalar on the right side, MATLAB will expand it to fill the region, which is allowed:

v(2:4) = 0;       % sets positions 2, 3, 4 to 0

Fourth, logical indices must correspond to the size of the array they are indexing, unless you are indexing along one dimension such as rows or columns. For example, if A is 3 by 3 and mask is 2 by 3, then A(mask) will result in an error, because the shapes do not match.

Finally, mixing row and column orientation carelessly can lead to unexpected shapes. For example, v(2:4) may produce a row or a column vector depending on v. When you reshape or concatenate later, you need to be aware of whether your slices are row vectors or column vectors.

Important points to remember:

  1. Indices in MATLAB start at 1 and must be positive integers or logical values.
  2. Use A(row, col) for matrices and : to select full rows or columns.
  3. The colon operator start:step:stop creates index ranges, and : alone selects an entire dimension.
  4. Linear indexing treats arrays as one long column, counted down columns first.
  5. Logical indexing selects elements where a condition is true and can be used both to read and to assign.
  6. The size of the right hand side of an indexed assignment must match the number of elements addressed, unless the right side is a scalar.
  7. Logical index arrays must be the same size as the target array, or must match the dimension they are used to index.

Views: 4

Comments

Please login to add a comment.

Don't have an account? Register now!