I have matrix lets say MAT of size 2*n
I want to sort the matrix by row num 2
BUT to keep each info from row 1 to its row 2 info
prev
C K A L E Y B
4 2 1 3 6 7 7
and after sort
A K L C E Y B
1 2 3 4 6 7 7
any idea?
you can use the second output argument of sort:
[~, si] = sort(MAT(2,:));
res = MAT(:,si);
Related
Let Matrices = [A B C D] be a set of square matrices. I want to construct
H = [A B C D;
B A B C;
C B A B;
D C B A]
If all I was interested in was the 4 by 4 case, then this would be enough. However, I want to construct the analogous matrix when Matrices = [A B C D E F] etc. What code could I write to do this?
This can be done as follows:
Concatenate the matrices into a 3D array;
Build the basic with numbers instead of matrices using toeplitz;
Extend this structure so that using linear indexing into the 3D array produces the desired result.
N = 2; % matrix size
M = 3; % number of matrices
matrices = arrayfun(#(x) {randi(9,N)}, 1:M); % input matrices
matrices_3D = cat(3, matrices{:}); % concatenate the matrices along the third dim
ind1 = repmat(reshape(1:N^2, N, N), M, M); % linear indices within each matrix
ind2 = (repelem(toeplitz(1:M), N, N)-1)*N^2; % linear indices to select the matrices
result = matrices_3D(ind1 + ind2); % build result
Example run:
>> celldisp(matrices)
matrices{1} =
1 4
2 6
matrices{2} =
6 4
5 9
matrices{3} =
5 4
6 5
>> result
result =
1 4 6 4 5 4
2 6 5 9 6 5
6 4 1 4 6 4
5 9 2 6 5 9
5 4 6 4 1 4
6 5 5 9 2 6
How can I generate the following matrix having m rows and n columns?
1st row 1 2 3 L n-1 n
2nd 2 3 4 L n 1
3rd 3 4 5 n-1 1 2
Nth M M M ....
N-1 m-1 m m+1 L m-3 m-2
last m m+1 m+2 l m-2 m-1
It's difficult to tell from your description, but it appears you want to create a matrix where the first row is 1:n and each successive row is a circular shift to the left of the previous row. If so, you can still use hankel for this (as Dev-iL mentions in their answer), but incorporate a remainder operation like so:
n = 5;
m = 8;
mat = rem(hankel(0:(m-1), (m-1):(m+n-2)), n)+1
mat =
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
This looks like a Hankel matrix. You should use the 2-input syntax for it,
H = hankel(c,r)
So for example, with m = 4 and n = 5 we get:
m = 4; n = 5;
X = hankel( 1:m, m:m+n-1 )
X =
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
Suppose I have two matrices p
p =
1 3 6 7 3 6
8 5 10 10 10 4
5 4 8 9 1 7
5 5 5 3 8 9
9 3 5 4 3 1
3 3 9 10 4 1
then after sorting the columns of matrix p into ascending order
y =
1 3 5 3 1 1
3 3 5 4 3 1
5 3 6 7 3 4
5 4 8 9 4 6
8 5 9 10 8 7
9 5 10 10 10 9
I want to know, given a value from y, what its row was in p
ex: the value 3 which is in matrix p located in row 6 column 1
then after sorting it located in matrix y in row 2 column 1
So I want at the end the values after sorting in matrix y, where it was originally in matrix p
Just use second output of sort:
[y ind] = sort(p);
Your desired result (original row of each value) is in matrix ind.
The Matlab sort command returns a second value which can be used to index into the original array or matrix. From the sort documentation:
[Y,I] = sort(X,DIM,MODE) also returns an index matrix I.
If X is a vector, then Y = X(I).
If X is an m-by-n matrix and DIM=1, then
for j = 1:n, Y(:,j) = X(I(:,j),j); end
Ok i understand exactly what you want.
I will give you my code that i write now, it is not optimal but you can optimize it or i can work with you in order to get the better code..
P and y have the same size.
[n,m]=size(p);
for L=1:m
i=1;
temp=y(i,L);
while(i<=n)
if(temp==y(i,L))
% So it is present in case i of p
disp(['It is present in line' num2str(i) ' of p']);
end
i=i+1;
end
end
VoilĂ !!
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.
I'm using MATLAB. I have a matrix with N elements filled with numbers [1; N], but there are only K unique number between them (K is much less than N). What is an efficient way to relabel the matrix so that it contains only numbers [1; K]? Equal numbers should become equal, and not equal should become not equal.
Example for N = 10, K = 4:
[1 4 8 9 4 1 8 9 4 1] -> [1 2 3 4 2 1 3 4 2 1]
N ~ 1 000 000
K ~ 10 000
Use the third output argument of unique:
a=[1 4 8 9 4 1 8 9 4 1];
[~, ~, b] = unique(a)
b =
1 2 3 4 2 1 3 4 2 1