Sorting a matrix in MATLAB - matlab

I have this problem that I need to sort a matrix in MATLAB.
Input:
[20 10 0 50 0;
300 100 50 50 100]
And I'd like the output to be:
[0 0 10 20 50;
50 100 100 300 50]
So I'd like it to sort the first column but the rows remain unchanged. Help is needed!

You did write the answer yourself, try sort
A = [20 10 0 50 0; 300 100 50 50 100];
[A(1,:) idx] = sort(A(1,:),2);
A(2,:) = A(2,idx);

You could also use sortrows and get the desired result in one line:
result = sortrows(A.',1).';

Related

How to avoid for loop in Matlab when building a new matrix from a database

I have a matrix with two columns with about 500 rows. The values of first column vary from 1 to 48. This means that there are repeating numbers in the first column.
I need to make to build a new matrix with 48 rows that each row includes information for a specific number in column 1. For example consider the following data:
x = [ 3 500
5 400
3 200
1 100
1 1100
2 450
3 890
1 110
2 800
....]
So, the out put matrix should be:
Output = [100 1100 110 ...0 0 0; 450 800 ... 0 0 0; 8200 890 0 0 0 ...; 0 0 0];
I know how to do it using for loop but I need to do it without a for loop.
I used the following lines
XX = X(:,2);
Output = XX(X(:,1)==(1:48)');
But it did no work because the number of rows in the new matrix is not the same.
Any help is appreciated.
You can do this with the sub2ind function, I recommend reading the documentation to understand how this works. We'll place all the x(:,2) values into a matrix M. The row that each value belongs in depends on the x(:,1) values, so we must determine which column the value belongs to.
Below j is calculated such that j(k) is equal to the number of times x(k,1) occurs in the vector x(1:k,1). This will be the column we want to place the value x(k,2) into.
x = [ 3 500
5 400
3 200
1 100
1 1100
2 450
3 890
1 110
2 800];
j = sum(triu(x(:,1)==x(:,1)')); % Calculate the column each value should be placed into
M = zeros(max(x(:,1)), max(j)); % Set up the empty matrix
ind = sub2ind(size(M), x(:,1), j(:)); % Get linear indices from subscripts
M(ind) = x(:,2)
M =
100 1100 110
450 800 0
500 200 890
0 0 0
400 0 0

using logical arrays to select certain elements into another matrix

I believe the answer to this is simple but my brain will not function.
Say I have a m x n matrix which is of type double & lets call it A. I also have a matrix B, which is m x n and is all NaN's.
I then want to find out which numbers are say equal to some number, let say 100. I can do the following,
A_index = A == 100;
So I now have a logical array, A_index. This is all fine.
My question is how do I select the elements from A where A_index is true into matrix B?
Some made up matrices
A= [ 50 100 75 90 100; 0 50 60 30 10; 100 25 80 250 100; 5 100 0 100 90];
A_index = A == 100;
B= zeros(4,5) * NaN;
Something like:
A= [ 50 100 75 90 100; 0 50 60 30 10; 100 25 80 250 100; 5 100 0 100 90];
A_index = A == 100;
B= zeros(4,5) * NaN;
B(A_index) = 100
This way you will get 100 in the entries of B where A is equal to 100
See the section on logical indexing in the MATLAB docs

Limited Sum in Matlab

Hi lets say that i have matrix size 5x5.
B=[1 2 3 4 5; 10 20 30 40 50; 100 200 300 400 500; 1000 2000 3000 4000 5000; 10000 20000 30000 40000 50000];
How do i use function sum, to sum rows between 2 and 4 and have result:
A = [1110;2220;3330;4440]
You'll find some useful information about matrix indexing in the documentation at http://www.mathworks.co.uk/help/matlab/math/matrix-indexing.html
To illustrate your example, you can use B(2:4,:) to retreive the following:
ans =
10 20 30 40 50
100 200 300 400 500
1000 2000 3000 4000 5000
You can then use the sum function as follows to achieve your desired result:
A = sum(B(2:4,:))
I hope this helps!
All the best,
Matt
MATLAB>> sum(B(2:4,1:4))
ans =
1110 2220 3330 4440
If you want to transpose the result, add ' at the end.

How can I divide each row of a matrix by a fixed row?

Suppose I have a matrix like:
100 200 300 400 500 600
1 2 3 4 5 6
10 20 30 40 50 60
...
I wish to divide each row by the second row (each element by the corresponding element), so I'll get:
100 100 100 100 100 100
1 1 1 1 1 1
10 10 10 10 10 10
...
Hw can I do it (without writing an explicit loop)?
Use bsxfun:
outMat = bsxfun (#rdivide, inMat, inMat(2,:));
The 1st argument to bsxfun is a handle to the function you want to apply, in this case right-division.
Here's a couple more equivalent ways:
M = [100 200 300 400 500 600
1 2 3 4 5 6
10 20 30 40 50 60];
%# BSXFUN
MM = bsxfun(#rdivide, M, M(2,:));
%# REPMAT
MM = M ./ repmat(M(2,:),size(M,1),1);
%# repetition by multiplication
MM = M ./ ( ones(size(M,1),1)*M(2,:) );
%# FOR-loop
MM = zeros(size(M));
for i=1:size(M,1)
MM(i,:) = M(i,:) ./ M(2,:);
end
The best solution is the one using BSXFUN (as posted by #Itamar Katz)
You can now use array vs matrix operations.
This will do the trick :
mat = [100 200 300 400 500 600
1 2 3 4 5 6
10 20 30 40 50 60];
result = mat ./ mat(2,:)
which will output :
result =
100 100 100 100 100 100
1 1 1 1 1 1
10 10 10 10 10 10
This will work in Octave and Matlab since R2016b.

Pulling a subset of a matrix in MATLAB

I want to cluster an array, this array contain some angle I want to calculate the difference between of these degree and select one group between this array, this group should have maximum number and the difference between the member of that should not be larger than specific number.
for example if specific number is 30
and array is
[10 20 30 40 100 120 140]
answer should be
[10 20 30 40]
100-30 >= 30 so it is not included.
A one-line solution:
a = [10 20 30 40 100 120 140];
s = 30;
b = a( abs(a-s) < s )
a = [10 20 30 40 100 120 140]; #initial array
b = []; #result array
s = 30;
for i = 1:length(a)
if abs(a(i) - s) < s
b = [b a(i)];
end
end