Behavior of "unique" with mixed complex numbers
Show older comments
I have a large set of complex number that I want to map to an integer grid on the complex plane, removing redundant values. A small subset of the data looks like:
Atest=[-12.9753 - 0.8003i;
-12.9938 - 0.4003i;
-13.0000 + 0.0000i;
-12.9938 + 0.4003i;
12.9938 + 0.4003i;
13.0000 + 0.0000i;
12.9938 - 0.4003i;];
I use round to map to the grid:
Around=round(Atest)
Around =
-13.0000 - 1.0000i
-13.0000 + 0.0000i
-13.0000 + 0.0000i
-13.0000 + 0.0000i
13.0000 + 0.0000i
13.0000 + 0.0000i
13.0000 + 0.0000i
I then use unique to remove the redundant values:
Aunique=unique(Around,'stable')
Aunique =
-13.0000 - 1.0000i
-13.0000 + 0.0000i
-13.0000 + 0.0000i
13.0000 + 0.0000i
Clearly, the result is not unique: the value -13 appears twice. If I apply unique to just the las 6 values of Around (the real values) I obtain the expected results:
Aunique=unique(Around(2:end),'stable')
Aunique =
-13
13
I would appreciate any suggestions for getting the unique values of an array with mixed real and complex values.
11 Comments
Bruno Luong
on 4 Dec 2020
"Clearly, the result is not unique: the value -13 appears twice"
Joel Miller
on 4 Dec 2020
Bruno Luong
on 4 Dec 2020
Edited: Bruno Luong
on 4 Dec 2020
Hmmm you are right. I apologize.
I though unique should work as intended with complex numbers, obviously it's not.
And the doc of uniquetol doesn't say anything about requirement of input array to be real.
To me it's a design flaw.
Paul
on 5 Dec 2020
Could this have something to do with how the round function leaves the sign bit? I'm not sure, but I did notice that:
>> Around
Around =
-13.0000 - 1.0000i
-13.0000 + 0.0000i
-13.0000 + 0.0000i
-13.0000 + 0.0000i
13.0000 + 0.0000i
13.0000 + 0.0000i
13.0000 + 0.0000i
>> format hex
>> Around
Around =
c02a000000000000 bff0000000000000i
c02a000000000000 8000000000000000i
c02a000000000000 0000000000000000i
c02a000000000000 0000000000000000i
402a000000000000 0000000000000000i
402a000000000000 0000000000000000i
402a000000000000 8000000000000000i
>> Aunique
Aunique =
c02a000000000000 bff0000000000000i
c02a000000000000 8000000000000000i
c02a000000000000 0000000000000000i
402a000000000000 0000000000000000i
>> format short
>> Aunique
Aunique =
-13.0000 - 1.0000i
-13.0000 + 0.0000i
-13.0000 + 0.0000i
13.0000 + 0.0000i
So it appears that the Around(2) and Around(3) might not be unique because of the sign bit on the imaginary part?
But, looking at Marco's answer I'm not sure that's the case:
>> [real(Around) imag(Around)]
ans =
c02a000000000000 bff0000000000000
c02a000000000000 8000000000000000
c02a000000000000 0000000000000000
c02a000000000000 0000000000000000
402a000000000000 0000000000000000
402a000000000000 0000000000000000
402a000000000000 8000000000000000
So imag preserves the sign bit on the imaginary part of Around(2), but unique doesn't seem to care about that using Marco's answer:
>> unique([real(Around) imag(Around)],'rows')
ans =
-13 -1
-13 0
13 0
>> format hex
>> ans
ans =
c02a000000000000 bff0000000000000
c02a000000000000 8000000000000000
402a000000000000 0000000000000000
Maybe unique works differently for complex and real inputs wrt to how it treats the sign bit on a value of zero?
Bruno Luong
on 5 Dec 2020
Edited: Bruno Luong
on 5 Dec 2020
Ah, I believe in Paul's explanation.
>> Around=round(Atest)
Around =
-13.0000 - 1.0000i
-13.0000 + 0.0000i
-13.0000 + 0.0000i
-13.0000 + 0.0000i
13.0000 + 0.0000i
13.0000 + 0.0000i
13.0000 + 0.0000i
>> Aunique=unique(Around,'stable')
Aunique =
-13.0000 - 1.0000i
-13.0000 + 0.0000i
-13.0000 + 0.0000i
13.0000 + 0.0000i
>> Aunique_c=-1i*unique(1i*Around,'stable')
Aunique_c =
-13.0000 - 1.0000i
-13.0000 + 0.0000i
13.0000 + 0.0000i
>>
In which case I call it a bug of UNIQUE, since it should NOT considere the sign bit whereas it's on real or imag part.
I play a little more and it seems the result depend on other thing beside the sign bit. I'm stumped.
Bruno Luong
on 5 Dec 2020
FYI I report the bug.
Paul
on 5 Dec 2020
I'm confused as to why Around(2) and Around(3:4) are not unique, but Around(7) and Around(5:6) are unique? Shouldn't the same rule apply?
Around =
c02a000000000000 bff0000000000000i
c02a000000000000 8000000000000000i
c02a000000000000 0000000000000000i
c02a000000000000 0000000000000000i
402a000000000000 0000000000000000i
402a000000000000 0000000000000000i
402a000000000000 8000000000000000i
Maybe this is one other thing that you already noticed, but flipping the matrix not only changes which entries are selected as unique, but also changes the number of unique entries?
>> Aunique=unique(Around,'stable')
Aunique =
c02a000000000000 bff0000000000000i
c02a000000000000 8000000000000000i
c02a000000000000 0000000000000000i
402a000000000000 0000000000000000i
>> Aunique=unique(flipud(Around),'stable')
Aunique =
402a000000000000 8000000000000000i
c02a000000000000 0000000000000000i
c02a000000000000 bff0000000000000i
Very troubling that the numel of the result depends on the order of input.
Will you post back here when you get a response from tech support?
Bruno Luong
on 5 Dec 2020
Edited: Bruno Luong
on 5 Dec 2020
"I'm confused as to why Around(2) and Around(3:4) are not unique, but Around(7) and Around(5:6) are unique? Shouldn't the same rule apply?"
When I wanted to construct a MWE for bug reporting, that's what I find out as well.
Thus I wrote "it seems the result depend on other thing beside the sign bit". It depends on globally on the array itself, and not only on the elements with zero sign bit.
Pretty much a nasty bug.
Joel Miller
on 7 Dec 2020
Bruno Luong
on 7 Dec 2020
Here is the reply from tech support
"Thank you for your inquiry and provided clear reproduction examples. It does appear as though this is a bug with the unique function executed on rounded complex arrays. The Development team has been informed of this bug and will investigate further.
Given the information above, I will close this case as 'Bug/Enhancement Submitted'. From a Technical Support perspective the case is now closed. From a Development standpoint, on the other hand, the matter is still open. It is being investigated and will be considered for a future Release or Update. Should this bug be fixed, you will be personally notified via email. Then, the status of this service request will be automatically changed to 'Bug Fixed/Enhancement Complete'. "
So obviously it's abug and they will fix it in future release.
Bruno Luong
on 11 Dec 2020
Another mail from tech:
"I just wanted to offer you a follow up email regarding a workaround for your use case. If you add complex(0)to 'Around', then call unique, it will give the right answer. For example:"
A = [-12.9753 - 0.8003i; -12.9938 - 0.4003i; -12.9938 + 0.4003i; 12.9938 + 0.4003i];
B = round(A) + complex(0);
C = unique(B);
But we already knew this solution from the cross-thread of atan2 and sign bit.
Accepted Answer
More Answers (0)
Categories
Find more on Data Type Identification in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!