Ticket #828 (closed defect: fixed)

Opened 4 years ago

Last modified 4 years ago

atan branch cuts wrong?

Reported by: rtoy Owned by: rme
Priority: normal Milestone:
Component: ANSI CL Compliance Version: trunk
Keywords: Cc:

Description (last modified by rme) (diff)

In ccl 1.6 (32-bit), we get

1> (atan #c(-1d-20 2d0))
#C(-1.5707963267948966D0 0.5493061443340549D0)

This is right, I think. However,

2> (atan #c(-0d0 2d0))
#C(1.5707963267948966D0 0.5493061443340549D0)

The spec says that on the imaginary axis above i, atan is continuous on Quadrant II. Since float-sign -0d0) -> -1d0, both answers should have the same sign for the realpart.

Change History

comment:1 Changed 4 years ago by gb

  • Status changed from new to closed
  • Resolution set to duplicate

duplicate o ticket:829

comment:2 Changed 4 years ago by rtoy

  • Status changed from closed to reopened
  • Resolution duplicate deleted

This ticket is about atan (inverse tangent). Ticket 829 is about atanh (inverse hyperbolic tangent).

Maybe atanh is implemented using atan (or vice versa) so these really are duplicates? If so, my apologies.

comment:3 Changed 4 years ago by rme

  • Owner set to rme
  • Status changed from reopened to new

comment:4 Changed 4 years ago by rme

Presumably, you meant to write

? (atan #c(-1d20 2d0))
#C(-1.5707963267948966D0 -0.0D0)

Your point about the signs of the real parts still stands, of course.

comment:5 Changed 4 years ago by rtoy

Oops. The argument is supposed to be #c(-1d-20 2d0) so that it is very close to #c(-0d0 2d0) so we can invoke "continuity" to say that the answers need to be close. I should to more cutting-and-pasting instead of retyping for bug reports.

comment:6 Changed 4 years ago by rme

  • Description modified (diff)

comment:7 Changed 4 years ago by rme

  • Status changed from new to closed
  • Resolution set to fixed

(In [14669]) In ATAN of a complex argument, compute the value in terms of the formula for ATANH, that is, use the formula:

atan(z) = atanh(iz)/i = -i atanh(iz).

Fixes ticket:828, and with any luck, won't screw up anything else.

comment:8 Changed 4 years ago by rme

It's not immediately clear to me why the formula we had been using doesn't get the branch cuts right; it's exactly the one listed in the spec.

comment:9 Changed 4 years ago by rtoy

I believe the difference is how you compute i*z = i*(x+i*y) = i*x - y. This is what your fix uses. But originally, the code did i*z = (0 + i) * (x + i*y) = -y + i*(+0*y + x). For the case z = #c(-0d0 2d0), the former gives #c(-2d0 -0d0). For the latter, we get #c(-2d0 0d0), erroneously choosing the wrong branch. I suspect that if you used the original code with the more careful computation of i*z, atan would have produced the correct result.

comment:10 Changed 4 years ago by rme

(In [14670]) In ATAN of a complex argument y, the main thing is to carefully compute iy (see ticket:828). Having done that, we can use the normal formula for ATAN and get correct results.

Note: See TracTickets for help on using tickets.