Sorting the complex array elements with imaginary part along with it.

I have a set of data points, which are complex numbers which have, let’s say, 8 rows and 6 columns. If you look at the program, you can see that data sets are arranged very randomly. 1st, 2nd, 3rd columns are okay, but 4th column, is bit anomalous. What I mean to say is that after element at B(5, 4) (i.e. 25.9868674011374) it is coming 2.74257567017122 [B(6, 4)] instead of 26.8410063269595 which has gone to B(6, 6). I want that column arranged in ascending order (every sorting should be done for real part). Also, in the 5th column, even though the real parts ae arranged in ascending order, the imaginary part are kind of swapped. For example, after B(2,5) it should be B(3,6) not B(3,5). I have tried ‘sort’ command, but it not working as I want.
For the people who is wondering wht is the problem with sort, just try to run this command:
A = [1+2i 3+i i 0 -i];
Dreal= sort(real(A));
Dimg = sort(imag(A));
D=[Dreal;Dimg];
What I want is -i, 0, i ,3+I,1+2i, what sort gives is something else.
Also, there may be instances where 4th, 5th and 6th column may behave ‘normally’, but 1st, 2nd, 3rd columns behaving erratically. So even if 4th, 5th and 6th columns are behaving ‘normally’ I want it to be sorted down in ascending order. Any way through this? By the by, I am using Matlab- 2015b. The code is:
clear all; clc;
B=[-2.14981736484179 + 0.00000000000000i,-1.38134547606946 + 0.00000000000000i,1.38451324569297 + 0.00000000000000i,22.5759136576435 + 0.00000000000000i,2.28536796878740 + 0.333911501246080i,2.28536796878740 - 0.333911501246080i;-2.22047322414157 + 0.00000000000000i,-1.43596350944258 + 0.00000000000000i,1.43889226552228 + 0.00000000000000i,23.4278498788255 + 0.00000000000000i,2.39484729461819 + 0.303429715954385i,2.39484729461819 - 0.303429715954385i;-2.29148887606605 + 0.00000000000000i,-1.49057388951113 + 0.00000000000000i,1.49328382360683 + 0.00000000000000i,24.2803021611395 + 0.00000000000000i,2.50423839041542 - 0.265225265037282i,2.50423839041542 + 0.265225265037282i;-2.36284412024645 + 0.00000000000000i,-1.54517861014711 + 0.00000000000000i,1.54768832224205 + 0.00000000000000i,25.1333019698605 + 0.00000000000000i,2.61351621914550 + 0.215386193278572i,2.61351621914550 - 0.215386193278572i;-2.43451884781340 + 0.00000000000000i,-1.59977935450756 + 0.00000000000000i,1.60210590260749 + 0.00000000000000i,25.9868674011374 + 0.00000000000000i,2.72266244928806 - 0.142395604889199i,2.72266244928806 + 0.142395604889199i;-2.50649346218904 + 0.00000000000000i,-1.65437753673930 + 0.00000000000000i,1.65653651325774 + 0.00000000000000i,2.74257567017122 + 0.00000000000000i,2.92075248853987 + 0.00000000000000i,26.8410063269595 + 0.00000000000000i;-2.57874914363635 + 0.00000000000000i,-1.70897433922564 + 0.00000000000000i,1.71097996266870 + 0.00000000000000i,2.74509085049068 + 0.00000000000000i,3.13593380433481 + 0.00000000000000i,27.6957188653678 + 0.00000000000000i;-2.65126800477853 + 0.00000000000000i,-1.76357074549849 + 0.00000000000000i,1.76543595943333 + 0.00000000000000i,2.78382099280761 + 0.00000000000000i,3.31458248082037 + 0.00000000000000i,28.5509993172157 + 0.00000000000000i];
k=1:1:4;
B1=sort(real(B));
B2=sort(imag(B));
B3=sort(B);
Thanks in advance...

Respuestas (2)

Chris Turnes
Chris Turnes el 9 de Mayo de 2017
If you have a recent version of MATLAB, try checking out the 'ComparisonMethod' Name-Value pair in sort. If you need this type of sorting on each column, the same option exists in the sortrows function.

3 comentarios

Most useful, indeed. Unfortunately, no can do here.
And, the doc isn't very useful for these added features when it only incorporates
Introduced before R2006a
which applies to the function name but says nothing about when significant features were added.
Yes, I missed the R2015b part in the description. The Name-Value pair was introduced in R2017a.
That isn't documented anywhwere excepting perhaps in release notes, is it? I think TMW needs to add to the info in the doc now on these significant changes...when a new function is introduced helps but oldies like this with really radical (for at least one definition :) ) enhancement/changes never get noted in any place easily found excepting going back to release notes which is very time consuming and not linked at all to functions/other doc.
Would be a fair amount of work undoubtedly, but every release that goes by with a few more mods makes the doc just that much more out of touch with evolution of "when could I have done that" which is often need when not everybody has the latest/greatest in cooperating groups.

Iniciar sesión para comentar.

dpb
dpb el 6 de Mayo de 2017
Editada: dpb el 7 de Mayo de 2017
EDIT: Incorporate Andrei's contribution and add for arrays--dpb
>> A
A =
1.0000 + 2.0000i
3.0000 + 1.0000i
0.0000 + 1.0000i
0.0000 + 0.0000i
0.0000 - 1.0000i
>> D=sortrows([real(A) imag(A)])*[1;1i];
D =
0.0000 - 1.0000i
0.0000 + 0.0000i
0.0000 + 1.0000i
1.0000 + 2.0000i
3.0000 + 1.0000i
>>
You're wanting an alphanumeric sort; Matlab SORT() sorts complex by ABS() and your above doesn't keep track of which complex part goes with which real...SORTROWS() does the work required to return the desired ordered index; just select from the original array in that order.
NB Above only works for a single column; otherwise [real() imag()] creates two submatrices of the real and complex portions and sortrows sorts them all indiscriminately from left to right, mixing up "who belongs to whom" for the various components.
How do you want it to be sorted, overall or by the complex columns?
If the former use
D=sortrows([real(B(:)) imag(B(:)])*[1;1i];
to get all NUMEL(B) in a column vector sorted alphanumerically. This loses where they were in the original array if that matters.
If you want each complex variable column sorted this way, then you'll have to loop over each column and reconstruct the array using
D=complex(zeros(size(B),zeros(size(B));
for I=1:size(B,2)
D(:,I)=sortrows([real(B(:,I)) imag(B(:I)])*[1;1i];
end

9 comentarios

Sreeraj T
Sreeraj T el 7 de Mayo de 2017
Editada: Stephen23 el 7 de Mayo de 2017
Thanks for putting your effort to solve my question and I clearly understood your answer. But could you just help me to do that same for B. I am unable to do it.
clear all; clc;
B=[-2.14981736484179 + 0.00000000000000i,-1.38134547606946 + 0.00000000000000i,1.38451324569297 + 0.00000000000000i,22.5759136576435 + 0.00000000000000i,2.28536796878740 + 0.333911501246080i,2.28536796878740 - 0.333911501246080i;-2.22047322414157 + 0.00000000000000i,-1.43596350944258 + 0.00000000000000i,1.43889226552228 + 0.00000000000000i,23.4278498788255 + 0.00000000000000i,2.39484729461819 + 0.303429715954385i,2.39484729461819 - 0.303429715954385i;-2.29148887606605 + 0.00000000000000i,-1.49057388951113 + 0.00000000000000i,1.49328382360683 + 0.00000000000000i,24.2803021611395 + 0.00000000000000i,2.50423839041542 - 0.265225265037282i,2.50423839041542 + 0.265225265037282i;-2.36284412024645 + 0.00000000000000i,-1.54517861014711 + 0.00000000000000i,1.54768832224205 + 0.00000000000000i,25.1333019698605 + 0.00000000000000i,2.61351621914550 + 0.215386193278572i,2.61351621914550 - 0.215386193278572i;-2.43451884781340 + 0.00000000000000i,-1.59977935450756 + 0.00000000000000i,1.60210590260749 + 0.00000000000000i,25.9868674011374 + 0.00000000000000i,2.72266244928806 - 0.142395604889199i,2.72266244928806 + 0.142395604889199i;-2.50649346218904 + 0.00000000000000i,-1.65437753673930 + 0.00000000000000i,1.65653651325774 + 0.00000000000000i,2.74257567017122 + 0.00000000000000i,2.92075248853987 + 0.00000000000000i,26.8410063269595 + 0.00000000000000i;-2.57874914363635 + 0.00000000000000i,-1.70897433922564 + 0.00000000000000i,1.71097996266870 + 0.00000000000000i,2.74509085049068 + 0.00000000000000i,3.13593380433481 + 0.00000000000000i,27.6957188653678 + 0.00000000000000i;-2.65126800477853 + 0.00000000000000i,-1.76357074549849 + 0.00000000000000i,1.76543595943333 + 0.00000000000000i,2.78382099280761 + 0.00000000000000i,3.31458248082037 + 0.00000000000000i,28.5509993172157 + 0.00000000000000i];
B1=sort(real(B));
B2=sort(imag(B));
B3=sort(B);
[~,ix] = sortrows([real(B) imag(B)]);
D=B(ix)
D just give first single column sorted out.
thanks in advance...
dpb
dpb el 7 de Mayo de 2017
Editada: dpb el 7 de Mayo de 2017
B is an 8x6 array, not a column vector here. ix is just a single row index vector, so B(ix) returns only those first eight values out of the array; hence the one short result vector.
Your B1, B2 will sort each column of the corresponding portion of B but loses the relationship between the real/complex parts so is of no help here. B3 sorts on complex values, but reverts to the builtin Matlab behavior noted earlier of being equivalent of sort(abs(B)) which is the same problem you had initially in not being alphanumeric.
How do you want it to be sorted, overall or by the complex columns?
If the former use
[~,ix]=sortrows([real(B(:)) imag(B(:)]);
to get all NUMEL(B) in a column vector sorted alphanumerically. This loses where they were in the original array if that matters.
If you want each imaginary variable column sorted this way, then you'll have to loop over each column and reconstruct the array using
D=complex(zeros(size(B),zeros(size(B));
for I=1:size(B,2)
[~,ix]=sortrows([real(B(:,I)) imag(B(:I)]);
D(:,I)=B(Iix,I);
end
to do each column in turn.
sortrows([real(A), imag(A)])*[1;1i]
Good catch for the single column shorthand, Andrei! Will shorten the previous...thanks.
I believe that there is a small typo error in the code that is written. And the correct code looks like: clear all; clc;
D=complex(zeros(size(B)),zeros(size(B)));
for I=1:size(B,2)
[~,ix]=sortrows([real(B(:,I)) imag(B(:,I))]);
D(:,I)=B(ix,I);
end
With this one also the problem is still there. You can see that if you compare D & B. please note that for -2.6513 + 0.0000i in B(8,1) corresponding B(8,8) is 28.5510 + 0.0000i. On the other hand, in D it has got interchanged.
dpb
dpb el 9 de Mayo de 2017
Editada: dpb el 9 de Mayo de 2017
NO! ABSOLUTELY NOT!
The above sorts each colunm of B alphanumerically; B(8,1)-->D(1,1)
D(8,8) <-- B(8,8)
If you want a global sort; use the first form except use the (:) subscript on the complex parts to return the overall column vector. Then reshape the resulting column vector if want 2D final result ordered from (1,1)-->(M,N).
But if i put:
D=complex(zeros(size(B)),zeros(size(B)));
for I=1:size(B,2)
[~,ix]=sortrows([real(B(:,I)) imag(B(:,I))])*[1;1i];
end
I am getting a error "Error using. Too many output arguments." I couldn't able to rectify it. I did all the possible things.
@sreeraj t: please show us the complete error message. This means all of the red text.
dpb
dpb el 11 de Mayo de 2017
Editada: dpb el 11 de Mayo de 2017
"I did all the possible things."
Excepting looking at the solution provided to see where you made an error... :)
In
[~,ix]=sortrows([real(B(:,I)) imag(B(:,I))])*[1;1i];
you left the two output values saving the index when using the two-step solution of finding an index array first. When using the shorthand of putting the two pieces back together on the fly by complex multiply, you're getting the answer for the whole column so the LHS is just the one output column vector result
D(:,I)=sortrows([real(B(:,I)) imag(B(:,I))])*[1;1i];
There can't be two output arguments from the complex multiply so Matlab rightly complains when you ask for them by [~,ix].

Iniciar sesión para comentar.

Categorías

Etiquetas

Preguntada:

el 6 de Mayo de 2017

Editada:

dpb
el 11 de Mayo de 2017

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by