tanh.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. const MAXLOG = 8.8029691931113054295988e+01 // log(2**127)
  72. z := Abs(x)
  73. switch {
  74. case z > 0.5*MAXLOG:
  75. if x < 0 {
  76. return -1
  77. }
  78. return 1
  79. case z >= 0.625:
  80. s := Exp(2 * z)
  81. z = 1 - 2/(s+1)
  82. if x < 0 {
  83. z = -z
  84. }
  85. default:
  86. if x == 0 {
  87. return x
  88. }
  89. s := x * x
  90. z = x + x*s*((tanhP[0]*s+tanhP[1])*s+tanhP[2])/(((s+tanhQ[0])*s+tanhQ[1])*s+tanhQ[2])
  91. }
  92. return z
  93. }