From: Daniel J S. <dan...@ie...> - 2012-09-07 21:31:04
|
In working with the fftfilt() routine and wanting to know if the inputs were purely imaginary I wondered why there is no such thing as isimag(). It seems as though it would be as useful as or more useful than iscomplex(). Here's the thing: iscomplex() appears to be simply the complement of isreal(), unless I'm missing a more sophisticated use of syntax: octave:5> x = 1 x = 1 octave:6> [isreal(x) iscomplex(x)] ans = 1 0 octave:7> x = i x = 0 + 1i octave:8> [isreal(x) iscomplex(x)] ans = 0 1 octave:9> x = 1+i x = 1 + 1i octave:10> [isreal(x) iscomplex(x)] ans = 0 1 octave:11> I ask, What's the point of having a function that is simply !isreal()? On the other hand isimag(), which is equivalent to "all (real (x) == 0)) && !isreal (x)", would be a nice shorthand. Just an observation. Usually duplication of function (or its complement) is weeded out of programming languages. Dan |
From: Michael D G. <mic...@gm...> - 2012-09-08 04:06:02
|
On 09/07/2012 05:30 PM, Daniel J Sebald wrote: > In working with the fftfilt() routine and wanting to know if the > inputs were purely imaginary I wondered why there is no such thing as > isimag(). It seems as though it would be as useful as or more useful > than iscomplex(). > > Here's the thing: iscomplex() appears to be simply the complement of > isreal(), unless I'm missing a more sophisticated use of syntax: > > octave:5> x = 1 > x = 1 > octave:6> [isreal(x) iscomplex(x)] > ans = > > 1 0 > > octave:7> x = i > x = 0 + 1i > octave:8> [isreal(x) iscomplex(x)] > ans = > > 0 1 > > octave:9> x = 1+i > x = 1 + 1i > octave:10> [isreal(x) iscomplex(x)] > ans = > > 0 1 > > octave:11> > > I ask, What's the point of having a function that is simply !isreal()? > On the other hand isimag(), which is equivalent to "all (real (x) == > 0)) && !isreal (x)", would be a nice shorthand. > > Just an observation. Usually duplication of function (or its > complement) is weeded out of programming languages. > > Dan I also recently noticed some quirks with complex: x = 1 + 0i is treated as real and not complex. but x = 0 + 1i is treated as imag and complex. But, this is consistent with Matlab. However, Matlab has no iscomplex and also differs in its example for help isreal. There, Matlab gives an example: x = magic(3); y = complex(x); which gives: >> y y = 8 1 6 3 5 7 4 9 2 >> isreal(y) ans = 0 but, ~isreal(y) gives: ans = 1 The text in the help messages says that isreal(y) returns false, because COMPLEX returns y with an all zero imaginary part. ------------------------------------------- but Octave gives: y = 8 + 0i 1 + 0i 6 + 0i 3 + 0i 5 + 0i 7 + 0i 4 + 0i 9 + 0i 2 + 0i and: octave:21> isreal(y) ans = 0 and: octave:29> ~isreal(y) ans = 1 The only difference is in the display of y. This hardly qualifies as a bug, but does add a bit to the confusion. Some people would imagine that real and imaginary would be treated "symmetrically." So far I do not see much point in making a change. |
From: Daniel J S. <dan...@ie...> - 2012-09-08 21:33:31
|
On 09/07/2012 11:05 PM, Michael D Godfrey wrote: > On 09/07/2012 05:30 PM, Daniel J Sebald wrote: >> In working with the fftfilt() routine and wanting to know if the >> inputs were purely imaginary I wondered why there is no such thing as >> isimag(). It seems as though it would be as useful as or more useful >> than iscomplex(). >> >> Here's the thing: iscomplex() appears to be simply the complement of >> isreal(), unless I'm missing a more sophisticated use of syntax: >> >> octave:5> x = 1 >> x = 1 >> octave:6> [isreal(x) iscomplex(x)] >> ans = >> >> 1 0 >> >> octave:7> x = i >> x = 0 + 1i >> octave:8> [isreal(x) iscomplex(x)] >> ans = >> >> 0 1 >> >> octave:9> x = 1+i >> x = 1 + 1i >> octave:10> [isreal(x) iscomplex(x)] >> ans = >> >> 0 1 >> >> octave:11> >> >> I ask, What's the point of having a function that is simply !isreal()? >> On the other hand isimag(), which is equivalent to "all (real (x) == >> 0)) && !isreal (x)", would be a nice shorthand. >> >> Just an observation. Usually duplication of function (or its >> complement) is weeded out of programming languages. >> >> Dan > I also recently noticed some quirks with complex: > x = 1 + 0i is treated as real and not complex. > but > x = 0 + 1i is treated as imag and complex. Talking of Octave, there is no "isimag()", so what do you mean "treated as imag"? > But, this is consistent with Matlab. However, Matlab has no iscomplex > and also > differs in its example for help isreal. There, Matlab gives an example: > x = magic(3); > y = complex(x); > > which gives: >> > y > > y = > > 8 1 6 > 3 5 7 > 4 9 2 >> > isreal(y) > > ans = > > 0 > but, ~isreal(y) gives: > ans = > > 1 > > The text in the help messages says that > isreal(y) returns > false, because COMPLEX returns y with an all zero imaginary > part. > ------------------------------------------- > but Octave gives: > > y = > > 8 + 0i 1 + 0i 6 + 0i > 3 + 0i 5 + 0i 7 + 0i > 4 + 0i 9 + 0i 2 + 0i > > and: > octave:21> isreal(y) > ans = 0 > and: > octave:29> ~isreal(y) > ans = 1 > > The only difference is in the display of y. Well, if y is complex, I sort of prefer the Octave printout format. > This hardly qualifies as a bug, but does add a bit > to the confusion. Add to, yes. Meaning it is already somewhat confusing by the Matlab standard. > Some people would imagine > that real and imaginary would be treated "symmetrically." I guess that is what I would prefer. For example PREFERRED, NOT CURRENT BEHAVIOR: octave:29> x = 1 x = 1 octave:30> isreal(x) ans = 1 octave:31> isimag(x) ans = 0 octave:32> iscomplex(x) ans = 0 octave:33> y = i y = 1i octave:34> isreal(y) ans = 0 octave:35> isimag(y) ans = 1 octave:36> iscomplex(y) ans = 0 octave:37> z = 1 + i z = 1 + 1i octave:38> isreal(z) ans = 0 octave:39> isimag(z) ans = 0 octave:40> iscomplex(z) ans = 1 The above scenario seems to me consistent and all three functions would be "orthogonal", i.e., not duplicate function or simple complement. If one were to mix-and-match real and imaginary, I'd think that promoting to "complex" in that case would make sense. ... Just trying a few things here, I've sort of lost my faith in the meaning of "isreal()". Generally speaking, it could mean: 1) The class of the variable is real, meaning there is no imaginary component present. 2) The variable has no imaginary component, or it does have an imaginary component which is zero. Unfortunately by having the property you describe above, i.e., "complex returns an all zero imaginary part", the two are sort of conflated. Consider for example if I want to test if the imaginary portion of some variable is zero: octave:41> isreal(1 + 0i) ans = 1 octave:42> isreal(complex(1,0)) ans = 0 Well, "isreal()" clearly doesn't mean that. I just put together a patch for fftfilt() that intends to check if the imaginary component of the inputs are zero using "isreal()", but I think I will change that to all(imag(x) == 0)) instead because the latter expression has clear definition. One could be lead to think that "isreal" DOES mean the imaginary portion is zero. Check this out: octave:50> z = complex([1 2 3],[1 0 2]) z = 1 + 1i 2 + 0i 3 + 2i octave:51> isreal(z(2)) ans = 1 octave:52> iscomplex(z(2)) ans = 0 Perhaps the above is a compatibility disagreement. Otherwise it is a little confounding. Conceptually, I can grasp either scenario 1 or scenario 2 above, but there seems to be a hybrid that escapes me. How do others feel about deprecating "iscomplex()" if it simply is the complement of "isreal()"? I would be open to an "iscomplex" and "isimag" that have a more "class-related" behavior as I pondered above. I don't think that would go against compatibility. I'm also wondering if it might be worth writing in the documentation for isreal() that "isreal(x) is not the same as all(imag(x)==0)". Dan |
From: Michael D G. <mic...@gm...> - 2012-09-09 01:52:30
|
On 09/08/2012 05:33 PM, Daniel J Sebald wrote: > How do others feel about deprecating "iscomplex()" if it simply is the > complement of "isreal()"? > > I would be open to an "iscomplex" and "isimag" that have a more > "class-related" behavior as I pondered above. I don't think that > would go against compatibility. > > I'm also wondering if it might be worth writing in the documentation > for isreal() that "isreal(x) is not the same as all(imag(x)==0)". > > Dan Dan, Just a brief answer to all you comments. It seems to me that the current state has just evolved from various forces. It is not either consistent nor likely to be clear to most users. Maybe its only good feature is that it is not obviously in direct conflict with Matlab. However, I think that any single change, without carefully thinking through all the issues, is likely to do as much harm as good. One thing that you said should be followed up: a clearer description of the current state should go somewhere in the Manual. And, this may just add to the noise, but a few days ago I created a vector which was composed of complex elements, and some "real" elements, i.e. isreal(x(4)) said 1 and whos x(4) said it was only 8 bytes. But, the vector was complex and whos x showed it as composed of 16 byte complex elements. Just another bit of schizophrenia. Since I have not been able to reproduce this I have not been able to try it on Matlab. I do think that creating an isimag() and at least deprecating iscomplex() is a good idea. However, someone with at least a day or two of time should go through this carefully and propose a good set of actions. Michael |
From: Daniel J S. <dan...@ie...> - 2012-09-09 06:35:55
|
On 09/08/2012 08:52 PM, Michael D Godfrey wrote: [snip] > And, this may just add to the noise, but a few days ago I created a > vector which was composed > of complex elements, and some "real" elements, i.e. isreal(x(4)) said 1 > and whos x(4) said > it was only 8 bytes. That is similar to the example: octave:20> z = complex([1 2 3],[1 0 2]) z = 1 + 1i 2 + 0i 3 + 2i octave:21> isreal(z) ans = 0 octave:22> isreal(z(1)) ans = 0 octave:23> isreal(z(2)) ans = 1 octave:24> whos z z(1) z(2) Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== c z 1x3 48 double c z(1) 1x1 16 double z(2) 1x1 8 double Total is 5 elements using 72 bytes ... Interchanging the square and curved parentheses is another, simpler illustration: octave:28> iscomplex(complex(1,0)) ans = 1 octave:29> iscomplex([complex(1,0)]) ans = 0 Dan |