On 2023-09-22 6:38 am, Martin Maechler wrote:
Mikael Jagan
     on Thu, 21 Sep 2023 00:47:39 -0400 writes:

     > Revisiting this thread from April:

     >      https://stat.ethz.ch/pipermail/r-devel/2023-April/082545.html

     > where the decision (not yet backported) was made for
     > as.complex(NA_real_) to give NA_complex_ instead of
     > complex(r=NA_real_, i=0), to be consistent with
     > help("as.complex") and as.complex(NA) and as.complex(NA_integer_).

     > Was any consideration given to the alternative?
     > That is, to changing as.complex(NA) and as.complex(NA_integer_) to
     > give complex(r=NA_real_, i=0), consistent with
     > as.complex(NA_real_), then amending help("as.complex")
     > accordingly?

Hmm, as, from R-core, mostly I was involved, I admit to say "no",
to my knowledge the (above) alternative wasn't considered.

   > The principle that
   > Im(as.complex(<real=(double|integer|logical)>)) should be zero
   > is quite fundamental, in my view, hence the "new" behaviour
   > seems to really violate the principle of least surprise ...

of course "least surprise"  is somewhat subjective.  Still,
I clearly agree that the above would be one desirable property.

I think that any solution will lead to *some* surprise for some
cases, I think primarily because there are *many* different
values z  for which  is.na(z)  is true,  and in any case
NA_complex_  is only of the many.

I also agree with Mikael that we should reconsider the issue
that was raised by Davis Vaughan here ("on R-devel") last April.

     > Another (but maybe weaker) argument is that
     > double->complex coercions happen more often than
     > logical->complex and integer->complex ones.  Changing the
     > behaviour of the more frequently performed coercion is
     > more likely to affect code "out there".

     > Yet another argument is that one expects

     >      identical(as.complex(NA_real_), NA_real_ + (0+0i))

     > to be TRUE, i.e., that coercing from double to complex is
     > equivalent to adding a complex zero.  The new behaviour
     > makes the above FALSE, since NA_real_ + (0+0i) gives
     > complex(r=NA_real_, i=0).

No!  --- To my own surprise (!) --- in current R-devel the above is TRUE,
and
       NA_real_ + (0+0i)  , the same as
       NA_real_ + 0i      , really gives  complex(r=NA, i=NA) :


Thank you for the correction - indeed, as.complex(NA_real_) and
NA_real_ + (0+0i) are identical in both R-patched and R-devel,
both giving complex(r=NA_real_, i=0) in R-patched and both giving
NA_complex_ in R-devel.  I was hallucating, it seems ...

Using showC() from ?complex

   showC <- function(z) noquote(sprintf("(R = %g, I = %g)", Re(z), Im(z)))

we see (in R-devel) quite consistently

showC(NA_real_ + 0i)
[1] (R = NA, I = NA)
showC(NA       + 0i)  # NA is 'logical'
[1] (R = NA, I = NA)


where as in R 4.3.1 and "R-patched" -- *in*consistently

showC(NA_real_ + 0i)
[1] (R = NA, I = 0)
showC(NA + 0i)
[1] (R = NA, I = NA)


.... and honestly, I do not see *where* (and when) we changed
the underlying code (in arithmetic.c !?)  in R-devel to *also*
produce  NA_complex_  in such complex *arithmetic*


R_binary() in arithmetic.c has always coerced REALSXP->CPLXSXP when
encountering one of each.  Surely then the changes in coerce.c are the
cause and this arithmetic behaviour is just a (bad, IMO) side effect?


     > Having said that, one might also (but more naively) expect

     >     identical(as.complex(as.double(NA_complex_)), NA_complex_)

     > to be TRUE.

as in current R-devel

     > Under my proposal it continues to be FALSE.

as in "R-release"

     > Well, I'd prefer if it gave FALSE with a warning
     > "imaginary parts discarded in coercion", but it seems that
     > as.double(complex(r=a, i=b)) never warns when either of
     > 'a' and 'b' is NA_real_ or NaN, even where "information"
     > {nonzero 'b'} is clearly lost ...

The question of *warning* here is related indeed, but I think
we should try to look at it only *secondary* to your first
proposal.

     > Whatever decision is made about as.complex(NA_real_),
     > maybe these points should be weighed before it becomes part of
     > R-release ...

     > Mikael

Indeed.

Can we please get other opinions / ideas here?


Thank you, Martin, for "reopening".

Mikael

Thank you in advance for your thoughts!
Martin

---

PS:

  Our *print()*ing  of complex NA's ("NA" here meaning NA or NaN)
  is also unsatisfactory, e.g. in the case where all entries of a
  vector are NA in the sense of is.na(.), but their
  Re() and Im() are not all NA:
showC <- function(z) noquote(sprintf("(R = %g, I = %g)", Re(z), Im(z)))
   z <- complex(, c(11, NA, NA), c(NA, 99, NA))
   z
   showC(z)

gives

   > z
   [1] NA NA NA
   > showC(z)
   [1] (R = 11, I = NA) (R = NA, I = 99) (R = NA, I = NA)

but that (printing of complex) *is* another issue,
in which we have the re-opened bugzilla PR#16752
     ==>   https://bugs.r-project.org/show_bug.cgi?id=16752

on which we also worked during the R Sprint in Warwick three
weeks ago, and where I want to commit changes in any case {but
think we should change even a bit more than we got to during the
Sprint}.


______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to