From maechler at stat.math.ethz.ch  Tue Sep 22 15:54:19 2015
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Tue, 22 Sep 2015 15:54:19 +0200
Subject: [Rd] Should as.complex(NaN) -> NA?
In-Reply-To: <77EB52C6DD32BA4D87471DCD70C8D70002B76B26@NA-PA-VBE03.na.tibco.com>
References: <77EB52C6DD32BA4D87471DCD70C8D70002B76B26@NA-PA-VBE03.na.tibco.com>
Message-ID: <22017.23947.70194.983519@stat.math.ethz.ch>

>>>>> William Dunlap <wdunlap at tibco.com>
>>>>>     on Wed, 31 Mar 2010 12:04:42 -0700 writes:

    > I'm having trouble grokking complex NaN's.  This first set
    > examples using complex(re=NaN,im=NaN) give what I expect
    >> Re(complex(re=NaN, im=NaN))
    >   [1] NaN
    >> Im(complex(re=NaN, im=NaN))
    >   [1] NaN
    >> Arg(complex(re=NaN, im=NaN))
    >   [1] NaN
    >> Mod(complex(re=NaN, im=NaN))
    >   [1] NaN
    >> abs(complex(re=NaN, im=NaN))
    >   [1] NaN and so do the following
    >> Re(complex(re=1, im=NaN))
    >   [1] 1
    >> Im(complex(re=1, im=NaN))
    >   [1] NaN
    >> Re(complex(re=NaN, im=1))
    >   [1] NaN
    >> Im(complex(re=NaN, im=1))
    >   [1] 1 but I don't have a good mental model that explains
    > why the following produce NA instead of NaN.
    >> as.complex(NaN)
    >   [1] NA
    >> Im(complex(modulus=NaN, argument=NaN))
    >   [1] NA
    >> Re(complex(modulus=NaN, argument=NaN))
    >   [1] NA
    >> Re(1i * NaN)
    >   [1] NA
    >> Im(1i * NaN)
    >   [1] NA
    >> Re(NaN + 1i)
    >   [1] NA
    >> Im(NaN + 1i)
    >   [1] NA

    > It may be that if as.complex(NaN), and its C equivalent,
    > were changed to return complex(re=NaN,im=NaN) then the
    > arithmetic examples would return NaN.  Is there a better
    > way for me to model how NaN's in complex numbers should
    > work or is this a bug?

We have finally re-found this posting (from > 5.5 year back!),
and even though my first gut answers would have been

1) it has always been like that in R  {which is true; this dates
  back to the very earliest R source code, in the nineties}.

2) it has been documented that as.complex(.) coerces everything
  NA-like to  NA_complex_

 '2)' actually has not quite been true: Coercing from character, e.g.,

  > as.complex("NaN")
  [1] NaN+0i

which differs from NA_complex_.

I now have committed fairly small changes to R-devel (svn 69410),
which change the behavior of the cases above you found hard to
model mentally and as further consequence, now

 identical(as.complex("NaN"),
           as.complex( NaN ))

is true.

The change has not tripped *any* problems in R's own extended
tests (including the recommended packages), but I do expect that
some packages may have changed behavior / output in border line
cases.

The following mental model should apply now (in R-devel >= svn 69410)
hopefully everywhere (please send exceptions!)

1. as.complex(.) coerces everything with "NA" to  NA_complex_ (=: "complex NA")

2. all (well, maybe with reasonable exceptions) operations
   involving complex NAs return (complex) NAs. 

3 a. Operations with complex NaNs return complex NaNs (but
     there are many versions of those).

  b. "+" and "-" with complex NaNs work coordinate-wise

  c. Most/all (?) other mathematical operations involving complex NaNs
     return  complex(re = NaN, im = NaN) ... by using the
     underlying C99 complex math library.
     complex(re = NaN, im = NaN) can be considered as "the complex NaN"
     (whereas e.g., complex(re = Inf, im = NaN) considered as
     one of the infinitely many complex infinities by at least
     some of the C library implementations.

---

I have found that  match(), unique(), and duplicated() still
behave pretty pecularly --- I'd say bugously --- even after the
69410 change.

Some illustration of the above -- but with the "old" R 3.2.2
behavior is available at http://rpubs.com/maechler/complex-NAs-v3_2_2 .

--
Martin Maechler



[Rd] Should as.complex(NaN) -> NA?
Martin Maechler