What does A=[x; y'] in Matlab mean? - matlab

I'm learning Matlab and I see a line that I don't understand:
A=[x; y']
What does it mean? ' usually means the transponate but I don't know what ; means in the vector. Can you help me?

The [ ] indicates create a matrix.
The ; indicates that the first vector is on the first line, and that the second one is on the second line.
The ' indicates the transponate.
Exemple :
>> x = [1,2,3,4]
x =
1 2 3 4
>> y = [5;6;7;8]
y =
5
6
7
8
>> y'
ans =
5 6 7 8
>> A = [x;y']
A =
1 2 3 4
5 6 7 8

[x y] means horizontal cat of the vectors, while [x;y] means vertical.
For example (Horizontal cat):
x = [1
2
3];
y = [4
5
6];
[x y] = [1 4
2 5
3 6];
(Vertical cat):
x = [1 2 3];
y = [4 5 6];
[x; y] =
[1 2 3;
4 5 6];

Just to be clear, in MATLAB ' is the complex conjugate transpose. If you want the non-conjugating transpose, you should use .'.

It indicates the end of a row when creating a matrix from other matrices.
For example
X = [1 2];
Y = [3,4]';
A = [X; Y']
gives a matrix
A = [ 1 2 ]
[ 3 4 ]
This is called vertical concatenation which basically means forming a matrix in row by row fashion from other matrices (like the example above). And yes you are right about ' indicating the transpose operator. As another example you could use it to create a transposed vector as follows
Y = [1 2 3 4 5];
X = [1; 2; 3; 4; 5];
Y = Y';
Comparing the above you will see that X is now equal to Y. Hope this helps.

Let set the size of x m*n (m rows and n columns) and the size of y n*p.
Then A is the matrix formed by the vertical concatenation of x and the transpose of y (operator '), and its size is (m+p)*n. The horizontal concatenation is done with comma instead of semi-column.
This notation is a nice shorthand for function vertcat.
See http://www.mathworks.fr/help/techdoc/math/f1-84864.html for more information

The semicolon ' ; ' is used to start a new row.
e.g. x=[1 2 3; 4 5 6; 7 8 9] means
x= 1 2 3
4 5 6
7 8 9
So if u take x=[1 2 3; 4 5 6] and y=[7 8 9]'
then z=[x; y'] means
z= 1 2 3
4 5 6
7 8 9

Related

Reshape vector with a step and window size

I have a vector, for example
A = [1 2 3 4 5 6 7 8]
I want to "reshape" it to matrix with windowsize=4 and stepsize=2, such that the resulting matrix is
b = [ 1 3 5;
2 4 6;
3 5 7;
4 6 8 ]
You can set up an indexing matrix, then just index into A...
A = [1 2 3 4 5 6 7 8];
windowsize = 4;
stepsize = 2;
% Implicit expansion to create a matrix of indices
idx = bsxfun( #plus, (1:windowsize).', 0:stepsize:(numel(A)-windowsize) );
b = A(idx);
Note; in this case idx and b are the same, but you need the final indexing step assuming A isn't just consecutive integers in your real example.

Rotate the rows of a matrix (like GAUSS function rotater)

I'm currently bringing some GAUSS code over to Matlab and I'm stuck trying to use the GAUSS "rotater" function.
The command reference entry for rotater says:
Purpose Rotates the rows of a matrix
Format y = rotater(x,r)
Input x: N x K matrix to be rotated. r: N x 1 or 1 x 1 matrix specifying the amount of rotation.
Output y: N x K rotated matrix.
Remarks The rotation is performed horizontally within each row of the matrix. A positive rotation value will cause the elements to move
to the right. A negative rotation will cause the elements to move to
the left. In either case, the elements that are pushed off the end of
the row will wrap around to the opposite end of the same row. If the rotation value is greater than or equal to the number of columns in x, then the rotation value will be calculated using (r % cols(x)).
Example 1
(I'm following Matlab's notation here, with straight brackets for matrices and a semicolon for a new ro)
If x = [1 2 3; 4 5 6], and r = [1; -1],then y = [3 1 2; 5 6 4]
Example 1
If x = [1 2 3; 4 5 6; 7 8 9; 10, 11, 12], and r = [0; 1; 2; 3], then y = [1 2 3; 6 4 5; 8 9 7; 10 11 12]
Maybe someone has found a function like that somewhere or can give me advice how to write it?
This can be done using bsxfun twice:
Compute rotated row indices by subtracting r with bsxfun and using mod. As usual, mod needs indices starting at 0, not 1. The rotated row indices are left as 0-based, because that's more convenient for step 2.
Get a linear index from columns and rotated rows, again using bsxfun. This linear index applied to x gives y:
Code:
[s1 s2] = size(x);
rows = mod(bsxfun(#plus, 1:s2, -r(:))-1, s2); % // step 1
y = x(bsxfun(#plus, rows*s1, (1:s1).')); %'// step 2
circshift is pretty close to what you're looking for except that 1) it works on columns rather than rows, and 2) it shifts the entire matrix by the same offset.
The first one is easy to fix, we just transpose. For the second one I haven't been able to find a vectorized approach, but in the meantime, here's a version with a for loop:
x = [1 2 3; 4 5 6; 7 8 9; 10 11 12]
r = [0 1 2 3]
B = x'
C = zeros(size(B));
for ii = 1:size(B,2)
C(:,ii) = circshift(B(:,ii),r(ii));
end
y = C'
The output is:
x =
1 2 3
4 5 6
7 8 9
10 11 12
r =
0 1 2 3
B =
1 4 7 10
2 5 8 11
3 6 9 12
y =
1 2 3
6 4 5
8 9 7
10 11 12
This can be done using a simple for loop to iterate over each row, and a function called 'circshift' from matlab.
I created a function the goes through each row and applies the appropriate shift to it. There may be more efficient ways to implement this, but this way works with your examples. I created a function
function rotated_arr = GaussRotate(input_array, rotation_vector)
[N,K] = size(input_array)
%creates array for return values
rotated_arr = zeros(N,K);
%if the rotation vector is a scalar
if (length(rotation_vector) == 1)
%replicate the value once for each row
rotation_vector = repmat(rotation_vector, [1,N]);
end
%if the rotation vector doesn't have as many entries as there are rows
%in the input array
if (length(rotation_vector) ~= N)
disp('ERROR GaussRotate: rotation_vector is the wrong size')
disp('if input_Array is NxK, rotation_vector must be Nx1 or 1x1')
return
end
%for each row
for idx=1:size(input_array,1)
%shift the row by the appropriate number of columns
%we use [0,shift] because we want to shift the columns, the row
%stays where it is (even though this is a 1xN at this point we
%still specify rows vs columns)
rotated_arr(idx,:) = circshift(input_array(idx,:),[0,rotation_vector(idx)]);
end
end
then simply called it with your examples
x = [1 2 3; 4 5 6];
r = [1; -1];
y = GaussRotate(x,r)
%produces [3 1 2; 5 6 4]
%I also made it support the 1x1 case
r = [-1]
%this will shift all elements one column to the left
y = GaussRotate(x,r)
%produces [2 3 1; 5 6 4]
x = [1 2 3; 4 5 6; 7 8 9; 10, 11, 12]
r = [0; 1; 2; 3]
y = GaussRotate(x,r)
%produces [1 2 3; 6 4 5; 8 9 7; 10 11 12]

Got confused with a vector indexed by a matrix, in Matlab

The following codes runs in Matlab:
a = [1 2 3 4]
b = [ 1 2 3; 1 2 3; 1 2 3]
a(b)
The result of a(b) is a matrix:
[ 1 2 3; 1 2 3; 1 2 3]
Can anyone explain what happened here? Why a vector can be indexed by a matrix, how to interpret the result?
That's a very standard MATLAB operation that you're doing. When you have a vector or a matrix, you can provide another vector or matrix in order to access specific values. Accessing values in MATLAB is not just limited to single indices (i.e. A(1), A(2) and so on).
For example, what you have there is a vector of a = [1 2 3 4]. When you try to use b to access the vector, what you are essentially doing is a lookup. The output is basically the same size as b, and what you are doing is creating a matrix where there are 3 rows, and each element accesses the first, second and third element. Not only can you do this for a vector, but you can do this for a matrix as well.
Bear in mind that when you're doing this for a matrix, you access the elements in column major format. For example, supposing we had this matrix:
A = [1 2
3 4
5 6
7 8]
A(1) would be 1, A(2) would be 3, A(3) would be 5 and so on. You would start with the first column, and increasing indices will traverse down the first column. Once you hit the 5th index, it skips over to the next column. So A(5) would be 2, A(6) would be 4 and so on.
Here are some examples to further your understanding. Let's define a matrix A such that:
A = [5 1 3
7 8 0
4 6 2]
Here is some MATLAB code to strengthen your understanding for this kind of indexing:
A = [5 1 3; 7 8 0; 4 6 2]; % 3 x 3 matrix
B = [1 2 3 4];
C = A(B); % C should give [5 7 4 1]
D = [5 6 7; 1 2 3; 4 5 6];
E = A(D); % E should give [8 6 3; 5 7 4; 1 8 6]
F = [9 8; 7 6; 1 2];
G = A(F); % G should give [2 0; 3 6; 5 7]
As such, the output when you access elements this way is whatever the size of the vector or matrix that you specify as the argument.
In order to be complete, let's do this for a vector:
V = [-1 9 7 3 0 5]; % A 6 x 1 vector
B = [1 2 3 4];
C = V(B); % C should give [-1 9 7 3]
D = [1 3 5 2];
E = V(D); % E should give [-1 7 0 9]
F = [1 2; 4 5; 6 3];
G = V(F); % G should give [-1 9; 3 0; 5 7]
NB: You have to make sure that you are not providing indexes that would make the accessing out of bounds. For example if you tried to specify the index of 5 in your example, it would give you an error. Also, if you tried anything bigger than 9 in my example, it would also give you an error. There are 9 elements in that 3 x 3 matrix, so specifying a column major index of anything bigger than 9 will give you an out of bounds error.
Notice that the return value of a(b) is the same size as b.
a(b) simply takes each element of b, call it b(i,j), as an index and returns the outputs a(b(i,j)) as a matrix the same size as b. You should play around with other examples to get a more intuitive feel for this:
b = [4 4 4; 4 4 4];
a(b) % Will return [4 4 4; 4 4 4]
c = [5; 5];
a(c) % Will error as 5 is out of a's index range

Sort a vector and count the identical occurrences

What is a Matlab-efficient way (no loop) to do the following operation: transform an input vector input into an output vector output such as output(i) is the number of integers in input that are less or equal than input(i).
For example:
input = [5 3 3 2 4 4 4]
would give:
output = [7 3 3 1 6 6 6]
First of all, don't use input for a variable name, it's a reserved keyword. I'll use X here instead.
An alternative way to obtain your desired result would be:
[U, V] = meshgrid(1:numel(X), 1:numel(X));
Y = sum(X(U) >= X(V))
and here's a one-liner:
Y = sum(bsxfun(#ge, X, X'))
EDIT:
If X has multiple rows and you want to apply this operation on each row, this is a little bit trickier. Here's what you can do:
[U, V] = meshgrid(1:numel(X), 1:size(X, 2));
V = V + size(X, 2) * idivide(U - 1, size(X, 2));
Xt = X';
Y = reshape(sum(Xt(U) >= Xt(V))', size(Xt))'
Example:
X =
5 3 3 2 4 4 4
3 9 7 7 1 2 2
Y =
7 3 3 1 6 6 6
4 7 6 6 1 3 3
I have found a possible answer:
output = arrayfun(#(x) sum(x>=input),input)
but it doesn't take advantage of vectorization.

Splice matlab vectors

I have two matlab vectors. The first has N elements, the other has k*N. I know what k is, and I want to splice the lists such that each element from the first vector appears before the corresponding k elements from the next vector. For example:
k = 3
x = [1 5 9]
y = [2 3 4 6 7 8 10 11 12]
should be combined to look like this:
z = [1 2 3 4 5 6 7 8 9 10 11 12]
Is there an easy way to do this quickly? My x's and y's are pretty big. Thanks!
You can do this via some reshaping
k = 3
x = [1 5 9]
y = [2 3 4 6 7 8 10 11 12]
%# make a k-by-n array
z = reshape(y,k,[]);
%# catenate with x
z = [x;z];
%# reorder
z = z(:)'