views:

129

answers:

3

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?

+7  A: 

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
Then what about `I(1:2)`?
I still think they are the same thing,aren't they?
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, 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
But Why `I(:)` is a column vector,but `I(3:4)` a row vector? They should be the same type IMO.
@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
@gnovice,thanks for the explanation! So `[]` is considered a column vector in matlab?
@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
But `a = reshape(I,[],1);` returns definitely a column vector,not a row vector,right?
@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
A: 

(:) 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
What about `(a:b:c)`? the `()` can't be missed here for comparation.
+2  A: 

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
In my post `I` has only 2 rows,so I think `(:)`="all indices",and `(1:2)`="all indices",so what's the difference?
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
Oh,your explanation makes sense now.But the last problem,why `I(:)` is a column vector,but `I(3:4)` a row vector?
+1 for your clarification:)
@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
@gnovice finally gives reason for the vector issue,but thank you very much!