Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complex atanh is inaccurate near singularities #55266

Closed
jwmerrill opened this issue Jul 26, 2024 · 0 comments · Fixed by #55268
Closed

Complex atanh is inaccurate near singularities #55266

jwmerrill opened this issue Jul 26, 2024 · 0 comments · Fixed by #55268
Labels
domain:complex Complex numbers domain:maths Mathematical functions kind:bug Indicates an unexpected problem or unintended behavior

Comments

@jwmerrill
Copy link

real(atanh(1+y*im)) should be asymptotic to log(2/abs(y))/2 for real y as y approches 0.

For example, this suggests that real(atanh(1+1e-200im)) should evaluate to log(2/1e-200)/2=230.60508288968455, but it currently evaluates to 177.09910463306602, which has no correct digits.

This appears to be caused by a small positive perturbation, ρ, that is added to the imaginary part of the input in the atanh computation

julia/base/complex.jl

Lines 1040 to 1042 in 1dee000

Ω = prevfloat(typemax(Tf))
θ = sqrt(Ω)/4
ρ = 1/θ
...

julia/base/complex.jl

Lines 1067 to 1068 in 1dee000

ym = ay+ρ
ξ = log(sqrt(sqrt(4+y*y))/sqrt(ym))

so that real(atanh(1+1e-200im)) in fact computes log(2/ρ)=177.09910463306602.

This perturbation is suggested by Kahan 86, but as far as I can tell, it is not necessary in either of the places it is used, and in fact harms rather than helps accuracy when the real part of the input is 1. It may be there to avoid division by 0 in atanh(1.0+0.0im), but the Julia implementation already handles this case with an explicit branch.

For comparison, cpython computes the correct answer:

> python3
Python 3.12.3 (main, Apr  9 2024, 08:09:14) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import cmath
>>> cmath.atanh(1+1e-200j)
(230.60508288968455+0.7853981633974483j)

Version Info:

julia> versioninfo()
Julia Version 1.10.4
Commit 48d4fd48430 (2024-06-04 10:41 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: macOS (arm64-apple-darwin22.4.0)
  CPU: 12 × Apple M2 Pro
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, apple-m1)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)
@giordano giordano added kind:bug Indicates an unexpected problem or unintended behavior domain:maths Mathematical functions domain:complex Complex numbers labels Jul 26, 2024
KristofferC pushed a commit that referenced this issue Aug 14, 2024
fixes #55266, and use `inv(z)`
rather than `1/z` and use `muladd` in a couple places.

---------

Co-authored-by: Mosè Giordano <giordano@users.noreply.github.com>
(cherry picked from commit b7aa5e3)
lazarusA pushed a commit to lazarusA/julia that referenced this issue Aug 17, 2024
…#55268)

fixes JuliaLang#55266, and use `inv(z)`
rather than `1/z` and use `muladd` in a couple places.

---------

Co-authored-by: Mosè Giordano <giordano@users.noreply.github.com>
KristofferC pushed a commit that referenced this issue Sep 12, 2024
fixes #55266, and use `inv(z)`
rather than `1/z` and use `muladd` in a couple places.

---------

Co-authored-by: Mosè Giordano <giordano@users.noreply.github.com>
(cherry picked from commit b7aa5e3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:complex Complex numbers domain:maths Mathematical functions kind:bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants