rubysl-complex 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +25 -0
  6. data/README.md +29 -0
  7. data/Rakefile +2 -0
  8. data/lib/complex.rb +1 -0
  9. data/lib/rubysl/complex.rb +2 -0
  10. data/lib/rubysl/complex/complex.rb +659 -0
  11. data/lib/rubysl/complex/version.rb +5 -0
  12. data/rubysl-complex.gemspec +23 -0
  13. data/spec/Complex_spec.rb +9 -0
  14. data/spec/abs2_spec.rb +10 -0
  15. data/spec/abs_spec.rb +10 -0
  16. data/spec/angle_spec.rb +7 -0
  17. data/spec/arg_spec.rb +7 -0
  18. data/spec/coerce_spec.rb +11 -0
  19. data/spec/comparison_spec.rb +23 -0
  20. data/spec/conj_spec.rb +7 -0
  21. data/spec/conjugate_spec.rb +7 -0
  22. data/spec/constants_spec.rb +9 -0
  23. data/spec/denominator_spec.rb +20 -0
  24. data/spec/divide_spec.rb +9 -0
  25. data/spec/equal_value_spec.rb +9 -0
  26. data/spec/exponent_spec.rb +10 -0
  27. data/spec/float/angle_spec.rb +9 -0
  28. data/spec/float/arg_spec.rb +9 -0
  29. data/spec/generic_spec.rb +25 -0
  30. data/spec/hash_spec.rb +10 -0
  31. data/spec/imag_spec.rb +10 -0
  32. data/spec/image_spec.rb +7 -0
  33. data/spec/inspect_spec.rb +10 -0
  34. data/spec/math/acos_spec.rb +30 -0
  35. data/spec/math/acosh_spec.rb +30 -0
  36. data/spec/math/asin_spec.rb +30 -0
  37. data/spec/math/asinh_spec.rb +30 -0
  38. data/spec/math/atan2_spec.rb +30 -0
  39. data/spec/math/atan_spec.rb +30 -0
  40. data/spec/math/atanh_spec.rb +34 -0
  41. data/spec/math/cos_spec.rb +30 -0
  42. data/spec/math/cosh_spec.rb +30 -0
  43. data/spec/math/exp_spec.rb +30 -0
  44. data/spec/math/fixtures/classes.rb +3 -0
  45. data/spec/math/log10_spec.rb +30 -0
  46. data/spec/math/log_spec.rb +30 -0
  47. data/spec/math/shared/acos.rb +41 -0
  48. data/spec/math/shared/acosh.rb +37 -0
  49. data/spec/math/shared/asin.rb +47 -0
  50. data/spec/math/shared/asinh.rb +32 -0
  51. data/spec/math/shared/atan.rb +32 -0
  52. data/spec/math/shared/atan2.rb +34 -0
  53. data/spec/math/shared/atanh.rb +30 -0
  54. data/spec/math/shared/cos.rb +30 -0
  55. data/spec/math/shared/cosh.rb +28 -0
  56. data/spec/math/shared/exp.rb +28 -0
  57. data/spec/math/shared/log.rb +39 -0
  58. data/spec/math/shared/log10.rb +41 -0
  59. data/spec/math/shared/sin.rb +30 -0
  60. data/spec/math/shared/sinh.rb +28 -0
  61. data/spec/math/shared/sqrt.rb +34 -0
  62. data/spec/math/shared/tan.rb +28 -0
  63. data/spec/math/shared/tanh.rb +32 -0
  64. data/spec/math/sin_spec.rb +30 -0
  65. data/spec/math/sinh_spec.rb +30 -0
  66. data/spec/math/sqrt_spec.rb +30 -0
  67. data/spec/math/tan_spec.rb +30 -0
  68. data/spec/math/tanh_spec.rb +30 -0
  69. data/spec/minus_spec.rb +9 -0
  70. data/spec/modulo_spec.rb +29 -0
  71. data/spec/multiply_spec.rb +9 -0
  72. data/spec/new_spec.rb +41 -0
  73. data/spec/numerator_spec.rb +12 -0
  74. data/spec/numeric/angle_spec.rb +11 -0
  75. data/spec/numeric/arg_spec.rb +11 -0
  76. data/spec/numeric/conj_spec.rb +11 -0
  77. data/spec/numeric/conjugate_spec.rb +11 -0
  78. data/spec/numeric/im_spec.rb +9 -0
  79. data/spec/numeric/imag_spec.rb +11 -0
  80. data/spec/numeric/image_spec.rb +11 -0
  81. data/spec/numeric/polar_spec.rb +11 -0
  82. data/spec/numeric/real_spec.rb +11 -0
  83. data/spec/plus_spec.rb +9 -0
  84. data/spec/polar_spec.rb +13 -0
  85. data/spec/real_spec.rb +10 -0
  86. data/spec/to_s_spec.rb +9 -0
  87. metadata +259 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 31178e7af89237346bf8e84d8110243f02b1b6a2
4
+ data.tar.gz: 7fce5e73fefcb231723503020de2438aae79956e
5
+ SHA512:
6
+ metadata.gz: ff6f9d1852f6b604a631188bb9b5969979fae448526997f977a67552bbfd67c5259641d1cc7d22d4528a84a44802c435400480eeeded6651dc1aa4a4632b5048
7
+ data.tar.gz: 91e053b6c27ceacc715bbc941977c0325bea3d03130921f398fb7759e62660aed941de1e353307fca1379af4678eacdb0a012936faa102c323874f0a93a1899c
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .rbx
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ before_install:
3
+ - gem update --system
4
+ - gem --version
5
+ - gem install rubysl-bundler
6
+ script: bundle exec mspec spec
7
+ rvm:
8
+ - rbx-nightly-18mode
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rubysl-complex.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2013, Brian Shirai
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ 3. Neither the name of the library nor the names of its contributors may be
13
+ used to endorse or promote products derived from this software without
14
+ specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT,
20
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # RubySL::Complex
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rubysl-complex'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rubysl-complex
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/lib/complex.rb ADDED
@@ -0,0 +1 @@
1
+ require "rubysl/complex"
@@ -0,0 +1,2 @@
1
+ require "rubysl/complex/complex"
2
+ require "rubysl/complex/version"
@@ -0,0 +1,659 @@
1
+ #
2
+ # complex.rb -
3
+ # $Release Version: 0.5 $
4
+ # $Revision: 1.3 $
5
+ # $Date: 1998/07/08 10:05:28 $
6
+ # by Keiju ISHITSUKA(SHL Japan Inc.)
7
+ #
8
+ # ----
9
+ #
10
+ # complex.rb implements the Complex class for complex numbers. Additionally,
11
+ # some methods in other Numeric classes are redefined or added to allow greater
12
+ # interoperability with Complex numbers.
13
+ #
14
+ # Complex numbers can be created in the following manner:
15
+ # - <tt>Complex(a, b)</tt>
16
+ # - <tt>Complex.polar(radius, theta)</tt>
17
+ #
18
+ # Additionally, note the following:
19
+ # - <tt>Complex::I</tt> (the mathematical constant <i>i</i>)
20
+ # - <tt>Numeric#im</tt> (e.g. <tt>5.im -> 0+5i</tt>)
21
+ #
22
+ # The following +Math+ module methods are redefined to handle Complex arguments.
23
+ # They will work as normal with non-Complex arguments.
24
+ # sqrt exp cos sin tan log log10
25
+ # cosh sinh tanh acos asin atan atan2 acosh asinh atanh
26
+ #
27
+
28
+
29
+ #
30
+ # Numeric is a built-in class on which Fixnum, Bignum, etc., are based. Here
31
+ # some methods are added so that all number types can be treated to some extent
32
+ # as Complex numbers.
33
+ #
34
+ class Numeric
35
+ #
36
+ # Returns a Complex number <tt>(0,<i>self</i>)</tt>.
37
+ #
38
+ def im
39
+ Complex(0, self)
40
+ end
41
+
42
+ #
43
+ # The real part of a complex number, i.e. <i>self</i>.
44
+ #
45
+ def real
46
+ self
47
+ end
48
+
49
+ #
50
+ # The imaginary part of a complex number, i.e. 0.
51
+ #
52
+ def image
53
+ 0
54
+ end
55
+ alias imag image
56
+
57
+ #
58
+ # See Complex#arg.
59
+ #
60
+ def arg
61
+ Math.atan2!(0, self)
62
+ end
63
+ alias angle arg
64
+
65
+ #
66
+ # See Complex#polar.
67
+ #
68
+ def polar
69
+ return abs, arg
70
+ end
71
+
72
+ #
73
+ # See Complex#conjugate (short answer: returns <i>self</i>).
74
+ #
75
+ def conjugate
76
+ self
77
+ end
78
+ alias conj conjugate
79
+ end
80
+
81
+
82
+ #
83
+ # Creates a Complex number. +a+ and +b+ should be Numeric. The result will be
84
+ # <tt>a+bi</tt>.
85
+ #
86
+ def Complex(a, b = 0)
87
+ if b == 0 and (a.kind_of?(Complex) or defined? Complex::Unify)
88
+ a
89
+ else
90
+ Complex.new( a.real-b.imag, a.imag+b.real )
91
+ end
92
+ end
93
+
94
+ #
95
+ # The complex number class. See complex.rb for an overview.
96
+ #
97
+ class Complex < Numeric
98
+ @RCS_ID='-$Id: complex.rb,v 1.3 1998/07/08 10:05:28 keiju Exp keiju $-'
99
+
100
+ undef step
101
+ undef div, divmod
102
+ undef floor, truncate, ceil, round
103
+
104
+ def Complex.generic?(other) # :nodoc:
105
+ other.kind_of?(Integer) or
106
+ other.kind_of?(Float) or
107
+ (defined?(Rational) and other.kind_of?(Rational))
108
+ end
109
+
110
+ #
111
+ # Creates a +Complex+ number in terms of +r+ (radius) and +theta+ (angle).
112
+ #
113
+ def Complex.polar(r, theta)
114
+ Complex(r*Math.cos(theta), r*Math.sin(theta))
115
+ end
116
+
117
+ #
118
+ # Creates a +Complex+ number <tt>a</tt>+<tt>b</tt><i>i</i>.
119
+ #
120
+ def Complex.new!(a, b=0)
121
+ new(a,b)
122
+ end
123
+
124
+ def initialize(a, b)
125
+ raise TypeError, "non numeric 1st arg `#{a.inspect}'" if !a.kind_of? Numeric
126
+ raise TypeError, "`#{a.inspect}' for 1st arg" if a.kind_of? Complex
127
+ raise TypeError, "non numeric 2nd arg `#{b.inspect}'" if !b.kind_of? Numeric
128
+ raise TypeError, "`#{b.inspect}' for 2nd arg" if b.kind_of? Complex
129
+ @real = a
130
+ @image = b
131
+ end
132
+
133
+ #
134
+ # Addition with real or complex number.
135
+ #
136
+ def + (other)
137
+ if other.kind_of?(Complex)
138
+ re = @real + other.real
139
+ im = @image + other.image
140
+ Complex(re, im)
141
+ elsif Complex.generic?(other)
142
+ Complex(@real + other, @image)
143
+ else
144
+ x , y = other.coerce(self)
145
+ x + y
146
+ end
147
+ end
148
+
149
+ #
150
+ # Subtraction with real or complex number.
151
+ #
152
+ def - (other)
153
+ if other.kind_of?(Complex)
154
+ re = @real - other.real
155
+ im = @image - other.image
156
+ Complex(re, im)
157
+ elsif Complex.generic?(other)
158
+ Complex(@real - other, @image)
159
+ else
160
+ x , y = other.coerce(self)
161
+ x - y
162
+ end
163
+ end
164
+
165
+ #
166
+ # Multiplication with real or complex number.
167
+ #
168
+ def * (other)
169
+ if other.kind_of?(Complex)
170
+ re = @real*other.real - @image*other.image
171
+ im = @real*other.image + @image*other.real
172
+ Complex(re, im)
173
+ elsif Complex.generic?(other)
174
+ Complex(@real * other, @image * other)
175
+ else
176
+ x , y = other.coerce(self)
177
+ x * y
178
+ end
179
+ end
180
+
181
+ #
182
+ # Division by real or complex number.
183
+ #
184
+ def / (other)
185
+ if other.kind_of?(Complex)
186
+ self*other.conjugate/other.abs2
187
+ elsif Complex.generic?(other)
188
+ Complex(@real/other, @image/other)
189
+ else
190
+ x, y = other.coerce(self)
191
+ x/y
192
+ end
193
+ end
194
+
195
+ def quo(other)
196
+ Complex(@real.quo(1), @image.quo(1)) / other
197
+ end
198
+
199
+ #
200
+ # Raise this complex number to the given (real or complex) power.
201
+ #
202
+ def ** (other)
203
+ if other == 0
204
+ return Complex(1)
205
+ end
206
+ if other.kind_of?(Complex)
207
+ r, theta = polar
208
+ ore = other.real
209
+ oim = other.image
210
+ nr = Math.exp!(ore*Math.log!(r) - oim * theta)
211
+ ntheta = theta*ore + oim*Math.log!(r)
212
+ Complex.polar(nr, ntheta)
213
+ elsif other.kind_of?(Integer)
214
+ if other > 0
215
+ x = self
216
+ z = x
217
+ n = other - 1
218
+ while n != 0
219
+ while (div, mod = n.divmod(2)
220
+ mod == 0)
221
+ x = Complex(x.real*x.real - x.image*x.image, 2*x.real*x.image)
222
+ n = div
223
+ end
224
+ z *= x
225
+ n -= 1
226
+ end
227
+ z
228
+ else
229
+ if defined? Rational
230
+ (Rational(1) / self) ** -other
231
+ else
232
+ self ** Float(other)
233
+ end
234
+ end
235
+ elsif Complex.generic?(other)
236
+ r, theta = polar
237
+ Complex.polar(r**other, theta*other)
238
+ else
239
+ x, y = other.coerce(self)
240
+ x**y
241
+ end
242
+ end
243
+
244
+ #
245
+ # Remainder after division by a real or complex number.
246
+ #
247
+ def % (other)
248
+ if other.kind_of?(Complex)
249
+ Complex(@real % other.real, @image % other.image)
250
+ elsif Complex.generic?(other)
251
+ Complex(@real % other, @image % other)
252
+ else
253
+ x , y = other.coerce(self)
254
+ x % y
255
+ end
256
+ end
257
+
258
+ #--
259
+ # def divmod(other)
260
+ # if other.kind_of?(Complex)
261
+ # rdiv, rmod = @real.divmod(other.real)
262
+ # idiv, imod = @image.divmod(other.image)
263
+ # return Complex(rdiv, idiv), Complex(rmod, rmod)
264
+ # elsif Complex.generic?(other)
265
+ # Complex(@real.divmod(other), @image.divmod(other))
266
+ # else
267
+ # x , y = other.coerce(self)
268
+ # x.divmod(y)
269
+ # end
270
+ # end
271
+ #++
272
+
273
+ #
274
+ # Absolute value (aka modulus): distance from the zero point on the complex
275
+ # plane.
276
+ #
277
+ def abs
278
+ Math.hypot(@real, @image)
279
+ end
280
+
281
+ #
282
+ # Square of the absolute value.
283
+ #
284
+ def abs2
285
+ @real*@real + @image*@image
286
+ end
287
+
288
+ #
289
+ # Argument (angle from (1,0) on the complex plane).
290
+ #
291
+ def arg
292
+ Math.atan2!(@image, @real)
293
+ end
294
+ alias angle arg
295
+
296
+ #
297
+ # Returns the absolute value _and_ the argument.
298
+ #
299
+ def polar
300
+ return abs, arg
301
+ end
302
+
303
+ #
304
+ # Complex conjugate (<tt>z + z.conjugate = 2 * z.real</tt>).
305
+ #
306
+ def conjugate
307
+ Complex(@real, -@image)
308
+ end
309
+ alias conj conjugate
310
+
311
+ #
312
+ # Compares the absolute values of the two numbers.
313
+ #
314
+ def <=> (other)
315
+ self.abs <=> other.abs
316
+ end
317
+
318
+ #
319
+ # Test for numerical equality (<tt>a == a + 0<i>i</i></tt>).
320
+ #
321
+ def == (other)
322
+ if other.kind_of?(Complex)
323
+ @real == other.real and @image == other.image
324
+ elsif Complex.generic?(other)
325
+ @real == other and @image == 0
326
+ else
327
+ other == self
328
+ end
329
+ end
330
+
331
+ #
332
+ # Attempts to coerce +other+ to a Complex number.
333
+ #
334
+ def coerce(other)
335
+ if Complex.generic?(other)
336
+ return Complex.new!(other), self
337
+ else
338
+ super
339
+ end
340
+ end
341
+
342
+ #
343
+ # FIXME
344
+ #
345
+ def denominator
346
+ @real.denominator.lcm(@image.denominator)
347
+ end
348
+
349
+ #
350
+ # FIXME
351
+ #
352
+ def numerator
353
+ cd = denominator
354
+ Complex(@real.numerator*(cd/@real.denominator),
355
+ @image.numerator*(cd/@image.denominator))
356
+ end
357
+
358
+ #
359
+ # Standard string representation of the complex number.
360
+ #
361
+ def to_s
362
+ if @real != 0
363
+ if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
364
+ if @image >= 0
365
+ @real.to_s+"+("+@image.to_s+")i"
366
+ else
367
+ @real.to_s+"-("+(-@image).to_s+")i"
368
+ end
369
+ else
370
+ if @image >= 0
371
+ @real.to_s+"+"+@image.to_s+"i"
372
+ else
373
+ @real.to_s+"-"+(-@image).to_s+"i"
374
+ end
375
+ end
376
+ else
377
+ if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
378
+ "("+@image.to_s+")i"
379
+ else
380
+ @image.to_s+"i"
381
+ end
382
+ end
383
+ end
384
+
385
+ #
386
+ # Returns a hash code for the complex number.
387
+ #
388
+ def hash
389
+ @real.hash ^ @image.hash
390
+ end
391
+
392
+ #
393
+ # Returns "<tt>Complex(<i>real</i>, <i>image</i>)</tt>".
394
+ #
395
+ def inspect
396
+ sprintf("Complex(%s, %s)", @real.inspect, @image.inspect)
397
+ end
398
+
399
+
400
+ #
401
+ # +I+ is the imaginary number. It exists at point (0,1) on the complex plane.
402
+ #
403
+ I = Complex(0,1)
404
+
405
+ # The real part of a complex number.
406
+ attr :real
407
+
408
+ # The imaginary part of a complex number.
409
+ attr :image
410
+ alias imag image
411
+
412
+ end
413
+
414
+ class Integer
415
+
416
+ unless defined?(1.numerator)
417
+ def numerator() self end
418
+ def denominator() 1 end
419
+
420
+ def gcd(other)
421
+ min = self.abs
422
+ max = other.abs
423
+ while min > 0
424
+ tmp = min
425
+ min = max % min
426
+ max = tmp
427
+ end
428
+ max
429
+ end
430
+
431
+ def lcm(other)
432
+ if self.zero? or other.zero?
433
+ 0
434
+ else
435
+ (self.div(self.gcd(other)) * other).abs
436
+ end
437
+ end
438
+
439
+ end
440
+
441
+ end
442
+
443
+ module Math
444
+ alias sqrt! sqrt
445
+ alias exp! exp
446
+ alias log! log
447
+ alias log10! log10
448
+ alias cos! cos
449
+ alias sin! sin
450
+ alias tan! tan
451
+ alias cosh! cosh
452
+ alias sinh! sinh
453
+ alias tanh! tanh
454
+ alias acos! acos
455
+ alias asin! asin
456
+ alias atan! atan
457
+ alias atan2! atan2
458
+ alias acosh! acosh
459
+ alias asinh! asinh
460
+ alias atanh! atanh
461
+
462
+ # Redefined to handle a Complex argument.
463
+ def sqrt(z)
464
+ if Complex.generic?(z)
465
+ if z >= 0
466
+ sqrt!(z)
467
+ else
468
+ Complex(0,sqrt!(-z))
469
+ end
470
+ else
471
+ if z.image < 0
472
+ sqrt(z.conjugate).conjugate
473
+ else
474
+ r = z.abs
475
+ x = z.real
476
+ Complex( sqrt!((r+x)/2), sqrt!((r-x)/2) )
477
+ end
478
+ end
479
+ end
480
+
481
+ # Redefined to handle a Complex argument.
482
+ def exp(z)
483
+ if Complex.generic?(z)
484
+ exp!(z)
485
+ else
486
+ Complex(exp!(z.real) * cos!(z.image), exp!(z.real) * sin!(z.image))
487
+ end
488
+ end
489
+
490
+ # Redefined to handle a Complex argument.
491
+ def cos(z)
492
+ if Complex.generic?(z)
493
+ cos!(z)
494
+ else
495
+ Complex(cos!(z.real)*cosh!(z.image),
496
+ -sin!(z.real)*sinh!(z.image))
497
+ end
498
+ end
499
+
500
+ # Redefined to handle a Complex argument.
501
+ def sin(z)
502
+ if Complex.generic?(z)
503
+ sin!(z)
504
+ else
505
+ Complex(sin!(z.real)*cosh!(z.image),
506
+ cos!(z.real)*sinh!(z.image))
507
+ end
508
+ end
509
+
510
+ # Redefined to handle a Complex argument.
511
+ def tan(z)
512
+ if Complex.generic?(z)
513
+ tan!(z)
514
+ else
515
+ sin(z)/cos(z)
516
+ end
517
+ end
518
+
519
+ def sinh(z)
520
+ if Complex.generic?(z)
521
+ sinh!(z)
522
+ else
523
+ Complex( sinh!(z.real)*cos!(z.image), cosh!(z.real)*sin!(z.image) )
524
+ end
525
+ end
526
+
527
+ def cosh(z)
528
+ if Complex.generic?(z)
529
+ cosh!(z)
530
+ else
531
+ Complex( cosh!(z.real)*cos!(z.image), sinh!(z.real)*sin!(z.image) )
532
+ end
533
+ end
534
+
535
+ def tanh(z)
536
+ if Complex.generic?(z)
537
+ tanh!(z)
538
+ else
539
+ sinh(z)/cosh(z)
540
+ end
541
+ end
542
+
543
+ # Redefined to handle a Complex argument.
544
+ def log(z)
545
+ if Complex.generic?(z) and z >= 0
546
+ log!(z)
547
+ else
548
+ r, theta = z.polar
549
+ Complex(log!(r.abs), theta)
550
+ end
551
+ end
552
+
553
+ # Redefined to handle a Complex argument.
554
+ def log10(z)
555
+ if Complex.generic?(z)
556
+ log10!(z)
557
+ else
558
+ log(z)/log!(10)
559
+ end
560
+ end
561
+
562
+ def acos(z)
563
+ if Complex.generic?(z) and z >= -1 and z <= 1
564
+ acos!(z)
565
+ else
566
+ -1.0.im * log( z + 1.0.im * sqrt(1.0-z*z) )
567
+ end
568
+ end
569
+
570
+ def asin(z)
571
+ if Complex.generic?(z) and z >= -1 and z <= 1
572
+ asin!(z)
573
+ else
574
+ -1.0.im * log( 1.0.im * z + sqrt(1.0-z*z) )
575
+ end
576
+ end
577
+
578
+ def atan(z)
579
+ if Complex.generic?(z)
580
+ atan!(z)
581
+ else
582
+ 1.0.im * log( (1.0.im+z) / (1.0.im-z) ) / 2.0
583
+ end
584
+ end
585
+
586
+ def atan2(y,x)
587
+ if Complex.generic?(y) and Complex.generic?(x)
588
+ atan2!(y,x)
589
+ else
590
+ -1.0.im * log( (x+1.0.im*y) / sqrt(x*x+y*y) )
591
+ end
592
+ end
593
+
594
+ def acosh(z)
595
+ if Complex.generic?(z) and z >= 1
596
+ acosh!(z)
597
+ else
598
+ log( z + sqrt(z*z-1.0) )
599
+ end
600
+ end
601
+
602
+ def asinh(z)
603
+ if Complex.generic?(z)
604
+ asinh!(z)
605
+ else
606
+ log( z + sqrt(1.0+z*z) )
607
+ end
608
+ end
609
+
610
+ def atanh(z)
611
+ if Complex.generic?(z) and z >= -1 and z <= 1
612
+ atanh!(z)
613
+ else
614
+ log( (1.0+z) / (1.0-z) ) / 2.0
615
+ end
616
+ end
617
+
618
+ module_function :sqrt!
619
+ module_function :sqrt
620
+ module_function :exp!
621
+ module_function :exp
622
+ module_function :log!
623
+ module_function :log
624
+ module_function :log10!
625
+ module_function :log10
626
+ module_function :cosh!
627
+ module_function :cosh
628
+ module_function :cos!
629
+ module_function :cos
630
+ module_function :sinh!
631
+ module_function :sinh
632
+ module_function :sin!
633
+ module_function :sin
634
+ module_function :tan!
635
+ module_function :tan
636
+ module_function :tanh!
637
+ module_function :tanh
638
+ module_function :acos!
639
+ module_function :acos
640
+ module_function :asin!
641
+ module_function :asin
642
+ module_function :atan!
643
+ module_function :atan
644
+ module_function :atan2!
645
+ module_function :atan2
646
+ module_function :acosh!
647
+ module_function :acosh
648
+ module_function :asinh!
649
+ module_function :asinh
650
+ module_function :atanh!
651
+ module_function :atanh
652
+
653
+ end
654
+
655
+ # Documentation comments:
656
+ # - source: original (researched from pickaxe)
657
+ # - a couple of fixme's
658
+ # - RDoc output for Bignum etc. is a bit short, with nothing but an
659
+ # (undocumented) alias. No big deal.