Mikael Jagan
2023-Nov-08 16:13 UTC
[Rd] c(NA, 0+1i) not the same as c(as.complex(NA), 0+1i)?
So, to summarize, the open questions are: (1) Should as.complex(NA_character_) give complex(r=NA_real_, i=0) instead of NA_complex_? (2) Should the first argument in c(NA, x) and c(NA_integer_, x), where typeof(x) == "complex", be promoted to complex(r=NA_real_, i=0) instead of NA_complex_? My opinions: (1) No. The imaginary part of the result of parsing the strings "<b>i", "<a>+<b>i", and "<a>-<b>i" can be nonzero. Consider, e.g., Im(eval(str2lang("0+1i"))) and Im(as.complex("0+1i")). If NA_character_ means "a string with unknown content", then we should not assume that the string is parsed as a real number. (2) Yes. I'd very much like to preserve the identity of c(Im(NA), Im(x)) and Im(c(NA, x)) for atomic (excluding raw, character) vectors 'x'. And while typing this response I noticed the following in current R-devel and current R-patched: > 0+1i [1] 0+1i > 1i [1] 0+1i > as.complex("0+1i") [1] 0+1i > as.complex("1i") [1] NA Warning message: NAs introduced by coercion That warning seems wrong to me ... Mikael On 2023-11-07 6:00 am, r-devel-request at r-project.org wrote:>>>>>> Michael Chirico >>>>>> on Mon, 6 Nov 2023 23:18:40 -0800 writes: > > Thanks Martin. My hang-up was not on what the outcome of as.complex(NA) > > should be, but rather, how I should read code like c(x, y) generally. Till > > now, I have thought of it like 'c(x, y)' is c(as(x, typeof(y)), y)` when > > "type(y) > type(x)". Basically in my mind, "coercion" in R <-> > > as.<newtype>(.) (or coerceVector() in C). > > > So I tracked down the source (which admittedly has been this way for much > > longer than the present discussion) to see what exactly c() is doing in > > this case: > > >https://github.com/r-devel/r-svn/blob/71e7480b07767f3b7d5c45a4247959aa4d83d910/src/main/bind.c#L418-L425 > > > And indeed! It's not "coercion" in the sense I just described... there's a > > branch for the 'x == NA_LOGICAL' case to_convert_ to NA_complex_. > > Yes; "of course" ... still, I did not answer your main question, > as you did ask +/- if c() should not get an adjustment to the > new as.complex(<numeric-alike>) |--> (Re = NA, Im = 0) > behavior. > > And that is still a valid open question. ... contrary to what I > wrote yesterday; sorry for that "answering a different > question". > > Martin > > > > On Mon, Nov 6, 2023 at 3:08?AM Martin Maechler<maechler at stat.math.ethz.ch> > > wrote: > > >> >>>>> Michael Chirico > >> >>>>> on Sun, 5 Nov 2023 09:41:42 -0800 writes: > >> > >> > This is another follow-up to the thread from September > >> > "Recent changes to as.complex(NA_real_)". > >> > >> > A test in data.table was broken by the changes for NA > >> > coercion to complex; the breakage essentially comes from > >> > >> > c(NA, 0+1i) > >> > # vs > >> > c(as.complex(NA), 0+1i) > >> > >> > The former is the output we tested against; the latter is > >> essentially (via > >> > coerceVector() in C) what's generated by our data.table::shift() > >> > >> > However, these are now (r85472) different: > >> > >> > Im(c(NA, 0+1i)) > >> > # [1] NA 1 > >> > Im(c(as.complex(NA), 0+1i)) > >> > # [1] 0 1 > >> > >> > >> > The former matches the behavior of directly using NA_complex_: > >> > >> > Im(c(NA_complex_, 0+1i)) > >> > # [1] NA 1 > >> > >> > On R4.3.2, they both match the NA_complex_ behavior: > >> > Im(c(NA, 0+1i)) > >> > # [1] NA 1 > >> > Im(c(as.complex(NA), 0+1i)) > >> > # [1] NA 1 > >> > >> > Is this intended behavior, does something need to be updated for c() > >> as > >> > well? > >> > >> > Certainly it's messing with my understanding of how c() behaves, > >> e.g. in ?c > >> > >> >> All arguments are coerced to a common type which is the type of the > >> > returned value > >> > >> I think you have confused yourself, and everything behaves as expected: > >> > >> As we now have (in R-devel, since {r85233 | maechler | 2023-09-29 }) > >> > >> ? ?as.complex(x)? now returns ?complex(real=x, imaginary=0)? > >> for_all_ numerical and logical ?x?, notably also for ?NA? > >> or ?NA_integer_?. > >> > >> ==> as.complex(NA) is indeed complex(real = NA, imaginary = 0) > >> > >> And now, in your > >> > >> c(as.complex(NA), 0+1i) > >> > >> you are calling c() on two complex numbers, i.e., there is*no* coercion > >> (and c(.) is rather "trivial"), and the same is true for > >> > >> c(NA_complex_, 0+1i) > >> > >> > >> However, in 85233, I had only modified & added examples to ?as.complex, > >> and now have added more (corresponding to the above NEWS entry); > -> svn rev 85475 > >> > >> ............. > >> > >> The underlying "dilemma" that nobody can help us with is that > >> "almost infinitely" many different complex numbers z fulfill > >> is.na(z) |--> TRUE > >> and only one of them is NA_complex_ and that may be unintuitive. > >> > >> OTOH, we already have for the doubles that there are at least two > >> different x fulfulling is.na(x), namely NaN and NA > >> and from C's point of view there are even considerably more > >> different NaN's .. but now I'm definitely digressing. > >> > >> Martin > >>
Martin Maechler
2023-Nov-09 08:13 UTC
[Rd] c(NA, 0+1i) not the same as c(as.complex(NA), 0+1i)?
>>>>> Mikael Jagan >>>>> on Wed, 8 Nov 2023 11:13:18 -0500 writes:> So, to summarize, the open questions are: > (1) Should as.complex(NA_character_) give complex(r=NA_real_, i=0) > instead of NA_complex_? > (2) Should the first argument in c(NA, x) and c(NA_integer_, x), > where typeof(x) == "complex", be promoted to complex(r=NA_real_, i=0) > instead of NA_complex_? > My opinions: > (1) No. The imaginary part of the result of parsing the strings "<b>i", > "<a>+<b>i", and "<a>-<b>i" can be nonzero. > Consider, e.g., Im(eval(str2lang("0+1i"))) and Im(as.complex("0+1i")). > If NA_character_ means "a string with unknown content", then we should > not assume that the string is parsed as a real number. > (2) Yes. I'd very much like to preserve the identity of c(Im(NA), Im(x)) > and Im(c(NA, x)) for atomic (excluding raw, character) vectors 'x'. > And while typing this response I noticed the following in current R-devel and > current R-patched: >> 0+1i > [1] 0+1i >> 1i > [1] 0+1i >> as.complex("0+1i") > [1] 0+1i >> as.complex("1i") > [1] NA > Warning message: > NAs introduced by coercion > That warning seems wrong to me ... Well, actually, as we now have had the parser accept 1i or 7i, 3.14i etc I think that it's not the *warning* that is wrong, but rather the *result* : Why should as.complex("1i") be different from one of these?> 1i[1] 0+1i> str2lang("1i")[1] 0+1i> scan(textConnection("1i"), complex())Read 1 item [1] 0+1i>> Mikael > On 2023-11-07 6:00 am, r-devel-request at r-project.org wrote: >>>>>>> Michael Chirico >>>>>>> on Mon, 6 Nov 2023 23:18:40 -0800 writes: >> > Thanks Martin. My hang-up was not on what the outcome of as.complex(NA) >> > should be, but rather, how I should read code like c(x, y) generally. Till >> > now, I have thought of it like 'c(x, y)' is c(as(x, typeof(y)), y)` when >> > "type(y) > type(x)". Basically in my mind, "coercion" in R <-> >> > as.<newtype>(.) (or coerceVector() in C). >> >> > So I tracked down the source (which admittedly has been this way for much >> > longer than the present discussion) to see what exactly c() is doing in >> > this case: >> >> >https://github.com/r-devel/r-svn/blob/71e7480b07767f3b7d5c45a4247959aa4d83d910/src/main/bind.c#L418-L425 >> >> > And indeed! It's not "coercion" in the sense I just described... there's a >> > branch for the 'x == NA_LOGICAL' case to_convert_ to NA_complex_. >> >> Yes; "of course" ... still, I did not answer your main question, >> as you did ask +/- if c() should not get an adjustment to the >> new as.complex(<numeric-alike>) |--> (Re = NA, Im = 0) >> behavior. >> >> And that is still a valid open question. ... contrary to what I >> wrote yesterday; sorry for that "answering a different >> question". >> >> Martin >> >> >> > On Mon, Nov 6, 2023 at 3:08?AM Martin Maechler<maechler at stat.math.ethz.ch> >> > wrote: >> >> >> >>>>> Michael Chirico >> >> >>>>> on Sun, 5 Nov 2023 09:41:42 -0800 writes: >> >> >> >> > This is another follow-up to the thread from September >> >> > "Recent changes to as.complex(NA_real_)". >> >> >> >> > A test in data.table was broken by the changes for NA >> >> > coercion to complex; the breakage essentially comes from >> >> >> >> > c(NA, 0+1i) >> >> > # vs >> >> > c(as.complex(NA), 0+1i) >> >> >> >> > The former is the output we tested against; the latter is >> >> essentially (via >> >> > coerceVector() in C) what's generated by our data.table::shift() >> >> >> >> > However, these are now (r85472) different: >> >> >> >> > Im(c(NA, 0+1i)) >> >> > # [1] NA 1 >> >> > Im(c(as.complex(NA), 0+1i)) >> >> > # [1] 0 1 >> >> >> >> >> >> > The former matches the behavior of directly using NA_complex_: >> >> >> >> > Im(c(NA_complex_, 0+1i)) >> >> > # [1] NA 1 >> >> >> >> > On R4.3.2, they both match the NA_complex_ behavior: >> >> > Im(c(NA, 0+1i)) >> >> > # [1] NA 1 >> >> > Im(c(as.complex(NA), 0+1i)) >> >> > # [1] NA 1 >> >> >> >> > Is this intended behavior, does something need to be updated for c() >> >> as >> >> > well? >> >> >> >> > Certainly it's messing with my understanding of how c() behaves, >> >> e.g. in ?c >> >> >> >> >> All arguments are coerced to a common type which is the type of the >> >> > returned value >> >> >> >> I think you have confused yourself, and everything behaves as expected: >> >> >> >> As we now have (in R-devel, since {r85233 | maechler | 2023-09-29 }) >> >> >> >> ? ?as.complex(x)? now returns ?complex(real=x, imaginary=0)? >> >> for_all_ numerical and logical ?x?, notably also for ?NA? >> >> or ?NA_integer_?. >> >> >> >> ==> as.complex(NA) is indeed complex(real = NA, imaginary = 0) >> >> >> >> And now, in your >> >> >> >> c(as.complex(NA), 0+1i) >> >> >> >> you are calling c() on two complex numbers, i.e., there is*no* coercion >> >> (and c(.) is rather "trivial"), and the same is true for >> >> >> >> c(NA_complex_, 0+1i) >> >> >> >> >> >> However, in 85233, I had only modified & added examples to ?as.complex, >> >> and now have added more (corresponding to the above NEWS entry); -> svn rev 85475 >> >> >> >> ............. >> >> >> >> The underlying "dilemma" that nobody can help us with is that >> >> "almost infinitely" many different complex numbers z fulfill >> >> is.na(z) |--> TRUE >> >> and only one of them is NA_complex_ and that may be unintuitive. >> >> >> >> OTOH, we already have for the doubles that there are at least two >> >> different x fulfulling is.na(x), namely NaN and NA >> >> and from C's point of view there are even considerably more >> >> different NaN's .. but now I'm definitely digressing. >> >> >> >> Martin >> >>
Possibly Parallel Threads
- c(NA, 0+1i) not the same as c(as.complex(NA), 0+1i)?
- c(NA, 0+1i) not the same as c(as.complex(NA), 0+1i)?
- c(NA, 0+1i) not the same as c(as.complex(NA), 0+1i)?
- c(NA, 0+1i) not the same as c(as.complex(NA), 0+1i)?
- c(NA, 0+1i) not the same as c(as.complex(NA), 0+1i)?