[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: isreal and iscomplex
From: |
Daniel J Sebald |
Subject: |
Re: isreal and iscomplex |
Date: |
Mon, 10 Sep 2012 18:02:22 -0500 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.24) Gecko/20111108 Fedora/3.1.16-1.fc14 Thunderbird/3.1.16 |
On 09/10/2012 03:28 PM, Rik wrote:
9/10/12
Dan,
I think part of the confusion is that you are encountering two sets of
functionality:
1) isreal function
2) automatic narrowing of complex->real
The isreal function, as you now know, does not check that the imaginary
part of an object is zero. Rather it checks that the storage class used
for the object is real (8 bytes) versus complex (16 bytes). It is a hard
requirement to keep isreal compatible with the Matlab function of the same
name so we can't re-define it. The other functions, iscomplex and isimag,
are Octave's alone and could be re-defined. As Michael has said, there
would need to be a very clear plan laid out so that it doesn't compromise
older scripts, etc.
The second functionality that you are encountering is the automatic
narrowing that Octave performs on complex numbers. Complex numbers take
twice as much memory to store and there is a significant incentive to
reduce results to real numbers if possible. Octave does this at many
places: when you type a number on the command line, when you define a
matrix, when you extract a value or range using indexing, etc. Thus,
isreal (1+0i) => isreal (1) => 1
isreal ([1+0i, 1]) => isreal ([1, 1]) => 1
x = [1, 1i, 1+1i];
isreal (x) => false because x is stored as a complex object
isreal (x(1)) => isreal (1) => true
The complex() function is guaranteed to return a complex result. Therefore,
isreal (complex(1,0)) => 1 because the object is complex EVEN though
the imaginary part is zero.
However, it is simple enough to re-engage narrowing by using the matrix
constructor operator '['.
isreal ([complex(1,0)]) => isreal ([1 + 0i]) => isreal ([1]) => 1
OK, I'm starting to get it now. Thanks.
Incidentally, I did a little benchmarking and automatic narrowing is ~25%
faster than using an equivalent vectorized operator.
Example code:
x = complex (ones (1e4), zeros (1e4));
tic; xreal = isreal ([x]); toc
Elapsed time is 1.78048 seconds.
tic; xreal = all (imag (x) == 0); toc
Elapsed time is 2.42 seconds.
That's not what I'm getting...
octave:1> x = complex (ones (1e4), zeros (1e4));
octave:2>
octave:2> cpustart = cputime();
octave:3> xisreal = isreal(x)
xisreal = 0
octave:4> cputime() - cpustart
ans = 0.0029990
octave:5>
octave:5> cpustart = cputime();
octave:6> xisreal = isreal([x])
xisreal = 1
octave:7> cputime() - cpustart
ans = 1.5658
octave:8>
octave:8> cpustart = cputime();
octave:9> xisreal = isreal(x(:))
xisreal = 1
octave:10> cputime() - cpustart
ans = 1.5678
octave:11>
octave:11> cpustart = cputime();
octave:12> xisreal = all (all (imag (x) == 0))
xisreal = 1
octave:13> cputime() - cpustart
ans = 1.4528
What brand of computer do you have there Rik?
In your patch for fftfilt you might want to take advantage of that fact.
Also, if you are already using indexing then the narrowing will happen
automatically. I could test whether column 2 of x is truly real (imaginary
part == 0) with
isreal (x(:,2))
which reads more naturally then
all (imag (x(:,2)) == 0)
I can straighten that out now given I understand how isreal() works.
You might want to check Matlab's own documentation for isreal
(http://www.mathworks.com/help/techdoc/ref/isreal.html). They do a good
job in the introduction and the Tips section of explaining all these corner
cases.
Octave could certainly use more in the documentation on this behavior since
it can be confusing.
Yes, definitely more documentation than just the two sentences currently
given. Having sorted through all this I can now summarize as follows:
...
The function isreal(A) tests that the STORAGE CLASS of variable A uses
only a real component. However, storage class IS NOT PRESERVED through
any mathematical operations. That is, reductions in memory space are
attempted with all matrix computations. Therefore, do not use isreal(A)
to test if all imaginary components of a complex matrix are zero.
Instead, use isreal(A(:)) or all(all(imag(A)==0)).
...
Well, now let's return to the notion of having an "iscomplex()" and
"isimag()". Is there some utility to that? I conclude "Maybe". Given
that "isreal" is cast in this storage class paradigm, the only time it
would make sense to have an "isimag()" is if there were a similar
reduction to 8-byte matrices if all real parts of the complex matrix are
zero. (To have isimag() mean otherwise would REALLY confuse matters.)
Currently, I'm guessing Octave isn't set up that way, i.e., to save
space after a mathematical operation by using just an imaginary
component if all real components are zero.
One little non-symmetry for a real-only/imaginary-only paradigm would be
the case where the complex matrix operation result is all 0 + 0i, in
which case the storage class would be "real" vector and all zeros. With
that behavior, "isreal()" would still behave in exactly the same way as
it currently does. However, note that "iscomplex()" would not be the
complement of "isreal()" under such a scenario because if the math
result had all real components zero and were stored in the 8-byte
imaginary component only then iscomplex() would be false. (And note I
avoided the word "complex" in my documentation summary above.)
Personally, I'd prefer "iscomplex()" be deprecated in the short term
since it currently is only the complement of "isreal()". That would
leave open its use in a real/imaginary/complex storage class
configuration, which is of very low priority right now. It would also
mean we have but one hunk of tricky function documentation to worry
about on the matter.
Dan
- isreal and iscomplex, Rik, 2012/09/10
- Re: isreal and iscomplex,
Daniel J Sebald <=
- Re: isreal benchmarking, Rik, 2012/09/11
- Re: isreal benchmarking, Daniel J Sebald, 2012/09/11
- Re: isreal benchmarking, John W. Eaton, 2012/09/11
- Message not available
- Message not available
- Message not available
- Re: isreal benchmarking, John W. Eaton, 2012/09/11
- Re: isreal benchmarking, Daniel J Sebald, 2012/09/11
- Re: isreal benchmarking, John W. Eaton, 2012/09/12
- Re: isreal benchmarking, Daniel J Sebald, 2012/09/12