int mpfi_abs (mpfi_ptr a, mpfi_srcptr b) { /* the result a contains the absolute values of every element of b */ int inexact_right, inexact = 0; if (MPFI_NAN_P (b)) { mpfr_set_nan (&(a->left)); mpfr_set_nan (&(a->right)); MPFR_RET_NAN; } if (MPFI_IS_NONNEG (b)) inexact = mpfi_set (a, b); else if (MPFI_IS_NONPOS (b)) inexact = mpfi_neg (a, b); else { /* b contains 0 */ if (mpfr_cmpabs (&(b->left), &(b->right)) < 0) { inexact_right = mpfr_set (&(a->right), &(b->right), MPFI_RNDU); } else { inexact_right = mpfr_neg (&(a->right), &(b->left), MPFI_RNDU); } mpfr_set_si (&(a->left), 0, MPFI_RNDD); if (inexact_right) inexact += 2; } return inexact; }
/* Return [matrix_l, matrix_r, indx]. */ static VALUE r_mpfi_square_matrix_lu_decomp (VALUE self) { MPFIMatrix *ptr_self, *ptr_ret_l, *ptr_ret_u; VALUE ret_l, ret_u, ret, ret_indx_ary; int i, j, *indx; r_mpfi_get_matrix_struct(ptr_self, self); r_mpfi_matrix_suitable_matrix_init (&ret_l, &ptr_ret_l, ptr_self->row, ptr_self->column); r_mpfi_matrix_suitable_matrix_init (&ret_u, &ptr_ret_u, ptr_self->row, ptr_self->column); indx = ALLOC_N(int, ptr_self->row); if (mpfi_square_matrix_lu_decomp (ptr_ret_u, indx, ptr_self) >= 0) { ret_indx_ary = rb_ary_new2(ptr_self->row); for (i = 1; i < ptr_ret_u->row; i++) { for (j = 0; j < i; j++) { mpfi_set(mpfi_matrix_get_element(ptr_ret_l, i, j), mpfi_matrix_get_element(ptr_ret_u, i, j)); mpfi_set_si(mpfi_matrix_get_element(ptr_ret_u, i, j), 0); } } for (i = 0; i < ptr_ret_u->row; i++) { mpfi_set_si(mpfi_matrix_get_element(ptr_ret_l, i, i), 1); } for (i = 0; i < ptr_ret_u->row; i++) { for (j = i + 1; j < ptr_ret_u->column; j++) { mpfi_set_si(mpfi_matrix_get_element(ptr_ret_l, i, j), 0); } } for (i = 0; i < ptr_ret_u->row; i++) { rb_ary_store(ret_indx_ary, i, INT2NUM(indx[i])); } ret = rb_ary_new3(3, ret_l, ret_u, ret_indx_ary); } else { ret = Qnil; } free(indx); return ret; }
/* Return element at _arg_.*/ static VALUE r_mpfi_matrix_at (VALUE self, VALUE arg) { MPFIMatrix *ptr_self; int i; r_mpfi_get_matrix_struct(ptr_self, self); i = NUM2INT(arg); if (i < ptr_self->size) { VALUE ret; MPFI *ptr_ret; r_mpfi_make_struct_init(ret, ptr_ret); mpfi_set(ptr_ret, ptr_self->data + i); return ret; } else { return Qnil; } }
/* Return element with _row_ and _column_.*/ static VALUE r_mpfi_matrix_element (VALUE self, VALUE row, VALUE column) { MPFIMatrix *ptr_self; int i, j; r_mpfi_get_matrix_struct(ptr_self, self); i = NUM2INT(row); j = NUM2INT(column); if (i < ptr_self->row && j < ptr_self->column) { VALUE ret; MPFI*ptr_ret; r_mpfi_make_struct_init(ret, ptr_ret); mpfi_set(ptr_ret, ptr_self->data + i + j * ptr_self->row); return ret; } else { return Qnil; } }
int mpfi_sub (mpfi_ptr a, mpfi_srcptr b, mpfi_srcptr c) { mpfr_t tmp; int inexact_left, inexact_right, inexact = 0; if (MPFI_IS_ZERO (c)) { return mpfi_set (a, b); } else if (MPFI_IS_ZERO (b)) { return mpfi_neg (a, c); } else { mpfr_init2 (tmp, mpfr_get_prec (&(a->left))); inexact_left = mpfr_sub (tmp, &(b->left), &(c->right), MPFI_RNDD); inexact_right = mpfr_sub (&(a->right), &(b->right), &(c->left), MPFI_RNDU); mpfr_set (&(a->left), tmp, MPFI_RNDD); /* exact */ mpfr_clear (tmp); /* do not allow -0 as lower bound */ if (mpfr_zero_p (&(a->left)) && mpfr_signbit (&(a->left))) { mpfr_neg (&(a->left), &(a->left), MPFI_RNDU); } /* do not allow +0 as upper bound */ if (mpfr_zero_p (&(a->right)) && !mpfr_signbit (&(a->right))) { mpfr_neg (&(a->right), &(a->right), MPFI_RNDD); } if (MPFI_NAN_P (a)) MPFR_RET_NAN; if (inexact_left) inexact += 1; if (inexact_right) inexact += 2; return inexact; } }
void mpfi_complex_set_imaginary_part (MPFIComplex *x, MPFI *a) { mpfi_set(x->im, a); }
void mpfi_complex_set_real_part (MPFIComplex *x, MPFI *a) { mpfi_set(x->re, a); }
static void check (mpfi_ptr left, mpfi_ptr right, mpfi_srcptr interval, mpfi_srcptr expected_left, mpfi_srcptr expected_right, int expected_inex) { int inex; inex = mpfi_bisect (left, right, interval); if (inex != expected_inex || !same_value (left, expected_left) || !same_value (right, expected_right)) { printf ("Failed line %lu.\n interval: ", test_line_number); mpfi_out_str (stdout, 16, 0, interval); printf ("\n returned left: "); mpfi_out_str (stdout, 16, 0, left); printf ("\nreturned right: "); mpfi_out_str (stdout, 16, 0, right); printf ("\n expected left: "); mpfi_out_str (stdout, 16, 0, expected_left); printf ("\nexpected right: "); mpfi_out_str (stdout, 16, 0, expected_right); printf ("\n"); if (inex != expected_inex) { printf ("inexact flag: got = %u, expected = %u\n", inex, expected_inex); } exit (1); } /* reuse variable tests */ if (mpfi_get_prec (interval) == mpfi_get_prec (expected_left)) { mpfi_set (left, interval); inex = mpfi_bisect (left, right, left); if (inex != expected_inex || !same_value (left, expected_left) || !same_value (right, expected_right)) { printf ("Error when reusing input argument as first output " "(line %lu).\n interval: ", test_line_number); mpfi_out_str (stdout, 16, 0, interval); printf ("\n returned left: "); mpfi_out_str (stdout, 16, 0, left); printf ("\nreturned right: "); mpfi_out_str (stdout, 16, 0, right); printf ("\n expected left: "); mpfi_out_str (stdout, 16, 0, expected_left); printf ("\nexpected right: "); mpfi_out_str (stdout, 16, 0, expected_right); printf ("\n"); if (inex != expected_inex) { printf ("inexact flag: got = %u, expected = %u\n", inex, expected_inex); } exit (1); } } if (mpfi_get_prec (interval) == mpfi_get_prec (expected_right)) { mpfi_set (right, interval); inex = mpfi_bisect (left, right, right); if (inex != expected_inex || !same_value (left, expected_left) || !same_value (right, expected_right)) { printf ("Error when reusing input argument as second output " "(line %lu).\n interval: ", test_line_number); mpfi_out_str (stdout, 16, 0, interval); printf ("\n returned left: "); mpfi_out_str (stdout, 16, 0, left); printf ("\nreturned right: "); mpfi_out_str (stdout, 16, 0, right); printf ("\n expected left: "); mpfi_out_str (stdout, 16, 0, expected_left); printf ("\nexpected right: "); mpfi_out_str (stdout, 16, 0, expected_right); printf ("\n"); if (inex != expected_inex) { printf ("inexact flag: got = %u, expected = %u\n", inex, expected_inex); } exit (1); } } }
int mpfi_blow (mpfi_ptr y, mpfi_srcptr x, double fact) /* if c = mid (x) and r = rad (x), y = [c - (1+fact)*r , c + (1+fact)*r] */ { mp_prec_t prec; mpfr_t radius, factor; mpfr_t centre; int inex_diam, inex_div, inex_conv, inex_factor, inex_rad; int inex_centre, inex_left, inex_right; int inexact = 0; if (MPFI_NAN_P (x)) { mpfr_set_nan (&(y->left)); mpfr_set_nan (&(y->right)); MPFR_RET_NAN; } prec = mpfi_get_prec (x); mpfr_init2 (radius, prec); mpfr_init2 (factor, prec); mpfr_init2 (centre, prec); inex_diam = mpfi_diam_abs (radius, x); if (mpfr_zero_p (radius)) { /* x is a singleton */ return mpfi_set (y, x); } inex_div = mpfr_div_2exp (radius, radius, 1, MPFI_RNDU); /* either underflow or exact*/ /* factor must be greater than 1 + |fact|, so it is not possible to perform this addition directly in C with the double precision since the usual rouding mode is rounding to nearest. */ inex_conv = mpfr_set_d (factor, fact < 0.0 ? -fact : fact, MPFI_RNDU); inex_factor = mpfr_add_ui (factor, factor, 1, MPFI_RNDU); inex_rad = mpfr_mul (radius, radius, factor, MPFI_RNDU); inex_centre = mpfi_mid (centre, x); inex_left = mpfr_sub (&(y->left), centre, radius, MPFI_RNDD); inex_right = mpfr_add (&(y->right), centre, radius, MPFI_RNDU); mpfr_clear (radius); mpfr_clear (factor); mpfr_clear (centre); if ( MPFI_NAN_P (y) ) MPFR_RET_NAN; /* do not allow -0 as lower bound */ if (mpfr_zero_p (&(y->left)) && mpfr_signbit (&(y->left))) { mpfr_neg (&(y->left), &(y->left), MPFI_RNDU); } /* do not allow +0 as upper bound */ if (mpfr_zero_p (&(y->right)) && !mpfr_signbit (&(y->right))) { mpfr_neg (&(y->right), &(y->right), MPFI_RNDD); } if (inex_diam || inex_div || inex_conv || inex_factor || inex_rad || inex_centre || inex_left) inexact += 1; if (inex_diam || inex_div || inex_conv || inex_factor || inex_rad || inex_centre || inex_right) inexact += 2; return inexact; }