From 41fdca3f042a506c6a656d9ec2af117462ae7ecc Mon Sep 17 00:00:00 2001 From: Paul Zimmermann Date: Wed, 5 Feb 2020 20:07:54 +0100 Subject: renamed mpc_check.c to mpcheck-double.c, plus clean-up --- tests/Makefile.am | 4 +- tests/mpc_check.c | 220 ------------------------------------------- tests/mpc_check_template1.c | 82 ---------------- tests/mpc_check_template2.c | 77 --------------- tests/mpc_check_template3.c | 91 ------------------ tests/mpcheck-double.c | 223 ++++++++++++++++++++++++++++++++++++++++++++ tests/mpcheck-template1.c | 82 ++++++++++++++++ tests/mpcheck-template2.c | 77 +++++++++++++++ tests/mpcheck-template3.c | 91 ++++++++++++++++++ 9 files changed, 475 insertions(+), 472 deletions(-) delete mode 100644 tests/mpc_check.c delete mode 100644 tests/mpc_check_template1.c delete mode 100644 tests/mpc_check_template2.c delete mode 100644 tests/mpc_check_template3.c create mode 100644 tests/mpcheck-double.c create mode 100644 tests/mpcheck-template1.c create mode 100644 tests/mpcheck-template2.c create mode 100644 tests/mpcheck-template3.c diff --git a/tests/Makefile.am b/tests/Makefile.am index d4dffec..f5cab22 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -66,8 +66,8 @@ DATA_SETS = abs.dat acos.dat acosh.dat add.dat add_fr.dat arg.dat \ sin.dat sinh.dat \ sqr.dat sqrt.dat strtoc.dat sub.dat sub_fr.dat tan.dat tanh.dat EXTRA_DIST = data_check.tpl tgeneric.tpl $(DATA_SETS) $(DESCRIPTIONS) \ - mpc_check.c \ - mpc_check_template1.c mpc_check_template2.c mpc_check_template3.c + mpcheck-double.c \ + mpcheck-template1.c mpcheck-template2.c mpcheck-template3.c LOG_COMPILER = $(VALGRIND) AM_LOG_FLAGS = $(VALGRIND_OPTS) diff --git a/tests/mpc_check.c b/tests/mpc_check.c deleted file mode 100644 index 185a185..0000000 --- a/tests/mpc_check.c +++ /dev/null @@ -1,220 +0,0 @@ -/* mpc_check -- compare mpc functions against the GNU libc implementation - -Copyright (C) 2020 INRIA - -This file is part of GNU MPC. - -GNU MPC is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for -more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see http://www.gnu.org/licenses/ . -*/ - -/* the GNU libc provides the following functions (as of 2.31), - with 'f' suffix for the float/binary32 version, with no suffix - for the double/binary64 version, with 'l' suffix for the long double - version, and with 'f128' suffix for the __float128 version: - - cabs casinh cexp csinh - cacos catan clog csqrt - cacosh catanh clog10 ctan - carg ccos cpow ctanh - casin ccosh csin -*/ - -#define _GNU_SOURCE /* for clog10 */ -#include -#include -#include -#include "mpc-tests.h" -#ifdef __GNUC__ -#include -#endif - -gmp_randstate_t state; -unsigned long seed = 1; -int verbose = 0; - -static unsigned long -ulp_error (mpfr_t x, mpfr_t y) -{ - mpfr_t z; - mpfr_prec_t p = mpfr_get_prec (y); - unsigned long n; - - if (mpfr_cmp (x, y) == 0) - return 0; - - mpfr_init2 (z, p); - mpfr_sub (z, x, y, MPFR_RNDN); - mpfr_abs (z, z, MPFR_RNDN); - /* divide by ulp(y) = 2^(EXP(y) - p) */ - mpfr_div_2si (z, z, mpfr_get_exp (y) - p, MPFR_RNDN); - n = mpfr_get_ui (z, MPFR_RNDZ); - mpfr_clear (z); - return n; -} - -#define FOO add -#define CFOO(x,y) (x+y) -#include "mpc_check_template3.c" - -#define FOO sub -#define CFOO(x,y) (x-y) -#include "mpc_check_template3.c" - -#define FOO mul -#define CFOO(x,y) (x*y) -#include "mpc_check_template3.c" - -#define FOO div -#define CFOO(x,y) (x/y) -#include "mpc_check_template3.c" - -#define FOO pow -#include "mpc_check_template3.c" - -#define FOO abs -#include "mpc_check_template2.c" - -#define FOO arg -#include "mpc_check_template2.c" - -#define FOO sqrt -#include "mpc_check_template1.c" - -#define FOO acos -#include "mpc_check_template1.c" - -#define FOO acosh -#include "mpc_check_template1.c" - -#define FOO asin -#include "mpc_check_template1.c" - -#define FOO asinh -#include "mpc_check_template1.c" - -#define FOO atan -#include "mpc_check_template1.c" - -#define FOO atanh -#include "mpc_check_template1.c" - -#define FOO cos -#include "mpc_check_template1.c" - -#define FOO cosh -#include "mpc_check_template1.c" - -#define FOO exp -#include "mpc_check_template1.c" - -#define FOO log -#include "mpc_check_template1.c" - -#define FOO log10 -#include "mpc_check_template1.c" - -#define FOO sin -#include "mpc_check_template1.c" - -#define FOO sinh -#include "mpc_check_template1.c" - -#define FOO tan -#include "mpc_check_template1.c" - -#define FOO tanh -#include "mpc_check_template1.c" - -int -main (int argc, char *argv[]) -{ - mpfr_prec_t p = 53; /* default precision */ - unsigned long n = 1000000; - - while (argc >= 2 && argv[1][0] == '-') - { - if (argc >= 3 && strcmp (argv[1], "-p") == 0) - { - p = atoi (argv[2]); - argc -= 2; - argv += 2; - } - else if (argc >= 3 && strcmp (argv[1], "-seed") == 0) - { - seed = atoi (argv[2]); - argc -= 2; - argv += 2; - } - else if (strcmp (argv[1], "-v") == 0) - { - verbose ++; - argc --; - argv ++; - } - else - { - fprintf (stderr, "Unknown option %s\n", argv[1]); - exit (1); - } - } - - MPC_ASSERT (p == 53); - - if (p == 53) - { - mpfr_set_emin (-1073); - mpfr_set_emax (1024); - } - - gmp_randinit_default (state); - -#ifdef __GNUC__ - printf ("GNU libc version: %s\n", gnu_get_libc_version ()); - printf ("GNU libc release: %s\n", gnu_get_libc_release ()); -#endif - printf ("Using random seed %lu\n", seed); - - /* (complex,complex) -> complex */ - test_add (p, n); - test_sub (p, n); - test_mul (p, n); - test_div (p, n); - test_pow (p, n); - - /* complex -> real */ - test_abs (p, n); - test_arg (p, n); - - /* complex -> complex */ - test_sqrt (p, n); - test_acos (p, n); - test_acosh (p, n); - test_asin (p, n); - test_asinh (p, n); - test_atan (p, n); - test_atanh (p, n); - test_cos (p, n); - test_cosh (p, n); - test_exp (p, n); - test_log (p, n); - test_log10 (p, n); - test_sin (p, n); - test_sinh (p, n); - test_tan (p, n); - test_tanh (p, n); - - gmp_randclear (state); - - return 0; -} diff --git a/tests/mpc_check_template1.c b/tests/mpc_check_template1.c deleted file mode 100644 index 771054b..0000000 --- a/tests/mpc_check_template1.c +++ /dev/null @@ -1,82 +0,0 @@ -/* template for complex -> complex function, for example acos - -Copyright (C) 2020 INRIA - -This file is part of GNU MPC. - -GNU MPC is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for -more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see http://www.gnu.org/licenses/ . -*/ - -#define CAT1(X,Y) X ## Y -#define CAT2(X,Y) CAT1(X,Y) -#define STRINGIFY(x) #x -#define TOSTRING(x) STRINGIFY(x) - -#define FUN CAT2(test_,FOO) -#define MPC_FOO CAT2(mpc_,FOO) -#define CFOO CAT2(c,FOO) -#define BAR TOSTRING(FOO) - -static void -FUN (mpfr_prec_t p, unsigned long n) -{ - unsigned long i = 0; - mpc_t x, z, t; - double complex xx, zz; - int inex; - unsigned long errors = 0, max_err_re = 0, max_err_im = 0; - - gmp_randseed_ui (state, seed); - - mpc_init2 (x, p); - mpc_init2 (z, p); - mpc_init2 (t, p); - for (i = 0; i < n; i++) - { - mpc_urandom (x, state); - inex = MPC_FOO (z, x, MPC_RNDNN); - mpfr_subnormalize (mpc_realref (z), MPC_INEX_RE(inex), MPFR_RNDN); - mpfr_subnormalize (mpc_imagref (z), MPC_INEX_IM(inex), MPFR_RNDN); - xx = mpc_get_dc (x, MPC_RNDNN); - zz = CFOO (xx); - mpc_set_dc (t, zz, MPFR_RNDN); - if (mpc_cmp (z, t) != 0) - { - unsigned long err_re = ulp_error (mpc_realref (t), mpc_realref (z)); - unsigned long err_im = ulp_error (mpc_imagref (t), mpc_imagref (z)); - if (verbose > 0 && (err_re > max_err_re || err_im > max_err_im)) - { - mpfr_printf (" mpc_%s and c%s differ by (%lu,%lu) ulp(s)\n for x=(%Re,%Re)\n", - BAR, BAR, err_re, err_im, - mpc_realref (x), mpc_imagref (x)); - mpfr_printf (" mpc_%s gives (%Re,%Re)\n", BAR, - mpc_realref (z), mpc_imagref (z)); - mpfr_printf (" c%s gives (%Re,%Re)\n", BAR, - mpc_realref (t), mpc_imagref (t)); - } - errors ++; - if (err_re > max_err_re) - max_err_re = err_re; - if (err_im > max_err_im) - max_err_im = err_im; - } - } - mpc_clear (x); - mpc_clear (z); - mpc_clear (t); - printf ("Number of errors for %s: %lu/%lu (max %lu,%lu)\n", BAR, - errors, n, max_err_re, max_err_im); -} - -#undef FOO diff --git a/tests/mpc_check_template2.c b/tests/mpc_check_template2.c deleted file mode 100644 index fdb26c3..0000000 --- a/tests/mpc_check_template2.c +++ /dev/null @@ -1,77 +0,0 @@ -/* template for complex -> real function, for example abs - -Copyright (C) 2020 INRIA - -This file is part of GNU MPC. - -GNU MPC is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for -more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see http://www.gnu.org/licenses/ . -*/ - -#define CAT1(X,Y) X ## Y -#define CAT2(X,Y) CAT1(X,Y) -#define STRINGIFY(x) #x -#define TOSTRING(x) STRINGIFY(x) - -#define FUN CAT2(test_,FOO) -#define MPC_FOO CAT2(mpc_,FOO) -#define CFOO CAT2(c,FOO) -#define BAR TOSTRING(FOO) - -static void -FUN (mpfr_prec_t p, unsigned long n) -{ - unsigned long i = 0; - mpc_t x; - mpfr_t z, t; - double complex xx; - double zz; - int inex; - unsigned long errors = 0, max_err = 0; - - gmp_randseed_ui (state, seed); - - mpc_init2 (x, p); - mpfr_init2 (z, p); - mpfr_init2 (t, p); - for (i = 0; i < n; i++) - { - mpc_urandom (x, state); - inex = MPC_FOO (z, x, MPC_RNDNN); - mpfr_subnormalize (z, inex, MPFR_RNDN); - xx = mpc_get_dc (x, MPC_RNDNN); - zz = CFOO (xx); - mpfr_set_d (t, zz, MPFR_RNDN); - if (mpfr_cmp (z, t) != 0) - { - unsigned long err = ulp_error (t, z); - if (verbose > 0 && err > max_err) - { - mpfr_printf (" mpc_%s and c%s differ by %lu ulp(s)\n for x=(%Re,%Re)\n", - BAR, BAR, err, - mpc_realref (x), mpc_imagref (x)); - mpfr_printf (" mpc_%s gives %Re\n", BAR, z); - mpfr_printf (" c%s gives %Re\n", BAR, t); - } - errors++; - if (err > max_err) - max_err = err; - } - } - mpc_clear (x); - mpfr_clear (z); - mpfr_clear (t); - printf ("Number of errors for %s: %lu/%lu (max %lu)\n", BAR, errors, n, max_err); -} - -#undef FOO diff --git a/tests/mpc_check_template3.c b/tests/mpc_check_template3.c deleted file mode 100644 index 506e7ac..0000000 --- a/tests/mpc_check_template3.c +++ /dev/null @@ -1,91 +0,0 @@ -/* template for (complex,complex) -> complex function, for example add - -Copyright (C) 2020 INRIA - -This file is part of GNU MPC. - -GNU MPC is free software; you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for -more details. - -You should have received a copy of the GNU Lesser General Public License -along with this program. If not, see http://www.gnu.org/licenses/ . -*/ - -#define CAT1(X,Y) X ## Y -#define CAT2(X,Y) CAT1(X,Y) -#define STRINGIFY(x) #x -#define TOSTRING(x) STRINGIFY(x) - -#define FUN CAT2(test_,FOO) -#define MPC_FOO CAT2(mpc_,FOO) -#ifndef CFOO -#define CFOO CAT2(c,FOO) -#endif -#define BAR TOSTRING(FOO) - -static void -FUN (mpfr_prec_t p, unsigned long n) -{ - unsigned long i = 0; - mpc_t x, y, z, t; - double complex xx, yy, zz; - int inex; - unsigned long errors = 0, max_err_re = 0, max_err_im = 0; - - gmp_randseed_ui (state, seed); - - mpc_init2 (x, p); - mpc_init2 (y, p); - mpc_init2 (z, p); - mpc_init2 (t, p); - for (i = 0; i < n; i++) - { - mpc_urandom (x, state); - mpc_urandom (y, state); - inex = MPC_FOO (z, x, y, MPC_RNDNN); - mpfr_subnormalize (mpc_realref (z), MPC_INEX_RE(inex), MPFR_RNDN); - mpfr_subnormalize (mpc_imagref (z), MPC_INEX_IM(inex), MPFR_RNDN); - xx = mpc_get_dc (x, MPC_RNDNN); - yy = mpc_get_dc (y, MPC_RNDNN); - zz = CFOO(xx, yy); - mpc_set_dc (t, zz, MPFR_RNDN); - if (mpc_cmp (z, t) != 0) - { - unsigned long err_re = ulp_error (mpc_realref (t), mpc_realref (z)); - unsigned long err_im = ulp_error (mpc_imagref (t), mpc_imagref (z)); - if (verbose > 0 && (err_re > max_err_re || err_im > max_err_im)) - { - printf (" mpc_%s and c%s differ by (%lu,%lu) ulp(s)\n", - BAR, BAR, err_re, err_im); - mpfr_printf (" for x=(%Re,%Re)\n y=(%Re,%Re)\n", - mpc_realref (x), mpc_imagref (x), - mpc_realref (y), mpc_imagref (y)); - mpfr_printf (" mpc_%s gives (%Re,%Re)\n", BAR, - mpc_realref (z), mpc_imagref (z)); - mpfr_printf (" c%s gives (%Re,%Re)\n", BAR, - mpc_realref (t), mpc_imagref (t)); - } - errors ++; - if (err_re > max_err_re) - max_err_re = err_re; - if (err_im > max_err_im) - max_err_im = err_im; - } - } - mpc_clear (x); - mpc_clear (y); - mpc_clear (z); - mpc_clear (t); - printf ("Number of errors for %s: %lu/%lu (max %lu,%lu)\n", BAR, errors, n, - max_err_re, max_err_im); -} - -#undef FOO -#undef CFOO diff --git a/tests/mpcheck-double.c b/tests/mpcheck-double.c new file mode 100644 index 0000000..b1ef696 --- /dev/null +++ b/tests/mpcheck-double.c @@ -0,0 +1,223 @@ +/* mpcheck-double -- compare mpc functions against "double complex" + from the GNU libc implementation + +Copyright (C) 2020 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +/* the GNU libc provides the following functions (as of 2.31), + with 'f' suffix for the float/binary32 version, with no suffix + for the double/binary64 version, with 'l' suffix for the long double + version, and with 'f128' suffix for the __float128 version: + + cabs casinh cexp csinh + cacos catan clog csqrt + cacosh catanh clog10 ctan + carg ccos cpow ctanh + casin ccosh csin +*/ + +#define _GNU_SOURCE /* for clog10 */ +#include +#include +#include +#include "mpc-tests.h" +#ifdef __GNUC__ +#include +#endif + +gmp_randstate_t state; +unsigned long seed = 1; +int verbose = 0; + +static unsigned long +ulp_error (mpfr_t x, mpfr_t y) +{ + mpfr_t z; + mpfr_prec_t p = mpfr_get_prec (y); + unsigned long n; + + if (mpfr_cmp (x, y) == 0) + return 0; + + mpfr_init2 (z, p); + mpfr_sub (z, x, y, MPFR_RNDN); + mpfr_abs (z, z, MPFR_RNDN); + /* divide by ulp(y) = 2^(EXP(y) - p) */ + mpfr_div_2si (z, z, mpfr_get_exp (y) - p, MPFR_RNDN); + n = mpfr_get_ui (z, MPFR_RNDZ); + mpfr_clear (z); + return n; +} + +#define FOO add +#define CFOO(x,y) (x+y) +#include "mpcheck-template3.c" + +#define FOO sub +#define CFOO(x,y) (x-y) +#include "mpcheck-template3.c" + +#define FOO mul +#define CFOO(x,y) (x*y) +#include "mpcheck-template3.c" + +#define FOO div +#define CFOO(x,y) (x/y) +#include "mpcheck-template3.c" + +#define FOO pow +#include "mpcheck-template3.c" + +#define FOO abs +#include "mpcheck-template2.c" + +#define FOO arg +#include "mpcheck-template2.c" + +#define FOO sqrt +#include "mpcheck-template1.c" + +#define FOO acos +#include "mpcheck-template1.c" + +#define FOO acosh +#include "mpcheck-template1.c" + +#define FOO asin +#include "mpcheck-template1.c" + +#define FOO asinh +#include "mpcheck-template1.c" + +#define FOO atan +#include "mpcheck-template1.c" + +#define FOO atanh +#include "mpcheck-template1.c" + +#define FOO cos +#include "mpcheck-template1.c" + +#define FOO cosh +#include "mpcheck-template1.c" + +#define FOO exp +#include "mpcheck-template1.c" + +#define FOO log +#include "mpcheck-template1.c" + +#define FOO log10 +#include "mpcheck-template1.c" + +#define FOO sin +#include "mpcheck-template1.c" + +#define FOO sinh +#include "mpcheck-template1.c" + +#define FOO tan +#include "mpcheck-template1.c" + +#define FOO tanh +#include "mpcheck-template1.c" + +int +main (int argc, char *argv[]) +{ + mpfr_prec_t p = 53; /* precision of 'double' */ + unsigned long n = 1000000; /* default number of random tests per function */ + + while (argc >= 2 && argv[1][0] == '-') + { + if (argc >= 3 && strcmp (argv[1], "-p") == 0) + { + p = atoi (argv[2]); + argc -= 2; + argv += 2; + } + else if (argc >= 3 && strcmp (argv[1], "-seed") == 0) + { + seed = atoi (argv[2]); + argc -= 2; + argv += 2; + } + else if (argc >= 3 && strcmp (argv[1], "-num") == 0) + { + n = atoi (argv[2]); + argc -= 2; + argv += 2; + } + else if (strcmp (argv[1], "-v") == 0) + { + verbose ++; + argc --; + argv ++; + } + else + { + fprintf (stderr, "Unknown option %s\n", argv[1]); + exit (1); + } + } + + /* set exponent range for 'double' */ + mpfr_set_emin (-1073); + mpfr_set_emax (1024); + + gmp_randinit_default (state); + +#ifdef __GNUC__ + printf ("GNU libc version: %s\n", gnu_get_libc_version ()); + printf ("GNU libc release: %s\n", gnu_get_libc_release ()); +#endif + printf ("Using random seed %lu\n", seed); + + /* (complex,complex) -> complex */ + test_add (p, n); + test_sub (p, n); + test_mul (p, n); + test_div (p, n); + test_pow (p, n); + + /* complex -> real */ + test_abs (p, n); + test_arg (p, n); + + /* complex -> complex */ + test_sqrt (p, n); + test_acos (p, n); + test_acosh (p, n); + test_asin (p, n); + test_asinh (p, n); + test_atan (p, n); + test_atanh (p, n); + test_cos (p, n); + test_cosh (p, n); + test_exp (p, n); + test_log (p, n); + test_log10 (p, n); + test_sin (p, n); + test_sinh (p, n); + test_tan (p, n); + test_tanh (p, n); + + gmp_randclear (state); + + return 0; +} diff --git a/tests/mpcheck-template1.c b/tests/mpcheck-template1.c new file mode 100644 index 0000000..771054b --- /dev/null +++ b/tests/mpcheck-template1.c @@ -0,0 +1,82 @@ +/* template for complex -> complex function, for example acos + +Copyright (C) 2020 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#define CAT1(X,Y) X ## Y +#define CAT2(X,Y) CAT1(X,Y) +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +#define FUN CAT2(test_,FOO) +#define MPC_FOO CAT2(mpc_,FOO) +#define CFOO CAT2(c,FOO) +#define BAR TOSTRING(FOO) + +static void +FUN (mpfr_prec_t p, unsigned long n) +{ + unsigned long i = 0; + mpc_t x, z, t; + double complex xx, zz; + int inex; + unsigned long errors = 0, max_err_re = 0, max_err_im = 0; + + gmp_randseed_ui (state, seed); + + mpc_init2 (x, p); + mpc_init2 (z, p); + mpc_init2 (t, p); + for (i = 0; i < n; i++) + { + mpc_urandom (x, state); + inex = MPC_FOO (z, x, MPC_RNDNN); + mpfr_subnormalize (mpc_realref (z), MPC_INEX_RE(inex), MPFR_RNDN); + mpfr_subnormalize (mpc_imagref (z), MPC_INEX_IM(inex), MPFR_RNDN); + xx = mpc_get_dc (x, MPC_RNDNN); + zz = CFOO (xx); + mpc_set_dc (t, zz, MPFR_RNDN); + if (mpc_cmp (z, t) != 0) + { + unsigned long err_re = ulp_error (mpc_realref (t), mpc_realref (z)); + unsigned long err_im = ulp_error (mpc_imagref (t), mpc_imagref (z)); + if (verbose > 0 && (err_re > max_err_re || err_im > max_err_im)) + { + mpfr_printf (" mpc_%s and c%s differ by (%lu,%lu) ulp(s)\n for x=(%Re,%Re)\n", + BAR, BAR, err_re, err_im, + mpc_realref (x), mpc_imagref (x)); + mpfr_printf (" mpc_%s gives (%Re,%Re)\n", BAR, + mpc_realref (z), mpc_imagref (z)); + mpfr_printf (" c%s gives (%Re,%Re)\n", BAR, + mpc_realref (t), mpc_imagref (t)); + } + errors ++; + if (err_re > max_err_re) + max_err_re = err_re; + if (err_im > max_err_im) + max_err_im = err_im; + } + } + mpc_clear (x); + mpc_clear (z); + mpc_clear (t); + printf ("Number of errors for %s: %lu/%lu (max %lu,%lu)\n", BAR, + errors, n, max_err_re, max_err_im); +} + +#undef FOO diff --git a/tests/mpcheck-template2.c b/tests/mpcheck-template2.c new file mode 100644 index 0000000..fdb26c3 --- /dev/null +++ b/tests/mpcheck-template2.c @@ -0,0 +1,77 @@ +/* template for complex -> real function, for example abs + +Copyright (C) 2020 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#define CAT1(X,Y) X ## Y +#define CAT2(X,Y) CAT1(X,Y) +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +#define FUN CAT2(test_,FOO) +#define MPC_FOO CAT2(mpc_,FOO) +#define CFOO CAT2(c,FOO) +#define BAR TOSTRING(FOO) + +static void +FUN (mpfr_prec_t p, unsigned long n) +{ + unsigned long i = 0; + mpc_t x; + mpfr_t z, t; + double complex xx; + double zz; + int inex; + unsigned long errors = 0, max_err = 0; + + gmp_randseed_ui (state, seed); + + mpc_init2 (x, p); + mpfr_init2 (z, p); + mpfr_init2 (t, p); + for (i = 0; i < n; i++) + { + mpc_urandom (x, state); + inex = MPC_FOO (z, x, MPC_RNDNN); + mpfr_subnormalize (z, inex, MPFR_RNDN); + xx = mpc_get_dc (x, MPC_RNDNN); + zz = CFOO (xx); + mpfr_set_d (t, zz, MPFR_RNDN); + if (mpfr_cmp (z, t) != 0) + { + unsigned long err = ulp_error (t, z); + if (verbose > 0 && err > max_err) + { + mpfr_printf (" mpc_%s and c%s differ by %lu ulp(s)\n for x=(%Re,%Re)\n", + BAR, BAR, err, + mpc_realref (x), mpc_imagref (x)); + mpfr_printf (" mpc_%s gives %Re\n", BAR, z); + mpfr_printf (" c%s gives %Re\n", BAR, t); + } + errors++; + if (err > max_err) + max_err = err; + } + } + mpc_clear (x); + mpfr_clear (z); + mpfr_clear (t); + printf ("Number of errors for %s: %lu/%lu (max %lu)\n", BAR, errors, n, max_err); +} + +#undef FOO diff --git a/tests/mpcheck-template3.c b/tests/mpcheck-template3.c new file mode 100644 index 0000000..506e7ac --- /dev/null +++ b/tests/mpcheck-template3.c @@ -0,0 +1,91 @@ +/* template for (complex,complex) -> complex function, for example add + +Copyright (C) 2020 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#define CAT1(X,Y) X ## Y +#define CAT2(X,Y) CAT1(X,Y) +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +#define FUN CAT2(test_,FOO) +#define MPC_FOO CAT2(mpc_,FOO) +#ifndef CFOO +#define CFOO CAT2(c,FOO) +#endif +#define BAR TOSTRING(FOO) + +static void +FUN (mpfr_prec_t p, unsigned long n) +{ + unsigned long i = 0; + mpc_t x, y, z, t; + double complex xx, yy, zz; + int inex; + unsigned long errors = 0, max_err_re = 0, max_err_im = 0; + + gmp_randseed_ui (state, seed); + + mpc_init2 (x, p); + mpc_init2 (y, p); + mpc_init2 (z, p); + mpc_init2 (t, p); + for (i = 0; i < n; i++) + { + mpc_urandom (x, state); + mpc_urandom (y, state); + inex = MPC_FOO (z, x, y, MPC_RNDNN); + mpfr_subnormalize (mpc_realref (z), MPC_INEX_RE(inex), MPFR_RNDN); + mpfr_subnormalize (mpc_imagref (z), MPC_INEX_IM(inex), MPFR_RNDN); + xx = mpc_get_dc (x, MPC_RNDNN); + yy = mpc_get_dc (y, MPC_RNDNN); + zz = CFOO(xx, yy); + mpc_set_dc (t, zz, MPFR_RNDN); + if (mpc_cmp (z, t) != 0) + { + unsigned long err_re = ulp_error (mpc_realref (t), mpc_realref (z)); + unsigned long err_im = ulp_error (mpc_imagref (t), mpc_imagref (z)); + if (verbose > 0 && (err_re > max_err_re || err_im > max_err_im)) + { + printf (" mpc_%s and c%s differ by (%lu,%lu) ulp(s)\n", + BAR, BAR, err_re, err_im); + mpfr_printf (" for x=(%Re,%Re)\n y=(%Re,%Re)\n", + mpc_realref (x), mpc_imagref (x), + mpc_realref (y), mpc_imagref (y)); + mpfr_printf (" mpc_%s gives (%Re,%Re)\n", BAR, + mpc_realref (z), mpc_imagref (z)); + mpfr_printf (" c%s gives (%Re,%Re)\n", BAR, + mpc_realref (t), mpc_imagref (t)); + } + errors ++; + if (err_re > max_err_re) + max_err_re = err_re; + if (err_im > max_err_im) + max_err_im = err_im; + } + } + mpc_clear (x); + mpc_clear (y); + mpc_clear (z); + mpc_clear (t); + printf ("Number of errors for %s: %lu/%lu (max %lu,%lu)\n", BAR, errors, n, + max_err_re, max_err_im); +} + +#undef FOO +#undef CFOO -- cgit v1.2.1