static void test_grandom (long nbtests, mpfr_prec_t prec, mpfr_rnd_t rnd, int verbose) { mpfr_t *t; mpfr_t av, va, tmp; int i, inexact; nbtests = (nbtests & 1) ? (nbtests + 1) : nbtests; t = (mpfr_t *) tests_allocate (nbtests * sizeof (mpfr_t)); for (i = 0; i < nbtests; ++i) mpfr_init2 (t[i], prec); for (i = 0; i < nbtests; i += 2) { inexact = mpfr_grandom (t[i], t[i + 1], RANDS, MPFR_RNDN); if ((inexact & 3) == 0 || (inexact & (3 << 2)) == 0) { /* one call in the loop pretended to return an exact number! */ printf ("Error: mpfr_grandom() returns a zero ternary value.\n"); exit (1); } } #ifdef HAVE_STDARG if (verbose) { mpfr_init2 (av, prec); mpfr_init2 (va, prec); mpfr_init2 (tmp, prec); mpfr_set_ui (av, 0, MPFR_RNDN); mpfr_set_ui (va, 0, MPFR_RNDN); for (i = 0; i < nbtests; ++i) { mpfr_add (av, av, t[i], MPFR_RNDN); mpfr_sqr (tmp, t[i], MPFR_RNDN); mpfr_add (va, va, tmp, MPFR_RNDN); } mpfr_div_ui (av, av, nbtests, MPFR_RNDN); mpfr_div_ui (va, va, nbtests, MPFR_RNDN); mpfr_sqr (tmp, av, MPFR_RNDN); mpfr_sub (va, va, av, MPFR_RNDN); mpfr_printf ("Average = %.5Rf\nVariance = %.5Rf\n", av, va); mpfr_clear (av); mpfr_clear (va); mpfr_clear (tmp); } #endif /* HAVE_STDARG */ for (i = 0; i < nbtests; ++i) mpfr_clear (t[i]); tests_free (t, nbtests * sizeof (mpfr_t)); return; }
/* check adding n random numbers, iterated k times */ static void check_random (int n, int k, mpfr_prec_t prec, mpfr_rnd_t rnd) { mpfr_t *x, s, ref_s; mpfr_ptr *y; int i, st, ret = 0, ref_ret = 0; gmp_randstate_t state; gmp_randinit_default (state); mpfr_init2 (s, prec); mpfr_init2 (ref_s, prec); x = (mpfr_t *) tests_allocate (n * sizeof (mpfr_t)); y = (mpfr_ptr *) tests_allocate (n * sizeof (mpfr_ptr)); for (i = 0; i < n; i++) { y[i] = x[i]; mpfr_init2 (x[i], prec); mpfr_urandom (x[i], state, rnd); } st = cputime (); for (i = 0; i < k; i++) ref_ret = mpfr_sum_naive (ref_s, x, n, rnd); printf ("mpfr_sum_naive took %dms\n", cputime () - st); st = cputime (); for (i = 0; i < k; i++) ret = mpfr_sum (s, y, n, rnd); printf ("mpfr_sum took %dms\n", cputime () - st); if (n <= 2) { MPFR_ASSERTN (mpfr_cmp (ref_s, s) == 0); MPFR_ASSERTN (ref_ret == ret); } for (i = 0; i < n; i++) mpfr_clear (x[i]); tests_free (x, n * sizeof (mpfr_t)); tests_free (y, n * sizeof (mpfr_ptr)); mpfr_clear (s); mpfr_clear (ref_s); gmp_randclear (state); }
/* Open a file in the SRCDIR directory, i.e. the "tests" source directory, which is different from the current directory when objdir is different from srcdir. One should generally use this function instead of fopen directly. */ FILE * src_fopen (const char *filename, const char *mode) { #ifndef SRCDIR return fopen (filename, mode); #else const char *srcdir = SRCDIR; char *buffer; size_t buffsize; FILE *f; buffsize = strlen (filename) + strlen (srcdir) + 2; buffer = (char *) tests_allocate (buffsize); if (buffer == NULL) { printf ("src_fopen: failed to alloc memory)\n"); exit (1); } sprintf (buffer, "%s/%s", srcdir, filename); f = fopen (buffer, mode); tests_free (buffer, buffsize); return f; #endif }
static void generic_tests (void) { mpfr_t exact_sum, sum1, sum2; mpfr_t *t; mpfr_ptr *p; mpfr_prec_t precmax = 444; int i, m, nmax = 500; int rnd_mode; t = (mpfr_t *) tests_allocate (nmax * sizeof(mpfr_t)); p = (mpfr_ptr *) tests_allocate (nmax * sizeof(mpfr_ptr)); for (i = 0; i < nmax; i++) { mpfr_init2 (t[i], precmax); p[i] = t[i]; } mpfr_inits2 (precmax, exact_sum, sum1, sum2, (mpfr_ptr) 0); for (m = 0; m < 4000; m++) { int non_uniform, n; mpfr_prec_t prec; non_uniform = randlimb () % 10; n = (randlimb () % nmax) + 1; prec = MPFR_PREC_MIN + (randlimb () % (precmax - MPFR_PREC_MIN + 1)); mpfr_set_prec (sum1, prec); mpfr_set_prec (sum2, prec); for (i = 0; i < n; i++) { mpfr_set_prec (t[i], MPFR_PREC_MIN + (randlimb () % (precmax - MPFR_PREC_MIN + 1))); mpfr_urandomb (t[i], RANDS); if (m % 8 != 0 && (m % 8 == 1 || (randlimb () & 1))) mpfr_neg (t[i], t[i], MPFR_RNDN); if (non_uniform && MPFR_NOTZERO (t[i])) mpfr_set_exp (t[i], randlimb () % 1000); /* putchar ("-0+"[SIGN (mpfr_sgn (t[i])) + 1]); */ } /* putchar ('\n'); */ get_exact_sum (exact_sum, t, n); RND_LOOP (rnd_mode) { int inex1, inex2; inex1 = mpfr_set (sum1, exact_sum, (mpfr_rnd_t) rnd_mode); inex2 = mpfr_sum (sum2, p, n, (mpfr_rnd_t) rnd_mode); if (!(mpfr_equal_p (sum1, sum2) && SAME_SIGN (inex1, inex2))) { printf ("generic_tests failed on m = %d, %s\n", m, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd_mode)); printf ("Expected "); mpfr_dump (sum1); printf ("with inex = %d\n", inex1); printf ("Got "); mpfr_dump (sum2); printf ("with inex = %d\n", inex2); exit (1); } } } for (i = 0; i < nmax; i++) mpfr_clear (t[i]); mpfr_clears (exact_sum, sum1, sum2, (mpfr_ptr) 0); tests_free (t, nmax * sizeof(mpfr_t)); tests_free (p, nmax * sizeof(mpfr_ptr)); }