Building matrices using column vector and matrix in matlab - matlab

I have a column vector A (6x1) with values [6 3 10 4 2 8]'; and a matrix B (6x5) with values
B = [1 2 3 0 4 ;
3 7 8 5 0 ;
0 9 1 0 1 ;
5 0 3 1 2 ;
4 6 7 6 4 ;
3 1 2 7 3]
I want to make five matrices with size 6x2 using Matlab.
The first column is vector A
The second column is columns from B, like [A, B(first col)], [A, B(second col)]
First matrix is [6 1; 3 3; 10 0; 4 5; 2 4; 8 3];
2nd matrix is [6 2; 3 7; 10 9; 4 0; 2 6; 8 1]
... and so on
Any help I really appreciate it

You could use a loop
C = NaN( size(B,1), 2, size(B,2) );
for ii = 1:size(B,2)
C(:,:,ii) = [A, B(:,ii)];
end
This gives you a 3D array, where each slice in the 3rd dimension is a 6x2 matrix (for this example) as desired. You would access the nth slice with C(:,:,n).
You can do this slightly more concisely with arrayfun, but it's basically a loop in disguise
C = arrayfun( #(ii) [A, B(:,ii)], 1:size(B,2), 'uni', 0 );
C = cat(3, C{:} );
You could omit the cat function if you're happy with results in a cell array, where you access the nth matrix with C{n}.

You could first make a copy of the columns of A, then concatenate A and B, and reshape:
At = repmat(A, 1, size(B,2));
C = reshape([At;B], 6, 2, []);
Or oneliner:
C = reshape([repmat(A, 1, size(B,2));B], 6, 2, []);
Then retrieve your matrices with C(:,:,k)

you can use this
first_matrix=[A,B(:,1)];
second_matrix=[A,B(:,2)];
third_matrix=[A,B(:,3)];
... and so on

Related

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

How do you pick out the ith matrix in a n-dimensional matrix?

For the sake of argument, let's say I have this 3 x 3 x 2 matrix:
A = [5 7 8; 0 1 9; 4 3 6];
A(:,:,2) = [1 0 4; 3 5 6; 9 8 7];
And I'd like to pick out the first matrix (dimension: 3 x 3 x 1), how do I do it?
Short answer, already in the comments, is:
A(:,:,1)
Longer answer:
You can pick out any (hyper)-rectangular subset of a matric by simply specifying the elements you want per dimension, weather there are 1, 2, 3, 4 or more dimensions in the array. In short:
Each dimension is specified, in order. Dimension 1 is specifies row, dimension 2 specifies column, dimensions 3 and up are not usually visualized, so just represnt 3 and up
For each dimension you can specify one of the following: a) A single index number, b) A vector of index numbers, or c) a logical vector the same length as the dimension you are selecting from d) :, which represents all elements in this dimension.
Per dimension specifiers are ANDed together, resulting in a (hyper)-rectangular array.
For example, using your A array:
A = [5 7 8; 0 1 9; 4 3 6];
A(:,:,2) = [1 0 4; 3 5 6; 9 8 7];
To subset the first matrix you need: all of dimension 1 ":", all of dimension 2 ":", and the first element of dimension 3 "1". Therefore:
A(:,:,1) %Returns 5 7 8
% 0 1 9
% 4 3 6
To get the first and third columns of the second page, use:
A(:, [1 3], 2) %Returns 1 4
% 3 6
% 9 7
To get all rows which end in 9 from the first matrax, you can use:
mask = A(:,3,1)==9; %Returns logical [0; 1; 0];
A(mask, :, 1); %Returns [0 1 9;

average 3rd column when 1st and 2nd column have same numbers

just lets make it simple, assume that I have a 10x3 matrix in matlab. The numbers in the first two columns in each row represent the x and y (position) and the number in 3rd columns show the corresponding value. For instance, [1 4 12] shows that the value of function in x=1 and y=4 is equal to 12. I also have same x, and y in different rows, and I want to average the values with same x,y. and replace all of them with averaged one.
For example :
A = [1 4 12
1 4 14
1 4 10
1 5 5
1 5 7];
I want to have
B = [1 4 12
1 5 6]
I really appreciate your help
Thanks
Ali
Like this?
A = [1 4 12;1 4 14;1 4 10; 1 5 5;1 5 7];
[x,y] = consolidator(A(:,1:2),A(:,3),#mean);
B = [x,y]
B =
1 4 12
1 5 6
Consolidator is on the File Exchange.
Using built-in functions:
sparsemean = accumarray(A(:,1:2), A(:,3).', [], #mean, 0, true);
[i,j,v] = find(sparsemean);
B = [i.' j.' v.'];
A = [1 4 12;1 4 14;1 4 10; 1 5 5;1 5 7]; %your example data
B = unique(A(:, 1:2), 'rows'); %find the unique xy pairs
C = nan(length(B), 1);
% calculate means
for ii = 1:length(B)
C(ii) = mean(A(A(:, 1) == B(ii, 1) & A(:, 2) == B(ii, 2), 3));
end
C =
12
6
The step inside the for loop uses logical indexing to find the mean of rows that match the current xy pair in the loop.
Use unique to get the unique rows and use the returned indexing array to find the ones that should be averaged and ask accumarray to do the averaging part:
[C,~,J]=unique(A(:,1:2), 'rows');
B=[C, accumarray(J,A(:,3),[],#mean)];
For your example
>> [C,~,J]=unique(A(:,1:2), 'rows')
C =
1 4
1 5
J =
1
1
1
2
2
C contains the unique rows and J shows which rows in the original matrix correspond to the rows in C then
>> accumarray(J,A(:,3),[],#mean)
ans =
12
6
returns the desired averages and
>> B=[C, accumarray(J,A(:,3),[],#mean)]
B =
1 4 12
1 5 6
is the answer.

how to get values of a matrix in MATLAB where the indices are given in a nx2 array

I have a matrix A of size nRows x nCols.
I have a nx2 matrix B which contains indices of the matrix A.
I want to get the values of A at the indices given in B.
lets say,
B = [1, 2;
2, 3;
3, 4]
A(1,2) = 1
A(2,3) = 2
A(3,4) = 1
I want to know any Matlab command which gives the following, given A and B (I don't want to use loops):
[1 2 1]
I guess this is what you are looking for:
A(sub2ind(size(A),B(:,1),B(:,2)))
This is what you want:
A = [1,2; 3, 4; 5, 6; 7,8; 9,0]; % this is your N by 2 matrix
B = [1,1; 1,2; 2,1; 3, 1; 4,2]; % these are your indexes
A(sub2ind(size(A), B(:,1), B(:,2)))
A =
1 2
3 4
5 6
7 8
9 0
B =
1 1
1 2
2 1
3 1
4 2
ans =
1
2
3
5
8

Expand a matrix with polynomials

Say I have a matrix A with 3 columns c1, c2 and c3.
1 2 9
3 0 7
3 1 4
And I want a new matrix of dimension (3x3n) in which the first column is c1, the second column is c1^2, the n column is c1^n, the n+1 column is c2, the n+2 column is c2^2 and so on. Is there a quickly way to do this in MATLAB?
Combining PERMUTE, BSXFUN, and RESHAPE, you can do this quite easily such that it works for any size of A. I have separated the instructions for clarity, you can combine them into one line if you want.
n = 2;
A = [1 2 9; 3 0 7; 3 1 4];
[r,c] = size(A);
%# reshape A into a r-by-1-by-c array
A = permute(A,[1 3 2]);
%# create a r-by-n-by-c array with the powers
A = bsxfun(#power,A,1:n);
%# reshape such that we get a r-by-n*c array
A = reshape(A,r,[])
A =
1 1 2 4 9 81
3 9 0 0 7 49
3 9 1 1 4 16
Try the following (don't have access to Matlab right now), it should work
A = [1 2 9; 3 0 7; 3 1 4];
B = [];
for i=1:n
B = [B A.^i];
end
B = [B(:,1:3:end) B(:,2:3:end) B(:,3:3:end)];
More memory efficient routine:
A = [1 2 9; 3 0 7; 3 1 4];
B = zeros(3,3*n);
for i=1:n
B(3*(i-1)+1:3*(i-1)+3,:) = A.^i;
end
B = [B(:,1:3:end) B(:,2:3:end) B(:,3:3:end)];
Here is one solution:
n = 4;
A = [1 2 9; 3 0 7; 3 1 4];
Soln = [repmat(A(:, 1), 1, n).^(repmat(1:n, 3, 1)), ...
repmat(A(:, 2), 1, n).^(repmat(1:n, 3, 1)), ...
repmat(A(:, 3), 1, n).^(repmat(1:n, 3, 1))];