tanh.go 2.7 KB

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