1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
9 // The original C code, the long comment, and the constants
10 // below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c.
11 // The go code is a simplified version of the original C.
13 // Cephes Math Library Release 2.8: June, 2000
14 // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
16 // The readme file at http://netlib.sandia.gov/cephes/ says:
17 // Some software in this archive may be from the book _Methods and
18 // Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
19 // International, 1989) or from the Cephes Mathematical Library, a
20 // commercial product. In either event, it is copyrighted by the author.
21 // What you see here may be used freely but it comes with no support or
24 // The two known misprints in the book are repaired here in the
25 // source listings for the gamma function and the incomplete beta
29 // moshier@na-net.ornl.gov
31 // Complex circular arc sine
35 // Inverse complex sine:
37 // w = -i clog( iz + csqrt( 1 - z ) ).
39 // casin(z) = -i casinh(iz)
44 // arithmetic domain # trials peak rms
45 // DEC -10,+10 10100 2.1e-15 3.4e-16
46 // IEEE -10,+10 30000 2.2e-14 2.7e-15
47 // Larger relative error can be observed for z near zero.
48 // Also tested by csin(casin(z)) = z.
50 // Asin returns the inverse sine of x.
51 func Asin(x complex128
) complex128
{
52 switch re
, im
:= real(x
), imag(x
); {
53 case im
== 0 && math
.Abs(re
) <= 1:
54 return complex(math
.Asin(re
), im
)
55 case re
== 0 && math
.Abs(im
) <= 1:
56 return complex(re
, math
.Asinh(im
))
60 return complex(re
, math
.NaN())
61 case math
.IsInf(re
, 0):
62 return complex(math
.NaN(), re
)
66 case math
.IsInf(im
, 0):
70 case math
.IsInf(re
, 0):
71 return complex(math
.Copysign(math
.Pi
/4, re
), im
)
73 return complex(math
.Copysign(0, re
), im
)
75 case math
.IsInf(re
, 0):
76 return complex(math
.Copysign(math
.Pi
/2, re
), math
.Copysign(re
, im
))
78 ct
:= complex(-imag(x
), real(x
)) // i * x
80 x1
:= complex(1-real(xx
), -imag(xx
)) // 1 - x*x
81 x2
:= Sqrt(x1
) // x2 = sqrt(1 - x*x)
83 return complex(imag(w
), -real(w
)) // -i * w
86 // Asinh returns the inverse hyperbolic sine of x.
87 func Asinh(x complex128
) complex128
{
88 switch re
, im
:= real(x
), imag(x
); {
89 case im
== 0 && math
.Abs(re
) <= 1:
90 return complex(math
.Asinh(re
), im
)
91 case re
== 0 && math
.Abs(im
) <= 1:
92 return complex(re
, math
.Asin(im
))
93 case math
.IsInf(re
, 0):
95 case math
.IsInf(im
, 0):
96 return complex(re
, math
.Copysign(math
.Pi
/4, im
))
100 return complex(re
, math
.Copysign(0.0, im
))
106 case math
.IsInf(im
, 0):
107 return complex(im
, re
)
111 case math
.IsInf(im
, 0):
112 return complex(math
.Copysign(im
, re
), math
.Copysign(math
.Pi
/2, im
))
115 x1
:= complex(1+real(xx
), imag(xx
)) // 1 + x*x
116 return Log(x
+ Sqrt(x1
)) // log(x + sqrt(1 + x*x))
119 // Complex circular arc cosine
123 // w = arccos z = PI/2 - arcsin z.
128 // arithmetic domain # trials peak rms
129 // DEC -10,+10 5200 1.6e-15 2.8e-16
130 // IEEE -10,+10 30000 1.8e-14 2.2e-15
132 // Acos returns the inverse cosine of x.
133 func Acos(x complex128
) complex128
{
135 return complex(math
.Pi
/2-real(w
), -imag(w
))
138 // Acosh returns the inverse hyperbolic cosine of x.
139 func Acosh(x complex128
) complex128
{
141 return complex(0, math
.Copysign(math
.Pi
/2, imag(x
)))
145 return complex(-imag(w
), real(w
)) // i * w
147 return complex(imag(w
), -real(w
)) // -i * w
150 // Complex circular arc tangent
159 // Re w = - arctan(-----------) + k PI
165 // Im w = - log(------------)
169 // Where k is an arbitrary integer.
171 // catan(z) = -i catanh(iz).
176 // arithmetic domain # trials peak rms
177 // DEC -10,+10 5900 1.3e-16 7.8e-18
178 // IEEE -10,+10 30000 2.3e-15 8.5e-17
179 // The check catan( ctan(z) ) = z, with |x| and |y| < PI/2,
180 // had peak relative error 1.5e-16, rms relative error
181 // 2.9e-17. See also clog().
183 // Atan returns the inverse tangent of x.
184 func Atan(x complex128
) complex128
{
185 switch re
, im
:= real(x
), imag(x
); {
187 return complex(math
.Atan(re
), im
)
188 case re
== 0 && math
.Abs(im
) <= 1:
189 return complex(re
, math
.Atanh(im
))
190 case math
.IsInf(im
, 0) || math
.IsInf(re
, 0):
192 return complex(math
.NaN(), math
.Copysign(0, im
))
194 return complex(math
.Copysign(math
.Pi
/2, re
), math
.Copysign(0, im
))
195 case math
.IsNaN(re
) || math
.IsNaN(im
):
198 x2
:= real(x
) * real(x
)
199 a
:= 1 - x2
- imag(x
)*imag(x
)
203 t
:= 0.5 * math
.Atan2(2*real(x
), a
)
213 return complex(w
, 0.25*math
.Log(c
))
216 // Atanh returns the inverse hyperbolic tangent of x.
217 func Atanh(x complex128
) complex128
{
218 z
:= complex(-imag(x
), real(x
)) // z = i * x
220 return complex(imag(z
), -real(z
)) // z = -i * z