HY Sin
HY Sin

Reputation: 17

Sorting whole matrix into only one column

I get a small project to do on scoring system. I found out that if i'm using excel to manipulated it, it definitely cause me a lot of time. I hope i get help from you guys.

A = [10 20 30 40 ...]       % (1xm array)
B = [0.02; 0.04;...]        % (nx1 array)
F = A/B                     % F should be (n x m matrix)
Z = zero (size(nxm), 3)     % I'm trying to create a matrix with n x m row and 3 column)

I would like to sort F into Z(1:end), Z(1:end) respective A will be in Z(2:end) and respective B will be in Z(3:end). May i know how should i write in Matlab?

Example:

       10      20    30    40    50 ...
0.02  500     1000  1500  2000   2500
0.04  250     500   750   1000   1250
0.06 166.67 333.33  500  666.67  833.33 
...

output Z

166.67  10  0.06
250     10  0.04
333.33  20  0.06
....

Hope anyone here can help me. Thanks.

Upvotes: 1

Views: 604

Answers (2)

jpjacobs
jpjacobs

Reputation: 9559

The thing you are looking for is either meshgrid, or bsxfun. The meshgrid solution:

A=[10 20 30 40];
B=[0.02 0.04 0.06 0.08];
[x,y]=meshgrid(A,B); % Generate 2 matrices having the elements to divide
F=x./y;              % Do elemnt-by-element divide
Z=[F(:),x(:),y(:)];  % put all values from the matrices together as columns,
                     % using linear indexing (:).

The bsxfun solution is more compact, faster, but less readable:

F=bsxfun(@rdivide,A',B); % Put the transpose at B if you want it 
                       % sorted along B.
x=bsxfun(@times,A,ones(size(B,2),1));  % a matric containing A as columns
y=bsxfun(@times,ones(1,size(A,2)),B'); % a matrix containing B repeated as rows
Z=[F(:),x(:),y(:)];

The trick with bsxfun is that it does singleton expansion. The inputs get repeated along each dimension having length 1, as much as needed to match the second operand.

So in the 4x4 case above you have (pseudo code):

[10 20 30 40] .* [0.01;
                  0.02;
                  0.04;
                  0.06]

will be expanded to (also pseudo code):

[10 20 30 40;    [0.01 0.01 0.01 0.01;
 10 20 30 40; .*  0.02 0.02 0.02 0.02;
 10 20 30 40;     0.04 0.04 0.04 0.04;
 10 20 30 40]     0.06 0.06 0.06 0.06]

It seems you want to have it sorted by F: you can easily accomplish this by using

Z_sort = sortrows(Z,[1]);

Upvotes: 1

nrz
nrz

Reputation: 10580

This is a solution using reshape and linear addressing:

The input data (A is a row vector, B is a column vector):

A = [ 10, 20, 30, 40 ];
B = [ 0.02; 0.04; 0.06; 0.08 ];

Here's the code:

F = bsxfun(@rdivide, A, B);
Fvector = reshape(F, 1, numel(F));

[SortedFvector, IX] = sort(Fvector);
Aindices = ceil(IX/size(B, 1));

Bindices = mod(IX, size(B, 1));
Bindices(Bindices == 0) = size(B, 1);

Z = [ SortedFvector', A(Aindices)', B(Bindices) ];

Upvotes: 1

Related Questions