extmath 2.3.0

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.
@@ -0,0 +1,804 @@
1
+ #!/usr/bin/env ruby
2
+ # Extmath version 2.3
3
+ # Extmath is a library (Ruby module) that extends Math.
4
+ # Copyright (C) 2003 Josef 'Jupp' Schugt <jupp@rubyforge.org>
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as
7
+ # published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU General Public License along with this program; if not, write to the
13
+ # Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
14
+
15
+ module Extmath
16
+
17
+ @@Inv_ln_2 = 1.0 / Math.log(2.0)
18
+ @@PI_by_2 = 0.5 * Math::PI
19
+ @@Gauss_factor = Math.sqrt(0.5 / Math::PI)
20
+
21
+ @@Deg2gon = 10.0 / 9.0
22
+ @@Deg2rad = Math::PI / 180.0
23
+ @@Gon2deg = 0.9
24
+ @@Gon2rad = Math::PI / 200.0
25
+ @@Rad2deg = 180.0 / Math::PI
26
+ @@Rad2gon = 200.0 / Math::PI
27
+
28
+ @@factorials = [ 1,
29
+ 1,
30
+ 2,
31
+ 6,
32
+ 24,
33
+ 120,
34
+ 720,
35
+ 5_040,
36
+ 40_320,
37
+ 362_880,
38
+ 3_628_800,
39
+ 39_916_800,
40
+ 479_001_600,
41
+ 6_227_020_800,
42
+ 87_178_291_200,
43
+ 1_307_674_368_000
44
+ ]
45
+
46
+ =begin
47
+ == Extmath version 2.3
48
+ === Constants
49
+ [ ((<C|Extmath::C>)) | ((<E|Extmath::E>)) | ((<PI|Extmath::PI>)) ]
50
+ === Methods
51
+ : Powers and roots
52
+ [ ((<hypot|Extmath.hypot>)) | ((<pow|Extmath.pow>)) | ((<root|Extmath.root>)) | ((<sqr|Extmath.sqr>)) | ((<sqrt|Extmath.sqrt>)) ]
53
+ : Exponential and logarithmic functions
54
+ [ ((<exp|Extmath.exp>)) | ((<exp10|Extmath.exp10>)) | ((<exp2|Extmath.exp2>)) | ((<frexp|Extmath.frexp>)) |
55
+ ((<ldexp|Extmath.ldexp>)) | ((<log|Extmath.log>)) | ((<log10|Extmath.log10>)) | ((<log2|Extmath.log2>)) ]
56
+ : Trigonometric functions
57
+ [ ((<acos|Extmath.acos>)) | ((<acot|Extmath.acot>)) | ((<acsc|Extmath.acsc>)) | ((<asec|Extmath.asec>)) | ((<asin|Extmath.asin>))
58
+ | ((<atan|Extmath.atan>)) | ((<atan2|Extmath.atan2>)) | ((<cos|Extmath.cos>)) | ((<cot|Extmath.cot>)) | ((<csc|Extmath.csc>)) |
59
+ ((<sec|Extmath.sec>)) | ((<sin|Extmath.sin>)) | ((<tan|Extmath.tan>)) ]
60
+ : Hyperbolic functions
61
+ [ ((<acosh|Extmath.acosh>)) | ((<acoth|Extmath.acoth>)) | ((<acsch|Extmath.acsch>)) | ((<asech|Extmath.asech>)) |
62
+ ((<asinh|Extmath.asinh>)) | ((<atanh|Extmath.atanh>)) | ((<cosh|Extmath.cosh>)) | ((<coth|Extmath.coth>)) |
63
+ ((<csch|Extmath.csch>)) | ((<sech|Extmath.sech>)) | ((<sinh|Extmath.sinh>)) | ((<tanh|Extmath.tanh>)) ]
64
+ : Conversion between degree, gon and radian
65
+ [ ((<deg2gon|Extmath.deg2gon>)) | ((<deg2rad|Extmath.deg2rad>)) | ((<gon2deg|Extmath.gon2deg>)) | ((<gon2rad|Extmath.gon2rad>)) |
66
+ ((<rad2deg|Extmath.rad2deg>)) | ((<rad2gon|Extmath.rad2gon>)) ]
67
+ : Special functions
68
+ [ ((<beta|Extmath.beta>)) | ((<erf|Extmath.erf>)) | ((<erfc|Extmath.erfc>)) | ((<lgamma|Extmath.lgamma>)) |
69
+ ((<sinc|Extmath.sinc>)) | ((<tgamma|Extmath.tgamma>)) ]
70
+ : Absolute value, sign and rounding
71
+ [ ((<abs|Extmath.abs>)) | ((<ceil|Extmath.ceil>)) | ((<floor|Extmath.floor>)) | ((<round|Extmath.round>)) |
72
+ ((<sign|Extmath.sign>)) ]
73
+ : Integer functions
74
+ [ ((<delta|Extmath.delta>)) | ((<epsilon|Extmath.epsilon>)) | ((<factorial|Extmath.factorial>)) | ((<gcd|Extmath.gcd>)) |
75
+ ((<lcm|Extmath.lcm>)) ]
76
+ : Solver
77
+ [ ((<linsolve|Extmath.linsolve>)) | ((<sqsolve|Extmath.sqsolve>)) ]
78
+ =end
79
+
80
+ =begin
81
+ == Constants
82
+ --- Extmath::C
83
+ Euler's constant ((*C*)), (({Extmath.C = 0.577_2...}))
84
+ =end
85
+ C = 0.577_215_664_901_532_861
86
+
87
+ =begin
88
+ --- Extmath::E
89
+ Same as (({Math::E})) - Euler's number, (({Extmath.E = 2.718_182_8...}))
90
+ =end
91
+ E = Math::E
92
+
93
+ =begin
94
+ --- Extmath::PI
95
+ Same as (({Math::PI})) - Ludolph's number, (({Extmath.PI = 3.141_59..})).
96
+ =end
97
+ PI = Math::PI
98
+
99
+ =begin
100
+ == Methods
101
+ --- Extmath.abs(x)
102
+ Absolute value of ((|x|))
103
+ =end
104
+ def Extmath.abs(x)
105
+ x.abs
106
+ end
107
+
108
+ =begin
109
+ --- Extmath.acos(x)
110
+ Same as (({Math.acos(((|x|)))})) - arcus cotangens of ((|x|))
111
+ =end
112
+ def Extmath.acos(x)
113
+ Math.acos(x)
114
+ end
115
+
116
+ =begin
117
+ --- Extmath.acosh(x)
118
+ Same as (({Math.acosh(((|x|)))})) - area cosinus hyperbolicus of ((|x|))
119
+ =end
120
+ def Extmath.acosh(x)
121
+ Math.acosh(x)
122
+ end
123
+
124
+ =begin
125
+ --- Extmath.acot(x)
126
+ Arcus cotangens of ((|x|))
127
+ =end
128
+ def Extmath.acot(x)
129
+ @@PI_by_2 - Math.atan(x)
130
+ end
131
+
132
+ =begin
133
+ --- Extmath.acoth(x)
134
+ Area cotangens hyperbolicus of ((|x|))
135
+ =end
136
+ def Extmath.acoth(x)
137
+ 0.5 * Math.log((x + 1.0) / (x - 1.0))
138
+ end
139
+
140
+ =begin
141
+ --- Extmath.acsc(x)
142
+ Arcus cosecans of ((|x|))
143
+ =end
144
+ def Extmath.acsc(x)
145
+ Math.asin(1.0 / x)
146
+ end
147
+
148
+ =begin
149
+ --- Extmath.acsch(x)
150
+ Area cosecans hyperbolicus of ((|x|))
151
+ =end
152
+ def Extmath.acsch(x)
153
+ Math.log(1.0 / x + Math.sqrt(1.0 + 1.0 / (x * x)))
154
+ end
155
+
156
+ =begin
157
+ --- Extmath.asec(x)
158
+ Arcus secans of ((|x|))
159
+ =end
160
+ def Extmath.asec(x)
161
+ Math.acos(1.0 / x)
162
+ end
163
+
164
+ =begin
165
+ --- Extmath.asech(x)
166
+ Area secans hyperbolicus of ((|x|))
167
+ =end
168
+ def Extmath.asech(x)
169
+ Math.log((1.0 + Math.sqrt(1.0 - x * x)) / x)
170
+ end
171
+
172
+ =begin
173
+ --- Extmath.asin(x)
174
+ Same as (({Math.asin(((|x|)))})) - arcus sinus of ((|x|))
175
+ =end
176
+ def Extmath.asin(x)
177
+ Math.asin(x)
178
+ end
179
+
180
+ =begin
181
+ --- Extmath.asinh(x)
182
+ Same as (({Math.sinh(((|x|)))})) - area sinus hyperbolicus of ((|x|))
183
+ =end
184
+ def Extmath.asinh(x)
185
+ Math.asinh(x)
186
+ end
187
+
188
+ =begin
189
+ --- Extmath.atan(x)
190
+ Same as (({Math.atan(((|x|)))})) - arcus tangens of ((|x|))
191
+ =end
192
+ def Extmath.atan(x)
193
+ Math.atan(x)
194
+ end
195
+
196
+ =begin
197
+ --- Extmath.atan2(x, y)
198
+ Same as (({Math.atan2(((|x|)), ((|y|)))})) - arcus tangens of ((|x|)) over
199
+ ((|y|))
200
+ =end
201
+ def Extmath.atan2(x, y)
202
+ Math.atan2(x, y)
203
+ end
204
+
205
+ =begin
206
+ --- Extmath.atanh(x)
207
+ Same as (({Math.atanh(((|x|)))})) - area tangens hyperbolicus of ((|x|))
208
+ =end
209
+ def Extmath.atanh(x)
210
+ Math.atanh(x)
211
+ end
212
+
213
+ =begin
214
+ --- Extmath.beta(x, y)
215
+ Beta function of ((|x|)) and ((|y|)) - (({beta(((|x|)), ((|y|))) =
216
+ tgamma(((|x|))) * tgamma(((|y|))) / tgamma(((|x|)) + ((|y|)))}))
217
+ =end
218
+ def Extmath.beta(x, y)
219
+ Math.exp(Extmath.lgamma(x) + Extmath.lgamma(y) - Extmath.lgamma(x+y))
220
+ end
221
+
222
+ =begin
223
+ --- Extmath.ceil(x)
224
+ Smallest integer not smaller than ((|x|))
225
+ =end
226
+ def Extmath.ceil(x)
227
+ x.ceil
228
+ end
229
+
230
+ =begin
231
+ --- Extmath.cos(x)
232
+ Same as (({Math.cos(((|x|)))})) - cosinus of ((|x|))
233
+ =end
234
+ def Extmath.cos(x)
235
+ Math.cos(x)
236
+ end
237
+
238
+ =begin
239
+ --- Extmath.cosh(x)
240
+ Same as (({Math.cosh(((|x|)))})) - cosinus hyperbolicus of ((|x|))
241
+ =end
242
+ def Extmath.cosh(x)
243
+ Math.cosh(x)
244
+ end
245
+
246
+ =begin
247
+ --- Extmath.cot(x)
248
+ Cotangens of ((|x|))
249
+ =end
250
+ def Extmath.cot(x)
251
+ Math.tan(@@PI_by_2 - x)
252
+ end
253
+
254
+ =begin
255
+ --- Extmath.coth(x)
256
+ Cotangens hyperbolicus of ((|x|))
257
+ =end
258
+ def Extmath.coth(x)
259
+ 1.0 / Math.tanh(x)
260
+ end
261
+
262
+ =begin
263
+ --- Extmath.csc(x)
264
+ Cosecans of ((|x|))
265
+ =end
266
+ def Extmath.csc(x)
267
+ 1.0 / Math.sin(x)
268
+ end
269
+
270
+ =begin
271
+ --- Extmath.csch(x)
272
+ Cosecans hyperbolicus of ((|x|))
273
+ =end
274
+ def Extmath.csch(x)
275
+ 1.0 / Math.sinh(x)
276
+ end
277
+
278
+ =begin
279
+ --- Extmath.deg2gon(x)
280
+ Converts ((|x|)) form degree to gon
281
+ =end
282
+ def Extmath.deg2gon(x)
283
+ return @@Deg2gon * x
284
+ end
285
+
286
+ =begin
287
+ --- Extmath.deg2rad(x)
288
+ Converts ((|x|)) form degree to radian
289
+ =end
290
+ def Extmath.deg2rad(x)
291
+ return @@Deg2rad * x
292
+ end
293
+
294
+ =begin
295
+ --- Extmath.delta(i, j)
296
+ Kronecker symbol of ((|i|)) and ((|j|)) - 1 if ((|i|)) and ((|j|)) are equal, 0 otherwise
297
+ =end
298
+ def Extmath.delta(i, j)
299
+ return Integer(i) == Integer(j) ? 1 : 0
300
+ end
301
+
302
+ =begin
303
+ --- Extmath.epsilon(i, j, k)
304
+ Levi-Civita symbol of ((|i|)), ((|j|)), and ((|k|)) - 1 if (((|i|)), ((|j|)), ((|k|))) is (1, 2, 3), (2, 3, 1), or (3, 1, 2),
305
+ -1 if it is (1, 3, 2), (2, 1, 3), or (3, 2, 1), 0 as long as ((|i|)), ((|j|)), and ((|k|)) are all elements of {1, 2, 3},
306
+ otherwise returns (({nil})).
307
+ =end
308
+ def Extmath.epsilon(i, j, k)
309
+ i = Integer(i)
310
+ return nil if i < 1 or i > 3
311
+ j = Integer(j)
312
+ return nil if j < 1 or j > 3
313
+ k = Integer(k)
314
+ return nil if k < 1 or k > 3
315
+ case i * 16 + j * 4 + k
316
+ when 27, 45, 54 then return 1
317
+ when 30, 39, 57 then return -1
318
+ end
319
+ 0
320
+ end
321
+
322
+ =begin
323
+ --- Extmath.erf(x)
324
+ Same as (({Math.erf(((|x|)))})) - Gau�ian error integral up to ((|x|))
325
+ =end
326
+ def Extmath.erf(x)
327
+ Math.erf(x)
328
+ end
329
+
330
+ =begin
331
+ --- Extmath.erfc(x)
332
+ Same as (({Math.erfc(((|x|)))})) - complementary Gau�ian error integral from ((|x|)) on
333
+ =end
334
+ def Extmath.erfc(x)
335
+ Math.erfc(x)
336
+ end
337
+
338
+ =begin
339
+ --- Extmath.exp(x)
340
+ Same as (({Math.exp(((|x|)))})) - e to the power ((|x|))
341
+ =end
342
+ def Extmath.exp(x)
343
+ Math.exp(x)
344
+ end
345
+
346
+ =begin
347
+ --- Extmath.exp10(x)
348
+ 10 to the power ((|x|))
349
+ =end
350
+ def Extmath.exp10(x)
351
+ 10.0 ** x
352
+ end
353
+
354
+ =begin
355
+ --- Extmath.exp2(x)
356
+ 2 to the power ((|x|))
357
+ =end
358
+ def Extmath.exp2(x)
359
+ 2.0 ** x
360
+ end
361
+
362
+ =begin
363
+ --- Extmath.factorial(n)
364
+ 1 * 2 * ... * ((|n|)), (({nil})) for negative numbers
365
+ =end
366
+ def Extmath.factorial(n)
367
+ n = Integer(n)
368
+ if n < 0
369
+ nil
370
+ elsif @@factorials.length > n
371
+ @@factorials[n]
372
+ else
373
+ h = @@factorials.last
374
+ (@@factorials.length .. n).each { |i| @@factorials.push h *= i }
375
+ h
376
+ end
377
+ end
378
+
379
+ =begin
380
+ --- Extmath.floor(x)
381
+ Largest integer not larger than ((|x|))
382
+ =end
383
+ def Extmath.floor(x)
384
+ x.floor
385
+ end
386
+
387
+ =begin
388
+ --- Extmath.frexp(x)
389
+ Same as (({Math.frexp(((|x|)))})) - two-element array containing the normalized fraction and exponent of ((|x|)).
390
+ =end
391
+ def Extmath.frexp(x)
392
+ Math.frexp(x)
393
+ end
394
+
395
+ =begin
396
+ --- Extmath.gcd(m, n)
397
+ Greatest common divisor of ((|m|)) and ((|n|)), (({nil})) for non-positive numbers - gcd is computed by means of the Euklidian
398
+ algorithm
399
+ =end
400
+ def Extmath.gcd(m, n)
401
+ m = Integer(m)
402
+ n = Integer(n)
403
+ if m <= 0 || n <= 0
404
+ return nil
405
+ end
406
+ loop {
407
+ if m < n
408
+ m, n = n, m
409
+ end
410
+ if (l = m % n) == 0
411
+ break
412
+ end
413
+ m = l
414
+ }
415
+ n
416
+ end
417
+
418
+ =begin
419
+ --- Extmath.gon2deg(x)
420
+ Converts ((|x|)) form gon to degree
421
+ =end
422
+ def Extmath.gon2deg(x)
423
+ return @@Gon2deg * x
424
+ end
425
+
426
+ =begin
427
+ --- Extmath.gon2rad(x)
428
+ Converts ((|x|)) form gon to radian
429
+ =end
430
+ def Extmath.gon2rad(x)
431
+ return @@Gon2rad * x
432
+ end
433
+
434
+ =begin
435
+ --- Extmath.hypot(x, y)
436
+ Same as (({Math.hypot(((|x|)), ((|y|)))})) - length of hypotenuse of a rectangular triangle with sides ((|x|)) and ((|y|)).
437
+ =end
438
+ def Extmath.hypot(x, y)
439
+ Math.hypot(x, y)
440
+ end
441
+
442
+ =begin
443
+ --- Extmath.lcm(m, n)
444
+ Least common multiple of ((|m|)) and ((|n|)) - computed by multiplying ((|m|)) and ((|n|)) and dividing the product by the gcd
445
+ of ((|m|)) and ((|n|)), (({nil})) for non-positive numbers.
446
+ =end
447
+ def Extmath.lcm(m, n)
448
+ m = Integer(m)
449
+ n = Integer(n)
450
+ if m <= 0 || n <= 0
451
+ return nil
452
+ end
453
+ m / gcd(m, n) * n
454
+ end
455
+
456
+ =begin
457
+ --- Extmath.ldexp(x, y)
458
+ ((|x|)) times 2 to the power ((|y|))
459
+ =end
460
+ def Extmath.ldexp(x, y)
461
+ Math.ldexp(x, y)
462
+ end
463
+
464
+ =begin
465
+ --- Extmath.lgamma(x)
466
+ Logarithmus naturalis of gamma function of ((|x|))
467
+ =end
468
+ def Extmath.lgamma(x)
469
+ h = x + 5.5
470
+ h -= (x + 0.5) * log(h)
471
+ sum = 1.000_000_000_190_015
472
+ sum += 76.180_091_729_471_46 / (x + 1.0)
473
+ sum -= 86.505_320_329_416_77 / (x + 2.0)
474
+ sum += 24.014_098_240_830_91 / (x + 3.0)
475
+ sum -= 1.231_739_572_450_155 / (x + 4.0)
476
+ sum += 0.120_865_097_386_617_9e-2 / (x + 5.0)
477
+ sum -= 0.539_523_938_495_3e-5 / (x + 6.0)
478
+ -h + log(2.506_628_274_631_000_5 * sum / x)
479
+ end
480
+
481
+ =begin
482
+ --- Extmath.linsolve(a, b, c)
483
+ Returns real solution(s) of (({((|a|))x + ((|b|)) = ((|c|))})) or (({nil})) if no or an infinite number of solutions exist. If
484
+ (({c})) is missing it is assumed to be 0.
485
+ =end
486
+ def Extmath.linsolve(a, b, c = 0.0)
487
+ a == 0 ? nil : (c - b) / a
488
+ end
489
+
490
+ =begin
491
+ --- Extmath.log(x)
492
+ Same as (({Math.log(((|x|)))})) - logarithmus naturalis of ((|x|))
493
+ =end
494
+ def Extmath.log(x)
495
+ Math.log(x)
496
+ end
497
+
498
+ =begin
499
+ --- Extmath.log10(x)
500
+ Same as (({Math.log10(((|x|)))})) - logarithmus decimalis of ((|x|))
501
+ =end
502
+ def Extmath.log10(x)
503
+ Math.log10(x)
504
+ end
505
+
506
+ =begin
507
+ --- Extmath.log2(x)
508
+ Logarithmus dualis of ((|x|))
509
+ =end
510
+ def Extmath.log2(x)
511
+ Math.log(x) * @@Inv_ln_2
512
+ end
513
+
514
+ =begin
515
+ --- Extmath.pow(x, y)
516
+ ((|x|)) to the power ((|y|))
517
+ =end
518
+ def Extmath.pow(x, y)
519
+ x ** y
520
+ end
521
+
522
+ =begin
523
+ --- Extmath.rad2deg(x)
524
+ Converts ((|x|)) form radian to degree
525
+ =end
526
+ def Extmath.rad2deg(x)
527
+ return @@Rad2deg * x
528
+ end
529
+
530
+ =begin
531
+ --- Extmath.rad2gon(x)
532
+ Converts ((|x|)) form radian to gon
533
+ =end
534
+ def Extmath.rad2gon(x)
535
+ return @@Rad2gon * x
536
+ end
537
+
538
+ =begin
539
+ --- Extmath.root(x, y)
540
+ ((|y|))-th root of ((|x|))
541
+ =end
542
+ def Extmath.root(x, y)
543
+ x ** (1.0 / y)
544
+ end
545
+
546
+ =begin
547
+ --- Extmath.round(x)
548
+ ((|x|)) rounded to nearest integer
549
+ =end
550
+ def Extmath.round(x)
551
+ x.round
552
+ end
553
+
554
+ =begin
555
+ --- Extmath.sec(x)
556
+ Secans of ((|x|))
557
+ =end
558
+ def Extmath.sec(x)
559
+ 1.0 / Math.cos(x)
560
+ end
561
+
562
+ =begin
563
+ --- Extmath.sech(x)
564
+ Secans hyperbolicus of ((|x|))
565
+ =end
566
+ def Extmath.sech(x)
567
+ 1.0 / Math.cosh(x)
568
+ end
569
+
570
+ =begin
571
+ --- Extmath.sign(x)
572
+ Sign of ((|x|)) - -1 for negative ((|x|)), +1 for positive ((|x|)) and zero for ((|x|)) = 0
573
+ =end
574
+ def Extmath.sign(x)
575
+ (x > 0.0) ? 1.0 : ((x < 0.0) ? -1.0 : 0.0)
576
+ end
577
+
578
+ =begin
579
+ --- Extmath.sin(x)
580
+ Same as (({Math.sin(((|x|)))})) - sinus of ((|x|))
581
+ =end
582
+ def Extmath.sin(x)
583
+ Math.sin(x)
584
+ end
585
+
586
+ =begin
587
+ --- Extmath.sinc(x)
588
+ Sinc function of ((|x|))
589
+ =end
590
+ def Extmath.sinc(x)
591
+ (x == 0.0) ? 1.0 : Math.sin(x) / x
592
+ end
593
+
594
+ =begin
595
+ --- Extmath.sinh(x)
596
+ Same as (({Math.sinh(x)})) - sinus hyperbolicus of ((|x|))
597
+ =end
598
+ def Extmath.sinh(x)
599
+ Math.sinh(x)
600
+ end
601
+
602
+ =begin
603
+ --- Extmath.sqr(x)
604
+ Square of ((|x|))
605
+ =end
606
+ def Extmath.sqr(x)
607
+ x * x
608
+ end
609
+
610
+ =begin
611
+ --- Extmath.sqrt(x)
612
+ Square root of ((|x|))
613
+ =end
614
+ def Extmath.sqrt(x)
615
+ Math.sqrt(x)
616
+ end
617
+
618
+ =begin
619
+ --- Extmath.sqsolve(a, b, c, d)
620
+ Returns array of real solution of (({((|a|))x**2 + ((|b|))x + ((|c|)) = ((|d|))})) or (({nil})) if no or an infinite number of
621
+ solutions exist. If (({d})) is missing it is assumed to be 0. See ((<Solving second order equations>))
622
+ =end
623
+ def Extmath.sqsolve(a, b, c, d = 0.0)
624
+ if a == 0.0
625
+ x = linsolve(b, c, d)
626
+ return x.nil? ? nil: [ linsolve(b, c, d) ]
627
+ else
628
+ return [0.0, linsolve(a, b)].sort if c == d
629
+ if b == 0.0
630
+ x = Extmath.linsolve(a, c, d)
631
+ x < 0.0 ? nil : [-Math.sqrt(x), Math.sqrt(x)]
632
+ else
633
+ x = b * b + 4.0 * a * (d - c)
634
+ return nil if x < 0.0
635
+ x = b < 0 ? b - Math.sqrt(x) : b + Math.sqrt(x)
636
+ [-0.5 * x / a, 2.0 * (d - c) / x].sort
637
+ end
638
+ end
639
+ end
640
+
641
+ =begin
642
+ --- Extmath.tan(x)
643
+ tangens of ((|x|))
644
+ =end
645
+ def Extmath.tan(x)
646
+ Math.tan(x)
647
+ end
648
+
649
+ =begin
650
+ --- Extmath.tanh(x)
651
+ tangens hyperbolicus of ((|x|))
652
+ =end
653
+ def Extmath.tanh(x)
654
+ Math.tanh(x)
655
+ end
656
+
657
+ =begin
658
+ --- Extmath.tgamma(x)
659
+ Gamma function of ((|x|))
660
+ =end
661
+ def Extmath.tgamma(x)
662
+ Extmath.exp(Extmath.lgamma(x))
663
+ end
664
+
665
+ end
666
+
667
+ =begin
668
+ == Solving second order equations
669
+ In order to solve ((*ax**2 + bx + c = d*)) ((<Extmath.sqsolve>)) identifies several cases:
670
+ : ((*a == 0:*))
671
+ The equation to be solved is the linear equation ((*bx + c = d*)). ((<Extmath.sqsolve>)) delegates the computation to
672
+ ((<Extmath.linsolve>)). If it results in (({nil})), (({nil})) is returned (not (({[nil]}))!). Otherwise a one-element array
673
+ containing result of ((<Extmath.linsolve>)) is returned.
674
+ : ((*a != 0:*))
675
+ The equation to be solved actually is a second order one.
676
+ : ((*c == d*))
677
+ The equation to be solved is ((*ax**2 + bx = 0*)). One solution of this equation obviously is ((*x = 0*)), the second one
678
+ solves ((*ax + b = 0*)). The solution of the latter is delegated to ((<Extmath.linsolve>)). An array containing both results in
679
+ ascending order is returned.
680
+ : ((*c != d*))
681
+ The equation cannot be separated into ((*x*)) times some factor.
682
+ : ((*b == 0*))
683
+ The equation to be solved is ((*ax**2 + c = d*)). This can be written as the linear equation ((*ay + c = d*)) with
684
+ ((*y = x ** 2*)). The solution of the linear equation is delegated to ((<Extmath.linsolve>)). If the returned value for
685
+ ((*y*)) is (({nil})), that becomes the overall return value. Otherwise an array containing the negative and positive square
686
+ root of ((*y*)) is returned
687
+ : ((*b != 0 *))
688
+ The equation cannot be reduced to simpler cases. We now first have to compute what is called the discriminant
689
+ ((*x = b**2 + 4a(d - c)*)) (that's what we need to compute the square root of). If the descriminant is negative no real
690
+ solution exists and (({nil})) is returned. The ternary operator checking whether ((*b*)) is negative does ensure better
691
+ numerical stability - only one of the two solutions is computed using the widely know formula for solving second order
692
+ equations. The second one is computed from the fact that the product of both solutions is ((*(c - d) / a*)). Take a look at a
693
+ book on numerical mathematics if you don't understand why this should be done.
694
+ == Changelog
695
+ === Version 2.2 -> 2.3
696
+ ==== Renamed Constants/Functions
697
+ * ((<ExtMath.pwr|Extmath.pow>)) became ((<Extmath.pow>)) because (({pow})) is the C name for this function.
698
+ * ((<ExtMath.ln_gamma|Extmath.lgamma>)) became ((<Extmath.lgamma>)) because (({lgamma})) is the C name for this function.
699
+ * ((<ExtMath.gamma|Extmath.tgamma>)) became ((<Extmath.tgamma>)) because (({tgamma})) is the C name for this function.
700
+ ==== New Constants/Functions
701
+ * ((<Extmath.deg2gon>)) (degree to gon)
702
+ * ((<Extmath.deg2rad>)) (degree to gon)
703
+ * ((<Extmath.gon2deg>)) (gon to degree)
704
+ * ((<Extmath.gon2rad>)) (gon to radian)
705
+ * ((<Extmath.rad2deg>)) (radian to degree)
706
+ * ((<Extmath.rad2gon>)) (radian to gon)
707
+ === Version 2.1 -> 2.2
708
+ ==== Renamed Constants/Functions
709
+ * ((<Extmath.acosech|Extmath.acsch>)) became ((<Extmath.acsch>))
710
+ * ((<Extmath.cosec|Extmath.csc>)) became ((<Extmath.csc>))
711
+ * ((<Extmath.cosech|Extmath.csch>)) became ((<Extmath.csch>))
712
+ ==== New Constants/Functions
713
+ * ((<Extmath.acsc>))
714
+ * ((<Extmath.asec>))
715
+ * ((<Extmath.linsolve>))
716
+ * ((<Extmath.round>))
717
+ * ((<Extmath.sqsolve>))
718
+ * ((<Extmath::C>)) (Euler's constant ((*C*)))
719
+ ==== Changed Implementations/Values
720
+ * ((<Extmath.abs>))
721
+ * ((<Extmath.ceil>))
722
+ * ((<Extmath.floor>))
723
+ ==== Misc Changes
724
+ * README accidentally was that of
725
+ ((<tldlib|URL:http://tldlib.rubyforge.org/>)). Corrected.
726
+ * Embedded documentation did contain old name (({ExtMath})), not (({Extmath})) - 'm' and 'M' almost look the same in the font I
727
+ use. Corrected.
728
+ * Numerical constants were grouped using underbars to enhance readability.
729
+ * Changelog was cleaned up, hyperlinks were added to HTML version.
730
+ * Much work was put into documentation.
731
+ === Version 2.0 -> 2.1
732
+ ==== New constants/functions
733
+ * ((<Extmath.acosech|Extmath.csch>))
734
+ * ((<Extmath.asech>))
735
+ * ((<Extmath.delta>))
736
+ * ((<Extmath.epsilon>))
737
+ ==== Misc Changes
738
+ * New embedded documentation was written using ((<RDtool|URL:http://www2.pos.to/~tosh/ruby/rdtool/en/index.html>))
739
+ * Online documentation of library is now generated from embedded documentation.
740
+ * HTML documentation contained in zip file has been replaced by plain text equivalent generated by Elinks which is available at
741
+ ((<elinks.or.cz|URL:http://elinks.or.cz/>)).
742
+ === Version 1.7 -> 2.0
743
+ ==== Removed Constants/Functions
744
+ * (({Extmath.binomial}))
745
+ * (({Extmath.gaussian}))
746
+ * (({Extmath.sqsolve}))
747
+ ==== Renamed Constants/Functions
748
+ * ((<ExtMath.lngamma|Extmath.lgamma>)) became ((<Extmath.ln_gamma|Extmath.lgamma>))
749
+ ==== Misc Changes
750
+ * Homepage was moved to ((<extmath.rubyforge.org|URL:http://extmath.rubyforge.org/>))
751
+ * Download page was moved to ((<Rubyforge|URL:http://rubyforge.org/projects/extmath/>))
752
+ * Library now assumes Ruby 1.8
753
+ * Library was renamed from (({ExtMath})) to (({Extmath}))
754
+ * Embedded documentation was removed.
755
+ * HTML documentation was added to zip file.
756
+ * Demonstration program was replaced by test unit.
757
+ === Version 1.6 -> 1.7
758
+ ==== Changed implementations
759
+ * ((*Bugfix:*)) Value of (({@@InvLn2})) was (({Math.log(2.0)})), corrected to (({1.0 / Math.log(2.0)})). Thanks to Joseph McDonald.
760
+ === Version 1.5 -> 1.6
761
+ ==== Misc Changes
762
+ * Documentation now uses RDTool
763
+ * Changelog now generated uses RDTool
764
+ === Version 1.4 -> 1.5
765
+ ==== New Constants/Functions
766
+ * ((<ExtMath.gcd|Extmath.gcd>))
767
+ * ((<ExtMath.lcm|Extmath.lcm>))
768
+ === Version 1.3 -> 1.4
769
+ === New Constants/Functions
770
+ * (({ExtMath.binomial}))
771
+ * (({ExtMath.gaussian}))
772
+ * (({ExtMath.sqsolve}))
773
+ ==== Changed Implementations/Values
774
+ * ((<ExtMath.log2|Extmath.log2>))
775
+ * ((<ExtMath.factorial|Extmath.factorial>))
776
+ === Version 1.2 -> 1.3
777
+ ==== New Constants/Functions
778
+ * ((<ExtMath.beta|Extmath.beta>))
779
+ * ((<ExtMath.ceil|Extmath.ceil>))
780
+ * ((<ExtMath.factorial|Extmath.factorial>))
781
+ * ((<ExtMath.floor|Extmath.floor>))
782
+ ==== Changed Implementations/Values
783
+ * ((<Extmath.lngamma|Extmath.lgamma>))
784
+ * ((<ExtMath.gamma|Extmath.tgamma>))
785
+ === Version 1.1 -> 1.2
786
+ ==== New Constants/Functions
787
+ * ((<ExtMath.abs|Extmath.abs>))
788
+ * ((<ExtMath.gamma|Extmath.tgamma>))
789
+ * ((<ExtMath.lngamma|Extmath.lgamma>))
790
+ * ((<ExtMath.sign|Extmath.sign>))
791
+ * ((<ExtMath.sinc|Extmath.sinc>))
792
+ === Version 1.0 -> 1.1
793
+ ==== New Constants/Functions
794
+ * ((<ExtMath.cosec|Extmath.csc>))
795
+ * ((<ExtMath.cosech|Extmath.csch>))
796
+ * ((<ExtMath.sec|Extmath.sec>))
797
+ * ((<ExtMath.sech|Extmath.sech>))
798
+ ==== Misc Changes
799
+ * Demonstration now also uses ((<ExtMath.cosec|Extmath.csc>)), ((<ExtMath.cosech|Extmath.csch>)), ((<ExtMath.sec|Extmath.sec>)),
800
+ and ((<ExtMath.sech|Extmath.sech>)).
801
+ * Small changes of Rubydoc documentation.
802
+ === Version 1.0
803
+ * First public release
804
+ =end