extmath 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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