[R] BUG: atan(1i) / 5 = NaN+Infi ?

Martin Maechler m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Fri Sep 6 13:10:13 CEST 2024


>>>>> Duncan Murdoch 
>>>>>     on Fri, 6 Sep 2024 05:54:23 -0400 writes:

    > On 2024-09-06 12:44 a.m., Richard O'Keefe wrote:
    >> I expect that atan(1i) = (0 + infinity i) and that atan(1i)/5 = (0 +
    >> infinity i)/5 = (0 + infinity i).
    >> Here's what I get in C:
    >> (0,1) = (0, 1)
    >> atan((0,1)) = (0, inf)
    >> atan((0,1))/5 = (0, inf)
    >> 
    >> Note the difference between I*infinity = (0,1)*infinity =
    >> (0*infinity,1*infinity) = (NaN,infinity)
    >> and (0,infinity)/5 = (0/5,infinity/5) = (0,infinity).
    >> The former involves multiplying 0 by infinity, which yields NaN.
    >> The latter does not.
    >> 
    >>> complex(1,0,Inf)*2
    >> [1] NaN+Infi
    >> There is no good reason for this. 0*2 is 0, not NaN.
    >> 
    >> In IEEE arithmetic, multiplying or dividing a complex number by a real number is
    >> NOT the same as multiplying or dividing by the complex version of that
    >> real number.
    >> (0,Inf) *  2    = (0*2, Inf*2)               = (0, Inf).
    >> (0,Inf) * (2,0) = (0*2 - Inf*0, 0*0 + Inf*2) = (NaN, Inf).
    >> 
    >> There really truly is a bug here, and it is treating R*Z, Z*R, and Z/R
    >> as if they were
    >> the same as W*Z, Z*W, and Z/W where W = complex(1,R,0).

    > I would only disagree with the statement above by distinguishing between 
    > a "bug" (where R is not behaving as documented) and a "design flaw" 
    > (where it is behaving as documented, but the behaviour is undesirable).

    > I think this is a design flaw rather than a bug.

    > The distinction is important:  if it is a design flaw, then a change is 
    > harder, because users who rely on the behaviour deserve more help in 
    > adapting than those who rely on a bug.  Bugs should be fixed.  Design 
    > flaws need thinking about, and sometimes shouldn't be fixed.

    > On the other hand, I was unable to find documentation saying that the 
    > current behaviour is intended, so I could be wrong.

    > Duncan Murdoch

I agree 100% (with Duncan).

I've now also carefully read  ?Arithmetic  and  ?complex
and could not find docu explicitly documenting the current
behavior, in the context of complex arithmetic not even
mentioning the "overall principle" used very often in R to

	1. coerce to common type
	2. then compute with that "pure type"

In ?complex, we have the (last sentence of the first) 'Note:'

 --->  For ‘+’ and ‘-’, R's own handling works strictly “coordinate wise”.

now, implicitly that implies that {+, -} are the only
ops/functions where coordinate-wise arithmetic is used/applied
and hence could it be _stretched_ to say that for
 * and /  coordinate wise does not always apply,
in our case not even when it would make sense, i.e., when one of
the two operands is real (in the '/' case, it must be the 2nd operand)
and hence 2d-vector space arithmetic  <scalar  *  vector>
should be applied naturally.

It is still true that this must be considered a design flaw
rather than a bug, even if only because the above  "overall
principle"  is predominant and tought very often when teaching R.

In this case, I do think we should look into the consequences of
indeed distinguishing
  <double> * <complex> 
  <complex> * <double>  and
  <complex> / <double>
from their respective current {1. coerce to complex, 2. use complex arith}
arithmetic.

Hence, thanks a lot for bringing this up, to Leo Mada and
notably to Richard O'Keefe  for providing context, notably wrt
to C standards  {which I'd want to follow mostly, but not
always ... but I'm not opening that now}...

Martin



More information about the R-help mailing list