// Computes z = Delta(q) (see Cohen). static void compute_Delta(mpc_t z, mpc_t q) { int d; int n; int power; mpc_t z0, z1, z2; mpc_init(z0); mpc_init(z1); mpc_init(z2); mpc_set_ui(z0, 1); d = -1; for(n=1; n<100; n++) { power = n *(3 * n - 1) / 2; mpc_pow_ui(z1, q, power); mpc_pow_ui(z2, q, n); mpc_mul(z2, z2, z1); mpc_add(z1, z1, z2); if (d) { mpc_sub(z0, z0, z1); d = 0; } else { mpc_add(z0, z0, z1); d = 1; } } mpc_pow_ui(z0, z0, 24); mpc_mul(z, z0, q); mpc_clear(z0); mpc_clear(z1); mpc_clear(z2); }
static void reuse_bug (void) { /* bug found by the automatic builds on http://hydra.nixos.org/build/1469029/log/raw */ mpc_t x, y, z; mp_prec_t prec = 2; for (prec = 2; prec <= 20; prec ++) { mpc_init2 (x, prec); mpc_init2 (y, prec); mpc_init2 (z, prec); mpfr_set_ui (mpc_realref (x), 0ul, MPFR_RNDN); mpfr_set_ui_2exp (mpc_imagref (x), 3ul, -2, MPFR_RNDN); mpc_set_ui (y, 8ul, MPC_RNDNN); mpc_pow (z, x, y, MPC_RNDNN); mpc_pow (y, x, y, MPC_RNDNN); if (mpfr_signbit (mpc_imagref (y)) != mpfr_signbit (mpc_imagref (z))) { printf ("Error: regression, reuse_bug reproduced\n"); exit (1); } mpc_clear (x); mpc_clear (y); mpc_clear (z); } }
static void check_ternary_value (void) { mpc_t x, y, z; mpfr_prec_t prec; mpc_init2 (x, 2); mpc_init2 (y, 2); mpc_init2 (z, 2); for (prec = 2; prec <= 1000; prec++) { mpc_set_prec (x, prec); mpc_set_prec (y, prec); mpc_set_ui (x, 1, MPC_RNDNN); mpc_mul_2ui (x, x, (unsigned long int) prec, MPC_RNDNN); mpc_set_ui (y, 1, MPC_RNDNN); if (mpc_add (z, x, y, MPC_RNDNN) == 0) { fprintf (stderr, "Error in mpc_add: 2^(-prec)+1 cannot be exact\n"); exit (1); } } mpc_clear (x); mpc_clear (y); mpc_clear (z); }
static bool do_mpc_arg2 (real_value *result_real, real_value *result_imag, int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t), const real_value *arg0_real, const real_value *arg0_imag, const real_value *arg1_real, const real_value *arg1_imag, const real_format *format) { if (!real_isfinite (arg0_real) || !real_isfinite (arg0_imag) || !real_isfinite (arg1_real) || !real_isfinite (arg1_imag)) return false; int prec = format->p; mpc_rnd_t crnd = format->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN; mpc_t m0, m1; mpc_init2 (m0, prec); mpc_init2 (m1, prec); mpfr_from_real (mpc_realref (m0), arg0_real, GMP_RNDN); mpfr_from_real (mpc_imagref (m0), arg0_imag, GMP_RNDN); mpfr_from_real (mpc_realref (m1), arg1_real, GMP_RNDN); mpfr_from_real (mpc_imagref (m1), arg1_imag, GMP_RNDN); mpfr_clear_flags (); bool inexact = func (m0, m0, m1, crnd); bool ok = do_mpc_ckconv (result_real, result_imag, m0, inexact, format); mpc_clear (m0); mpc_clear (m1); return ok; }
static void check_different_precisions(void) { /* check reuse when real and imaginary part have different precisions. */ mpc_t z, expected, got; int res; mpc_init2(z, 128); mpc_init2(expected, 128); mpc_init2(got, 128); /* change precision of one part */ mpfr_set_prec (mpc_imagref (z), 32); mpfr_set_prec (mpc_imagref (expected), 32); mpfr_set_prec (mpc_imagref (got), 32); mpfr_set_str (mpc_realref (z), "0x100000000fp-32", 16, GMP_RNDN); mpfr_set_str (mpc_imagref (z), "-1", 2, GMP_RNDN); mpfr_set_str (mpc_realref (expected), "+1", 2, GMP_RNDN); mpfr_set_str (mpc_imagref (expected), "0x100000000fp-32", 16, GMP_RNDN); mpc_set (got, z, MPC_RNDNN); res = mpc_mul_i (got, got, +1, MPC_RNDNN); if (MPC_INEX_RE(res) != 0 || MPC_INEX_IM(res) >=0) { printf("Wrong inexact flag for mpc_mul_i(z, z, n)\n" " got (re=%2d, im=%2d)\nexpected (re= 0, im=-1)\n", MPC_INEX_RE(res), MPC_INEX_IM(res)); exit(1); } if (mpc_cmp(got, expected) != 0) { printf ("Error for mpc_mul_i(z, z, n) for\n"); MPC_OUT (z); printf ("n=+1\n"); MPC_OUT (expected); MPC_OUT (got); exit (1); } mpc_neg (expected, expected, MPC_RNDNN); mpc_set (got, z, MPC_RNDNN); mpc_mul_i (got, got, -1, MPC_RNDNN); if (mpc_cmp(got, expected) != 0) { printf ("Error for mpc_mul_i(z, z, n) for\n"); MPC_OUT (z); printf ("n=-1\n"); MPC_OUT (expected); MPC_OUT (got); exit (1); } mpc_clear (z); mpc_clear (expected); mpc_clear (got); }
static void compare_mpc_pow (mpfr_prec_t pmax, int iter, unsigned long nbits) /* copied from tpow_ui.c and replaced unsigned by signed */ { mpfr_prec_t p; mpc_t x, y, z, t; long n; int i, inex_pow, inex_pow_si; mpc_rnd_t rnd; mpc_init3 (y, sizeof (unsigned long) * CHAR_BIT, MPFR_PREC_MIN); for (p = MPFR_PREC_MIN; p <= pmax; p++) for (i = 0; i < iter; i++) { mpc_init2 (x, p); mpc_init2 (z, p); mpc_init2 (t, p); mpc_urandom (x, rands); n = (signed long) gmp_urandomb_ui (rands, nbits); mpc_set_si (y, n, MPC_RNDNN); for (rnd = 0; rnd < 16; rnd ++) { inex_pow = mpc_pow (z, x, y, rnd); inex_pow_si = mpc_pow_si (t, x, n, rnd); if (mpc_cmp (z, t) != 0) { printf ("mpc_pow and mpc_pow_si differ for x="); mpc_out_str (stdout, 10, 0, x, MPC_RNDNN); printf (" n=%li\n", n); printf ("mpc_pow gives "); mpc_out_str (stdout, 10, 0, z, MPC_RNDNN); printf ("\nmpc_pow_si gives "); mpc_out_str (stdout, 10, 0, t, MPC_RNDNN); printf ("\n"); exit (1); } if (inex_pow != inex_pow_si) { printf ("mpc_pow and mpc_pow_si give different flags for x="); mpc_out_str (stdout, 10, 0, x, MPC_RNDNN); printf (" n=%li\n", n); printf ("mpc_pow gives %d\n", inex_pow); printf ("mpc_pow_si gives %d\n", inex_pow_si); exit (1); } } mpc_clear (x); mpc_clear (z); mpc_clear (t); } mpc_clear (y); }
// Computes j = j(tau). static void compute_j(mpc_t j, mpc_t tau) { mpc_t h; mpc_t z0; mpc_init(h); mpc_init(z0); compute_h(h, tau); //mpc_mul_ui(z0, h, 256); mpc_mul_2exp(z0, h, 8); mpc_add_ui(z0, z0, 1); mpc_pow_ui(z0, z0, 3); mpc_div(j, z0, h); mpc_clear(z0); mpc_clear(h); }
// Computes z = h(tau) // (called h() by Blake et al, f() by Cohen.) static void compute_h(mpc_t z, mpc_t tau) { mpc_t z0, z1, q; mpc_init(q); mpc_init(z0); mpc_init(z1); compute_q(q, tau); mpc_mul(z0, q, q); compute_Delta(z0, z0); compute_Delta(z1, q); mpc_div(z, z0, z1); mpc_clear(q); mpc_clear(z0); mpc_clear(z1); }
static void check_regular (void) { mpc_t x, y; int rnd_re, rnd_im; mpfr_prec_t prec; testmul (247, -65, -223, 416, 8, 24); testmul (5, -896, 5, -32, 3, 2); testmul (-3, -512, -1, -1, 2, 16); testmul (266013312, 121990769, 110585572, 116491059, 27, 0); testmul (170, 9, 450, 251, 8, 0); testmul (768, 85, 169, 440, 8, 16); testmul (145, 1816, 848, 169, 8, 24); mpc_init2 (x, 1000); mpc_init2 (y, 1000); /* Bug 20081114: mpc_mul_karatsuba returned wrong inexact value for imaginary part */ mpc_set_prec (x, 7); mpc_set_prec (y, 7); mpfr_set_str (mpc_realref (x), "0xB4p+733", 16, MPFR_RNDN); mpfr_set_str (mpc_imagref (x), "0x90p+244", 16, MPFR_RNDN); mpfr_set_str (mpc_realref (y), "0xECp-146", 16, MPFR_RNDN); mpfr_set_str (mpc_imagref (y), "0xACp-471", 16, MPFR_RNDN); cmpmul (x, y, MPC_RNDNN); mpfr_set_str (mpc_realref (x), "0xB4p+733", 16, MPFR_RNDN); mpfr_set_str (mpc_imagref (x), "0x90p+244", 16, MPFR_RNDN); mpfr_set_str (mpc_realref (y), "0xACp-471", 16, MPFR_RNDN); mpfr_set_str (mpc_imagref (y), "-0xECp-146", 16, MPFR_RNDN); cmpmul (x, y, MPC_RNDNN); for (prec = 2; prec < 1000; prec = (mpfr_prec_t) (prec * 1.1 + 1)) { mpc_set_prec (x, prec); mpc_set_prec (y, prec); test_default_random (x, -1024, 1024, 128, 0); test_default_random (y, -1024, 1024, 128, 0); for (rnd_re = 0; rnd_re < 4; rnd_re ++) for (rnd_im = 0; rnd_im < 4; rnd_im ++) cmpmul (x, y, MPC_RND (rnd_re, rnd_im)); } mpc_clear (x); mpc_clear (y); }
int mpc_atanh (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) { /* atanh(op) = -i*atan(i*op) */ int inex; mpfr_t tmp; mpc_t z, a; MPC_RE (z)[0] = MPC_IM (op)[0]; MPC_IM (z)[0] = MPC_RE (op)[0]; MPFR_CHANGE_SIGN (MPC_RE (z)); /* Note reversal of precisions due to later multiplication by -i */ mpc_init3 (a, MPC_PREC_IM(rop), MPC_PREC_RE(rop)); inex = mpc_atan (a, z, RNDC (INV_RND (MPC_RND_IM (rnd)), MPC_RND_RE (rnd))); /* change a to -i*a, i.e., x+i*y to y-i*x */ tmp[0] = MPC_RE (a)[0]; MPC_RE (a)[0] = MPC_IM (a)[0]; MPC_IM (a)[0] = tmp[0]; MPFR_CHANGE_SIGN (MPC_IM (a)); mpc_set (rop, a, rnd); mpc_clear (a); return MPC_INEX (MPC_INEX_IM (inex), -MPC_INEX_RE (inex)); }
static void testmul (long a, long b, long c, long d, mpfr_prec_t prec, mpc_rnd_t rnd) { mpc_t x, y; mpc_init2 (x, prec); mpc_init2 (y, prec); mpc_set_si_si (x, a, b, rnd); mpc_set_si_si (y, c, d, rnd); cmpmul (x, y, rnd); mpc_clear (x); mpc_clear (y); }
static void test_reuse (void) { mpc_t z; mpfr_t y; int inex; mpfr_init2 (y, 2); mpc_init2 (z, 2); mpc_set_si_si (z, 0, -1, MPC_RNDNN); mpfr_neg (mpc_realref (z), mpc_realref (z), MPFR_RNDN); mpc_div_2ui (z, z, 4, MPC_RNDNN); mpfr_set_ui (y, 512, MPFR_RNDN); inex = mpc_pow_fr (z, z, y, MPC_RNDNN); if (MPC_INEX_RE(inex) != 0 || MPC_INEX_IM(inex) != 0 || mpfr_cmp_ui_2exp (mpc_realref(z), 1, -2048) != 0 || mpfr_cmp_ui (mpc_imagref(z), 0) != 0 || mpfr_signbit (mpc_imagref(z)) == 0) { printf ("Error in test_reuse, wrong ternary value or output\n"); printf ("inex=(%d %d)\n", MPC_INEX_RE(inex), MPC_INEX_IM(inex)); printf ("z="); mpc_out_str (stdout, 2, 0, z, MPC_RNDNN); printf ("\n"); exit (1); } mpfr_clear (y); mpc_clear (z); }
static void check_ternary_value (void) { mpfr_prec_t prec; mpc_t z; const long int s = -1; mpc_init2 (z, 2); for (prec=2; prec <= 1024; prec++) { mpc_set_prec (z, prec); mpc_set_ui (z, 3ul, MPC_RNDNN); if (mpc_add_si (z, z, s, MPC_RNDDU)) { printf ("Error in mpc_add_si: 3+(-1) should be exact\n"); exit (1); } else if (mpc_cmp_si (z, 2l) != 0) { printf ("Error in mpc_add_si: 3+(-1) should be 2\n"); exit (1); } mpc_mul_2exp (z, z, (unsigned long int) prec, MPC_RNDNN); if (mpc_add_si (z, z, s, MPC_RNDNN) == 0) { printf ("Error in mpc_add_si: 2^(prec+1)-1 cannot be exact\n"); exit (1); } } mpc_clear (z); }
static bool do_mpc_arg1 (real_value *result_real, real_value *result_imag, int (*func) (mpc_ptr, mpc_srcptr, mpc_rnd_t), const real_value *arg_real, const real_value *arg_imag, const real_format *format) { /* To proceed, MPFR must exactly represent the target floating point format, which only happens when the target base equals two. */ if (format->b != 2 || !real_isfinite (arg_real) || !real_isfinite (arg_imag)) return false; int prec = format->p; mpc_rnd_t crnd = format->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN; mpc_t m; mpc_init2 (m, prec); mpfr_from_real (mpc_realref (m), arg_real, GMP_RNDN); mpfr_from_real (mpc_imagref (m), arg_imag, GMP_RNDN); mpfr_clear_flags (); bool inexact = func (m, m, crnd); bool ok = do_mpc_ckconv (result_real, result_imag, m, inexact, format); mpc_clear (m); return ok; }
static void improve_root (mps_context * ctx, mps_polynomial * p, mps_approximation * root, long precision) { mpc_t newton_correction; rdpe_t corr_mod, epsilon; mpc_set_prec (root->mvalue, precision); mpc_init2 (newton_correction, precision); mps_polynomial_mnewton (ctx, p, root, newton_correction, mpc_get_prec (root->mvalue)); mpc_sub_eq (root->mvalue, newton_correction); mpc_rmod (corr_mod, newton_correction); rdpe_add_eq (root->drad, corr_mod); if (ctx->debug_level & MPS_DEBUG_IMPROVEMENT) MPS_DEBUG_MPC (ctx, 15, newton_correction, "Newton correction"); mpc_rmod (corr_mod, root->mvalue); rdpe_set_2dl (epsilon, 1.0, 2 - precision); rdpe_mul_eq (corr_mod, epsilon); rdpe_add_eq (root->drad, corr_mod); mpc_clear (newton_correction); }
static rdpe_t * evaluate_root_conditioning (mps_context * ctx, mps_polynomial * p, mps_approximation ** appr, int n) { int i; rdpe_t * root_conditioning = rdpe_valloc (n); for (i = 0; i < n; i++) { mpc_t value; rdpe_t error, module; mpc_init2 (value, appr[i]->wp); mps_polynomial_meval (ctx, p, appr[i]->mvalue, value, error); mpc_rmod (module, value); /* Get the relative error of this evaluation */ if (!rdpe_eq_zero (module)) rdpe_div_eq (error, module); else rdpe_set_d (error, DBL_EPSILON * p->degree); /* log2(error) + wp - log(n) is a good estimate of log(k) */ rdpe_set_d (root_conditioning[i], rdpe_log (error) / LOG2 + appr[i]->wp - log2 (n)); rdpe_exp_eq (root_conditioning[i]); rdpe_div_eq (root_conditioning[i], appr[i]->drad); mpc_clear (value); } return root_conditioning; }
static void check_ternary_value (mpfr_prec_t prec_max, mpfr_prec_t step) { mpfr_prec_t prec; mpc_t z; mpfr_t f; mpc_init2 (z, 2); mpfr_init (f); for (prec = 2; prec < prec_max; prec += step) { mpc_set_prec (z, prec); mpfr_set_prec (f, prec); mpc_set_ui (z, 1, MPC_RNDNN); mpfr_set_ui (f, 1, MPFR_RNDN); if (mpc_add_fr (z, z, f, MPC_RNDNZ)) { printf ("Error in mpc_add_fr: 1+1 should be exact\n"); exit (1); } mpc_set_ui (z, 1, MPC_RNDNN); mpc_mul_2ui (z, z, (unsigned long int) prec, MPC_RNDNN); if (mpc_add_fr (z, z, f, MPC_RNDNN) == 0) { fprintf (stderr, "Error in mpc_add_fr: 2^prec+1 cannot be exact\n"); exit (1); } } mpc_clear (z); mpfr_clear (f); }
static void check_ternary_value (void) { unsigned int i; mpc_t z; mpc_init2 (z, 2); for (i=2; i <= 1024; i++) { mpc_set_prec (z, i); mpc_set_ui (z, 1, MPC_RNDNN); if (mpc_add_ui (z, z, 1, MPC_RNDNZ)) { printf ("Error in mpc_add_ui: 1+1 should be exact\n"); exit (1); } mpc_set_ui (z, 1, MPC_RNDNN); mpc_mul_2exp (z, z, i, MPC_RNDNN); if (mpc_add_ui (z, z, 1, MPC_RNDNN) == 0) { printf ("Error in mpc_add_ui: 2^prec+1 cannot be exact\n"); exit (1); } } mpc_clear (z); }
int mpc_asinh (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) { /* asinh(op) = -i*asin(i*op) */ int inex; mpc_t z, a; mpfr_t tmp; /* z = i*op */ MPC_RE (z)[0] = MPC_IM (op)[0]; MPC_IM (z)[0] = MPC_RE (op)[0]; MPFR_CHANGE_SIGN (MPC_RE (z)); /* Note reversal of precisions due to later multiplication by -i */ mpc_init3 (a, MPC_PREC_IM(rop), MPC_PREC_RE(rop)); inex = mpc_asin (a, z, RNDC (INV_RND (MPC_RND_IM (rnd)), MPC_RND_RE (rnd))); /* if a = asin(i*op) = x+i*y, and we want y-i*x */ /* change a to -i*a */ tmp[0] = MPC_RE (a)[0]; MPC_RE (a)[0] = MPC_IM (a)[0]; MPC_IM (a)[0] = tmp[0]; MPFR_CHANGE_SIGN (MPC_IM (a)); mpc_set (rop, a, MPC_RNDNN); /* exact */ mpc_clear (a); return MPC_INEX (MPC_INEX_IM (inex), -MPC_INEX_RE (inex)); }
int main (void) { mpc_t z; test_start (); test_end (); mpc_init2 (z, 6); mpc_set_ui_ui (z, 17, 42, MPC_RNDNN); mpfr_set_ui (mpc_realref (z), 18, GMP_RNDN); if (mpfr_get_ui (mpc_realref (z), GMP_RNDN) != 18) { fprintf (stderr, "Error in mpfr_set_ui/mpc_realref\n"); exit (1); } mpfr_set_ui (mpc_imagref (z), 43, GMP_RNDN); if (mpfr_get_ui (mpc_imagref (z), GMP_RNDN) != 43) { fprintf (stderr, "Error in mpfr_set_ui/mpc_imagref\n"); exit (1); } mpc_clear (z); return 0; }
/* tests intermediate underflow; WONTFIX */ static int test_underflow (void) { mpc_t z; mpfr_exp_t emin = mpfr_get_emin (); mpfr_set_emin (-10); mpc_init2 (z, 21); mpfr_set_si (mpc_realref(z), -1, GMP_RNDZ); mpfr_set_ui_2exp (mpc_imagref(z), 1, 20, GMP_RNDZ); mpfr_add_ui (mpc_imagref(z), mpc_imagref(z), 1, GMP_RNDZ); mpfr_div_2exp (mpc_imagref(z), mpc_imagref(z), 20, GMP_RNDZ); mpc_atan (z, z, MPC_RNDNN); if (mpfr_cmp_si_2exp (mpc_realref(z), -1066635, 20) != 0 || mpfr_cmp_si_2exp (mpc_imagref(z), 1687619, 22)) { printf ("Error in test_coverage\n"); printf ("expected (-1066635/2^20 1687619/2^22)\n"); printf ("got "); mpc_out_str (stdout, 10, 20, z, MPC_RNDNN); printf ("\n"); exit (1); } mpc_clear (z); mpfr_set_emin (emin); }
static void check_special (void) { mpc_t z[3], res; mpc_ptr t[3]; int i, inex; /* z[0] = (1,2), z[1] = (2,3), z[2] = (3,4) */ for (i = 0; i < 3; i++) { mpc_init2 (z[i], 17); mpc_set_ui_ui (z[i], i+1, i+2, MPC_RNDNN); t[i] = z[i]; } mpc_init2 (res, 17); /* dot product of empty vectors is 0 */ inex = mpc_dot (res, t, t, 0, MPC_RNDNN); MPC_ASSERT (inex == 0); MPC_ASSERT (mpfr_zero_p (mpc_realref (res))); MPC_ASSERT (mpfr_zero_p (mpc_imagref (res))); MPC_ASSERT (mpfr_signbit (mpc_realref (res)) == 0); MPC_ASSERT (mpfr_signbit (mpc_imagref (res)) == 0); /* (1,2)*(1,2) = (-3,4) */ inex = mpc_dot (res, t, t, 1, MPC_RNDNN); MPC_ASSERT (inex == 0); MPC_ASSERT (mpfr_regular_p (mpc_realref (res))); MPC_ASSERT (mpfr_regular_p (mpc_imagref (res))); MPC_ASSERT (mpfr_cmp_si (mpc_realref (res), -3) == 0); MPC_ASSERT (mpfr_cmp_ui (mpc_imagref (res), 4) == 0); /* (1,2)*(1,2) + (2,3)*(2,3) = (-8,16) */ inex = mpc_dot (res, t, t, 2, MPC_RNDNN); MPC_ASSERT (inex == 0); MPC_ASSERT (mpfr_regular_p (mpc_realref (res))); MPC_ASSERT (mpfr_regular_p (mpc_imagref (res))); MPC_ASSERT (mpfr_cmp_si (mpc_realref (res), -8) == 0); MPC_ASSERT (mpfr_cmp_ui (mpc_imagref (res), 16) == 0); /* (1,2)*(1,2) + (2,3)*(2,3) + (3,4)*(3,4) = (-15,40) */ inex = mpc_dot (res, t, t, 3, MPC_RNDNN); MPC_ASSERT (inex == 0); MPC_ASSERT (mpfr_regular_p (mpc_realref (res))); MPC_ASSERT (mpfr_regular_p (mpc_imagref (res))); MPC_ASSERT (mpfr_cmp_si (mpc_realref (res), -15) == 0); MPC_ASSERT (mpfr_cmp_ui (mpc_imagref (res), 40) == 0); for (i = 0; i < 3; i++) mpc_clear (z[i]); mpc_clear (res); }
static void pure_real_argument (void) { /* cosh(x -i*0) = cosh(x) +i*0 if x<0 */ /* cosh(x -i*0) = cosh(x) -i*0 if x>0 */ /* cosh(x +i*0) = cosh(x) -i*0 if x<0 */ /* cosh(x -i*0) = cosh(x) +i*0 if x>0 */ mpc_t u; mpc_t z; mpc_t cosh_z; mpc_init2 (z, 2); mpc_init2 (u, 100); mpc_init2 (cosh_z, 100); /* cosh(1 +i*0) = cosh(1) +i*0 */ mpc_set_ui_ui (z, 1, 0, MPC_RNDNN); mpfr_cosh (MPC_RE (u), MPC_RE (z), GMP_RNDN); mpfr_set_ui (MPC_IM (u), 0, GMP_RNDN); mpc_cosh (cosh_z, z, MPC_RNDNN); if (mpc_cmp (cosh_z, u) != 0 || mpfr_signbit (MPC_IM (cosh_z))) TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN); /* cosh(1 -i*0) = cosh(1) -i*0 */ mpc_conj (z, z, MPC_RNDNN); mpc_conj (u, u, MPC_RNDNN); mpc_cosh (cosh_z, z, MPC_RNDNN); if (mpc_cmp (cosh_z, u) != 0 || !mpfr_signbit (MPC_IM (cosh_z))) TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN); /* cosh(-1 +i*0) = cosh(1) -i*0 */ mpc_neg (z, z, MPC_RNDNN); mpc_cosh (cosh_z, z, MPC_RNDNN); if (mpc_cmp (cosh_z, u) != 0 || !mpfr_signbit (MPC_IM (cosh_z))) TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN); /* cosh(-1 -i*0) = cosh(1) +i*0 */ mpc_conj (z, z, MPC_RNDNN); mpc_conj (u, u, MPC_RNDNN); mpc_cosh (cosh_z, z, MPC_RNDNN); if (mpc_cmp (cosh_z, u) != 0 || mpfr_signbit (MPC_IM (cosh_z))) TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN); mpc_clear (cosh_z); mpc_clear (z); mpc_clear (u); }
void mpcFinalizer(SEXP ptr) { mpc_t *z = (mpc_t *)R_ExternalPtrAddr(ptr); if (z) { mpc_clear(*z); free(z); R_ClearExternalPtr(ptr); } }
int main (void) { mpc_t z, x; mp_prec_t prec; test_start (); mpc_init2 (z, 1000); mpc_init2 (x, 1000); check_file ("inp_str.dat"); for (prec = 2; prec <= 1000; prec+=7) { mpc_set_prec (z, prec); mpc_set_prec (x, prec); mpc_set_si_si (x, 1, 1, MPC_RNDNN); check_io_str (z, x); mpc_set_si_si (x, -1, 1, MPC_RNDNN); check_io_str (z, x); mpfr_set_inf (MPC_RE(x), -1); mpfr_set_inf (MPC_IM(x), +1); check_io_str (z, x); test_default_random (x, -1024, 1024, 128, 25); check_io_str (z, x); } #ifndef NO_STREAM_REDIRECTION mpc_set_si_si (x, 1, -4, MPC_RNDNN); mpc_div_ui (x, x, 3, MPC_RNDDU); check_stdout(z, x); #endif mpc_clear (z); mpc_clear (x); test_end (); return 0; }
static void pure_imaginary_argument (void) { /* cosh(+0 +i*y) = cos y +i*0*sin y */ /* cosh(-0 +i*y) = cos y -i*0*sin y */ mpc_t u; mpc_t z; mpc_t cosh_z; mpc_init2 (z, 2); mpc_init2 (u, 100); mpc_init2 (cosh_z, 100); /* cosh(+0 +i) = cos(1) + i*0 */ mpc_set_ui_ui (z, 0, 1, MPC_RNDNN); mpfr_cos (MPC_RE (u), MPC_IM (z), GMP_RNDN); mpfr_set_ui (MPC_IM (u), 0, GMP_RNDN); mpc_cosh (cosh_z, z, MPC_RNDNN); if (mpc_cmp (cosh_z, u) != 0 || mpfr_signbit (MPC_IM (cosh_z))) TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN); /* cosh(+0 -i) = cos(1) - i*0 */ mpc_conj (z, z, MPC_RNDNN); mpc_conj (u, u, MPC_RNDNN); mpc_cosh (cosh_z, z, MPC_RNDNN); if (mpc_cmp (cosh_z, u) != 0 || !mpfr_signbit (MPC_IM (cosh_z))) TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN); /* cosh(-0 +i) = cos(1) - i*0 */ mpc_neg (z, z, MPC_RNDNN); mpc_cosh (cosh_z, z, MPC_RNDNN); if (mpc_cmp (cosh_z, u) != 0 || !mpfr_signbit (MPC_IM (cosh_z))) TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN); /* cosh(-0 -i) = cos(1) + i*0 */ mpc_conj (z, z, MPC_RNDNN); mpc_conj (u, u, MPC_RNDNN); mpc_cosh (cosh_z, z, MPC_RNDNN); if (mpc_cmp (cosh_z, u) != 0 || mpfr_signbit (MPC_IM (cosh_z))) TEST_FAILED ("mpc_cosh", z, cosh_z, u, MPC_RNDNN); mpc_clear (cosh_z); mpc_clear (z); mpc_clear (u); }
static void bug20091120 (void) { mpc_t x, y; mpc_init2 (x, 53); mpc_init3 (y, 17, 42); mpc_set_ui_ui (x, 1, 1, MPC_RNDNN); mpc_asinh (y, x, MPC_RNDNN); if (mpfr_get_prec (mpc_realref(y)) != 17 || mpfr_get_prec (mpc_imagref(y)) != 42) { printf ("Error, mpc_asinh changed the precisions!!!\n"); exit (1); } mpc_clear (x); mpc_clear (y); }
static void timemul (void) { /* measures the time needed with different precisions for naive and */ /* Karatsuba multiplication */ mpc_t x, y, z; unsigned long int i, j; const unsigned long int tests = 10000; struct tms time_old, time_new; double passed1, passed2; mpc_init (x); mpc_init (y); mpc_init_set_ui_ui (z, 1, 0, MPC_RNDNN); for (i = 1; i < 50; i++) { mpc_set_prec (x, i * BITS_PER_MP_LIMB); mpc_set_prec (y, i * BITS_PER_MP_LIMB); mpc_set_prec (z, i * BITS_PER_MP_LIMB); test_default_random (x, -1, 1, 128, 25); test_default_random (y, -1, 1, 128, 25); times (&time_old); for (j = 0; j < tests; j++) mpc_mul_naive (z, x, y, MPC_RNDNN); times (&time_new); passed1 = ((double) (time_new.tms_utime - time_old.tms_utime)) / 100; times (&time_old); for (j = 0; j < tests; j++) mpc_mul_karatsuba (z, x, y, MPC_RNDNN); times (&time_new); passed2 = ((double) (time_new.tms_utime - time_old.tms_utime)) / 100; printf ("Time for %3li limbs naive/Karatsuba: %5.2f %5.2f\n", i, passed1, passed2); } mpc_clear (x); mpc_clear (y); mpc_clear (z); }
static void mps_context_shrink (mps_context * s, int n) { int i; for (i = n; i < s->n - s->zero_roots; i++) { mps_approximation_free (s, s->root[i]); } s->root = mps_realloc (s->root, sizeof(mps_approximation*) * n); s->order = mps_realloc (s->order, sizeof(int) * n); s->fppc1 = mps_realloc (s->fppc1, sizeof(cplx_t) * (n + 1)); for (i = n + 1; i <= s->n - s->zero_roots; i++) mpc_clear (s->mfpc1[i]); s->mfpc1 = mps_realloc (s->mfpc1, sizeof(mpc_t) * (n + 1)); for (i = n + 1; i <= s->n- s->zero_roots; i++) mpc_clear (s->mfppc1[i]); s->mfppc1 = mps_realloc (s->mfppc1, sizeof(mpc_t) * (n + 1)); /* temporary vectors */ s->spar1 = mps_realloc (s->spar1, sizeof(mps_boolean) * (n + 2)); s->again_old = mps_realloc (s->again_old, sizeof(mps_boolean) * (n)); s->fap1 = mps_realloc (s->fap1, sizeof(double) * (n + 1)); s->fap2 = mps_realloc (s->fap2, sizeof(double) * (n + 1)); s->dap1 = mps_realloc (s->dap1, sizeof(rdpe_t) * (n + 1)); s->dpc1 = mps_realloc (s->dpc1, sizeof(cdpe_t) * (n + 1)); s->dpc2 = mps_realloc (s->dpc2, sizeof(cdpe_t) * (n + 1)); /* Setting some default here, that were not settable because we didn't know * the degree of the polynomial */ for (i = 0; i < n; i++) s->root[i]->wp = DBL_DIG * LOG2_10; }
int mpc_acosh (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) { /* acosh(z) = NaN + i*NaN, if z=0+i*NaN -i*acos(z), if sign(Im(z)) = - i*acos(z), if sign(Im(z)) = + http://functions.wolfram.com/ElementaryFunctions/ArcCosh/27/02/03/01/01/ */ mpc_t a; mpfr_t tmp; int inex; if (mpfr_zero_p (MPC_RE (op)) && mpfr_nan_p (MPC_IM (op))) { mpfr_set_nan (MPC_RE (rop)); mpfr_set_nan (MPC_IM (rop)); return 0; } /* Note reversal of precisions due to later multiplication by i or -i */ mpc_init3 (a, MPC_PREC_IM(rop), MPC_PREC_RE(rop)); if (mpfr_signbit (MPC_IM (op))) { inex = mpc_acos (a, op, RNDC (INV_RND (MPC_RND_IM (rnd)), MPC_RND_RE (rnd))); /* change a to -i*a, i.e., -y+i*x to x+i*y */ tmp[0] = MPC_RE (a)[0]; MPC_RE (a)[0] = MPC_IM (a)[0]; MPC_IM (a)[0] = tmp[0]; MPFR_CHANGE_SIGN (MPC_IM (a)); inex = MPC_INEX (MPC_INEX_IM (inex), -MPC_INEX_RE (inex)); } else { inex = mpc_acos (a, op, RNDC (MPC_RND_IM (rnd), INV_RND(MPC_RND_RE (rnd)))); /* change a to i*a, i.e., y-i*x to x+i*y */ tmp[0] = MPC_RE (a)[0]; MPC_RE (a)[0] = MPC_IM (a)[0]; MPC_IM (a)[0] = tmp[0]; MPFR_CHANGE_SIGN (MPC_RE (a)); inex = MPC_INEX (-MPC_INEX_IM (inex), MPC_INEX_RE (inex)); } mpc_set (rop, a, rnd); mpc_clear (a); return inex; }