Home | History | Annotate | Line # | Download | only in tests
tsqr.c revision 1.1.1.2
      1      1.1  mrg /* tsqr -- test file for mpc_sqr.
      2      1.1  mrg 
      3  1.1.1.2  mrg Copyright (C) 2002, 2005, 2008, 2010, 2011, 2012, 2013 INRIA
      4      1.1  mrg 
      5      1.1  mrg This file is part of GNU MPC.
      6      1.1  mrg 
      7      1.1  mrg GNU MPC is free software; you can redistribute it and/or modify it under
      8      1.1  mrg the terms of the GNU Lesser General Public License as published by the
      9      1.1  mrg Free Software Foundation; either version 3 of the License, or (at your
     10      1.1  mrg option) any later version.
     11      1.1  mrg 
     12      1.1  mrg GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
     13      1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
     14      1.1  mrg FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
     15      1.1  mrg more details.
     16      1.1  mrg 
     17      1.1  mrg You should have received a copy of the GNU Lesser General Public License
     18      1.1  mrg along with this program. If not, see http://www.gnu.org/licenses/ .
     19      1.1  mrg */
     20      1.1  mrg 
     21      1.1  mrg #include <stdlib.h>
     22      1.1  mrg #include "mpc-tests.h"
     23      1.1  mrg 
     24      1.1  mrg static void
     25      1.1  mrg cmpsqr (mpc_srcptr x, mpc_rnd_t rnd)
     26      1.1  mrg    /* computes the square of x with the specific function or by simple     */
     27      1.1  mrg    /* multiplication using the rounding mode rnd and compares the results  */
     28      1.1  mrg    /* and return values.                                                   */
     29      1.1  mrg    /* In our current test suite, the real and imaginary parts of x have    */
     30      1.1  mrg    /* the same precision, and we use this precision also for the result.   */
     31      1.1  mrg    /* Furthermore, we check whether computing the square in the same       */
     32      1.1  mrg    /* place yields the same result.                                        */
     33      1.1  mrg    /* We also compute the result with four times the precision and check   */
     34      1.1  mrg    /* whether the rounding is correct. Error reports in this part of the   */
     35      1.1  mrg    /* algorithm might still be wrong, though, since there are two          */
     36      1.1  mrg    /* consecutive roundings.                                               */
     37      1.1  mrg {
     38      1.1  mrg   mpc_t z, t, u;
     39      1.1  mrg   int   inexact_z, inexact_t;
     40      1.1  mrg 
     41      1.1  mrg   mpc_init2 (z, MPC_MAX_PREC (x));
     42      1.1  mrg   mpc_init2 (t, MPC_MAX_PREC (x));
     43      1.1  mrg   mpc_init2 (u, 4 * MPC_MAX_PREC (x));
     44      1.1  mrg 
     45      1.1  mrg   inexact_z = mpc_sqr (z, x, rnd);
     46      1.1  mrg   inexact_t = mpc_mul (t, x, x, rnd);
     47      1.1  mrg 
     48      1.1  mrg   if (mpc_cmp (z, t))
     49      1.1  mrg     {
     50      1.1  mrg       fprintf (stderr, "sqr and mul differ for rnd=(%s,%s) \nx=",
     51      1.1  mrg                mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
     52      1.1  mrg                mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
     53      1.1  mrg       mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
     54      1.1  mrg       fprintf (stderr, "\nmpc_sqr gives ");
     55      1.1  mrg       mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
     56      1.1  mrg       fprintf (stderr, "\nmpc_mul gives ");
     57      1.1  mrg       mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
     58      1.1  mrg       fprintf (stderr, "\n");
     59      1.1  mrg       exit (1);
     60      1.1  mrg     }
     61      1.1  mrg   if (inexact_z != inexact_t)
     62      1.1  mrg     {
     63      1.1  mrg       fprintf (stderr, "The return values of sqr and mul differ for rnd=(%s,%s) \nx=  ",
     64      1.1  mrg                mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
     65      1.1  mrg                mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
     66      1.1  mrg       mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
     67      1.1  mrg       fprintf (stderr, "\nx^2=");
     68      1.1  mrg       mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
     69      1.1  mrg       fprintf (stderr, "\nmpc_sqr gives %i", inexact_z);
     70      1.1  mrg       fprintf (stderr, "\nmpc_mul gives %i", inexact_t);
     71      1.1  mrg       fprintf (stderr, "\n");
     72      1.1  mrg       exit (1);
     73      1.1  mrg     }
     74      1.1  mrg 
     75      1.1  mrg   mpc_set (t, x, MPC_RNDNN);
     76      1.1  mrg   inexact_t = mpc_sqr (t, t, rnd);
     77      1.1  mrg   if (mpc_cmp (z, t))
     78      1.1  mrg     {
     79      1.1  mrg       fprintf (stderr, "sqr and sqr in place differ for rnd=(%s,%s) \nx=",
     80      1.1  mrg                mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
     81      1.1  mrg                mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
     82      1.1  mrg       mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
     83      1.1  mrg       fprintf (stderr, "\nmpc_sqr          gives ");
     84      1.1  mrg       mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
     85      1.1  mrg       fprintf (stderr, "\nmpc_sqr in place gives ");
     86      1.1  mrg       mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
     87      1.1  mrg       fprintf (stderr, "\n");
     88      1.1  mrg       exit (1);
     89      1.1  mrg     }
     90      1.1  mrg   if (inexact_z != inexact_t)
     91      1.1  mrg     {
     92      1.1  mrg       fprintf (stderr, "The return values of sqr and sqr in place differ for rnd=(%s,%s) \nx=  ",
     93      1.1  mrg                mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
     94      1.1  mrg                mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
     95      1.1  mrg       mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
     96      1.1  mrg       fprintf (stderr, "\nx^2=");
     97      1.1  mrg       mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
     98      1.1  mrg       fprintf (stderr, "\nmpc_sqr          gives %i", inexact_z);
     99      1.1  mrg       fprintf (stderr, "\nmpc_sqr in place gives %i", inexact_t);
    100      1.1  mrg       fprintf (stderr, "\n");
    101      1.1  mrg       exit (1);
    102      1.1  mrg     }
    103      1.1  mrg 
    104      1.1  mrg   mpc_sqr (u, x, rnd);
    105      1.1  mrg   mpc_set (t, u, rnd);
    106      1.1  mrg   if (mpc_cmp (z, t))
    107      1.1  mrg     {
    108      1.1  mrg       fprintf (stderr, "rounding in sqr might be incorrect for rnd=(%s,%s) \nx=",
    109      1.1  mrg                mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
    110      1.1  mrg                mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
    111      1.1  mrg       mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
    112      1.1  mrg       fprintf (stderr, "\nmpc_sqr                     gives ");
    113      1.1  mrg       mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
    114      1.1  mrg       fprintf (stderr, "\nmpc_sqr quadruple precision gives ");
    115      1.1  mrg       mpc_out_str (stderr, 2, 0, u, MPC_RNDNN);
    116      1.1  mrg       fprintf (stderr, "\nand is rounded to                 ");
    117      1.1  mrg       mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
    118      1.1  mrg       fprintf (stderr, "\n");
    119      1.1  mrg       exit (1);
    120      1.1  mrg     }
    121      1.1  mrg 
    122      1.1  mrg   mpc_clear (z);
    123      1.1  mrg   mpc_clear (t);
    124      1.1  mrg   mpc_clear (u);
    125      1.1  mrg }
    126      1.1  mrg 
    127      1.1  mrg 
    128      1.1  mrg static void
    129      1.1  mrg testsqr (long a, long b, mpfr_prec_t prec, mpc_rnd_t rnd)
    130      1.1  mrg {
    131      1.1  mrg   mpc_t x;
    132      1.1  mrg 
    133      1.1  mrg   mpc_init2 (x, prec);
    134      1.1  mrg 
    135      1.1  mrg   mpc_set_si_si (x, a, b, rnd);
    136      1.1  mrg 
    137      1.1  mrg   cmpsqr (x, rnd);
    138      1.1  mrg 
    139      1.1  mrg   mpc_clear (x);
    140      1.1  mrg }
    141      1.1  mrg 
    142      1.1  mrg 
    143      1.1  mrg static void
    144      1.1  mrg reuse_bug (void)
    145      1.1  mrg {
    146      1.1  mrg   mpc_t z1;
    147      1.1  mrg 
    148      1.1  mrg   /* reuse bug found by Paul Zimmermann 20081021 */
    149      1.1  mrg   mpc_init2 (z1, 2);
    150      1.1  mrg   /* RE (z1^2) overflows, IM(z^2) = -0 */
    151  1.1.1.2  mrg   mpfr_set_str (mpc_realref (z1), "0.11", 2, MPFR_RNDN);
    152  1.1.1.2  mrg   mpfr_mul_2si (mpc_realref (z1), mpc_realref (z1), mpfr_get_emax (), MPFR_RNDN);
    153  1.1.1.2  mrg   mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
    154      1.1  mrg   mpc_conj (z1, z1, MPC_RNDNN);
    155      1.1  mrg   mpc_sqr (z1, z1, MPC_RNDNN);
    156      1.1  mrg   if (!mpfr_inf_p (mpc_realref (z1)) || mpfr_signbit (mpc_realref (z1))
    157      1.1  mrg       ||!mpfr_zero_p (mpc_imagref (z1)) || !mpfr_signbit (mpc_imagref (z1)))
    158      1.1  mrg     {
    159      1.1  mrg       printf ("Error: Regression, bug 20081021 reproduced\n");
    160      1.1  mrg       MPC_OUT (z1);
    161      1.1  mrg       exit (1);
    162      1.1  mrg     }
    163      1.1  mrg 
    164      1.1  mrg   mpc_clear (z1);
    165      1.1  mrg }
    166      1.1  mrg 
    167  1.1.1.2  mrg #define MPC_FUNCTION_CALL                                       \
    168  1.1.1.2  mrg   P[0].mpc_inex = mpc_sqr (P[1].mpc, P[2].mpc, P[3].mpc_rnd)
    169  1.1.1.2  mrg #define MPC_FUNCTION_CALL_REUSE_OP1                             \
    170  1.1.1.2  mrg   P[0].mpc_inex = mpc_sqr (P[1].mpc, P[1].mpc, P[3].mpc_rnd)
    171  1.1.1.2  mrg 
    172  1.1.1.2  mrg #include "data_check.tpl"
    173  1.1.1.2  mrg #include "tgeneric.tpl"
    174  1.1.1.2  mrg 
    175      1.1  mrg int
    176      1.1  mrg main (void)
    177      1.1  mrg {
    178      1.1  mrg   test_start ();
    179      1.1  mrg 
    180      1.1  mrg   testsqr (247, -65, 8, 24);
    181      1.1  mrg   testsqr (5, -896, 3, 2);
    182      1.1  mrg   testsqr (-3, -512, 2, 16);
    183      1.1  mrg   testsqr (266013312, 121990769, 27, 0);
    184      1.1  mrg   testsqr (170, 9, 8, 0);
    185      1.1  mrg   testsqr (768, 85, 8, 16);
    186      1.1  mrg   testsqr (145, 1816, 8, 24);
    187      1.1  mrg   testsqr (0, 1816, 8, 24);
    188      1.1  mrg   testsqr (145, 0, 8, 24);
    189      1.1  mrg 
    190  1.1.1.2  mrg   data_check_template ("sqr.dsc", "sqr.dat");
    191  1.1.1.2  mrg 
    192  1.1.1.2  mrg   tgeneric_template ("sqr.dsc", 2, 1024, 1, 1024);
    193      1.1  mrg 
    194      1.1  mrg   reuse_bug ();
    195      1.1  mrg 
    196      1.1  mrg   test_end ();
    197      1.1  mrg 
    198      1.1  mrg   return 0;
    199      1.1  mrg }
    200