github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/num/hyperdual/hyperdual_hyperbolic.go (about)

     1  // Copyright ©2018 The Gonum 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 hyperdual
     6  
     7  import "math"
     8  
     9  // Sinh returns the hyperbolic sine of d.
    10  //
    11  // Special cases are:
    12  //	Sinh(±0) = (±0+Nϵ₁+Nϵ₂±0ϵ₁ϵ₂)
    13  //	Sinh(±Inf) = ±Inf
    14  //	Sinh(NaN) = NaN
    15  func Sinh(d Number) Number {
    16  	if d.Real == 0 {
    17  		return Number{
    18  			Real:    d.Real,
    19  			E1mag:   d.E1mag,
    20  			E2mag:   d.E1mag,
    21  			E1E2mag: d.Real,
    22  		}
    23  	}
    24  	if math.IsInf(d.Real, 0) {
    25  		return Number{
    26  			Real:    d.Real,
    27  			E1mag:   math.Inf(1),
    28  			E2mag:   math.Inf(1),
    29  			E1E2mag: d.Real,
    30  		}
    31  	}
    32  	fn := math.Sinh(d.Real)
    33  	deriv := math.Cosh(d.Real)
    34  	return Number{
    35  		Real:    fn,
    36  		E1mag:   deriv * d.E1mag,
    37  		E2mag:   deriv * d.E2mag,
    38  		E1E2mag: deriv*d.E1E2mag + fn*d.E1mag*d.E2mag,
    39  	}
    40  }
    41  
    42  // Cosh returns the hyperbolic cosine of d.
    43  //
    44  // Special cases are:
    45  //	Cosh(±0) = 1
    46  //	Cosh(±Inf) = +Inf
    47  //	Cosh(NaN) = NaN
    48  func Cosh(d Number) Number {
    49  	if math.IsInf(d.Real, 0) {
    50  		return Number{
    51  			Real:    math.Inf(1),
    52  			E1mag:   d.Real,
    53  			E2mag:   d.Real,
    54  			E1E2mag: math.Inf(1),
    55  		}
    56  	}
    57  	fn := math.Cosh(d.Real)
    58  	deriv := math.Sinh(d.Real)
    59  	return Number{
    60  		Real:    fn,
    61  		E1mag:   deriv * d.E1mag,
    62  		E2mag:   deriv * d.E2mag,
    63  		E1E2mag: deriv*d.E1E2mag + fn*d.E1mag*d.E2mag,
    64  	}
    65  }
    66  
    67  // Tanh returns the hyperbolic tangent of d.
    68  //
    69  // Special cases are:
    70  //	Tanh(±0) = (±0+Nϵ₁+Nϵ₂∓0ϵ₁ϵ₂)
    71  //	Tanh(±Inf) = (±1+0ϵ₁+0ϵ₂∓0ϵ₁ϵ₂)
    72  //	Tanh(NaN) = NaN
    73  func Tanh(d Number) Number {
    74  	switch d.Real {
    75  	case 0:
    76  		return Number{
    77  			Real:    d.Real,
    78  			E1mag:   d.E1mag,
    79  			E2mag:   d.E2mag,
    80  			E1E2mag: -d.Real,
    81  		}
    82  	case math.Inf(1):
    83  		return Number{
    84  			Real:    1,
    85  			E1mag:   0,
    86  			E2mag:   0,
    87  			E1E2mag: negZero,
    88  		}
    89  	case math.Inf(-1):
    90  		return Number{
    91  			Real:    -1,
    92  			E1mag:   0,
    93  			E2mag:   0,
    94  			E1E2mag: 0,
    95  		}
    96  	}
    97  	fn := math.Tanh(d.Real)
    98  	deriv := 1 - fn*fn
    99  	return Number{
   100  		Real:    fn,
   101  		E1mag:   deriv * d.E1mag,
   102  		E2mag:   deriv * d.E2mag,
   103  		E1E2mag: deriv*d.E1E2mag - d.E1mag*d.E2mag*(2*fn*deriv),
   104  	}
   105  }
   106  
   107  // Asinh returns the inverse hyperbolic sine of d.
   108  //
   109  // Special cases are:
   110  //	Asinh(±0) = (±0+Nϵ₁+Nϵ₂∓0ϵ₁ϵ₂)
   111  //	Asinh(±Inf) = ±Inf
   112  //	Asinh(NaN) = NaN
   113  func Asinh(d Number) Number {
   114  	if d.Real == 0 {
   115  		return Number{
   116  			Real:    d.Real,
   117  			E1mag:   d.E1mag,
   118  			E2mag:   d.E2mag,
   119  			E1E2mag: -d.Real,
   120  		}
   121  	}
   122  	fn := math.Asinh(d.Real)
   123  	deriv1 := d.Real*d.Real + 1
   124  	deriv := 1 / math.Sqrt(deriv1)
   125  	return Number{
   126  		Real:    fn,
   127  		E1mag:   deriv * d.E1mag,
   128  		E2mag:   deriv * d.E2mag,
   129  		E1E2mag: deriv*d.E1E2mag + d.E1mag*d.E2mag*(-d.Real*(deriv/deriv1)),
   130  	}
   131  }
   132  
   133  // Acosh returns the inverse hyperbolic cosine of d.
   134  //
   135  // Special cases are:
   136  //	Acosh(+Inf) = +Inf
   137  //	Acosh(1) = (0+Infϵ₁+Infϵ₂-Infϵ₁ϵ₂)
   138  //	Acosh(x) = NaN if x < 1
   139  //	Acosh(NaN) = NaN
   140  func Acosh(d Number) Number {
   141  	if d.Real <= 1 {
   142  		if d.Real == 1 {
   143  			return Number{
   144  				Real:    0,
   145  				E1mag:   math.Inf(1),
   146  				E2mag:   math.Inf(1),
   147  				E1E2mag: math.Inf(-1),
   148  			}
   149  		}
   150  		return Number{
   151  			Real:    math.NaN(),
   152  			E1mag:   math.NaN(),
   153  			E2mag:   math.NaN(),
   154  			E1E2mag: math.NaN(),
   155  		}
   156  	}
   157  	fn := math.Acosh(d.Real)
   158  	deriv1 := d.Real*d.Real - 1
   159  	deriv := 1 / math.Sqrt(deriv1)
   160  	return Number{
   161  		Real:    fn,
   162  		E1mag:   deriv * d.E1mag,
   163  		E2mag:   deriv * d.E2mag,
   164  		E1E2mag: deriv*d.E1E2mag + d.E1mag*d.E2mag*(-d.Real*(deriv/deriv1)),
   165  	}
   166  }
   167  
   168  // Atanh returns the inverse hyperbolic tangent of d.
   169  //
   170  // Special cases are:
   171  //	Atanh(1) = +Inf
   172  //	Atanh(±0) = (±0+Nϵ₁+Nϵ₂±0ϵ₁ϵ₂)
   173  //	Atanh(-1) = -Inf
   174  //	Atanh(x) = NaN if x < -1 or x > 1
   175  //	Atanh(NaN) = NaN
   176  func Atanh(d Number) Number {
   177  	if d.Real == 0 {
   178  		return Number{
   179  			Real:    d.Real,
   180  			E1mag:   d.E1mag,
   181  			E2mag:   d.E2mag,
   182  			E1E2mag: d.Real,
   183  		}
   184  	}
   185  	if math.Abs(d.Real) == 1 {
   186  		return Number{
   187  			Real:    math.Inf(int(d.Real)),
   188  			E1mag:   math.NaN(),
   189  			E2mag:   math.NaN(),
   190  			E1E2mag: math.Inf(int(d.Real)),
   191  		}
   192  	}
   193  	fn := math.Atanh(d.Real)
   194  	deriv1 := 1 - d.Real*d.Real
   195  	deriv := 1 / deriv1
   196  	return Number{
   197  		Real:    fn,
   198  		E1mag:   deriv * d.E1mag,
   199  		E2mag:   deriv * d.E2mag,
   200  		E1E2mag: deriv*d.E1E2mag + d.E1mag*d.E2mag*(2*d.Real/(deriv1*deriv1)),
   201  	}
   202  }