|  | // Copyright 2010 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | package cmplx | 
|  |  | 
|  | import "math" | 
|  |  | 
|  | // The original C code, the long comment, and the constants | 
|  | // below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c. | 
|  | // The go code is a simplified version of the original C. | 
|  | // | 
|  | // Cephes Math Library Release 2.8:  June, 2000 | 
|  | // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier | 
|  | // | 
|  | // The readme file at http://netlib.sandia.gov/cephes/ says: | 
|  | //    Some software in this archive may be from the book _Methods and | 
|  | // Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster | 
|  | // International, 1989) or from the Cephes Mathematical Library, a | 
|  | // commercial product. In either event, it is copyrighted by the author. | 
|  | // What you see here may be used freely but it comes with no support or | 
|  | // guarantee. | 
|  | // | 
|  | //   The two known misprints in the book are repaired here in the | 
|  | // source listings for the gamma function and the incomplete beta | 
|  | // integral. | 
|  | // | 
|  | //   Stephen L. Moshier | 
|  | //   moshier@na-net.ornl.gov | 
|  |  | 
|  | // Complex circular sine | 
|  | // | 
|  | // DESCRIPTION: | 
|  | // | 
|  | // If | 
|  | //     z = x + iy, | 
|  | // | 
|  | // then | 
|  | // | 
|  | //     w = sin x  cosh y  +  i cos x sinh y. | 
|  | // | 
|  | // csin(z) = -i csinh(iz). | 
|  | // | 
|  | // ACCURACY: | 
|  | // | 
|  | //                      Relative error: | 
|  | // arithmetic   domain     # trials      peak         rms | 
|  | //    DEC       -10,+10      8400       5.3e-17     1.3e-17 | 
|  | //    IEEE      -10,+10     30000       3.8e-16     1.0e-16 | 
|  | // Also tested by csin(casin(z)) = z. | 
|  |  | 
|  | // Sin returns the sine of x. | 
|  | func Sin(x complex128) complex128 { | 
|  | switch re, im := real(x), imag(x); { | 
|  | case im == 0 && (math.IsInf(re, 0) || math.IsNaN(re)): | 
|  | return complex(math.NaN(), im) | 
|  | case math.IsInf(im, 0): | 
|  | switch { | 
|  | case re == 0: | 
|  | return x | 
|  | case math.IsInf(re, 0) || math.IsNaN(re): | 
|  | return complex(math.NaN(), im) | 
|  | } | 
|  | case re == 0 && math.IsNaN(im): | 
|  | return x | 
|  | } | 
|  | s, c := math.Sincos(real(x)) | 
|  | sh, ch := sinhcosh(imag(x)) | 
|  | return complex(s*ch, c*sh) | 
|  | } | 
|  |  | 
|  | // Complex hyperbolic sine | 
|  | // | 
|  | // DESCRIPTION: | 
|  | // | 
|  | // csinh z = (cexp(z) - cexp(-z))/2 | 
|  | //         = sinh x * cos y  +  i cosh x * sin y . | 
|  | // | 
|  | // ACCURACY: | 
|  | // | 
|  | //                      Relative error: | 
|  | // arithmetic   domain     # trials      peak         rms | 
|  | //    IEEE      -10,+10     30000       3.1e-16     8.2e-17 | 
|  |  | 
|  | // Sinh returns the hyperbolic sine of x. | 
|  | func Sinh(x complex128) complex128 { | 
|  | switch re, im := real(x), imag(x); { | 
|  | case re == 0 && (math.IsInf(im, 0) || math.IsNaN(im)): | 
|  | return complex(re, math.NaN()) | 
|  | case math.IsInf(re, 0): | 
|  | switch { | 
|  | case im == 0: | 
|  | return complex(re, im) | 
|  | case math.IsInf(im, 0) || math.IsNaN(im): | 
|  | return complex(re, math.NaN()) | 
|  | } | 
|  | case im == 0 && math.IsNaN(re): | 
|  | return complex(math.NaN(), im) | 
|  | } | 
|  | s, c := math.Sincos(imag(x)) | 
|  | sh, ch := sinhcosh(real(x)) | 
|  | return complex(c*sh, s*ch) | 
|  | } | 
|  |  | 
|  | // Complex circular cosine | 
|  | // | 
|  | // DESCRIPTION: | 
|  | // | 
|  | // If | 
|  | //     z = x + iy, | 
|  | // | 
|  | // then | 
|  | // | 
|  | //     w = cos x  cosh y  -  i sin x sinh y. | 
|  | // | 
|  | // ACCURACY: | 
|  | // | 
|  | //                      Relative error: | 
|  | // arithmetic   domain     # trials      peak         rms | 
|  | //    DEC       -10,+10      8400       4.5e-17     1.3e-17 | 
|  | //    IEEE      -10,+10     30000       3.8e-16     1.0e-16 | 
|  |  | 
|  | // Cos returns the cosine of x. | 
|  | func Cos(x complex128) complex128 { | 
|  | switch re, im := real(x), imag(x); { | 
|  | case im == 0 && (math.IsInf(re, 0) || math.IsNaN(re)): | 
|  | return complex(math.NaN(), -im*math.Copysign(0, re)) | 
|  | case math.IsInf(im, 0): | 
|  | switch { | 
|  | case re == 0: | 
|  | return complex(math.Inf(1), -re*math.Copysign(0, im)) | 
|  | case math.IsInf(re, 0) || math.IsNaN(re): | 
|  | return complex(math.Inf(1), math.NaN()) | 
|  | } | 
|  | case re == 0 && math.IsNaN(im): | 
|  | return complex(math.NaN(), 0) | 
|  | } | 
|  | s, c := math.Sincos(real(x)) | 
|  | sh, ch := sinhcosh(imag(x)) | 
|  | return complex(c*ch, -s*sh) | 
|  | } | 
|  |  | 
|  | // Complex hyperbolic cosine | 
|  | // | 
|  | // DESCRIPTION: | 
|  | // | 
|  | // ccosh(z) = cosh x  cos y + i sinh x sin y . | 
|  | // | 
|  | // ACCURACY: | 
|  | // | 
|  | //                      Relative error: | 
|  | // arithmetic   domain     # trials      peak         rms | 
|  | //    IEEE      -10,+10     30000       2.9e-16     8.1e-17 | 
|  |  | 
|  | // Cosh returns the hyperbolic cosine of x. | 
|  | func Cosh(x complex128) complex128 { | 
|  | switch re, im := real(x), imag(x); { | 
|  | case re == 0 && (math.IsInf(im, 0) || math.IsNaN(im)): | 
|  | return complex(math.NaN(), re*math.Copysign(0, im)) | 
|  | case math.IsInf(re, 0): | 
|  | switch { | 
|  | case im == 0: | 
|  | return complex(math.Inf(1), im*math.Copysign(0, re)) | 
|  | case math.IsInf(im, 0) || math.IsNaN(im): | 
|  | return complex(math.Inf(1), math.NaN()) | 
|  | } | 
|  | case im == 0 && math.IsNaN(re): | 
|  | return complex(math.NaN(), im) | 
|  | } | 
|  | s, c := math.Sincos(imag(x)) | 
|  | sh, ch := sinhcosh(real(x)) | 
|  | return complex(c*ch, s*sh) | 
|  | } | 
|  |  | 
|  | // calculate sinh and cosh | 
|  | func sinhcosh(x float64) (sh, ch float64) { | 
|  | if math.Abs(x) <= 0.5 { | 
|  | return math.Sinh(x), math.Cosh(x) | 
|  | } | 
|  | e := math.Exp(x) | 
|  | ei := 0.5 / e | 
|  | e *= 0.5 | 
|  | return e - ei, e + ei | 
|  | } |