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