MATLAB Answers

column operator erases complex property

12 views (last 30 days)
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

  17 Comments

Paul
Paul on 19 Oct 2020
Walter,
Would you expect the other types of indexing as I showed above also to be treated like an expression?
Also, doesn't Bruno's orignal example show that that (:) does NOT change the data pointer?
Walter Roberson
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
Bruno Luong on 19 Oct 2020
@Vanishta, you miss my point, the COMPLEX command allocates real+imaginary internally, even if imagnary part is 0. That is user intention of using complex command.
The whole purpose of the TIP part of the document is actually tells that user is allowed to create complex array with 0s value in imaginary part.
I expect (:) to preserve that allocation (and keep the data pointer constant) as with RESHAPE. Which is NOT the case.
Why doing such thing, you might ask? Because if I do change a subset of elements of the initial array, it will be faster (assumming array are not shared)
>> format debug
>> z=complex(1:3,0)
z =
Structure address = 2258b2d6a40
m = 1
n = 3
pr = 225a25023c0
1.0000 + 0.0000i 2.0000 + 0.0000i 3.0000 + 0.0000i
>> z(3)=1i % I might do this kind of assigment in for-loop
z =
Structure address = 2258b2d6a40
m = 1
n = 3
pr = 225a25023c0
1.0000 + 0.0000i 2.0000 + 0.0000i 0.0000 + 1.0000i
Unfortunately (:) operator would erase my allocation with COMPLEX.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 18 Oct 2020
For reasons I do not understand, z(:) is being treated as an expression. If you make z larger but complex, then reshape(z,[],1) keeps the same data pointer, but z(:) creates a new data pointer each time -- which is not the case if z is not complex.
I have two speculations at the moment:
  1. Hypothetically, since array indexing is treated as an expression, Mathworks might have wanted consistency around dropping the complex part of expressions when the complex part was all zero. This explanation is a bit weak as it does not explain why they did not treat reshape() the same way, and does not explain why scalar z keeps the same data pointer (but non-scalar z does not.)
  2. Hypothetically, it might have to do with the change to representation of complex in R2018a. This explanation is a bit weak as it does not explain why they did not treat reshape() the same way, and does not explain why scalar z keeps the same data pointer (but non-scalar z does not.) On the other hand, this hypothesis has the merit that it would be testable by going back to R2017b and seeing if (:) had the same behaviour there.

  4 Comments

Show 1 older comment
Walter Roberson
Walter Roberson on 19 Oct 2020
Thanks, per... that eliminates (2) .
z(:) is also supposed to be z(1:end) but z(1:end) is documented as making copies. There thus seems to be a conflict here between whether z(:) is z(1:end) "copied" or is reshape(z,[],1) (uncopied), and that conflict seems to be resolved different ways depending upon whether z is real-only or has complex components.
Bruno Luong
Bruno Luong on 19 Oct 2020
Walter; I too guess it's 1).
To me (:) would be less intrusive than what I just discover. I have tendency to use it a lot, but possibly I would think twice now.
Walter Roberson
Walter Roberson on 19 Oct 2020
Hmmm... what is the difference between
z(:)
subsref(z,struct('type',{'()'}, 'subs', {{':'}}))
The second of those always creates a new data pointer even for real data, but the first of them does not create a new data pointer for real-valued z, or for scalar complex valued z (but the scalar part potentially loses complex 0)

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!