# All about the Colon Operator

I have written several blog articles that cover some aspects of the `:` operator. Based on some recent posts to the MATLAB newsgroup, it seems worthwhile for me to compile the information.

### Contents

### Uses of :

There are several ways that you can use the `:` operator in MATLAB, and they serve different purposes. Most, but not all of them, have to do with indexing into an array.

- Creating a list of numbers
- Collapsing trailing dimensions (right- or left-hand side)
- Creating a column vector (right-hand side behavior related to
`reshape`) - Retaining an array shape during assignment (left-hand side behavior)
- Working with all the entries in specified dimensions

### Creating a List of Numbers

You can use the `:` operator to create a vector of evenly-spaced numbers. Here are the integers from -3 to 3.

list1 = -3:3

list1 = -3 -2 -1 0 1 2 3

Here are the first few odd positive integers.

list2 = 1:2:10

list2 = 1 3 5 7 9

Here's how to divide the interval between 0 and `pi` into equally spaced samples.

nsamp = 5; sliceOfPi = (0:1/(nsamp-1):1)*pi

sliceOfPi = 0 0.7854 1.5708 2.3562 3.1416

Note that even though only a few digits of each value in `sliceOfPi` are printed out, they are double precision numbers. To see more digits, check out the function `format`.

### Collapsing Trailing Dimensions

I have a 4-dimensional array and would like to find the sum of all the elements that are in the final row and column.

b = rand(3,2,6,4); b32sum = sum(b(3,2,:))

b32sum = 11.4622

If instead, I sum using **all** the dimensions, in this case, I get a 1x1x1x4 array instead of scalar output. If I sum these output values, I get my overall
sum.

b32sumAll = sum(b(3,2,:,:)) overall = sum(b32sumAll)

b32sumAll(:,:,1,1) = 2.8279 b32sumAll(:,:,1,2) = 3.4177 b32sumAll(:,:,1,3) = 1.9352 b32sumAll(:,:,1,4) = 3.2815 overall = 11.4622

### Creating a Column Vector

Here's the size of the array `b32sumAll`.

size(b32sumAll)

ans = 1 1 1 4

If I want to transform this into a column vector, I can use `reshape`, `permute` or `:` on the right-hand side.

b32vecR = reshape(b32sumAll,[],1); b32vecP = permute(b32sumAll, [4 1:3]); b32vec = b32sumAll(:) allthesame = isequal(b32vec, b32vecP, b32vecR)

b32vec = 2.8279 3.4177 1.9352 3.2815 allthesame = 1

### Retaining Array Shape During Assignment

Now let me pour some new values into `b32sumAll`, the array that looks almost like a vector.

b32sumAll(:) = [1 2; 3 5]

b32sumAll(:,:,1,1) = 1 b32sumAll(:,:,1,2) = 3 b32sumAll(:,:,1,3) = 2 b32sumAll(:,:,1,4) = 5

Notice that I only have to have the same number of elements on both the left- and right-hand sides. The values are poured in from the right-hand side ordered as if that array had been turned into a column vector. Note that a scalar for the right-hand side is also acceptable and then MATLAB performs a scalar expansion to fill the left-hand side.

### Working with All the Entries in Specified Dimensions

If I want to manipulate values in some specific dimensions, I can also use the `:` operator to specify the dimensions I'd like to leave alone. For example, suppose I want to perform a left shift on the values
in the second dimension of my 3-D array. Let me first create an array for illustration.

a3 = zeros(2,3,2); a3(:) = 1:numel(a3)

a3(:,:,1) = 1 3 5 2 4 6 a3(:,:,2) = 7 9 11 8 10 12

Now let's shift the column values all over to the left, and have the right-most one become the last column. Note that columns are dimension 2. Here's a way to do this.

a3r1 = a3(:,[2:size(a3,2) 1],:)

a3r1(:,:,1) = 3 5 1 4 6 2 a3r1(:,:,2) = 9 11 7 10 12 8

How do I do this if the array could be any number of dimensions, not just 3? I can't index with `:`, because I don't know how many `:` to use, since I don't knwo the dimension. In this case, use the string value `':'`, create the indices in a cell array, and use the notion of the comma-separated list to perform the actual indexing. For
`a3`, here's what this looks like.

indices = {':', [2:size(a3,2) 1],':'} a3rnew = a3(indices{:}) sameshifts = isequal(a3r1, a3rnew)

indices = ':' [1x3 double] ':' a3rnew(:,:,1) = 3 5 1 4 6 2 a3rnew(:,:,2) = 9 11 7 10 12 8 sameshifts = 1

Now, more generally, when the number of dimensions is not known, I simply create a cell array of all `':'` string values, replace the specific dimensions I care about with some other indexing expression, and then I can use the index
cell array to do the operation.

```
a5 = zeros(2,5,2,3,4);
a5(:) = 1:numel(a5);
indices = repmat({':'}, 1, ndims(a5));
myshift = [2:size(a5,2) 1]
indices{2} = myshift
a5new = a5(indices{:});
```

myshift = 2 3 4 5 1 indices = ':' [1x5 double] ':' ':' ':'

Let's compare two "rows" and see that the values have shifted left by 1 column.

a5(1,:,2,2,3) a5new(1,:,2,2,3)

ans = 151 153 155 157 159 ans = 153 155 157 159 151

### Related Reference Material

For more in depth understanding of the various ways in which the `:` operator can be used, look in the MATLAB documention

and in related blog articles

### : is Complicated

The `:` operator behaves differently in MATLAB depending on its usage. This can lead to confusion. Have I missed anything major
on this topic? Let me know.

## 댓글

댓글을 남기려면 링크 를 클릭하여 MathWorks 계정에 로그인하거나 계정을 새로 만드십시오.