How to assemble 2x2x1000 array from four 1000x1 arrays - matlab

We have four 771x1 arrays that we want to form a 2x2x771 array.
How to make R from H L N and P?
H = [1 2 3 4 5]';
L = [6 7 8 9 10]';
N = [11 12 13 14 15]';
P = [16 17 18 19 20]';
R = [1 6; 11 16];
R(:,:,2) = [2 7; 12 17];
R(:,:,3) = [3 8; 13 18];
R(:,:,4) = [4 9; 14 19];
R(:,:,5) = [5 10; 15 20];
R

Simple:
R=permute(reshape([H,L,N,P]',2,2,[]),[2 1 3])

Related

Reshaping vector to n-d matrix in row-wise order

I'm trying to convert a vector into a 3d matrix in a row-wise manner.
For example, my vector is:
a = 1:18;
and I'd like to convert this to a 2x3x3 matrix:
b(:,:,1) = [1 2 3; 4 5 6];
b(:,:,2) = [7 8 9; 10 11 12];
b(:,:,3) = [13 14 15; 16 17 18];
but the reshape function (i.e. reshape(a, 2,3,3)) arranges the elements in a column-wise fashion as:
val(:,:,1) =
1 3 5
2 4 6
val(:,:,2) =
7 9 11
8 10 12
val(:,:,3) =
13 15 17
14 16 18
How can I obtain the matrix b from vector a?
Use combination of reshape and permute.
b = permute(reshape(a,3,2,3),[2 1 3]);
b(:,:,1) =
1 2 3
4 5 6
b(:,:,2) =
7 8 9
10 11 12
b(:,:,3) =
13 14 15
16 17 18
I found a (or the) solution:
b = permute(reshape(reshape(a,3,[])',2,3,[]), [1,3,2])
b(:,:,1) =
1 2 3
4 5 6
b(:,:,2) =
7 8 9
10 11 12
b(:,:,3) =
13 14 15
16 17 18

Matlab determine index position in matrix

Hin everyone..I have matrix
col = [1 2 3 9 10 15 16 17]
I need to divide A into 3 with length B = [3 2 3],
result required :
col1 = [1 2 3] -> from col(1:3)
col2 = [9 10] -> from col(4:5)
col3 = [15 16 17] -> from col(6:8)
Thank you so much...
mat2cell can be use:
A = [1 2 3 9 10 15 16 17];
B = [3 2 3];
mat2cell(A,1, B)
Result:
{
[1,1] =
1 2 3
[1,2] =
9 10
[1,3] =
15 16 17
}
I assume that lenghts in B match col length, so every element is accounted for. If so, you can do it using simple for loop as follows:
col = [1 2 3 9 10 15 16 17];
B = [3 2 3];
start_idx = 1;
for b = B
col_part = col(start_idx : start_idx+b-1)
start_idx = start_idx+b;
end
Results in:
col_part =
1 2 3
col_part =
9 10
col_part =
15 16 17

How to manipulate matrix addition and multiplication for Euclidean distance computation?

I have the following:
A = [1 2 3; 4 5 6; 7 8 9];
B = [10 11 12; 13 14 15];
[N1, D1] = size(A);
[N2, D2] = size(B);
A_sq = sum(A.^2, 2);
B_sq = sum(B.^2, 2)';
D = A_sq(:,ones(1,N2)) + B_sq(ones(1,N1),:) - 2.*(A*B');
where D is N1 x D1 matrix.
I want to write expression for D in one single step, i.e., something like this (this is for illustration purpose, but it should compute the same Euclidean distance as the code above):
D = sum(A - B).^2;
I will appreciate any advise.
If you have the Statistics Toolbox you can use pdist2, which does just that:
D = pdist2(A,B).^2
Or you can do it manually with bsxfun and permute:
D = permute((sum(bsxfun(#minus, A, permute(B, [3 2 1])).^2,2)), [1 3 2]);
For your example matrices
A = [1 2 3; 4 5 6; 7 8 9];
B = [10 11 12; 13 14 15];
either of the above gives
D =
243 432
108 243
27 108

Sort the row of one matrix with respect to another matrix

I have two different matrices A and B:
A =
[7 8 9;
4 5 6]
B =
[22 32 12;
9 8 10]
sortB =
[12 22 32;
8 9 10]
sortindex_B=[3 1 2;2 1 3];, i.e., 12 is in the third position of matrix B, 22 in first, and 32 in second position; similarly for the second row.
Now I want to sort A depending on Sortindex_B (i.e., in matrix A I want 7 as the third element, 8 as the first, and 9 as the second element of the first row; and similarly for the second row: 4 at the second, 5 at the first, and 6 as the third element). Hence the result should look like:
A_final =
[8 9 7;
5 4 6]
How can I achieve this?
You can ask for the sorting index matrix from sort command, when sorting B, and thereafter operate on A as a cell, in so making cellfun available:
A = [7 8 9; 4 5 6];
B = [22 32 12; 9 8 10];
[sortB, I] = sort(B,2);
Icell = mat2cell(I,ones(1, size(I,1)),size(I,2));
Acell = mat2cell(A,ones(1, size(I,1)),size(I,2));
sortA = cell2mat(...
cellfun(#(x,y) y(x), Icell, Acell, 'UniformOutput', false))
Output (you state first row output as 8 9 7, but did you really mean 9 7 8?)
sortA =
9 7 8
5 4 6
For sorting as specifically specified in your question; re-map index matrix I:
A = [7 8 9; 4 5 6];
B = [22 32 12; 9 8 10];
[sortB, I] = sort(B,2);
%// re-map I
for i = 1:size(I,1)
Itmp = I(i,:);
for j = 1:size(I,2)
I(i,Itmp(j)) = j;
end
end
Icell = mat2cell(I,ones(1, size(I,1)),size(I,2));
ImapCell = mat2cell(Imap,ones(1, size(I,1)),size(I,2));
Acell = mat2cell(A,ones(1, size(I,1)),size(I,2));
sortA = cell2mat(...
cellfun(#(x,y) y(x), Icell, Acell, 'UniformOutput', false))
Output
sortA =
8 9 7
5 4 6
Use a combination of sort as in dfri's answer and sub2ind:
A = [7 8 9;
4 5 6];
B = [22 32 12;
9 8 10];
[sortB, sortindex_B] = sort(B,2);
[~, colIdx] = sort(sortindex_B,2);
rowIdx = ndgrid(1:size(B,1),1:size(B,2));
idx = sub2ind(size(B),rowIdx,colIdx);
sortA = A(idx)
ans =
8 9 7
5 4 6
you will have to do this row by row using the index values that the sort function returns.
Something like this should do the trick and is expandable to any number of rows that your matrix A and B may have. This does also validate that A and B are the same size before it continues.
B= [22 32 12; 9 8 10]
A = [7 8 9; 4 5 6];
assert(all(size(A) == size(B)));
sortB = zeros(size(B));
finalA= zeros(size(A));
for i = 1:size(B,1)
[sorted,idx] = sort(B(i,:));
sortB(i,:) = sorted;
tempA = A(i,:);
tempA = tempA(idx);
finalA(i,:) = tempA;
end
There are many clever ways to do this, including this for loop. I hope the comments will explain the logic.
clear; %// input the sample data
A = [7 8 9; 4 5 6];
B = [22 32 12; 9 8 10];
sortB = [12 22 32; 8 9 10];
%// loop through every element in B
[R C]=size(B);
for i=1:C
for j=1:R
%// Where does A(j,i) need to go in Afinal?
%// It needs to go in the j-th row, and in
%// whatever column of B(j,:) equals sortB(j,i).
Afinal( j , find( B(j,:) ==sortB(j,i)) ) = A(j,i);
end
end
And the result:
>> Afinal
Afinal =
8 9 7
5 4 6

How to cut a matrix in Matlab?

I would like to transform the matrix A into the matrix B without using cells (e.g. mat2cell) in Matlab, where
A=[1 2 3;
4 5 6;
7 8 9;
10 11 12;
13 14 15;
16 17 18;
19 20 21;
22 23 24;
25 26 27];
B=[1 2 3 10 11 12 19 20 21;
4 5 6 13 14 15 22 23 24;
7 8 9 16 17 18 25 26 27];
All you need is some reshape + permute magic -
N = 3; %// Cut after every N rows and this looks like the no. of columns in A
B = reshape(permute(reshape(A,N,size(A,1)/N,[]),[1 3 2]),N,[])
This builds a linear index to rearrange the entries of A and then reshapes into the desired matrix B:
m = 3; %// cut size in rows of A. Assumed to divide size(A,1)
n = size(A,2);
p = size(A,1);
ind = bsxfun(#plus, ...
bsxfun(#plus, (1:m).', (0:n-1)*p), permute((0:p/m-1)*m, [1 3 2]));
B = reshape(A(ind(:)), m, [])