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 5package hyperdual 6 7import "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 15func 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 48func 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 73func 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 113func 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 140func 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 176func 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} 203