Home | History | Annotate | Line # | Download | only in tests
random.c revision 1.1
      1  1.1  mrg /* random.c -- Handle seed for random numbers.
      2  1.1  mrg 
      3  1.1  mrg // Copyright (C) 2008, 2009, 2010, 2011 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 /* Put test_start at the beginning of your test function and
     22  1.1  mrg    test_end at the end.
     23  1.1  mrg    These are an adaptation of those of MPFR. */
     24  1.1  mrg 
     25  1.1  mrg #include "config.h"
     26  1.1  mrg #include <stdlib.h>
     27  1.1  mrg #include "mpc-tests.h"
     28  1.1  mrg 
     29  1.1  mrg 
     30  1.1  mrg #ifdef TIME_WITH_SYS_TIME
     31  1.1  mrg # include <sys/time.h>
     32  1.1  mrg # include <time.h>
     33  1.1  mrg #else
     34  1.1  mrg # ifdef HAVE_SYS_TIME_H
     35  1.1  mrg #  include <sys/time.h>
     36  1.1  mrg # else
     37  1.1  mrg #  include <time.h>
     38  1.1  mrg # endif
     39  1.1  mrg #endif
     40  1.1  mrg 
     41  1.1  mrg gmp_randstate_t  rands;
     42  1.1  mrg static char      rands_initialized;
     43  1.1  mrg 
     44  1.1  mrg void
     45  1.1  mrg test_start (void)
     46  1.1  mrg {
     47  1.1  mrg   char *environment_seed;
     48  1.1  mrg   unsigned long seed;
     49  1.1  mrg 
     50  1.1  mrg   if (rands_initialized)
     51  1.1  mrg     {
     52  1.1  mrg       fprintf (stderr,
     53  1.1  mrg                "Put test_start at the beginning of your test function.\n");
     54  1.1  mrg       exit (1);
     55  1.1  mrg     }
     56  1.1  mrg 
     57  1.1  mrg   gmp_randinit_default (rands);
     58  1.1  mrg   rands_initialized = 1;
     59  1.1  mrg 
     60  1.1  mrg   environment_seed = getenv ("GMP_CHECK_RANDOMIZE");
     61  1.1  mrg   if (environment_seed == NULL)
     62  1.1  mrg       gmp_randseed_ui (rands, 0xfac11e);
     63  1.1  mrg   else
     64  1.1  mrg     {
     65  1.1  mrg       seed = (unsigned long int) atoi (environment_seed);
     66  1.1  mrg       if (seed == 0 || seed == 1)
     67  1.1  mrg         {
     68  1.1  mrg #if defined HAVE_GETTIMEOFDAY
     69  1.1  mrg           struct timeval  tv;
     70  1.1  mrg           gettimeofday (&tv, NULL);
     71  1.1  mrg           seed = (unsigned long int) (tv.tv_sec + tv.tv_usec);
     72  1.1  mrg #else
     73  1.1  mrg           time_t  tv;
     74  1.1  mrg           time (&tv);
     75  1.1  mrg           seed = (unsigned long int) tv;
     76  1.1  mrg #endif
     77  1.1  mrg           gmp_randseed_ui (rands, seed);
     78  1.1  mrg           printf ("Seed GMP_CHECK_RANDOMIZE=%lu "
     79  1.1  mrg                   "(include this in bug reports)\n", seed);
     80  1.1  mrg         }
     81  1.1  mrg       else
     82  1.1  mrg         {
     83  1.1  mrg           printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%lu\n", seed);
     84  1.1  mrg           gmp_randseed_ui (rands, seed);
     85  1.1  mrg         }
     86  1.1  mrg     }
     87  1.1  mrg }
     88  1.1  mrg 
     89  1.1  mrg void
     90  1.1  mrg test_end (void)
     91  1.1  mrg {
     92  1.1  mrg   if (rands_initialized)
     93  1.1  mrg     {
     94  1.1  mrg       rands_initialized = 0;
     95  1.1  mrg       gmp_randclear (rands);
     96  1.1  mrg     }
     97  1.1  mrg   mpfr_free_cache ();
     98  1.1  mrg }
     99  1.1  mrg 
    100  1.1  mrg /* Set z to a non zero value random value with absolute values of Re(z) and
    101  1.1  mrg    Im(z) either zero (but not both in the same time) or otherwise greater than
    102  1.1  mrg    or equal to 2^{emin-1} and less than 2^emax.
    103  1.1  mrg    Each part is negative with probability equal to NEGATIVE_PROBABILITY / 256.
    104  1.1  mrg    The result has one zero part (but never the two of them) with probability
    105  1.1  mrg    equal to ZERO_PROBABILITY / 256.
    106  1.1  mrg */
    107  1.1  mrg void
    108  1.1  mrg test_default_random (mpc_ptr z, mpfr_exp_t emin, mpfr_exp_t emax,
    109  1.1  mrg                      unsigned int negative_probability,
    110  1.1  mrg                      unsigned int zero_probability)
    111  1.1  mrg {
    112  1.1  mrg   const unsigned long range = (unsigned long int) (emax - emin) + 1;
    113  1.1  mrg   unsigned long r;
    114  1.1  mrg 
    115  1.1  mrg   if (!rands_initialized)
    116  1.1  mrg     {
    117  1.1  mrg       fprintf (stderr,
    118  1.1  mrg                "Put test_start at the beginning of your test function.\n");
    119  1.1  mrg       exit (1);
    120  1.1  mrg     }
    121  1.1  mrg 
    122  1.1  mrg   do
    123  1.1  mrg     {
    124  1.1  mrg       mpc_urandom (z, rands);
    125  1.1  mrg     } while (mpfr_zero_p (mpc_realref (z)) || mpfr_zero_p (mpc_imagref (z)));
    126  1.1  mrg 
    127  1.1  mrg   if (zero_probability > 256)
    128  1.1  mrg     zero_probability = 256;
    129  1.1  mrg   r = gmp_urandomb_ui (rands, 19);
    130  1.1  mrg   if ((r & 0x1FF) < zero_probability
    131  1.1  mrg       || ((r >> 9) & 0x1FF) < zero_probability)
    132  1.1  mrg     {
    133  1.1  mrg       int zero_re_p = (r & 0x1FF) < zero_probability;
    134  1.1  mrg       int zero_im_p = ((r >> 9) & 0x1FF) < zero_probability;
    135  1.1  mrg 
    136  1.1  mrg       if (zero_re_p && zero_im_p)
    137  1.1  mrg         {
    138  1.1  mrg           /* we just want one zero part. */
    139  1.1  mrg           zero_re_p = (r >> 18) & 1;
    140  1.1  mrg           zero_im_p = !zero_re_p;
    141  1.1  mrg         }
    142  1.1  mrg       if (zero_re_p)
    143  1.1  mrg         mpfr_set_ui (mpc_realref (z), 0, GMP_RNDN);
    144  1.1  mrg       if (zero_im_p)
    145  1.1  mrg         mpfr_set_ui (mpc_imagref (z), 0, GMP_RNDN);
    146  1.1  mrg     }
    147  1.1  mrg   if (!mpfr_zero_p (mpc_realref (z)))
    148  1.1  mrg     mpfr_set_exp (mpc_realref (z), (mpfr_exp_t) gmp_urandomm_ui (rands, range) + emin);
    149  1.1  mrg 
    150  1.1  mrg   if (!mpfr_zero_p (mpc_imagref (z)))
    151  1.1  mrg     mpfr_set_exp (mpc_imagref (z), (mpfr_exp_t) gmp_urandomm_ui (rands, range) + emin);
    152  1.1  mrg 
    153  1.1  mrg   if (negative_probability > 256)
    154  1.1  mrg     negative_probability = 256;
    155  1.1  mrg   r = gmp_urandomb_ui (rands, 16);
    156  1.1  mrg   if ((r & 0xFF) < negative_probability)
    157  1.1  mrg     mpfr_neg (mpc_realref (z), mpc_realref (z), GMP_RNDN);
    158  1.1  mrg   if (((r>>8) & 0xFF) < negative_probability)
    159  1.1  mrg     mpfr_neg (mpc_imagref (z), mpc_imagref (z), GMP_RNDN);
    160  1.1  mrg }
    161