column operator erases complex property
Show older comments
Why column (:) changes my data? (R2020b)
>> z=complex(3,0)
z =
3.000000000000000 + 0.000000000000000i
>> isreal(z)
ans =
logical
0
>> isreal(reshape(z,[],1))
ans =
logical
0
>> isreal(z(:)) %%%% <= only column returns 1
ans =
logical
1
21 Comments
Walter Roberson
on 18 Oct 2020
Interesting. I wonder if debugging would show a different data pointer, unlike reshape?
Bruno Luong
on 18 Oct 2020
Edited: Bruno Luong
on 18 Oct 2020
Bcoz z is declared using complex function with two arguments, real numbès 3 and 0. The output is one complex number with one row and one col. For which the real part exists and equal to 3.
Use of : operator makes z as vector with two col and one row. So may be using it isreal(z(:)) makes z as real vector with real values only
Bruno Luong
on 18 Oct 2020
Edited: Bruno Luong
on 18 Oct 2020
VBBV
on 18 Oct 2020
@Bruno I told how matlab function isreal() is assuming complex number in this special case Thru the use of : operator. May be you can consider it as bug in 2020b
Even more interestingly, it's not an issue on the GPU,
z=gpuArray(complex(3,0))
isreal(z)
isreal(reshape(z,[],1))
isreal(z(:))
z =
3.0000 + 0.0000i
ans =
logical
0
ans =
logical
0
ans =
logical
0
Walter Roberson
on 18 Oct 2020
Vasishta:
When you use : as the only subscript, the result always has exactly 1 column, even if the original array had dimensions that were only 0 such as zeros(0,0)
Paul
on 18 Oct 2020
Seems like any kind of indexing loses the complex attribute:
>> z
z =
3.0000 + 0.0000i
>> isreal(z(1)),isreal(z(1,1)),isreal(z(true))
ans =
logical
1
ans =
logical
1
ans =
logical
1
VBBV
on 18 Oct 2020
Edited: Walter Roberson
on 19 Oct 2020
@Bruno See the Information in Tips section of the documentation link
VBBV
on 19 Oct 2020
Edited: Walter Roberson
on 19 Oct 2020
@ Bruno
z = complex(12,1);
z =
12.0000 + 1.0000i
isreal(z(:))
ans =
logical
0
So zero is special case
VBBV
on 19 Oct 2020
@ Walter
Ok. What I had thought is use of only : operator in a matrix considers all rows and all cols of matrix
Walter Roberson
on 19 Oct 2020
Edited: Walter Roberson
on 19 Oct 2020
Visashta:
The Tips section of complex() is telling you that complex() is a special function that can explicitly construct variables that have complex part that is all zero, but that the form A+B*i is considered an expression adding A and i*B and that since that is an expression, any all-zero imaginary part will be dropped.
Yes, complex part all-zero is a special case in MATLAB, and the boundaries of that special case are exactly what we are exploring here. It has always been the case that an all-zero complex part will not be lost when you copy or pass a variable, but that it would normally be lost if you use the variable in an expression. The question then arises whether calling reshape() or indexing with (:) should be considered an expression for the purposes of losing the all-zero part. Bruno demonstrated that reshape() does not lose the all-zero complex component, which fits in with the known implementation of reshape() as being about changing the dimension header while using exactly the same data pointer(s) .
Indexing with (:) has long been discussed as being a short-cut for reshape() into a column vector, and if that is the case then because reshape() does not lose the all-zero complex part, it would be unexpected that (:) would lose the all-zero complex part.
We can then ask the question of whether (:) is instead considered an expression rather than just a shortcut to reshape() into a single column. But if it were an expression, then we would expect that for real-valued z, z(:) would copy the data instead of sharing it, leading to a different data pointer. A minor bit of testing shows that is not the case, that when z only contains real values that z(:) shares data.
So... z(:) with complex z is somehow being treated specially, and losing all-zero complex part. z(:) with complex z is giving back a different data pointer.
Next we test
>> format debug
>> z = complex([1 2 3],4)
z =
Structure address = 1dc3db9a0
m = 1
n = 3
pr = 6040044bac60
1.0000 + 4.0000i 2.0000 + 4.0000i 3.0000 + 4.0000i
>> reshape(z,[],1)
ans =
Structure address = 1dc3d95a0
m = 3
n = 1
pr = 6040044bac60
1.0000 + 4.0000i
2.0000 + 4.0000i
3.0000 + 4.0000i
>> z(:)
ans =
Structure address = 1dc3d8d00
m = 3
n = 1
pr = 608005e83260
1.0000 + 4.0000i
2.0000 + 4.0000i
3.0000 + 4.0000i
Notice that when we did the reshape() that the data pointer stayed the same, but when we did the (:) that the data pointer changed. That does not happen when z has no complex part.
>> z1 = [1 2 3]
z1 =
Structure address = 1dc3da500
m = 1
n = 3
pr = 60800d076ca0
1 2 3
>> reshape(z1,[],1)
ans =
Structure address = 1dc3d9c60
m = 3
n = 1
pr = 60800d076ca0
1
2
3
>> z1(:)
ans =
Structure address = 1dc3d8d00
m = 3
n = 1
pr = 60800d076ca0
1
2
3
The problem therefor expands a bit beyond what Bruno originally posted, becoming instead the question:
What is (:) treated like an expression for complex z, but treated as reshape() for non-complex z?
With it being treated as an expression, losing the all-zero part would be automatic.
Walter Roberson
on 19 Oct 2020
Bruno's original example shows the same data pointer for scalar z. With non-scalar z, the data pointer is changed.
Other forms of indexing are expected to be treated as an expression.
>> z1 = [1 2 3]
z1 =
Structure address = 1dc3da500
m = 1
n = 3
pr = 60800d076ca0
1 2 3
>> z1(:)
ans =
Structure address = 1ed9c1960
m = 3
n = 1
pr = 60800d076ca0
1
2
3
>> z1(1:3)
ans =
Structure address = 19e7fcb20
m = 1
n = 3
pr = 60800d06ffa0
1 2 3
This is at least consistent between real and complex: this kind of indexing creates new data structures even for real-only data. It is also explicitly documented as creating unshared data: indexing at 1:end in particular is the documented way to create unshared copies of objects (though at the moment I do not recall at the moment whether it creates deep or shallow copies.)
Bruno Luong
on 19 Oct 2020
Edited: Bruno Luong
on 19 Oct 2020
Walter Roberson
on 28 Mar 2022
Weird! I cannot account for the sort(z) and sortrows() output!
Bruno Luong
on 28 Mar 2022
Walter Roberson
on 29 Mar 2022
The part I was forgetting was this from sort:
- If A is complex, then by default, sort sorts the elements by magnitude. If more than one element has equal magnitude, then the elements are sorted by phase angle on the interval (−π, π].
But these days there is a 'ComparisonMethod' option, of 'real' or 'magnitude'
Accepted Answer
More Answers (0)
Categories
Find more on Image Arithmetic 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!