cmath 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []