1 |
1 |
##
|
|
2 |
# = Trigonometric and transcendental functions for complex numbers.
|
|
3 |
#
|
2 |
4 |
# CMath is a library that provides trigonometric and transcendental
|
3 |
|
# functions for complex numbers.
|
|
5 |
# functions for complex numbers. The functions in this module accept
|
|
6 |
# integers, floating-point numbers or complex numbers as arguments.
|
|
7 |
#
|
|
8 |
# Note that the selection of functions is similar, but not identical,
|
|
9 |
# to that in module math. The reason for having two modules is that
|
|
10 |
# some users aren’t interested in complex numbers, and perhaps don’t
|
|
11 |
# even know what they are. They would rather have Math.sqrt(-1) raise
|
|
12 |
# an exception than return a complex number.
|
|
13 |
#
|
|
14 |
# == Brief overview of complex numbers
|
|
15 |
#
|
|
16 |
# A complex number is a number that can be expressed in the form
|
|
17 |
# a + bi, where a and b are real numbers and i is the imaginary unit,
|
|
18 |
# that satisfies the equation x**2 = −1, that is, i**2 = −1. In this
|
|
19 |
# expression, a is the real part and b is the imaginary part of the
|
|
20 |
# complex number.
|
|
21 |
#
|
|
22 |
# In ruby, you can create complex object with Complex, ::rect, ::polar
|
|
23 |
# or #to_c method.
|
|
24 |
#
|
|
25 |
# Complex(1) #=> (1+0i)
|
|
26 |
# Complex.polar(2, 3) #=> (-1.9799849932008908+0.2822400161197344i)
|
|
27 |
# 3.to_c #=> (3+0i)
|
4 |
28 |
#
|
5 |
29 |
# == Usage
|
6 |
30 |
#
|
7 |
|
# To start using this library, simply:
|
|
31 |
# To start using this library, simply require cmath library:
|
8 |
32 |
#
|
9 |
33 |
# require "cmath"
|
10 |
34 |
#
|
11 |
|
# Square root of a negative number is a complex number.
|
|
35 |
# And after call any CMath function. For example:
|
|
36 |
#
|
|
37 |
# CMath.sqrt(-9) #=> 0+3.0i
|
|
38 |
# CMath.exp(Complex(0,0)) #=> 1.0+0.0i
|
|
39 |
# CMath.log10(-5.to_c) #=> (0.6989700043360187+1.3643763538418412i)
|
12 |
40 |
#
|
13 |
|
# CMath.sqrt(-9) #=> 0+3.0i
|
|
41 |
# == References
|
|
42 |
#
|
|
43 |
# Kahan, W: Branch cuts for complex elementary functions
|
|
44 |
# Solomentsev, E.D. (2001), "Complex number", in Hazewinkel, Michiel,
|
|
45 |
# <em>Encyclopedia of Mathematics, Springer, ISBN 978-1-55608-010-4
|
14 |
46 |
#
|
15 |
47 |
|
16 |
48 |
module CMath
|
... | ... | |
44 |
76 |
##
|
45 |
77 |
# Math::E raised to the +z+ power
|
46 |
78 |
#
|
47 |
|
# exp(Complex(0,0)) #=> 1.0+0.0i
|
48 |
|
# exp(Complex(0,PI)) #=> -1.0+1.2246467991473532e-16i
|
49 |
|
# exp(Complex(0,PI/2.0)) #=> 6.123233995736766e-17+1.0i
|
|
79 |
# CMath.exp(Complex(0,PI)) #=> -1.0+1.2246467991473532e-16i
|
50 |
80 |
def exp(z)
|
51 |
81 |
begin
|
52 |
82 |
if z.real?
|
... | ... | |
62 |
92 |
end
|
63 |
93 |
|
64 |
94 |
##
|
65 |
|
# Returns the natural logarithm of Complex. If a second argument is given,
|
|
95 |
# Returns the natural logarithm of Complex. If a second argument is given,
|
66 |
96 |
# it will be the base of logarithm.
|
67 |
97 |
#
|
68 |
|
# log(Complex(0,0)) #=> -Infinity+0.0i
|
|
98 |
# CMath.log(Complex(1,4)) #=> (1.416606672028108+1.3258176636680326i)
|
|
99 |
# CMath.log(Complex(1,4), 10) #=> (0.6152244606891369+0.5757952953408879i)
|
69 |
100 |
def log(z, b=::Math::E)
|
70 |
101 |
begin
|
71 |
102 |
if z.real? && z >= 0 && b >= 0
|
... | ... | |
80 |
111 |
|
81 |
112 |
##
|
82 |
113 |
# returns the base 2 logarithm of +z+
|
|
114 |
#
|
|
115 |
# CMath.log2(-1) => (0.0+4.532360141827194i)
|
83 |
116 |
def log2(z)
|
84 |
117 |
begin
|
85 |
118 |
if z.real? and z >= 0
|
... | ... | |
94 |
127 |
|
95 |
128 |
##
|
96 |
129 |
# returns the base 10 logarithm of +z+
|
|
130 |
#
|
|
131 |
# CMath.log10(-1) #=> (0.0+1.3643763538418412i)
|
97 |
132 |
def log10(z)
|
98 |
133 |
begin
|
99 |
134 |
if z.real? and z >= 0
|
... | ... | |
108 |
143 |
|
109 |
144 |
##
|
110 |
145 |
# Returns the non-negative square root of Complex.
|
111 |
|
# sqrt(-1) #=> 0+1.0i
|
112 |
|
# sqrt(Complex(-1,0)) #=> 0.0+1.0i
|
113 |
|
# sqrt(Complex(0,8)) #=> 2.0+2.0i
|
|
146 |
#
|
|
147 |
# CMath.sqrt(Complex(-1,0)) #=> 0.0+1.0i
|
114 |
148 |
def sqrt(z)
|
115 |
149 |
begin
|
116 |
150 |
if z.real?
|
... | ... | |
136 |
170 |
|
137 |
171 |
##
|
138 |
172 |
# returns the principal value of the cube root of +z+
|
|
173 |
#
|
|
174 |
# CMath.cbrt(Complex(1,4)) #=> (1.449461632813119+0.6858152562177092i)
|
139 |
175 |
def cbrt(z)
|
140 |
176 |
z ** (1.0/3)
|
141 |
177 |
end
|
142 |
178 |
|
143 |
179 |
##
|
144 |
180 |
# returns the sine of +z+, where +z+ is given in radians
|
|
181 |
#
|
|
182 |
# CMath.sin(Complex(Math::PI)) #=> (1.2246467991473532e-16-0.0i)
|
145 |
183 |
def sin(z)
|
146 |
184 |
begin
|
147 |
185 |
if z.real?
|
... | ... | |
157 |
195 |
|
158 |
196 |
##
|
159 |
197 |
# returns the cosine of +z+, where +z+ is given in radians
|
|
198 |
#
|
|
199 |
# CMath.cos(Complex(Math::PI)) #=> (-1.0-0.0i)
|
160 |
200 |
def cos(z)
|
161 |
201 |
begin
|
162 |
202 |
if z.real?
|
... | ... | |
172 |
212 |
|
173 |
213 |
##
|
174 |
214 |
# returns the tangent of +z+, where +z+ is given in radians
|
|
215 |
#
|
|
216 |
# CMath.tan(Complex(Math::PI)) #=> (-1.2246467991473532e-16+0.0i)
|
175 |
217 |
def tan(z)
|
176 |
218 |
begin
|
177 |
219 |
if z.real?
|
... | ... | |
186 |
228 |
|
187 |
229 |
##
|
188 |
230 |
# returns the hyperbolic sine of +z+, where +z+ is given in radians
|
|
231 |
#
|
|
232 |
# CMath.sinh(Complex(Math::PI)) #=> (11.548739357257746+0.0i)
|
189 |
233 |
def sinh(z)
|
190 |
234 |
begin
|
191 |
235 |
if z.real?
|
... | ... | |
201 |
245 |
|
202 |
246 |
##
|
203 |
247 |
# returns the hyperbolic cosine of +z+, where +z+ is given in radians
|
|
248 |
#
|
|
249 |
# CMath.cosh(Complex(Math::PI)) #=> (11.591953275521519+0.0i)
|
204 |
250 |
def cosh(z)
|
205 |
251 |
begin
|
206 |
252 |
if z.real?
|
... | ... | |
216 |
262 |
|
217 |
263 |
##
|
218 |
264 |
# returns the hyperbolic tangent of +z+, where +z+ is given in radians
|
|
265 |
#
|
|
266 |
# CMath.tanh(Complex(Math::PI)) #=> (0.99627207622075+0.0i)
|
219 |
267 |
def tanh(z)
|
220 |
268 |
begin
|
221 |
269 |
if z.real?
|
... | ... | |
230 |
278 |
|
231 |
279 |
##
|
232 |
280 |
# returns the arc sine of +z+
|
|
281 |
#
|
|
282 |
# CMath.asin(Complex(Math::PI)) #=> (1.5707963267948966-1.8115262724608532i)
|
233 |
283 |
def asin(z)
|
234 |
284 |
begin
|
235 |
285 |
if z.real? and z >= -1 and z <= 1
|
... | ... | |
244 |
294 |
|
245 |
295 |
##
|
246 |
296 |
# returns the arc cosine of +z+
|
|
297 |
#
|
|
298 |
# CMath.acos(Complex(Math::PI)) #=> (0.0+1.8115262724608536i)
|
247 |
299 |
def acos(z)
|
248 |
300 |
begin
|
249 |
301 |
if z.real? and z >= -1 and z <= 1
|
... | ... | |
258 |
310 |
|
259 |
311 |
##
|
260 |
312 |
# returns the arc tangent of +z+
|
|
313 |
#
|
|
314 |
# CMath.atan(Complex(Math::PI)) #=> (1.2626272556789118+0.0i)
|
261 |
315 |
def atan(z)
|
262 |
316 |
begin
|
263 |
317 |
if z.real?
|
... | ... | |
273 |
327 |
##
|
274 |
328 |
# returns the arc tangent of +y+ divided by +x+ using the signs of +y+ and
|
275 |
329 |
# +x+ to determine the quadrant
|
|
330 |
#
|
|
331 |
# CMath.atan2(Complex(Math::PI), 0) #=> (1.5707963267948966+0.0i)
|
276 |
332 |
def atan2(y,x)
|
277 |
333 |
begin
|
278 |
334 |
if y.real? and x.real?
|
... | ... | |
287 |
343 |
|
288 |
344 |
##
|
289 |
345 |
# returns the inverse hyperbolic sine of +z+
|
|
346 |
#
|
|
347 |
# CMath.asinh(Complex(Math::PI)) #=> (1.8622957433108482+0.0i)
|
290 |
348 |
def asinh(z)
|
291 |
349 |
begin
|
292 |
350 |
if z.real?
|
... | ... | |
301 |
359 |
|
302 |
360 |
##
|
303 |
361 |
# returns the inverse hyperbolic cosine of +z+
|
|
362 |
#
|
|
363 |
# CMath.acosh(Complex(Math::PI)) #=> (1.8115262724608532+0.0i)
|
304 |
364 |
def acosh(z)
|
305 |
365 |
begin
|
306 |
366 |
if z.real? and z >= 1
|
... | ... | |
315 |
375 |
|
316 |
376 |
##
|
317 |
377 |
# returns the inverse hyperbolic tangent of +z+
|
|
378 |
#
|
|
379 |
# CMath.atanh(Complex(Math::PI)) #=> (0.32976531495669914-1.5707963267948966i)
|
318 |
380 |
def atanh(z)
|
319 |
381 |
begin
|
320 |
382 |
if z.real? and z >= -1 and z <= 1
|
321 |
|
-
|