Davis Vaughan
2023-Apr-14 16:29 UTC
[Rd] Possible inconsistency between `as.complex(NA_real_)` and the docs
Hi all, Surprisingly (at least to me), `as.complex(NA_real_)` results in `complex(real = NA_real_, imaginary = 0)` rather than `NA_complex_`. It seems to me that this goes against the docs of `as.complex()`, which say this in the Details section: "Up to R versions 3.2.x, all forms of NA and NaN were coerced to a complex NA, i.e., the NA_complex_ constant, for which both the real and imaginary parts are NA. Since R 3.3.0, typically only objects which are NA in parts are coerced to complex NA, but others with NaN parts, are not. As a consequence, complex arithmetic where only NaN's (but no NA's) are involved typically will not give complex NA but complex numbers with real or imaginary parts of NaN." To me this suggests that `NA_real_`, which is "NA in parts", should have been coerced to "complex NA". `NA_integer_` is actually coerced to `NA_complex_`, which to me is further evidence that `NA_real_` should have been as well. Here is the original commit where this behavior was changed in R 3.3.0: https://github.com/wch/r-source/commit/4a4c2052e5a541981a249d4fcf92b54ca7f0a2df ``` # This is expected, based on the docs x <- as.complex(NaN) Re(x) #> [1] NaN Im(x) #> [1] 0 # This is not expected. The docs say: # "Since R 3.3.0, typically only objects which are NA in parts are coerced to complex NA" # but that doesn't seem true for `NA_real_`. x <- as.complex(NA_real_) Re(x) #> [1] NA Im(x) #> [1] 0 # It does seem to be the case for `NA_integer_` x <- as.complex(NA_integer_) Re(x) #> [1] NA Im(x) #> [1] NA ``` Thanks, Davis Vaughan
Martin Maechler
2023-Apr-22 16:41 UTC
[Rd] Possible inconsistency between `as.complex(NA_real_)` and the docs
> Hi all, > > Surprisingly (at least to me), `as.complex(NA_real_)` results in > `complex(real = NA_real_, imaginary = 0)` rather than `NA_complex_`.Well, the logic here is really the mathematical equivalence: if you turn a real number x in to a complex one, say z, then z = x + i * 0 , i.e., real part x and imaginary part 0.> It seems to me that this goes against the docs of `as.complex()`, > which say this in the Details section: > > "Up to R versions 3.2.x, all forms of NA and NaN were coerced to a > complex NA, i.e., the NA_complex_ constant, for which both the real > and imaginary parts are NA. Since R 3.3.0, typically only objects > which are NA in parts are coerced to complex NA, but others with NaN > parts, are not. As a consequence, complex arithmetic where only NaN's > (but no NA's) are involved typically will not give complex NA but > complex numbers with real or imaginary parts of NaN."The above was written in svn commit 69410 (the github mirror of which you mention below) ------------------------------------------------------------------------ r69410 | maechler | 2015-09-22 10:11:34 +0200 (Tue, 22 Sep 2015) | 1 line more consistent behavior of complex number NaN / NA - not back-compatible ------------------------------------------------------------------------ which I had to amend a day later in ------------------------------------------------------------------------ r69423 | maechler | 2015-09-23 19:23:57 +0200 (Wed, 23 Sep 2015) | 1 line even NaN + NA_complex_ is platform dependent ------------------------------------------------------------------------ just with adding the following at the end of example(as.complex) : showC <- function(z) noquote(sprintf("(R = \%g, I = \%g)", Re(z), Im(z))) ## The exact result of this *depends* on the platform, compiler, math-library: (NpNA <- NaN + NA_complex_) ; str(NpNA) # *behaves* as 'cplx NA' .. stopifnot(is.na(NpNA), is.na(NA_complex_), is.na(Re(NA_complex_)), is.na(Im(NA_complex_))) showC(NpNA)# but not always is {shows '(R = NaN, I = NA)' on some platforms} ## and this is not TRUE everywhere: identical(NpNA, NA_complex_) showC(NA_complex_) # always == (R = NA, I = NA) And that was a while ago. In the mean time I've become more aware of the fact that --- to my large chagrin --- our distinction of NA and NaN unfortunately has more problems in quite platform-dependent arithmetic than I had still hoped at the time.> To me this suggests that `NA_real_`, which is "NA in parts", should > have been coerced to "complex NA". > > `NA_integer_` is actually coerced to `NA_complex_`, which to me is > further evidence that `NA_real_` should have been as well.Yeah.. I agree that as.complex(.) should return the same for integer and double NA. I see where and how the change would need to happen. .. we'll see if it is feasible (I guess "yes" with 0.98 subjective probability)> Here is the original commit where this behavior was changed in R 3.3.0: > https://github.com/wch/r-source/commit/4a4c2052e5a541981a249d4fcf92b54ca7f0a2df > > ``` > # This is expected, based on the docs > x <- as.complex(NaN) > Re(x) > #> [1] NaN > Im(x) > #> [1] 0 > > # This is not expected. The docs say: > # "Since R 3.3.0, typically only objects which are NA in parts are > coerced to complex NA" > # but that doesn't seem true for `NA_real_`. > x <- as.complex(NA_real_) > Re(x) > #> [1] NA > Im(x) > #> [1] 0 > > # It does seem to be the case for `NA_integer_` > x <- as.complex(NA_integer_) > Re(x) > #> [1] NA > Im(x) > #> [1] NA > ``` > > Thanks, > Davis Vaughan > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel