Source file src/math/tanh.go
1 // Copyright 2009 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. 4 5 package math 6 7 // The original C code, the long comment, and the constants 8 // below were from http://netlib.sandia.gov/cephes/cmath/sin.c, 9 // available from http://www.netlib.org/cephes/cmath.tgz. 10 // The go code is a simplified version of the original C. 11 // tanh.c 12 // 13 // Hyperbolic tangent 14 // 15 // SYNOPSIS: 16 // 17 // double x, y, tanh(); 18 // 19 // y = tanh( x ); 20 // 21 // DESCRIPTION: 22 // 23 // Returns hyperbolic tangent of argument in the range MINLOG to MAXLOG. 24 // MAXLOG = 8.8029691931113054295988e+01 = log(2**127) 25 // MINLOG = -8.872283911167299960540e+01 = log(2**-128) 26 // 27 // A rational function is used for |x| < 0.625. The form 28 // x + x**3 P(x)/Q(x) of Cody & Waite is employed. 29 // Otherwise, 30 // tanh(x) = sinh(x)/cosh(x) = 1 - 2/(exp(2x) + 1). 31 // 32 // ACCURACY: 33 // 34 // Relative error: 35 // arithmetic domain # trials peak rms 36 // IEEE -2,2 30000 2.5e-16 5.8e-17 37 // 38 // Cephes Math Library Release 2.8: June, 2000 39 // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier 40 // 41 // The readme file at http://netlib.sandia.gov/cephes/ says: 42 // Some software in this archive may be from the book _Methods and 43 // Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster 44 // International, 1989) or from the Cephes Mathematical Library, a 45 // commercial product. In either event, it is copyrighted by the author. 46 // What you see here may be used freely but it comes with no support or 47 // guarantee. 48 // 49 // The two known misprints in the book are repaired here in the 50 // source listings for the gamma function and the incomplete beta 51 // integral. 52 // 53 // Stephen L. Moshier 54 // moshier@na-net.ornl.gov 55 // 56 57 var tanhP = [...]float64{ 58 -9.64399179425052238628e-1, 59 -9.92877231001918586564e1, 60 -1.61468768441708447952e3, 61 } 62 var tanhQ = [...]float64{ 63 1.12811678491632931402e2, 64 2.23548839060100448583e3, 65 4.84406305325125486048e3, 66 } 67 68 // Tanh returns the hyperbolic tangent of x. 69 // 70 // Special cases are: 71 // 72 // Tanh(±0) = ±0 73 // Tanh(±Inf) = ±1 74 // Tanh(NaN) = NaN 75 func Tanh(x float64) float64 { 76 if haveArchTanh { 77 return archTanh(x) 78 } 79 return tanh(x) 80 } 81 82 func tanh(x float64) float64 { 83 const MAXLOG = 8.8029691931113054295988e+01 // log(2**127) 84 z := Abs(x) 85 switch { 86 case z > 0.5*MAXLOG: 87 if x < 0 { 88 return -1 89 } 90 return 1 91 case z >= 0.625: 92 s := Exp(2 * z) 93 z = 1 - 2/(s+1) 94 if x < 0 { 95 z = -z 96 } 97 default: 98 if x == 0 { 99 return x 100 } 101 s := x * x 102 z = x + x*s*((tanhP[0]*s+tanhP[1])*s+tanhP[2])/(((s+tanhQ[0])*s+tanhQ[1])*s+tanhQ[2]) 103 } 104 return z 105 } 106