number 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -29,8 +29,7 @@ void bounds_free (Bounds* bounds)
29
29
  }
30
30
  }
31
31
 
32
- // add flag for EXACT calculation of mpfr, e.g. mpc_abs returns 0
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);
@@ -1,6 +1,6 @@
1
1
  #include "number.h"
2
2
 
3
- int complex_re_contain_p (Complex* a, Complex* b)
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 complex_im_contain_p (Complex* a, Complex* b)
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 complex_contain_p (Complex* a, Complex* b)
623
+ int complex_enclose_p (Complex* a, Complex* b)
624
624
  {
625
- return complex_re_contain_p(a, b) && complex_im_contain_p(a, b);
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) || (complex_re_contain_p(a, b) && complex_im_contain_p(b, a) || (complex_im_contain_p(a, b) && complex_re_contain_p(b, a)));
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)
@@ -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 mpc_init_set_r_r (mpc_t num, Real* re, Real* im)
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 (REAL(im))
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 mpfr_init_set_r (mpfr_t num, Real* real)
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
- mpfr_init2(num, PREC);
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(num, ROUND_NEAREST);
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
- mpfr_init2(num_re, PREC);
350
- mpfr_init2(num_im, PREC);
351
-
352
- mpc_init2(num_quotient, PREC);
353
- mpc_init_set_r_r(num_numerator, a->re->n, a->im->n);
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
- mpc_div(num_quotient, num_numerator, num_denominator, MPC_RNDNN);
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
- mpc_real(num_re, num_quotient, MPFR_RNDN);
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
- re = (Interval*)interval_new((Real*)real_neg_inf(), true, (Real*)real_from_mpfr(num_re, ROUND_NEAREST), true, (Real*)real_pos_inf());
362
- im = (Interval*)interval_new((Real*)real_neg_inf(), true, (Real*)real_from_mpfr(num_im, ROUND_NEAREST), true, (Real*)real_pos_inf());
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
- mpc_clear(num_numerator);
365
- mpc_clear(num_denominator);
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
- mpfr_t num_n_re;
419
- mpfr_t num_ll_re;
420
- mpfr_t num_lu_re;
421
- mpfr_t num_ul_re;
422
- mpfr_t num_uu_re;
423
- mpfr_t num_re_abs;
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
- mpfr_init2(num_n_re, PREC);
439
- mpfr_init2(num_ll_re, PREC);
440
- mpfr_init2(num_lu_re, PREC);
441
- mpfr_init2(num_ul_re, PREC);
442
- mpfr_init2(num_uu_re, PREC);
443
-
444
- mpc_init_set_r_r(num_n, complex->re->n, complex->im->n);
445
- mpc_abs(num_n_re, num_n, MPC_RNDNN);
446
-
447
- mpc_init_set_r_r(num_ll, complex->re->l, complex->im->l);
448
- mpc_init_set_r_r(num_lu, complex->re->l, complex->im->u);
449
- mpc_init_set_r_r(num_ul, complex->re->u, complex->im->l);
450
- mpc_init_set_r_r(num_uu, complex->re->u, complex->im->u);
451
-
452
- mpc_abs(num_ll_re, num_ll, MPC_RNDDD);
453
- mpc_abs(num_lu_re, num_lu, MPC_RNDDU);
454
- mpc_abs(num_ul_re, num_ul, MPC_RNDUD);
455
- mpc_abs(num_uu_re, num_uu, MPC_RNDUU);
456
-
457
- mpc_clear(num_n);
458
- mpc_clear(num_ll);
459
- mpc_clear(num_lu);
460
- mpc_clear(num_ul);
461
- mpc_clear(num_uu);
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, num_ll_re, complex->re->L);
465
- bounds_update_re(bounds, num_lu_re, complex->re->L);
466
- bounds_update_re(bounds, num_ul_re, complex->re->R);
467
- bounds_update_re(bounds, num_uu_re, complex->re->R);
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
- re_l_abs = (Real*)real_abs(complex->re->l);
472
- re_u_abs = (Real*)real_abs(complex->re->u);
515
+ l_abs = (Real*)real_abs(complex->re->l);
516
+ u_abs = (Real*)real_abs(complex->re->u);
473
517
 
474
- mpfr_init_set_r(num_re_abs, real_lt_p(re_l_abs, re_u_abs) ? re_l_abs : re_u_abs);
475
- bounds_update_re(bounds, num_re_abs, true);
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(re_l_abs);
478
- real_free(re_u_abs);
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
- im_l_abs = (Real*)real_abs(complex->im->l);
486
- im_u_abs = (Real*)real_abs(complex->im->u);
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
- real_free(im_l_abs);
492
- real_free(im_u_abs);
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
- mpfr_clear(num_im_abs);
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(num_ll_re, 1);
500
- bounds_update_re(bounds, num_ll_re, true);
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(num_n_re, ROUND_NEAREST), bounds->re_max_closed, real_from_mpfr(bounds->re_max, ROUND_UP1));
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
- mpfr_clear(num_n_re);
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
- mpfr_t num_diag;
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
- mpfr_init_set_r(num_diag, diag2);
563
- mpfr_sqrt(num_diag, num_diag, MPFR_RNDN);
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(num_diag, ROUND_DOWN), true, (Real*)real_from_mpfr(num_diag, ROUND_NEAREST), true, (Real*)real_from_mpfr(num_diag, ROUND_UP1));
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
- mpfr_t num_n_re;
610
- mpfr_t num_n_im;
611
- mpc_t num_n;
612
- mpc_t num_ll;
613
- mpc_t num_lu;
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
- mpfr_init2(num_n_re, PREC);
623
- mpfr_init2(num_n_im, PREC);
624
-
625
- mpc_init_set_r_r(num_n, complex->re->n, complex->im->n);
626
- mpc_sqrt(num_n, num_n, MPC_RNDNN);
627
- mpc_real(num_n_re, num_n, MPFR_RNDN);
628
- mpc_imag(num_n_im, num_n, MPFR_RNDN);
629
-
630
- mpc_init_set_r_r(num_ll, complex->re->l, complex->im->l);
631
- mpc_init_set_r_r(num_lu, complex->re->l, complex->im->u);
632
- mpc_init_set_r_r(num_ul, complex->re->u, complex->im->l);
633
- mpc_init_set_r_r(num_uu, complex->re->u, complex->im->u);
634
-
635
- mpc_sqrt(num_ll, num_ll, MPC_RNDDD);
636
- mpc_sqrt(num_lu, num_lu, MPC_RNDDU);
637
- mpc_sqrt(num_ul, num_ul, MPC_RNDUD);
638
- mpc_sqrt(num_uu, num_uu, MPC_RNDUU);
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, num_ll, complex->re->L, complex->im->L);
642
- bounds_update(bounds, num_lu, complex->re->L, complex->im->R);
643
- bounds_update(bounds, num_ul, complex->re->R, complex->im->L);
644
- bounds_update(bounds, num_uu, complex->re->R, complex->im->R);
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
- zero = (Real*)real_zero();
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, num_re_sqrt, complex->re->L);
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(num_n_re, ROUND_NEAREST), bounds->re_max_closed, real_from_mpfr(bounds->re_max, ROUND_UP1));
660
- im = (Interval*)interval_new(real_from_mpfr(bounds->im_min, ROUND_DOWN), bounds->im_min_closed, real_from_mpfr(num_n_im, ROUND_NEAREST), bounds->im_max_closed, real_from_mpfr(bounds->im_max, ROUND_UP1));
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
- mpfr_clear(num_n_re);
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
  }
@@ -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
 
@@ -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);
@@ -59,8 +59,10 @@ typedef struct
59
59
  {
60
60
  int re_min_closed;
61
61
  int re_max_closed;
62
+ int re_max_exact;
62
63
  int im_min_closed;
63
64
  int im_max_closed;
65
+ int im_max_exact;
64
66
  mpfr_t re_min;
65
67
  mpfr_t re_max;
66
68
  mpfr_t im_min;
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 init_tmp_nums ()
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(num, PREC);
806
- mpfr_init_set_r(a_num, a);
807
- mpfr_init_set_r(b_num, b);
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 (Real*)real_from_mpfr(num, round_mode);
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.4
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-16 00:00:00 Z
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.