# 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
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
```

View as plain text