octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

isreal and iscomplex


From: Rik
Subject: isreal and iscomplex
Date: Mon, 10 Sep 2012 13:28:05 -0700

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

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.

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)

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.

--Rik



reply via email to

[Prev in Thread] Current Thread [Next in Thread]