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 // Tanh(±0) = ±0 72 // Tanh(±Inf) = ±1 73 // Tanh(NaN) = NaN 74 func Tanh(x float64) float64 { 75 if haveArchTanh { 76 return archTanh(x) 77 } 78 return tanh(x) 79 } 80 81 func tanh(x float64) float64 { 82 const MAXLOG = 8.8029691931113054295988e+01 // log(2**127) 83 z := Abs(x) 84 switch { 85 case z > 0.5*MAXLOG: 86 if x < 0 { 87 return -1 88 } 89 return 1 90 case z >= 0.625: 91 s := Exp(2 * z) 92 z = 1 - 2/(s+1) 93 if x < 0 { 94 z = -z 95 } 96 default: 97 if x == 0 { 98 return x 99 } 100 s := x * x 101 z = x + x*s*((tanhP[0]*s+tanhP[1])*s+tanhP[2])/(((s+tanhQ[0])*s+tanhQ[1])*s+tanhQ[2]) 102 } 103 return z 104 } 105