number 0.9.4 → 0.9.5
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.
- data/ext/bounds.c +7 -6
- data/ext/compare.c +5 -5
- data/ext/complex.c +182 -162
- data/ext/interval.c +1 -1
- data/ext/number.c +3 -2
- data/ext/number.h +2 -0
- data/ext/real.c +11 -5
- metadata +2 -3
- data/README +0 -13
data/ext/bounds.c
CHANGED
@@ -29,8 +29,7 @@ void bounds_free (Bounds* bounds)
|
|
29
29
|
}
|
30
30
|
}
|
31
31
|
|
32
|
-
|
33
|
-
void bounds_update_re (Bounds* bounds, mpfr_t num, int re_closed)
|
32
|
+
void bounds_update_re (Bounds* bounds, mpfr_t num, int re_closed, int exact)
|
34
33
|
{
|
35
34
|
int min_cmp;
|
36
35
|
int max_cmp;
|
@@ -47,11 +46,12 @@ void bounds_update_re (Bounds* bounds, mpfr_t num, int re_closed)
|
|
47
46
|
if (max_cmp != 1)
|
48
47
|
{
|
49
48
|
mpfr_set(bounds->re_max, num, MPFR_RNDN);
|
49
|
+
bounds->re_max_exact = exact;
|
50
50
|
bounds->re_max_closed = (max_cmp) ? re_closed : bounds->re_max_closed || re_closed;
|
51
51
|
}
|
52
52
|
}
|
53
53
|
|
54
|
-
void bounds_update_im (Bounds* bounds, mpfr_t num, int im_closed)
|
54
|
+
void bounds_update_im (Bounds* bounds, mpfr_t num, int im_closed, int exact)
|
55
55
|
{
|
56
56
|
int min_cmp;
|
57
57
|
int max_cmp;
|
@@ -68,11 +68,12 @@ void bounds_update_im (Bounds* bounds, mpfr_t num, int im_closed)
|
|
68
68
|
if (max_cmp != 1)
|
69
69
|
{
|
70
70
|
mpfr_set(bounds->im_max, num, MPFR_RNDN);
|
71
|
+
bounds->im_max_exact = exact;
|
71
72
|
bounds->im_max_closed = (max_cmp) ? im_closed : bounds->im_max_closed || im_closed;
|
72
73
|
}
|
73
74
|
}
|
74
75
|
|
75
|
-
void bounds_update (Bounds* bounds, mpc_t num, int re_closed, int im_closed)
|
76
|
+
void bounds_update (Bounds* bounds, mpc_t num, int re_closed, int im_closed, int mpc_inex)
|
76
77
|
{
|
77
78
|
mpfr_t re;
|
78
79
|
mpfr_t im;
|
@@ -83,8 +84,8 @@ void bounds_update (Bounds* bounds, mpc_t num, int re_closed, int im_closed)
|
|
83
84
|
mpc_real(re, num, MPFR_RNDN);
|
84
85
|
mpc_imag(im, num, MPFR_RNDN);
|
85
86
|
|
86
|
-
bounds_update_re(bounds, re, re_closed);
|
87
|
-
bounds_update_im(bounds, im, im_closed);
|
87
|
+
bounds_update_re(bounds, re, re_closed, MPC_INEX_RE(mpc_inex) == 0);
|
88
|
+
bounds_update_im(bounds, im, im_closed, MPC_INEX_IM(mpc_inex) == 0);
|
88
89
|
|
89
90
|
mpfr_clear(re);
|
90
91
|
mpfr_clear(im);
|
data/ext/compare.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#include "number.h"
|
2
2
|
|
3
|
-
int
|
3
|
+
int complex_re_enclose_p (Complex* a, Complex* b)
|
4
4
|
{
|
5
5
|
return interval_span_p(a->re, b->re->l) && interval_span_p(a->re, b->re->u);
|
6
6
|
}
|
@@ -355,7 +355,7 @@ int complex_im_contain_zero_p (Complex* complex)
|
|
355
355
|
return interval_span_zero_p(complex->im);
|
356
356
|
}
|
357
357
|
|
358
|
-
int
|
358
|
+
int complex_im_enclose_p (Complex* a, Complex* b)
|
359
359
|
{
|
360
360
|
return interval_span_p(a->im, b->im->l) && interval_span_p(a->im, b->im->u);
|
361
361
|
}
|
@@ -620,9 +620,9 @@ int complex_im_u_le_u_p (Complex* a, Complex* b)
|
|
620
620
|
return real_le_p(a->im->u, b->im->u);
|
621
621
|
}
|
622
622
|
|
623
|
-
int
|
623
|
+
int complex_enclose_p (Complex* a, Complex* b)
|
624
624
|
{
|
625
|
-
return
|
625
|
+
return complex_re_enclose_p(a, b) && complex_im_enclose_p(a, b);
|
626
626
|
}
|
627
627
|
|
628
628
|
int complex_contain_ll_p (Complex* a, Complex* b)
|
@@ -657,7 +657,7 @@ int complex_contain_zero_p (Complex* complex)
|
|
657
657
|
|
658
658
|
int complex_intersect_p (Complex* a, Complex* b)
|
659
659
|
{
|
660
|
-
return (complex_re_intersect_p(a, b) && complex_im_intersect_p(a, b)) || complex_contain_ll_p(a, b) || complex_contain_lu_p(a, b) || complex_contain_ul_p(a, b) || complex_contain_uu_p(a, b) || (
|
660
|
+
return (complex_re_intersect_p(a, b) && complex_im_intersect_p(a, b)) || complex_contain_ll_p(a, b) || complex_contain_lu_p(a, b) || complex_contain_ul_p(a, b) || complex_contain_uu_p(a, b) || (complex_re_enclose_p(a, b) && complex_im_enclose_p(b, a) || (complex_im_enclose_p(a, b) && complex_re_enclose_p(b, a)));
|
661
661
|
}
|
662
662
|
|
663
663
|
int complex_disjoint_p (Complex* a, Complex* b)
|
data/ext/complex.c
CHANGED
@@ -1,9 +1,73 @@
|
|
1
1
|
#include "number.h"
|
2
2
|
|
3
|
+
mpfr_t tmp_complex_from_float_str,
|
4
|
+
tmp_divide_re,
|
5
|
+
tmp_divide_im,
|
6
|
+
tmp_abs_n_re,
|
7
|
+
tmp_abs_ll_re,
|
8
|
+
tmp_abs_lu_re,
|
9
|
+
tmp_abs_ul_re,
|
10
|
+
tmp_abs_uu_re,
|
11
|
+
tmp_abs_re_abs,
|
12
|
+
tmp_abs_im_abs,
|
13
|
+
tmp_abs_zero,
|
14
|
+
tmp_diagonal,
|
15
|
+
tmp_sqrt_n_re,
|
16
|
+
tmp_sqrt_n_im;
|
17
|
+
|
18
|
+
mpc_t tmp_divide_numerator,
|
19
|
+
tmp_divide_denominator,
|
20
|
+
tmp_divide_quotient,
|
21
|
+
tmp_abs_n,
|
22
|
+
tmp_abs_ll,
|
23
|
+
tmp_abs_lu,
|
24
|
+
tmp_abs_ul,
|
25
|
+
tmp_abs_uu,
|
26
|
+
tmp_sqrt_n,
|
27
|
+
tmp_sqrt_ll,
|
28
|
+
tmp_sqrt_lu,
|
29
|
+
tmp_sqrt_ul,
|
30
|
+
tmp_sqrt_uu,
|
31
|
+
tmp_sqrt_re_sqrt;
|
32
|
+
|
33
|
+
void init_complex_tmp_nums ()
|
34
|
+
{
|
35
|
+
mpfr_init2(tmp_complex_from_float_str, PREC);
|
36
|
+
mpfr_init2(tmp_divide_re, PREC);
|
37
|
+
mpfr_init2(tmp_divide_im, PREC);
|
38
|
+
mpfr_init2(tmp_abs_ll_re, PREC);
|
39
|
+
mpfr_init2(tmp_abs_n_re, PREC);
|
40
|
+
mpfr_init2(tmp_abs_ll_re, PREC);
|
41
|
+
mpfr_init2(tmp_abs_lu_re, PREC);
|
42
|
+
mpfr_init2(tmp_abs_ul_re, PREC);
|
43
|
+
mpfr_init2(tmp_abs_uu_re, PREC);
|
44
|
+
mpfr_init2(tmp_abs_re_abs, PREC);
|
45
|
+
mpfr_init2(tmp_abs_im_abs, PREC);
|
46
|
+
mpfr_init2(tmp_abs_zero, PREC);
|
47
|
+
mpfr_init2(tmp_diagonal, PREC);
|
48
|
+
mpfr_init2(tmp_sqrt_n_re, PREC);
|
49
|
+
mpfr_init2(tmp_sqrt_n_im, PREC);
|
50
|
+
|
51
|
+
mpc_init2(tmp_divide_numerator, PREC);
|
52
|
+
mpc_init2(tmp_divide_denominator, PREC);
|
53
|
+
mpc_init2(tmp_divide_quotient, PREC);
|
54
|
+
mpc_init2(tmp_abs_n, PREC);
|
55
|
+
mpc_init2(tmp_abs_ll, PREC);
|
56
|
+
mpc_init2(tmp_abs_lu, PREC);
|
57
|
+
mpc_init2(tmp_abs_ul, PREC);
|
58
|
+
mpc_init2(tmp_abs_uu, PREC);
|
59
|
+
mpc_init2(tmp_sqrt_n, PREC);
|
60
|
+
mpc_init2(tmp_sqrt_ll, PREC);
|
61
|
+
mpc_init2(tmp_sqrt_lu, PREC);
|
62
|
+
mpc_init2(tmp_sqrt_ul, PREC);
|
63
|
+
mpc_init2(tmp_sqrt_uu, PREC);
|
64
|
+
mpc_init2(tmp_sqrt_re_sqrt, PREC);
|
65
|
+
}
|
66
|
+
|
3
67
|
/*
|
4
68
|
* Sets the value of num to the complex value represented by re and im.
|
5
69
|
*/
|
6
|
-
void
|
70
|
+
void mpc_set_r_r (mpc_t num, Real* re, Real* im)
|
7
71
|
{
|
8
72
|
char buf[10000];
|
9
73
|
char tmp_re_buf[10000];
|
@@ -21,7 +85,11 @@ void mpc_init_set_r_r (mpc_t num, Real* re, Real* im)
|
|
21
85
|
sprintf(re_buf, "%s", NaN(re) ? "@nan@" : POS_INF(re) ? "@inf@" : "-@inf@");
|
22
86
|
}
|
23
87
|
|
24
|
-
if (
|
88
|
+
if (!im)
|
89
|
+
{
|
90
|
+
sprintf(im_buf, "0");
|
91
|
+
}
|
92
|
+
else if (REAL(im))
|
25
93
|
{
|
26
94
|
gmp_sprintf(tmp_im_buf, "%+Zd", im->num);
|
27
95
|
sprintf(im_buf, "%c0.%se%ld", *tmp_im_buf, tmp_im_buf + 1, im->exp);
|
@@ -32,15 +100,13 @@ void mpc_init_set_r_r (mpc_t num, Real* re, Real* im)
|
|
32
100
|
}
|
33
101
|
|
34
102
|
sprintf(buf, "(%s %s)", re_buf, im_buf);
|
35
|
-
|
36
|
-
mpc_init2(num, PREC);
|
37
103
|
mpc_set_str(num, buf, 10, MPC_RNDNN);
|
38
104
|
}
|
39
105
|
|
40
106
|
/*
|
41
107
|
* Sets the value of num to the floating point value represented by real.
|
42
108
|
*/
|
43
|
-
void
|
109
|
+
void mpfr_set_r (mpfr_t num, Real* real)
|
44
110
|
{
|
45
111
|
char sign;
|
46
112
|
char buf[10000];
|
@@ -56,7 +122,6 @@ void mpfr_init_set_r (mpfr_t num, Real* real)
|
|
56
122
|
sprintf(buf, "%s", NaN(real) ? "@nan@" : POS_INF(real) ? "@inf@" : "-@inf@");
|
57
123
|
}
|
58
124
|
|
59
|
-
mpfr_init2(num, PREC);
|
60
125
|
mpfr_set_str(num, buf, 10, MPFR_RNDN);
|
61
126
|
}
|
62
127
|
|
@@ -171,17 +236,14 @@ Complex* complex_from_int_str (char* buf)
|
|
171
236
|
*/
|
172
237
|
Complex* complex_from_float_str (char* buf)
|
173
238
|
{
|
174
|
-
mpfr_t num;
|
175
239
|
Real* real;
|
176
240
|
Complex* result;
|
177
241
|
|
178
|
-
|
179
|
-
mpfr_set_str(num, buf, 10, MPFR_RNDN);
|
242
|
+
mpfr_set_str(tmp_complex_from_float_str, buf, 10, MPFR_RNDN);
|
180
243
|
|
181
|
-
real = (Real*)real_from_mpfr(
|
244
|
+
real = (Real*)real_from_mpfr(tmp_complex_from_float_str, ROUND_NEAREST);
|
182
245
|
result = (Complex*)complex_from_real(real);
|
183
246
|
|
184
|
-
mpfr_clear(num);
|
185
247
|
real_free(real);
|
186
248
|
|
187
249
|
return result;
|
@@ -323,11 +385,6 @@ Complex* complex_multiply (Complex* a, Complex* b)
|
|
323
385
|
*/
|
324
386
|
Complex* complex_divide (Complex* a, Complex* b)
|
325
387
|
{
|
326
|
-
mpc_t num_numerator;
|
327
|
-
mpc_t num_denominator;
|
328
|
-
mpc_t num_quotient;
|
329
|
-
mpfr_t num_re;
|
330
|
-
mpfr_t num_im;
|
331
388
|
Interval* denominator_re;
|
332
389
|
Interval* denominator_im;
|
333
390
|
Interval* denominator;
|
@@ -346,26 +403,22 @@ Complex* complex_divide (Complex* a, Complex* b)
|
|
346
403
|
|
347
404
|
if (real_zero_p(denominator->l) || real_zero_p(denominator->u) || interval_span_zero_p(denominator))
|
348
405
|
{
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
mpc_init_set_r_r(num_denominator, b->re->n, b->im->n);
|
406
|
+
mpfr_set_prec(tmp_divide_re, PREC);
|
407
|
+
mpfr_set_prec(tmp_divide_im, PREC);
|
408
|
+
mpc_set_prec(tmp_divide_quotient, PREC);
|
409
|
+
mpc_set_prec(tmp_divide_numerator, PREC);
|
410
|
+
mpc_set_prec(tmp_divide_denominator, PREC);
|
355
411
|
|
356
|
-
|
412
|
+
mpc_set_r_r(tmp_divide_numerator, a->re->n, a->im->n);
|
413
|
+
mpc_set_r_r(tmp_divide_denominator, b->re->n, b->im->n);
|
357
414
|
|
358
|
-
|
359
|
-
mpc_imag(num_im, num_quotient, MPFR_RNDN);
|
415
|
+
mpc_div(tmp_divide_quotient, tmp_divide_numerator, tmp_divide_denominator, MPC_RNDNN);
|
360
416
|
|
361
|
-
|
362
|
-
|
417
|
+
mpc_real(tmp_divide_re, tmp_divide_quotient, MPFR_RNDN);
|
418
|
+
mpc_imag(tmp_divide_im, tmp_divide_quotient, MPFR_RNDN);
|
363
419
|
|
364
|
-
|
365
|
-
|
366
|
-
mpc_clear(num_quotient);
|
367
|
-
mpfr_clear(num_re);
|
368
|
-
mpfr_clear(num_im);
|
420
|
+
re = (Interval*)interval_new((Real*)real_neg_inf(), true, (Real*)real_from_mpfr(tmp_divide_re, ROUND_NEAREST), true, (Real*)real_pos_inf());
|
421
|
+
im = (Interval*)interval_new((Real*)real_neg_inf(), true, (Real*)real_from_mpfr(tmp_divide_im, ROUND_NEAREST), true, (Real*)real_pos_inf());
|
369
422
|
}
|
370
423
|
else
|
371
424
|
{
|
@@ -415,102 +468,83 @@ Complex* complex_modulo (Complex* a, Complex* b)
|
|
415
468
|
*/
|
416
469
|
Complex* complex_abs (Complex* complex)
|
417
470
|
{
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
mpfr_t num_im_abs;
|
425
|
-
mpc_t num_n;
|
426
|
-
mpc_t num_ll;
|
427
|
-
mpc_t num_lu;
|
428
|
-
mpc_t num_ul;
|
429
|
-
mpc_t num_uu;
|
430
|
-
Real* re_l_abs;
|
431
|
-
Real* re_u_abs;
|
432
|
-
Real* im_l_abs;
|
433
|
-
Real* im_u_abs;
|
434
|
-
|
471
|
+
int ll_mpc_ternary;
|
472
|
+
int lu_mpc_ternary;
|
473
|
+
int ul_mpc_ternary;
|
474
|
+
int uu_mpc_ternary;
|
475
|
+
Real* l_abs;
|
476
|
+
Real* u_abs;
|
435
477
|
Bounds* bounds;
|
436
478
|
Interval* re;
|
437
479
|
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
mpc_abs(
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
480
|
+
mpfr_set_prec(tmp_abs_n_re, PREC);
|
481
|
+
mpfr_set_prec(tmp_abs_ll_re, PREC);
|
482
|
+
mpfr_set_prec(tmp_abs_lu_re, PREC);
|
483
|
+
mpfr_set_prec(tmp_abs_ul_re, PREC);
|
484
|
+
mpfr_set_prec(tmp_abs_uu_re, PREC);
|
485
|
+
mpfr_set_prec(tmp_abs_re_abs, PREC);
|
486
|
+
mpfr_set_prec(tmp_abs_im_abs, PREC);
|
487
|
+
mpfr_set_prec(tmp_abs_zero, PREC);
|
488
|
+
mpc_set_prec(tmp_abs_n, PREC);
|
489
|
+
mpc_set_prec(tmp_abs_ll, PREC);
|
490
|
+
mpc_set_prec(tmp_abs_lu, PREC);
|
491
|
+
mpc_set_prec(tmp_abs_ul, PREC);
|
492
|
+
mpc_set_prec(tmp_abs_uu, PREC);
|
493
|
+
|
494
|
+
mpc_set_r_r(tmp_abs_n, complex->re->n, complex->im->n);
|
495
|
+
mpc_abs(tmp_abs_n_re, tmp_abs_n, MPC_RNDNN);
|
496
|
+
|
497
|
+
mpc_set_r_r(tmp_abs_ll, complex->re->l, complex->im->l);
|
498
|
+
mpc_set_r_r(tmp_abs_lu, complex->re->l, complex->im->u);
|
499
|
+
mpc_set_r_r(tmp_abs_ul, complex->re->u, complex->im->l);
|
500
|
+
mpc_set_r_r(tmp_abs_uu, complex->re->u, complex->im->u);
|
501
|
+
|
502
|
+
ll_mpc_ternary = mpc_abs(tmp_abs_ll_re, tmp_abs_ll, MPC_RNDDD);
|
503
|
+
lu_mpc_ternary = mpc_abs(tmp_abs_lu_re, tmp_abs_lu, MPC_RNDDU);
|
504
|
+
ul_mpc_ternary = mpc_abs(tmp_abs_ul_re, tmp_abs_ul, MPC_RNDUD);
|
505
|
+
uu_mpc_ternary = mpc_abs(tmp_abs_uu_re, tmp_abs_uu, MPC_RNDUU);
|
462
506
|
|
463
507
|
bounds = (Bounds*)bounds_new();
|
464
|
-
bounds_update_re(bounds,
|
465
|
-
bounds_update_re(bounds,
|
466
|
-
bounds_update_re(bounds,
|
467
|
-
bounds_update_re(bounds,
|
508
|
+
bounds_update_re(bounds, tmp_abs_ll_re, complex->re->L, MPC_INEX_RE(ll_mpc_ternary) == 0);
|
509
|
+
bounds_update_re(bounds, tmp_abs_lu_re, complex->re->L, MPC_INEX_RE(lu_mpc_ternary) == 0);
|
510
|
+
bounds_update_re(bounds, tmp_abs_ul_re, complex->re->R, MPC_INEX_RE(ul_mpc_ternary) == 0);
|
511
|
+
bounds_update_re(bounds, tmp_abs_uu_re, complex->re->R, MPC_INEX_RE(uu_mpc_ternary) == 0);
|
468
512
|
|
469
513
|
if (interval_span_zero_p(complex->im))
|
470
514
|
{
|
471
|
-
|
472
|
-
|
515
|
+
l_abs = (Real*)real_abs(complex->re->l);
|
516
|
+
u_abs = (Real*)real_abs(complex->re->u);
|
473
517
|
|
474
|
-
|
475
|
-
bounds_update_re(bounds,
|
518
|
+
mpfr_set_r(tmp_abs_re_abs, real_lt_p(l_abs, u_abs) ? l_abs : u_abs);
|
519
|
+
bounds_update_re(bounds, tmp_abs_re_abs, true, true);
|
476
520
|
|
477
|
-
real_free(
|
478
|
-
real_free(
|
479
|
-
|
480
|
-
mpfr_clear(num_re_abs);
|
521
|
+
real_free(l_abs);
|
522
|
+
real_free(u_abs);
|
481
523
|
}
|
482
524
|
|
483
525
|
if (interval_span_zero_p(complex->re))
|
484
526
|
{
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
mpfr_init_set_r(num_im_abs, real_lt_p(im_l_abs, im_u_abs) ? im_l_abs : im_u_abs);
|
489
|
-
bounds_update_re(bounds, num_im_abs, true);
|
527
|
+
l_abs = (Real*)real_abs(complex->im->l);
|
528
|
+
u_abs = (Real*)real_abs(complex->im->u);
|
490
529
|
|
491
|
-
|
492
|
-
|
530
|
+
mpfr_set_r(tmp_abs_im_abs, real_lt_p(l_abs, u_abs) ? l_abs : u_abs);
|
531
|
+
bounds_update_re(bounds, tmp_abs_im_abs, true, true);
|
493
532
|
|
494
|
-
|
533
|
+
real_free(l_abs);
|
534
|
+
real_free(u_abs);
|
495
535
|
}
|
496
536
|
|
497
537
|
if (interval_span_zero_p(complex->re) && interval_span_zero_p(complex->im))
|
498
538
|
{
|
499
|
-
mpfr_set_zero(
|
500
|
-
bounds_update_re(bounds,
|
539
|
+
mpfr_set_zero(tmp_abs_zero, 1);
|
540
|
+
bounds_update_re(bounds, tmp_abs_zero, true, true);
|
501
541
|
}
|
502
542
|
|
503
|
-
re = (Interval*)interval_new(real_from_mpfr(bounds->re_min, ROUND_DOWN), bounds->re_min_closed, real_from_mpfr(
|
543
|
+
re = (Interval*)interval_new(real_from_mpfr(bounds->re_min, ROUND_DOWN), bounds->re_min_closed, real_from_mpfr(tmp_abs_n_re, ROUND_NEAREST), bounds->re_max_closed, real_from_mpfr(bounds->re_max, bounds->re_max_exact ? ROUND_UP : ROUND_UP1));
|
504
544
|
|
505
545
|
bounds_free(bounds);
|
506
546
|
|
507
|
-
|
508
|
-
mpfr_clear(num_ll_re);
|
509
|
-
mpfr_clear(num_lu_re);
|
510
|
-
mpfr_clear(num_ul_re);
|
511
|
-
mpfr_clear(num_uu_re);
|
512
|
-
|
513
|
-
return complex_new(re, (Interval*)interval_zero());
|
547
|
+
return (Complex*)complex_new(re, (Interval*)interval_zero());
|
514
548
|
}
|
515
549
|
|
516
550
|
/*
|
@@ -542,7 +576,7 @@ Complex* complex_area (Complex* complex)
|
|
542
576
|
*/
|
543
577
|
Complex* complex_diagonal (Complex* complex)
|
544
578
|
{
|
545
|
-
|
579
|
+
int mpfr_ternary;
|
546
580
|
Real* re_width;
|
547
581
|
Real* im_width;
|
548
582
|
Real* re_width2;
|
@@ -559,10 +593,10 @@ Complex* complex_diagonal (Complex* complex)
|
|
559
593
|
|
560
594
|
diag2 = (Real*)real_add(re_width2, im_width2);
|
561
595
|
|
562
|
-
|
563
|
-
mpfr_sqrt(
|
596
|
+
mpfr_set_r(tmp_diagonal, diag2);
|
597
|
+
mpfr_ternary = mpfr_sqrt(tmp_diagonal, tmp_diagonal, MPFR_RNDN);
|
564
598
|
|
565
|
-
re = (Interval*)interval_new((Real*)real_from_mpfr(
|
599
|
+
re = (Interval*)interval_new((Real*)real_from_mpfr(tmp_diagonal, ROUND_DOWN), true, (Real*)real_from_mpfr(tmp_diagonal, ROUND_NEAREST), true, (Real*)real_from_mpfr(tmp_diagonal, (mpfr_ternary == 0) ? ROUND_UP : ROUND_UP1));
|
566
600
|
|
567
601
|
real_free(re_width);
|
568
602
|
real_free(im_width);
|
@@ -570,8 +604,6 @@ Complex* complex_diagonal (Complex* complex)
|
|
570
604
|
real_free(im_width2);
|
571
605
|
real_free(diag2);
|
572
606
|
|
573
|
-
mpfr_clear(num_diag);
|
574
|
-
|
575
607
|
return (Complex*)complex_new(re, (Interval*)interval_zero());
|
576
608
|
}
|
577
609
|
|
@@ -581,7 +613,7 @@ Complex* complex_diagonal (Complex* complex)
|
|
581
613
|
*/
|
582
614
|
Complex* complex_conjugate (Complex* complex)
|
583
615
|
{
|
584
|
-
return complex_new((Interval*)interval_dup(complex->re), (Interval*)interval_negate(complex->im));
|
616
|
+
return (Complex*)complex_new((Interval*)interval_dup(complex->re), (Interval*)interval_negate(complex->im));
|
585
617
|
}
|
586
618
|
|
587
619
|
/*
|
@@ -589,7 +621,7 @@ Complex* complex_conjugate (Complex* complex)
|
|
589
621
|
*/
|
590
622
|
Complex* complex_negate (Complex* complex)
|
591
623
|
{
|
592
|
-
return complex_new((Interval*)interval_negate(complex->re), (Interval*)interval_negate(complex->im));
|
624
|
+
return (Complex*)complex_new((Interval*)interval_negate(complex->re), (Interval*)interval_negate(complex->im));
|
593
625
|
}
|
594
626
|
|
595
627
|
/*
|
@@ -598,7 +630,7 @@ Complex* complex_negate (Complex* complex)
|
|
598
630
|
*/
|
599
631
|
Complex* complex_reflect (Complex* complex)
|
600
632
|
{
|
601
|
-
return complex_new((Interval*)interval_dup(complex->im), (Interval*)interval_dup(complex->re));
|
633
|
+
return (Complex*)complex_new((Interval*)interval_dup(complex->im), (Interval*)interval_dup(complex->re));
|
602
634
|
}
|
603
635
|
|
604
636
|
/*
|
@@ -606,69 +638,57 @@ Complex* complex_reflect (Complex* complex)
|
|
606
638
|
*/
|
607
639
|
Complex* complex_sqrt (Complex* complex)
|
608
640
|
{
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
mpc_t num_ul;
|
615
|
-
mpc_t num_uu;
|
616
|
-
mpc_t num_re_sqrt;
|
617
|
-
Real* zero;
|
641
|
+
int ll_mpc_ternary;
|
642
|
+
int lu_mpc_ternary;
|
643
|
+
int ul_mpc_ternary;
|
644
|
+
int uu_mpc_ternary;
|
645
|
+
int re_sqrt_mpc_ternary;
|
618
646
|
Bounds* bounds;
|
619
647
|
Interval* re;
|
620
648
|
Interval* im;
|
621
649
|
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
650
|
+
mpfr_set_prec(tmp_sqrt_n_re, PREC);
|
651
|
+
mpfr_set_prec(tmp_sqrt_n_im, PREC);
|
652
|
+
mpc_set_prec(tmp_sqrt_n, PREC);
|
653
|
+
mpc_set_prec(tmp_sqrt_ll, PREC);
|
654
|
+
mpc_set_prec(tmp_sqrt_lu, PREC);
|
655
|
+
mpc_set_prec(tmp_sqrt_ul, PREC);
|
656
|
+
mpc_set_prec(tmp_sqrt_uu, PREC);
|
657
|
+
mpc_set_prec(tmp_sqrt_re_sqrt, PREC);
|
658
|
+
|
659
|
+
mpc_set_r_r(tmp_sqrt_n, complex->re->n, complex->im->n);
|
660
|
+
mpc_sqrt(tmp_sqrt_n, tmp_sqrt_n, MPC_RNDNN);
|
661
|
+
mpc_real(tmp_sqrt_n_re, tmp_sqrt_n, MPFR_RNDN);
|
662
|
+
mpc_imag(tmp_sqrt_n_im, tmp_sqrt_n, MPFR_RNDN);
|
663
|
+
|
664
|
+
mpc_set_r_r(tmp_sqrt_ll, complex->re->l, complex->im->l);
|
665
|
+
mpc_set_r_r(tmp_sqrt_lu, complex->re->l, complex->im->u);
|
666
|
+
mpc_set_r_r(tmp_sqrt_ul, complex->re->u, complex->im->l);
|
667
|
+
mpc_set_r_r(tmp_sqrt_uu, complex->re->u, complex->im->u);
|
668
|
+
|
669
|
+
ll_mpc_ternary = mpc_sqrt(tmp_sqrt_ll, tmp_sqrt_ll, MPC_RNDDD);
|
670
|
+
lu_mpc_ternary = mpc_sqrt(tmp_sqrt_lu, tmp_sqrt_lu, MPC_RNDDU);
|
671
|
+
ul_mpc_ternary = mpc_sqrt(tmp_sqrt_ul, tmp_sqrt_ul, MPC_RNDUD);
|
672
|
+
uu_mpc_ternary = mpc_sqrt(tmp_sqrt_uu, tmp_sqrt_uu, MPC_RNDUU);
|
639
673
|
|
640
674
|
bounds = (Bounds*)bounds_new();
|
641
|
-
bounds_update(bounds,
|
642
|
-
bounds_update(bounds,
|
643
|
-
bounds_update(bounds,
|
644
|
-
bounds_update(bounds,
|
675
|
+
bounds_update(bounds, tmp_sqrt_ll, complex->re->L, complex->im->L, ll_mpc_ternary);
|
676
|
+
bounds_update(bounds, tmp_sqrt_lu, complex->re->L, complex->im->R, lu_mpc_ternary);
|
677
|
+
bounds_update(bounds, tmp_sqrt_ul, complex->re->R, complex->im->L, ul_mpc_ternary);
|
678
|
+
bounds_update(bounds, tmp_sqrt_uu, complex->re->R, complex->im->R, uu_mpc_ternary);
|
645
679
|
|
646
680
|
if (interval_span_zero_p(complex->im))
|
647
681
|
{
|
648
|
-
|
649
|
-
|
650
|
-
mpc_init_set_r_r(num_re_sqrt, complex->re->l, zero);
|
651
|
-
mpc_sqrt(num_re_sqrt, num_re_sqrt, MPC_RNDDD);
|
682
|
+
mpc_set_r_r(tmp_sqrt_re_sqrt, complex->re->l, 0);
|
683
|
+
re_sqrt_mpc_ternary = mpc_sqrt(tmp_sqrt_re_sqrt, tmp_sqrt_re_sqrt, MPC_RNDDD);
|
652
684
|
|
653
|
-
bounds_update(bounds,
|
654
|
-
|
655
|
-
real_free(zero);
|
656
|
-
mpc_clear(num_re_sqrt);
|
685
|
+
bounds_update(bounds, tmp_sqrt_re_sqrt, complex->re->L, true, re_sqrt_mpc_ternary);
|
657
686
|
}
|
658
687
|
|
659
|
-
re = (Interval*)interval_new(real_from_mpfr(bounds->re_min, ROUND_DOWN), bounds->re_min_closed, real_from_mpfr(
|
660
|
-
im = (Interval*)interval_new(real_from_mpfr(bounds->im_min, ROUND_DOWN), bounds->im_min_closed, real_from_mpfr(
|
688
|
+
re = (Interval*)interval_new((Real*)real_from_mpfr(bounds->re_min, ROUND_DOWN), bounds->re_min_closed, (Real*)real_from_mpfr(tmp_sqrt_n_re, ROUND_NEAREST), bounds->re_max_closed, (Real*)real_from_mpfr(bounds->re_max, bounds->re_max_exact ? ROUND_UP : ROUND_UP1));
|
689
|
+
im = (Interval*)interval_new((Real*)real_from_mpfr(bounds->im_min, ROUND_DOWN), bounds->im_min_closed, (Real*)real_from_mpfr(tmp_sqrt_n_im, ROUND_NEAREST), bounds->im_max_closed, (Real*)real_from_mpfr(bounds->im_max, bounds->im_max_exact ? ROUND_UP : ROUND_UP1));
|
661
690
|
|
662
691
|
bounds_free(bounds);
|
663
692
|
|
664
|
-
|
665
|
-
mpfr_clear(num_n_im);
|
666
|
-
|
667
|
-
mpc_clear(num_n);
|
668
|
-
mpc_clear(num_ll);
|
669
|
-
mpc_clear(num_lu);
|
670
|
-
mpc_clear(num_ul);
|
671
|
-
mpc_clear(num_uu);
|
672
|
-
|
673
|
-
return complex_new(re, im);
|
693
|
+
return (Complex*)complex_new(re, im);
|
674
694
|
}
|
data/ext/interval.c
CHANGED
@@ -335,7 +335,7 @@ Interval* interval_divide (Interval* a, Interval* b)
|
|
335
335
|
L = bounds->min_closed;
|
336
336
|
R = bounds->max_closed;
|
337
337
|
|
338
|
-
n = (Real*)real_divide(a->n, b->n);
|
338
|
+
n = (Real*)real_divide(a->n, b->n, ROUND_NEAREST);
|
339
339
|
l = (Real*)real_dup(bounds->min);
|
340
340
|
u = (Real*)real_dup(bounds->max);
|
341
341
|
|
data/ext/number.c
CHANGED
@@ -1351,10 +1351,11 @@ VALUE rb_Number_complex_bounds_eq_p (VALUE a, VALUE b)
|
|
1351
1351
|
|
1352
1352
|
void Init_number ()
|
1353
1353
|
{
|
1354
|
-
init_tmp_nums();
|
1355
|
-
|
1356
1354
|
digs = 17;
|
1357
1355
|
|
1356
|
+
init_real_tmp_nums();
|
1357
|
+
init_complex_tmp_nums();
|
1358
|
+
|
1358
1359
|
rb_define_method(rb_cString, "to_number", rb_String_to_number, 0);
|
1359
1360
|
rb_define_method(rb_cInteger, "to_number", rb_Integer_to_number, 0);
|
1360
1361
|
rb_define_method(rb_cFloat, "to_number", rb_Float_to_number, 0);
|
data/ext/number.h
CHANGED
data/ext/real.c
CHANGED
@@ -26,7 +26,7 @@ mpz_t a_tmp,
|
|
26
26
|
/*
|
27
27
|
* Initializes mpz_t variables for use in Real functions.
|
28
28
|
*/
|
29
|
-
void
|
29
|
+
void init_real_tmp_nums ()
|
30
30
|
{
|
31
31
|
mpz_init(a_tmp);
|
32
32
|
mpz_init(b_tmp);
|
@@ -796,22 +796,28 @@ Real* real_divide (Real* a, Real* b, int round_mode)
|
|
796
796
|
mpfr_t a_num;
|
797
797
|
mpfr_t b_num;
|
798
798
|
mpfr_t num;
|
799
|
+
Real* result;
|
799
800
|
|
800
801
|
if (!REAL(a) || !REAL(b))
|
801
802
|
{
|
802
803
|
return (NaN(a) || NaN(b) || (!REAL(a) && !REAL(b))) ? real_nan() : !REAL(b) ? real_zero() : (POS(a) && POS(b)) ? real_pos_inf() : real_neg_inf();
|
803
804
|
}
|
804
805
|
|
805
|
-
mpfr_init2(
|
806
|
-
|
807
|
-
|
806
|
+
mpfr_init2(a_num, PREC);
|
807
|
+
mpfr_init2(b_num, PREC);
|
808
|
+
mpfr_set_r(a_num, a);
|
809
|
+
mpfr_set_r(b_num, b);
|
808
810
|
|
811
|
+
mpfr_init2(num, PREC);
|
809
812
|
mpfr_div(num, a_num, b_num, MPFR_RNDN);
|
810
813
|
|
814
|
+
result = (Real*)real_from_mpfr(num, round_mode);
|
815
|
+
|
811
816
|
mpfr_clear(a_num);
|
812
817
|
mpfr_clear(b_num);
|
818
|
+
mpfr_clear(num);
|
813
819
|
|
814
|
-
return
|
820
|
+
return result;
|
815
821
|
}
|
816
822
|
|
817
823
|
//{
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: number
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.9.
|
5
|
+
version: 0.9.5
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Jesse Sielaff
|
@@ -12,7 +12,7 @@ autorequire:
|
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date: 2011-07-
|
15
|
+
date: 2011-07-17 00:00:00 Z
|
16
16
|
dependencies: []
|
17
17
|
|
18
18
|
description: The Number gem is intended to be a drop-in replacement for Ruby's Numeric classes when arbitrary-precision complex interval calculations are warranted. The basis of the arbitrary-precision calculations is the GNU MP, MPFR, and MPC libraries.
|
@@ -24,7 +24,6 @@ extensions:
|
|
24
24
|
extra_rdoc_files: []
|
25
25
|
|
26
26
|
files:
|
27
|
-
- README
|
28
27
|
- ext/bounds.c
|
29
28
|
- ext/compare.c
|
30
29
|
- ext/complex.c
|
data/README
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
Use the global function Number() to create Number objects.
|
2
|
-
|
3
|
-
Number(1)
|
4
|
-
Number(1,2)
|
5
|
-
Number(1,2,3)
|
6
|
-
Number(Number(1,2,3), Number(4,5,6))
|
7
|
-
|
8
|
-
Number objects coerce Numeric objects into Number objects.
|
9
|
-
|
10
|
-
Number(1) + 1
|
11
|
-
5 / Number(1,2,3)
|
12
|
-
|
13
|
-
Stay tuned. More documentation to come.
|