The meaning of colon operator in MATLAB - matlab

I came across some MATLAB syntax with a colon that I don't fully understand.
First Question:
The expression: 0:pi/4:pi
results in the answer: 0 0.7854 1.5708 2.3562 3.1416
Why is this the case? I thought that colon operator is used as a quick way to refer to indices so that we don't have to write out the full list. (e.g. 1:3 -> 1 2 3)
Second Question:
Similar to above, say if I have a matrix X = [1 2 3 4 5 6 7 8 9]. How can I interpret the expression X(:,1:3)? Specifically, what does the colon operator without the left and right numbers mean?

Actually a:b generates a vector. You could use it as index only because the (...) accepts a list also, e.g.
octave-3.0.3:10> a = [1,4,7]
a =
1 4 7
octave-3.0.3:11> b = [1,4,9,16,25,36,49]
b =
1 4 9 16 25 36 49
octave-3.0.3:12> b(a) # gets [b(1), b(4), b(7)]
ans =
1 16 49
Now, the a:b:c syntax is equivalent to [a, a+b, a+2*b, ...] until c, e.g.
octave-3.0.3:15> 4:7:50
ans =
4 11 18 25 32 39 46
which explains what you get in 0:pi/4:pi.
A lone : selects the whole axes (row/column), e.g.
octave-3.0.3:16> a = [1,2,3;4,5,6;7,8,9]
a =
1 2 3
4 5 6
7 8 9
octave-3.0.3:17> a(:,1) # means a(1:3, 1)
ans =
1
4
7
octave-3.0.3:18> a(1,:) # means a(1, 1:3)
ans =
1 2 3
See the official MATLAB doc on colon (:) for detail.

My two pennies to KennyTM's answer.
Actually scalar and vector variables in MATLAB have 2 dimensions. Scalar has 1 row and 1 column, and vector has either 1 row or column. Just try size(X).
Colon (:) operator for indexing simply means all. Syntax X(:,1:3) means get all rows and columns from 1 to 3. Since your variable X has only 1 row, you will get first 3 values in this row.

Related

Shortest command to extract a submatrix using a vector containing the indexes of the 2 corners [matlab]

Let's say we have the following matrix
A=magic(4)
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
and we want to extract 3 submatrices, identified by the indexes for top left and bottom right corners. The indexes for a submatrix are contained in a row of the matrix i; columns 1 and 2 of i are the row indexes of the corners, columns 3 and 4 of i are the column indexes of the corners.
i.e.
i =
1 1 1 3
2 4 1 2
3 4 3 4
>> A(i(1,1):i(1,2),i(1,3):i(1,4))
ans =
16 2 3
>> A(i(2,1):i(2,2),i(2,3):i(2,4))
ans =
5 11
9 7
4 14
>> A(i(3,1):i(3,2),i(3,3):i(3,4))
ans =
6 12
15 1
The command A(i(,):i(,),i(,):i(,)) which I used to extract the submatrices is not very convenient, so I wonder is there a better way to do the job ?
If you don't want to type it all out then why not write a wrapper function?
A = magic(4);
S = #(r) A(i(r,1):i(r,2),i(r,3):i(r,4));
S(1)
S(2)
S(3)
If A may change after the definition of S then you would need to make it a parameter to the function.
S = #(A,r) A(i(r,1):i(r,2),i(r,3):i(r,4));
A = magic(4)
S(A,1)
S(A,2)
S(A,3)
Similarly if i may change then you would need to make it a parameter as well.
Edit
Unfortunately, contrary to my comment, if you want to perform assignment then A(I(r)) won't work exactly the same as what you've posted since this always returns an array instead of a matrix. One possible workaround is to use cell arrays in place of comma-separated-lists, but this isn't as elegant as the read only option. For example
S = #(r) {i(r,1):i(r,2) , i(r,3):i(r,4)};
s = S(1); A(s{:})
s = S(2); A(s{:})
s = S(3); A(s{:})
Following the same principle you could pre-define a cell array from i to make access one line.
s = arrayfun(#(r) {i(r,1):i(r,2),i(r,3):i(r,4)}, 1:size(i,1), 'UniformOutput', false);
A(s{1}{:})
A(s{2}{:})
A(s{3}{:})

What is meant by variable = (matrix,scalar) in Octave?

a=magic(5)
k=a,3
When I print k, it simply shows a.
m=size(a,3)
n=size(a,6)
when I print m and n, they print different values.
Anyone please explain what this function is?
On Octave 4.2.1
k=a,3
assigns the matrix a to the variable k, then, as a second instruction, prints on the CommandWindow the value 3.
The , (comma) is used in order to have two instruction on the same row.
An alterntive could be replacing the , with the ; which has the effect of suppressing the output on the CommandWindow of the assignment k=a
With respect to
m=size(a,3)
n=size(a,6)
the second parameter n the call to size specifies the dimension of the matrix (the first parameter) for which you want to know the size.
a is a two "dimensional" matrix of size (5 x 5) while the instruction size(a,3) looks for the size of the third dimension of a.
In a similar way, size(a,6) looks for the size of the a's sixth dimension. In these case, the a is considered as (5 x 5 x 1) and (5 x 5 x 1 x 1 x 1 x 1)
The return value, for is 1
This is the output in the CommandWondow:
>> a=magic(5)
a =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>> k=a,3
k =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
ans = 3
>> m=size(a,3)
m = 1
>> n=size(a,6)
n = 1
In matlab / octave, there are three ways to terminate an expression (e.g. 1+2):
With a semicolon ;
With a comma ,
With a newline (i.e. pressing enter)
The first one (i.e. the semicolon) when used, evaluates the expression, but suppresses its output. The other two (i.e. the comma and the newline), both evaluate the statement and also display its result.
Why have both a comma and a newline? Because, with a comma, you can evaluate multiple expressions on the same line (and have all of them display their results).
Note: Given the fact that most people write their expressions in separate lines, the comma tends not to be used very much, so it is less known.
Examples:
octave:1> 1+2, 3+4
ans = 3
ans = 7
octave:2> 1+2; 3+4;
octave:3> 1+2; 3+4
ans = 7
octave:4> 1+2, 3+4;
ans = 3
octave:5> for i = 1:3; i; end % output in each iteration is suppressed
octave:6> for i = 1:3; i, end % whereas with a comma, output is not suppressed
i = 1
i = 2
i = 3
Therefore your statements:
a = magic(5)
k = a, 3
are essentially equivalent to
a = magic(5) % newline used: display value of a after assignment
k = a, % comma used, assign value of a to k, then display k
3 % newline used: displays the value '3' after pressing enter
Furthermore the size function doesn't do what you think it does. size(a,3) returns the size of array a in the 3rd dimension.

What the meaning of this index in MATLAB?

data = reshape(1:21504,[256,4,21]);
data(:,5:4:end)
I test some indexes, such as:
data(:,5:4:end) ~= data(:,5:4:end,1)
data(:,5:4:end) ~= data(:,1,5:4:end)
So what is the meaning of data(:,5:4:end)?
I test some other indexes, such as:
data(1,1) == data(1,1,1)
data(1,1:3) == data(1,1:3,1)
And find some strange behavior ,such as data(1,1:10,1) returns error but data(1,1:10) is ok.
So What's happening here?
How can I understand this mechanism?
>> size(data)
ans =
256 4 21
data(1,1:10,1) selects column 1-10 from first row (all three dimensions are explicitly set), but there are only 4 columns. Therefore the error.
data(1,1:10), on the other hand, uses Linear indexing, which interpretes dimensions 2 and 3 as one long strung of values and selects its first 10 values.
Linear Indexing
What does this expression A(14) do?
When you index into the matrix A using only one subscript, MATLAB treats A as if its elements were strung out in a long column vector, by going down the columns consecutively, as in:
16
5
9
...
8
12
1
The expression A(14) simply extracts the 14th element of the implicit column vector. Indexing into a matrix with a single subscript in this way is often called linear indexing.
Here are the elements of the matrix A along with their linear indices:
matrix_with_linear_indices.gif
The linear index of each element is shown in the upper left.
From the diagram you can see that A(14) is the same as A(2,4).
The single subscript can be a vector containing more than one linear index, as in:
A([6 12 15])
ans =
11 15 12
Consider again the problem of extracting just the (2,1), (3,2), and (4,4) elements of A. You can use linear indexing to extract those elements:
A([2 7 16])
ans =
5 7 1
That's easy to see for this example, but how do you compute linear indices in general? MATLAB provides a function called sub2ind that converts from row and column subscripts to linear indices. You can use it to extract the desired elements this way:
idx = sub2ind(size(A), [2 3 4], [1 2 4])
ans =
2 7 16
A(idx)
ans =
5 7 1
(Copied from http://de.mathworks.com/company/newsletters/articles/matrix-indexing-in-matlab.html)
data(:, 5:4:end) will access all elements in the first dimension of data and starting from index 5 every 4th index until the last index in the second dimension of data. The syntax for this indexing technique can be explained like this:
data(startIndex:step:endIndex)
If data has more dimensions than you used for indexing, this will assume : for every dimension after that.
To sum up my question:
data=reshape(1:24,2,3,4)
data(:,:,1) =
1 3 5
2 4 6
data(:,:,2) =
7 9 11
8 10 12
data(:,:,3) =
13 15 17
14 16 18
data(:,:,4) =
19 21 23
20 22 24
Using this example you can know what Matlab doing:
data(:,1)
ans =
1
2
data(:,12)
ans =
23
24
data(:,[1,12])
ans =
1 23
2 24
data(:,5:4:end)
ans =
9 17
10 18
If you use data(:,13),it throws an error.

Matlab, Sum Function for a Matrix row

Basically the sum function calculate the sum of the columns, that is to say if we have a 4x4 matrix we would get a 1X4 vector
A = magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
sum(A)
ans =
34 34 34 34
But if I want to get the Summation of the rows then i have 2 methods, the first is to get the transpose of the matrix then get the summation of the transposed matrix,and finally get the transpose of the result...., The Second method is to use dimension argument for the Sum function "sum(A, 2)"
A = magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
sum(A,2)
ans =
34
34
34
34
The problem is here I cannot understand how this is done, If anyone could please tell me the idea/concept behind this method,
It's hard to tell exactly how sum internally works, but we can guess it does something similar to this.
Matlab stores matrices (or N-dimensional arrays) in memory using column-major order. This means the order for the elements in memory for a 3 x 4 matrix is
1 4 7 10
2 5 8 11
3 6 9 12
So it first stores element (1,1), then (1,2), then (13), then (2,1), ...
In fact, this is the order you use when you apply linear indexing (that is, index a matrix with a single number). For example, let
A = [7 8 6 2
9 0 3 5
6 3 2 1];
Then A(4) gives 8.
With this in mind, it's easy to guess that what sum(A,1) does is traverse elements consecutively: A(1)+A(2)+A(3) to obtain the sum of the first column, then A(4)+A(5)+A(6) to sum the second column, etc. In contrast, sum(A,2) proceeds in steps of size(A,1) (3 in this example): A(1)+A(4)+A(7)+A(10) to compute the sum of the first row, etc.
As a side note, this is probably related with the observed fact that sum(A,1) is faster than sum(A,2).
I'm really not sure what you are asking. sum takes two inputs, the first of which is a multidimensional array A, say.
Now let's take sA = size(A), and d between 1 and ndims(A).
To understand what B = sum(A,d) does, first we find out what the size of B is.
That's easy, sB = sA; sB(d) = 1;. So in a way, it will "reduce" the size of A along dimension d.
The rest is trivial: every element in B is the sum of elements in A along dimension d.
Basically, sum(A) = sum(A,1) which outputs the sum of the columns in the matrix. 1 indicates the columns. So, sum(A,2) outputs the sum of the rows in the matrix. 2 indicating the rows. More than that, the sum command will output the entire matrix because there is only 2 dimensions (rows and columns)

Find the increasing and decreasing trend in a curve MATLAB

a=[2 3 6 7 2 1 0.01 6 8 10 12 15 18 9 6 5 4 2].
Here is an array i need to extract the exact values where the increasing and decreasing trend starts.
the output for the array a will be [2(first element) 2 6 9]
a=[2 3 6 7 2 1 0.01 6 8 10 12 15 18 9 6 5 4 2].
^ ^ ^ ^
| | | |
Kindly help me to get the result in MATLAB for any similar type of array..
You just have to find where the sign of the difference between consecutive numbers changes.
With some common sense and the functions diff, sign and find, you get this solution:
a = [2 3 6 7 2 1 0.01 6 8 10 12 15 18 9 6 5 4 2];
sda = sign(diff(a));
idx = [1 find(sda(1:end-1)~=sda(2:end))+2 ];
result = a(idx);
EDIT:
The sign function messes things up when there are two consecutive numbers which are the same, because sign(0) = 0, which is falsely identified as a trend change. You'd have to filter these out. You can do this by first removing the consecutive duplicates from the original data. Since you only want the values where the trend change starts, and not the position where it actually starts, this is easiest:
a(diff(a)==0) = [];
This is a great place to use the diff function.
Your first step will be to do the following:
B = [0 diff(a)]
The reason we add the 0 there is to keep the matrix the same length because of the way the diff function works. It will start with the first element in the matrix and then report the difference between that and the next element. There's no leading element before the first one so is just truncates the matrix by one element. We add a zero because there is no change there as it's the starting element.
If you look at the results in B now it is quite obvious where the inflection points are (where you go from positive to negative numbers).
To pull this out programatically there are a number of things you can do. I tend to use a little multiplication and the find command.
Result = find(B(1:end-1).*B(2:end)<0)
This will return the index where you are on the cusp of the inflection. In this case it will be:
ans =
4 7 13