cmath 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/cmath.rb +435 -0
  3. metadata +75 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d42dc899125f373b7953813dbe8e5226001c9779
4
+ data.tar.gz: ee0a1d6fc8df6798862f99869604674c6ea3f919
5
+ SHA512:
6
+ metadata.gz: c334a831c7b61a3d1820a6a8df40d61ff8534b861992bd51a935f3eabf73676d3bb999e223417ad9549f33dec431afaf863b7b48ea519c2414aefe10d71fcbe2
7
+ data.tar.gz: 1cac15ae11662d078caee91e77efd5432660e34996d56b4268a894c6228b6293b467041ef18b72715dd903316cb5c814b16c904afe78578807c8831383a2c1a4
@@ -0,0 +1,435 @@
1
+ # frozen_string_literal: true
2
+ ##
3
+ # = Trigonometric and transcendental functions for complex numbers.
4
+ #
5
+ # CMath is a library that provides trigonometric and transcendental
6
+ # functions for complex numbers. The functions in this module accept
7
+ # integers, floating-point numbers or complex numbers as arguments.
8
+ #
9
+ # Note that the selection of functions is similar, but not identical,
10
+ # to that in module math. The reason for having two modules is that
11
+ # some users aren't interested in complex numbers, and perhaps don't
12
+ # even know what they are. They would rather have Math.sqrt(-1) raise
13
+ # an exception than return a complex number.
14
+ #
15
+ # For more information you can see Complex class.
16
+ #
17
+ # == Usage
18
+ #
19
+ # To start using this library, simply require cmath library:
20
+ #
21
+ # require "cmath"
22
+
23
+ module CMath
24
+
25
+ include Math
26
+
27
+ # Backup of Math is needed because mathn.rb replaces Math with CMath.
28
+ RealMath = Math # :nodoc:
29
+ private_constant :RealMath
30
+
31
+ %w[
32
+ exp
33
+ log
34
+ log2
35
+ log10
36
+ sqrt
37
+ cbrt
38
+ sin
39
+ cos
40
+ tan
41
+ sinh
42
+ cosh
43
+ tanh
44
+ asin
45
+ acos
46
+ atan
47
+ atan2
48
+ asinh
49
+ acosh
50
+ atanh
51
+ ].each do |meth|
52
+ define_method(meth + '!') do |*args, &block|
53
+ warn("CMath##{meth}! is deprecated; use CMath##{meth} or Math##{meth}") if $VERBOSE
54
+ RealMath.send(meth, *args, &block)
55
+ end
56
+ end
57
+
58
+ ##
59
+ # Math::E raised to the +z+ power
60
+ #
61
+ # CMath.exp(1.i * Math::PI) #=> (-1.0+1.2246467991473532e-16i)
62
+ def exp(z)
63
+ begin
64
+ if z.real?
65
+ RealMath.exp(z)
66
+ else
67
+ ere = RealMath.exp(z.real)
68
+ Complex(ere * RealMath.cos(z.imag),
69
+ ere * RealMath.sin(z.imag))
70
+ end
71
+ rescue NoMethodError
72
+ handle_no_method_error
73
+ end
74
+ end
75
+
76
+ ##
77
+ # Returns the natural logarithm of Complex. If a second argument is given,
78
+ # it will be the base of logarithm.
79
+ #
80
+ # CMath.log(1 + 4i) #=> (1.416606672028108+1.3258176636680326i)
81
+ # CMath.log(1 + 4i, 10) #=> (0.6152244606891369+0.5757952953408879i)
82
+ def log(z, b=::Math::E)
83
+ begin
84
+ if z.real? && z >= 0 && b >= 0
85
+ RealMath.log(z, b)
86
+ else
87
+ Complex(RealMath.log(z.abs), z.arg) / log(b)
88
+ end
89
+ rescue NoMethodError
90
+ handle_no_method_error
91
+ end
92
+ end
93
+
94
+ ##
95
+ # Returns the base 2 logarithm of +z+
96
+ #
97
+ # CMath.log2(-1) => (0.0+4.532360141827194i)
98
+ def log2(z)
99
+ begin
100
+ if z.real? and z >= 0
101
+ RealMath.log2(z)
102
+ else
103
+ log(z) / RealMath.log(2)
104
+ end
105
+ rescue NoMethodError
106
+ handle_no_method_error
107
+ end
108
+ end
109
+
110
+ ##
111
+ # Returns the base 10 logarithm of +z+
112
+ #
113
+ # CMath.log10(-1) #=> (0.0+1.3643763538418412i)
114
+ def log10(z)
115
+ begin
116
+ if z.real? and z >= 0
117
+ RealMath.log10(z)
118
+ else
119
+ log(z) / RealMath.log(10)
120
+ end
121
+ rescue NoMethodError
122
+ handle_no_method_error
123
+ end
124
+ end
125
+
126
+ ##
127
+ # Returns the non-negative square root of Complex.
128
+ #
129
+ # CMath.sqrt(-1 + 0i) #=> 0.0+1.0i
130
+ def sqrt(z)
131
+ begin
132
+ if z.real?
133
+ if z < 0
134
+ Complex(0, RealMath.sqrt(-z))
135
+ else
136
+ RealMath.sqrt(z)
137
+ end
138
+ else
139
+ if z.imag < 0 ||
140
+ (z.imag == 0 && z.imag.to_s[0] == '-')
141
+ sqrt(z.conjugate).conjugate
142
+ else
143
+ r = z.abs
144
+ x = z.real
145
+ Complex(RealMath.sqrt((r + x) / 2.0), RealMath.sqrt((r - x) / 2.0))
146
+ end
147
+ end
148
+ rescue NoMethodError
149
+ handle_no_method_error
150
+ end
151
+ end
152
+
153
+ ##
154
+ # Returns the principal value of the cube root of +z+
155
+ #
156
+ # CMath.cbrt(1 + 4i) #=> (1.449461632813119+0.6858152562177092i)
157
+ def cbrt(z)
158
+ z ** (1.0/3)
159
+ end
160
+
161
+ ##
162
+ # Returns the sine of +z+, where +z+ is given in radians
163
+ #
164
+ # CMath.sin(1 + 1i) #=> (1.2984575814159773+0.6349639147847361i)
165
+ def sin(z)
166
+ begin
167
+ if z.real?
168
+ RealMath.sin(z)
169
+ else
170
+ Complex(RealMath.sin(z.real) * RealMath.cosh(z.imag),
171
+ RealMath.cos(z.real) * RealMath.sinh(z.imag))
172
+ end
173
+ rescue NoMethodError
174
+ handle_no_method_error
175
+ end
176
+ end
177
+
178
+ ##
179
+ # Returns the cosine of +z+, where +z+ is given in radians
180
+ #
181
+ # CMath.cos(1 + 1i) #=> (0.8337300251311491-0.9888977057628651i)
182
+ def cos(z)
183
+ begin
184
+ if z.real?
185
+ RealMath.cos(z)
186
+ else
187
+ Complex(RealMath.cos(z.real) * RealMath.cosh(z.imag),
188
+ -RealMath.sin(z.real) * RealMath.sinh(z.imag))
189
+ end
190
+ rescue NoMethodError
191
+ handle_no_method_error
192
+ end
193
+ end
194
+
195
+ ##
196
+ # Returns the tangent of +z+, where +z+ is given in radians
197
+ #
198
+ # CMath.tan(1 + 1i) #=> (0.27175258531951174+1.0839233273386943i)
199
+ def tan(z)
200
+ begin
201
+ if z.real?
202
+ RealMath.tan(z)
203
+ else
204
+ sin(z) / cos(z)
205
+ end
206
+ rescue NoMethodError
207
+ handle_no_method_error
208
+ end
209
+ end
210
+
211
+ ##
212
+ # Returns the hyperbolic sine of +z+, where +z+ is given in radians
213
+ #
214
+ # CMath.sinh(1 + 1i) #=> (0.6349639147847361+1.2984575814159773i)
215
+ def sinh(z)
216
+ begin
217
+ if z.real?
218
+ RealMath.sinh(z)
219
+ else
220
+ Complex(RealMath.sinh(z.real) * RealMath.cos(z.imag),
221
+ RealMath.cosh(z.real) * RealMath.sin(z.imag))
222
+ end
223
+ rescue NoMethodError
224
+ handle_no_method_error
225
+ end
226
+ end
227
+
228
+ ##
229
+ # Returns the hyperbolic cosine of +z+, where +z+ is given in radians
230
+ #
231
+ # CMath.cosh(1 + 1i) #=> (0.8337300251311491+0.9888977057628651i)
232
+ def cosh(z)
233
+ begin
234
+ if z.real?
235
+ RealMath.cosh(z)
236
+ else
237
+ Complex(RealMath.cosh(z.real) * RealMath.cos(z.imag),
238
+ RealMath.sinh(z.real) * RealMath.sin(z.imag))
239
+ end
240
+ rescue NoMethodError
241
+ handle_no_method_error
242
+ end
243
+ end
244
+
245
+ ##
246
+ # Returns the hyperbolic tangent of +z+, where +z+ is given in radians
247
+ #
248
+ # CMath.tanh(1 + 1i) #=> (1.0839233273386943+0.27175258531951174i)
249
+ def tanh(z)
250
+ begin
251
+ if z.real?
252
+ RealMath.tanh(z)
253
+ else
254
+ sinh(z) / cosh(z)
255
+ end
256
+ rescue NoMethodError
257
+ handle_no_method_error
258
+ end
259
+ end
260
+
261
+ ##
262
+ # Returns the arc sine of +z+
263
+ #
264
+ # CMath.asin(1 + 1i) #=> (0.6662394324925153+1.0612750619050355i)
265
+ def asin(z)
266
+ begin
267
+ if z.real? and z >= -1 and z <= 1
268
+ RealMath.asin(z)
269
+ else
270
+ (-1.0).i * log(1.0.i * z + sqrt(1.0 - z * z))
271
+ end
272
+ rescue NoMethodError
273
+ handle_no_method_error
274
+ end
275
+ end
276
+
277
+ ##
278
+ # Returns the arc cosine of +z+
279
+ #
280
+ # CMath.acos(1 + 1i) #=> (0.9045568943023813-1.0612750619050357i)
281
+ def acos(z)
282
+ begin
283
+ if z.real? and z >= -1 and z <= 1
284
+ RealMath.acos(z)
285
+ else
286
+ (-1.0).i * log(z + 1.0.i * sqrt(1.0 - z * z))
287
+ end
288
+ rescue NoMethodError
289
+ handle_no_method_error
290
+ end
291
+ end
292
+
293
+ ##
294
+ # Returns the arc tangent of +z+
295
+ #
296
+ # CMath.atan(1 + 1i) #=> (1.0172219678978514+0.4023594781085251i)
297
+ def atan(z)
298
+ begin
299
+ if z.real?
300
+ RealMath.atan(z)
301
+ else
302
+ 1.0.i * log((1.0.i + z) / (1.0.i - z)) / 2.0
303
+ end
304
+ rescue NoMethodError
305
+ handle_no_method_error
306
+ end
307
+ end
308
+
309
+ ##
310
+ # returns the arc tangent of +y+ divided by +x+ using the signs of +y+ and
311
+ # +x+ to determine the quadrant
312
+ #
313
+ # CMath.atan2(1 + 1i, 0) #=> (1.5707963267948966+0.0i)
314
+ def atan2(y,x)
315
+ begin
316
+ if y.real? and x.real?
317
+ RealMath.atan2(y,x)
318
+ else
319
+ (-1.0).i * log((x + 1.0.i * y) / sqrt(x * x + y * y))
320
+ end
321
+ rescue NoMethodError
322
+ handle_no_method_error
323
+ end
324
+ end
325
+
326
+ ##
327
+ # returns the inverse hyperbolic sine of +z+
328
+ #
329
+ # CMath.asinh(1 + 1i) #=> (1.0612750619050357+0.6662394324925153i)
330
+ def asinh(z)
331
+ begin
332
+ if z.real?
333
+ RealMath.asinh(z)
334
+ else
335
+ log(z + sqrt(1.0 + z * z))
336
+ end
337
+ rescue NoMethodError
338
+ handle_no_method_error
339
+ end
340
+ end
341
+
342
+ ##
343
+ # returns the inverse hyperbolic cosine of +z+
344
+ #
345
+ # CMath.acosh(1 + 1i) #=> (1.0612750619050357+0.9045568943023813i)
346
+ def acosh(z)
347
+ begin
348
+ if z.real? and z >= 1
349
+ RealMath.acosh(z)
350
+ else
351
+ log(z + sqrt(z * z - 1.0))
352
+ end
353
+ rescue NoMethodError
354
+ handle_no_method_error
355
+ end
356
+ end
357
+
358
+ ##
359
+ # returns the inverse hyperbolic tangent of +z+
360
+ #
361
+ # CMath.atanh(1 + 1i) #=> (0.4023594781085251+1.0172219678978514i)
362
+ def atanh(z)
363
+ begin
364
+ if z.real? and z >= -1 and z <= 1
365
+ RealMath.atanh(z)
366
+ else
367
+ log((1.0 + z) / (1.0 - z)) / 2.0
368
+ end
369
+ rescue NoMethodError
370
+ handle_no_method_error
371
+ end
372
+ end
373
+
374
+ module_function :exp!
375
+ module_function :exp
376
+ module_function :log!
377
+ module_function :log
378
+ module_function :log2!
379
+ module_function :log2
380
+ module_function :log10!
381
+ module_function :log10
382
+ module_function :sqrt!
383
+ module_function :sqrt
384
+ module_function :cbrt!
385
+ module_function :cbrt
386
+
387
+ module_function :sin!
388
+ module_function :sin
389
+ module_function :cos!
390
+ module_function :cos
391
+ module_function :tan!
392
+ module_function :tan
393
+
394
+ module_function :sinh!
395
+ module_function :sinh
396
+ module_function :cosh!
397
+ module_function :cosh
398
+ module_function :tanh!
399
+ module_function :tanh
400
+
401
+ module_function :asin!
402
+ module_function :asin
403
+ module_function :acos!
404
+ module_function :acos
405
+ module_function :atan!
406
+ module_function :atan
407
+ module_function :atan2!
408
+ module_function :atan2
409
+
410
+ module_function :asinh!
411
+ module_function :asinh
412
+ module_function :acosh!
413
+ module_function :acosh
414
+ module_function :atanh!
415
+ module_function :atanh
416
+
417
+ module_function :frexp
418
+ module_function :ldexp
419
+ module_function :hypot
420
+ module_function :erf
421
+ module_function :erfc
422
+ module_function :gamma
423
+ module_function :lgamma
424
+
425
+ private
426
+ def handle_no_method_error # :nodoc:
427
+ if $!.name == :real?
428
+ raise TypeError, "Numeric Number required"
429
+ else
430
+ raise
431
+ end
432
+ end
433
+ module_function :handle_no_method_error
434
+
435
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cmath
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tadayoshi Funaba
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-02-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: CMath is a library that provides trigonometric and transcendental functions
42
+ for complex numbers. The functions in this module accept integers, floating-point
43
+ numbers or complex numbers as arguments.
44
+ email:
45
+ -
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - lib/cmath.rb
51
+ homepage: https://github.com/ruby/cmath
52
+ licenses:
53
+ - BSD-2-Clause
54
+ metadata: {}
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 2.5.0dev
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubyforge_project:
71
+ rubygems_version: 2.6.12
72
+ signing_key:
73
+ specification_version: 4
74
+ summary: Provides Trigonometric and Transcendental functions for complex numbers
75
+ test_files: []