2

Given the following example:

>> I=[2 1 3;3 2 4]

I =

     2     1     3
     3     2     4

>> I(:)

ans =

     2
     3
     1
     2
     3
     4

>> I(1:2)

ans =

     2     3

Why does I(:) return a column vector while I(1:2) returns a shorter row vector?

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
user198729
  • 61,774
  • 108
  • 250
  • 348
  • I smell legacy support. Matlab is full of that kind of thing. – Mike DeSimone Apr 25 '10 at 05:19
  • @Mike, it isn't legacy. Matlab is simply a completely different type of language than C, C++, Java, Python, etc. It is meant for mathematicians (who are used to 1-based indexing), more than for programmers. While it is useful in its own right (it has very good matrix support), some of the things it does (like not caching functions and reopening/closing a file for every single function invocation) make it non-ideal for anything but prototyping. – Michael Aaron Safyan Apr 25 '10 at 05:25
  • @Mike: Actually, I believe that the `(:)` syntax is relatively *new*, as opposed to an old holdover syntax. – gnovice Apr 25 '10 at 05:32
  • The final question: Why `I(:)` is a column vector,but `I(3:4)` a row vector? – user198729 Apr 25 '10 at 05:34
  • @gnovice: I was thinking the `(1:2)` syntax was the legacy. Many, many other things in Matlab prefer column vectors for their 1-D data. – Mike DeSimone Apr 25 '10 at 06:51

3 Answers3

9

The (:) syntax, when used as an index on the right-hand side of an equation, is a special operation that reshapes an entire matrix of any dimension into a single column vector. The following two lines of code therefore give the same result:

a = I(:);               % Create a column vector with ":"
a = reshape(I, [], 1);  % Create a column vector with RESHAPE

When numerical values are included on either side of a single colon, it denotes a range of linear indices into an array. So I(1:2) selects the first and second elements from I (i.e. the values in the first column). One thing to remember is that the syntax 1:2 actually creates a vector [1 2], so I(1:2) is the same as I([1 2]). Since the linear index [1 2] is a row vector, the returned values are shaped as a row vector [2 3]. If you use the index I([1; 2]) or I((1:2).'), the linear index is a column vector, so the returned values will be shaped as a column vector [2; 3].

When you have multiple indices separated by commas, the indices are applied to different dimensions of the matrix being indexed. For example, I(1:2, 1:2) will return the 2-by-2 matrix [2 1; 3 2]. The first 1:2 in the index is applied to the rows, so rows one and two are selected. The second 1:2 in the index is applied to the columns, so columns one and two are selected.

The MATLAB documentation describing the colon operator and matrix indexing should help give you a better understanding of how to use : effectively.

gnovice
  • 125,304
  • 15
  • 256
  • 359
  • I still think they are the same thing,aren't they? – user198729 Apr 25 '10 at 05:17
  • So `I(1:2)` selects only values in the first column,but `I(:)` selects all values in the matrix, is that kinda thing reasonable? – user198729 Apr 25 '10 at 05:25
  • 1
    @user198729, I(1:2) selects the first two elements; it happens, in your particular case, that they are in the first column. If you had a 1x2 matrix, then it would give you the first row. See my answer. As to reasonableness, I don't like it (I found it very confusing, since I come from a C/C++ background and was expecting something different), but that kind of thing is really subjective. – Michael Aaron Safyan Apr 25 '10 at 05:28
  • But Why `I(:)` is a column vector,but `I(3:4)` a row vector? They should be the same type IMO. – user198729 Apr 25 '10 at 05:42
  • @user198729: I added some explanation to my answer that points out how the shape of the linear index determines the shape of the output. Since the index `:` has no real shape, the output of `I(:)` is (arbitrarily) chosen to be a column vector. – gnovice Apr 25 '10 at 05:56
  • @gnovice,thanks for the explanation! So `[]` is considered a column vector in matlab? – user198729 Apr 25 '10 at 05:57
  • @user198729: Well, `[]` actually has a shape, which is 0-by-0, so it's neither a column nor a row vector. It's simply "empty". – gnovice Apr 25 '10 at 05:59
  • But `a = reshape(I,[],1);` returns definitely a column vector,not a row vector,right? – user198729 Apr 25 '10 at 06:01
  • @user198729: Passing a `[]` as an argument to the function RESHAPE is a way of telling it to figure out what that dimension should be. In this case, you are telling RESHAPE to make the output an N-by-1 vector, where RESHAPE must figure out what N should be (which ends up being 6, or the number of total elements in the matrix). – gnovice Apr 25 '10 at 06:04
2

Examples of Matlab Indexing

[rows,cols] = size(M); % M is a rows x cols matrix

Accessing entry at row i, column j:

x = M(i,j);

Accessing all items on row i:

r = M(i,:);

Accessing all items on column j:

c = M(:,j);

Accessing entry at row i, column j, treating M as a vector:

x = M(rows*(j-1)+i);

Accessing the sub-matrix from row i to row j and from column p to column q:

S = M(i:j,p:q);

Accessing the entire matrix (redundant):

M = M(:,:);

Explanation
The colon operator either gives a range of indices (1:2 is the indices in range 1 to 2, inclusive, while 3:5 gives the range 3, 4, 5) or it gives the entire range for the given dimension if no range is specified.

This, in conjunction to the fact that indexing a matrix with just a single index gives you the entry that would result from stepping through that many entries (going down the rows, incrementing the column and resetting the row after the last row) instead of giving you just the specified row/column leads to your observations.

Michael Aaron Safyan
  • 93,612
  • 16
  • 138
  • 200
  • In my post `I` has only 2 rows,so I think `(:)`="all indices",and `(1:2)`="all indices",so what's the difference? – user198729 Apr 25 '10 at 05:22
  • 1
    1:2 just means indices 1...2 inclusive (so 1 and 2). Similarly, 2:5 would be indices 2,3,4,5. If you omit index markers with the colon, only then is it interpreted as "all indices". – Michael Aaron Safyan Apr 25 '10 at 05:23
  • Oh,your explanation makes sense now.But the last problem,why `I(:)` is a column vector,but `I(3:4)` a row vector? – user198729 Apr 25 '10 at 05:29
  • @user198729, both should be giving you col vectors (see what happens when you try to multiply it); I think it might just be the way it is displaying it, although I'm really not certain on that one. – Michael Aaron Safyan Apr 25 '10 at 05:42
  • @gnovice finally gives reason for the vector issue,but thank you very much! – user198729 Apr 25 '10 at 05:55
0

(:) vectorizes a matrix along the columns, i.e. the elements are read along the columns are concatenated into a single column vector. a:b:c returns a sequence of numbers from a to c with increments of b. If b is omitted, it is by default set to 1.

The sequence a:b:c can be used to index a matrix linearly along the column. If used to index a multidimensional array then it selects elements along that dimension. For e.g.

I(1,2:3) 

returns a matrix formed by rows 1 and columns 2:3 of I, i.e. [1 3]

Also, we can arrive at an index in any manner, and use it to index I.

index = [1 2 3];
disp(I(index));

The above displays the first three elements in column-major order (along the columns), i.e. [2 ; 3 ; 1]

Jacob
  • 34,255
  • 14
  • 110
  • 165