1
2
3
4
5 package cmplx
6
7 import "math"
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 func Sin(x complex128) complex128 {
54 switch re, im := real(x), imag(x); {
55 case im == 0 && (math.IsInf(re, 0) || math.IsNaN(re)):
56 return complex(math.NaN(), im)
57 case math.IsInf(im, 0):
58 switch {
59 case re == 0:
60 return x
61 case math.IsInf(re, 0) || math.IsNaN(re):
62 return complex(math.NaN(), im)
63 }
64 case re == 0 && math.IsNaN(im):
65 return x
66 }
67 s, c := math.Sincos(real(x))
68 sh, ch := sinhcosh(imag(x))
69 return complex(s*ch, c*sh)
70 }
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 func Sinh(x complex128) complex128 {
87 switch re, im := real(x), imag(x); {
88 case re == 0 && (math.IsInf(im, 0) || math.IsNaN(im)):
89 return complex(re, math.NaN())
90 case math.IsInf(re, 0):
91 switch {
92 case im == 0:
93 return complex(re, im)
94 case math.IsInf(im, 0) || math.IsNaN(im):
95 return complex(re, math.NaN())
96 }
97 case im == 0 && math.IsNaN(re):
98 return complex(math.NaN(), im)
99 }
100 s, c := math.Sincos(imag(x))
101 sh, ch := sinhcosh(real(x))
102 return complex(c*sh, s*ch)
103 }
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 func Cos(x complex128) complex128 {
125 switch re, im := real(x), imag(x); {
126 case im == 0 && (math.IsInf(re, 0) || math.IsNaN(re)):
127 return complex(math.NaN(), -im*math.Copysign(0, re))
128 case math.IsInf(im, 0):
129 switch {
130 case re == 0:
131 return complex(math.Inf(1), -re*math.Copysign(0, im))
132 case math.IsInf(re, 0) || math.IsNaN(re):
133 return complex(math.Inf(1), math.NaN())
134 }
135 case re == 0 && math.IsNaN(im):
136 return complex(math.NaN(), 0)
137 }
138 s, c := math.Sincos(real(x))
139 sh, ch := sinhcosh(imag(x))
140 return complex(c*ch, -s*sh)
141 }
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156 func Cosh(x complex128) complex128 {
157 switch re, im := real(x), imag(x); {
158 case re == 0 && (math.IsInf(im, 0) || math.IsNaN(im)):
159 return complex(math.NaN(), re*math.Copysign(0, im))
160 case math.IsInf(re, 0):
161 switch {
162 case im == 0:
163 return complex(math.Inf(1), im*math.Copysign(0, re))
164 case math.IsInf(im, 0) || math.IsNaN(im):
165 return complex(math.Inf(1), math.NaN())
166 }
167 case im == 0 && math.IsNaN(re):
168 return complex(math.NaN(), im)
169 }
170 s, c := math.Sincos(imag(x))
171 sh, ch := sinhcosh(real(x))
172 return complex(c*ch, s*sh)
173 }
174
175
176 func sinhcosh(x float64) (sh, ch float64) {
177 if math.Abs(x) <= 0.5 {
178 return math.Sinh(x), math.Cosh(x)
179 }
180 e := math.Exp(x)
181 ei := 0.5 / e
182 e *= 0.5
183 return e - ei, e + ei
184 }
185
View as plain text