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 }