Home | History | Annotate | Line # | Download | only in tests
random.c revision 1.1.1.1.8.2
      1  1.1.1.1.8.2  tls /* random.c -- Handle seed for random numbers.
      2  1.1.1.1.8.2  tls 
      3  1.1.1.1.8.2  tls // Copyright (C) 2008, 2009, 2010, 2011 INRIA
      4  1.1.1.1.8.2  tls 
      5  1.1.1.1.8.2  tls This file is part of GNU MPC.
      6  1.1.1.1.8.2  tls 
      7  1.1.1.1.8.2  tls GNU MPC is free software; you can redistribute it and/or modify it under
      8  1.1.1.1.8.2  tls the terms of the GNU Lesser General Public License as published by the
      9  1.1.1.1.8.2  tls Free Software Foundation; either version 3 of the License, or (at your
     10  1.1.1.1.8.2  tls option) any later version.
     11  1.1.1.1.8.2  tls 
     12  1.1.1.1.8.2  tls GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
     13  1.1.1.1.8.2  tls WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
     14  1.1.1.1.8.2  tls FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
     15  1.1.1.1.8.2  tls more details.
     16  1.1.1.1.8.2  tls 
     17  1.1.1.1.8.2  tls You should have received a copy of the GNU Lesser General Public License
     18  1.1.1.1.8.2  tls along with this program. If not, see http://www.gnu.org/licenses/ .
     19  1.1.1.1.8.2  tls */
     20  1.1.1.1.8.2  tls 
     21  1.1.1.1.8.2  tls /* Put test_start at the beginning of your test function and
     22  1.1.1.1.8.2  tls    test_end at the end.
     23  1.1.1.1.8.2  tls    These are an adaptation of those of MPFR. */
     24  1.1.1.1.8.2  tls 
     25  1.1.1.1.8.2  tls #include "config.h"
     26  1.1.1.1.8.2  tls #include <stdlib.h>
     27  1.1.1.1.8.2  tls #include "mpc-tests.h"
     28  1.1.1.1.8.2  tls 
     29  1.1.1.1.8.2  tls 
     30  1.1.1.1.8.2  tls #ifdef TIME_WITH_SYS_TIME
     31  1.1.1.1.8.2  tls # include <sys/time.h>
     32  1.1.1.1.8.2  tls # include <time.h>
     33  1.1.1.1.8.2  tls #else
     34  1.1.1.1.8.2  tls # ifdef HAVE_SYS_TIME_H
     35  1.1.1.1.8.2  tls #  include <sys/time.h>
     36  1.1.1.1.8.2  tls # else
     37  1.1.1.1.8.2  tls #  include <time.h>
     38  1.1.1.1.8.2  tls # endif
     39  1.1.1.1.8.2  tls #endif
     40  1.1.1.1.8.2  tls 
     41  1.1.1.1.8.2  tls gmp_randstate_t  rands;
     42  1.1.1.1.8.2  tls static char      rands_initialized;
     43  1.1.1.1.8.2  tls 
     44  1.1.1.1.8.2  tls void
     45  1.1.1.1.8.2  tls test_start (void)
     46  1.1.1.1.8.2  tls {
     47  1.1.1.1.8.2  tls   char *environment_seed;
     48  1.1.1.1.8.2  tls   unsigned long seed;
     49  1.1.1.1.8.2  tls 
     50  1.1.1.1.8.2  tls   if (rands_initialized)
     51  1.1.1.1.8.2  tls     {
     52  1.1.1.1.8.2  tls       fprintf (stderr,
     53  1.1.1.1.8.2  tls                "Put test_start at the beginning of your test function.\n");
     54  1.1.1.1.8.2  tls       exit (1);
     55  1.1.1.1.8.2  tls     }
     56  1.1.1.1.8.2  tls 
     57  1.1.1.1.8.2  tls   gmp_randinit_default (rands);
     58  1.1.1.1.8.2  tls   rands_initialized = 1;
     59  1.1.1.1.8.2  tls 
     60  1.1.1.1.8.2  tls   environment_seed = getenv ("GMP_CHECK_RANDOMIZE");
     61  1.1.1.1.8.2  tls   if (environment_seed == NULL)
     62  1.1.1.1.8.2  tls       gmp_randseed_ui (rands, 0xfac11e);
     63  1.1.1.1.8.2  tls   else
     64  1.1.1.1.8.2  tls     {
     65  1.1.1.1.8.2  tls       seed = (unsigned long int) atoi (environment_seed);
     66  1.1.1.1.8.2  tls       if (seed == 0 || seed == 1)
     67  1.1.1.1.8.2  tls         {
     68  1.1.1.1.8.2  tls #if defined HAVE_GETTIMEOFDAY
     69  1.1.1.1.8.2  tls           struct timeval  tv;
     70  1.1.1.1.8.2  tls           gettimeofday (&tv, NULL);
     71  1.1.1.1.8.2  tls           seed = (unsigned long int) (tv.tv_sec + tv.tv_usec);
     72  1.1.1.1.8.2  tls #else
     73  1.1.1.1.8.2  tls           time_t  tv;
     74  1.1.1.1.8.2  tls           time (&tv);
     75  1.1.1.1.8.2  tls           seed = (unsigned long int) tv;
     76  1.1.1.1.8.2  tls #endif
     77  1.1.1.1.8.2  tls           gmp_randseed_ui (rands, seed);
     78  1.1.1.1.8.2  tls           printf ("Seed GMP_CHECK_RANDOMIZE=%lu "
     79  1.1.1.1.8.2  tls                   "(include this in bug reports)\n", seed);
     80  1.1.1.1.8.2  tls         }
     81  1.1.1.1.8.2  tls       else
     82  1.1.1.1.8.2  tls         {
     83  1.1.1.1.8.2  tls           printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%lu\n", seed);
     84  1.1.1.1.8.2  tls           gmp_randseed_ui (rands, seed);
     85  1.1.1.1.8.2  tls         }
     86  1.1.1.1.8.2  tls     }
     87  1.1.1.1.8.2  tls }
     88  1.1.1.1.8.2  tls 
     89  1.1.1.1.8.2  tls void
     90  1.1.1.1.8.2  tls test_end (void)
     91  1.1.1.1.8.2  tls {
     92  1.1.1.1.8.2  tls   if (rands_initialized)
     93  1.1.1.1.8.2  tls     {
     94  1.1.1.1.8.2  tls       rands_initialized = 0;
     95  1.1.1.1.8.2  tls       gmp_randclear (rands);
     96  1.1.1.1.8.2  tls     }
     97  1.1.1.1.8.2  tls   mpfr_free_cache ();
     98  1.1.1.1.8.2  tls }
     99  1.1.1.1.8.2  tls 
    100  1.1.1.1.8.2  tls /* Set z to a non zero value random value with absolute values of Re(z) and
    101  1.1.1.1.8.2  tls    Im(z) either zero (but not both in the same time) or otherwise greater than
    102  1.1.1.1.8.2  tls    or equal to 2^{emin-1} and less than 2^emax.
    103  1.1.1.1.8.2  tls    Each part is negative with probability equal to NEGATIVE_PROBABILITY / 256.
    104  1.1.1.1.8.2  tls    The result has one zero part (but never the two of them) with probability
    105  1.1.1.1.8.2  tls    equal to ZERO_PROBABILITY / 256.
    106  1.1.1.1.8.2  tls */
    107  1.1.1.1.8.2  tls void
    108  1.1.1.1.8.2  tls test_default_random (mpc_ptr z, mpfr_exp_t emin, mpfr_exp_t emax,
    109  1.1.1.1.8.2  tls                      unsigned int negative_probability,
    110  1.1.1.1.8.2  tls                      unsigned int zero_probability)
    111  1.1.1.1.8.2  tls {
    112  1.1.1.1.8.2  tls   const unsigned long range = (unsigned long int) (emax - emin) + 1;
    113  1.1.1.1.8.2  tls   unsigned long r;
    114  1.1.1.1.8.2  tls 
    115  1.1.1.1.8.2  tls   if (!rands_initialized)
    116  1.1.1.1.8.2  tls     {
    117  1.1.1.1.8.2  tls       fprintf (stderr,
    118  1.1.1.1.8.2  tls                "Put test_start at the beginning of your test function.\n");
    119  1.1.1.1.8.2  tls       exit (1);
    120  1.1.1.1.8.2  tls     }
    121  1.1.1.1.8.2  tls 
    122  1.1.1.1.8.2  tls   do
    123  1.1.1.1.8.2  tls     {
    124  1.1.1.1.8.2  tls       mpc_urandom (z, rands);
    125  1.1.1.1.8.2  tls     } while (mpfr_zero_p (mpc_realref (z)) || mpfr_zero_p (mpc_imagref (z)));
    126  1.1.1.1.8.2  tls 
    127  1.1.1.1.8.2  tls   if (zero_probability > 256)
    128  1.1.1.1.8.2  tls     zero_probability = 256;
    129  1.1.1.1.8.2  tls   r = gmp_urandomb_ui (rands, 19);
    130  1.1.1.1.8.2  tls   if ((r & 0x1FF) < zero_probability
    131  1.1.1.1.8.2  tls       || ((r >> 9) & 0x1FF) < zero_probability)
    132  1.1.1.1.8.2  tls     {
    133  1.1.1.1.8.2  tls       int zero_re_p = (r & 0x1FF) < zero_probability;
    134  1.1.1.1.8.2  tls       int zero_im_p = ((r >> 9) & 0x1FF) < zero_probability;
    135  1.1.1.1.8.2  tls 
    136  1.1.1.1.8.2  tls       if (zero_re_p && zero_im_p)
    137  1.1.1.1.8.2  tls         {
    138  1.1.1.1.8.2  tls           /* we just want one zero part. */
    139  1.1.1.1.8.2  tls           zero_re_p = (r >> 18) & 1;
    140  1.1.1.1.8.2  tls           zero_im_p = !zero_re_p;
    141  1.1.1.1.8.2  tls         }
    142  1.1.1.1.8.2  tls       if (zero_re_p)
    143  1.1.1.1.8.2  tls         mpfr_set_ui (mpc_realref (z), 0, GMP_RNDN);
    144  1.1.1.1.8.2  tls       if (zero_im_p)
    145  1.1.1.1.8.2  tls         mpfr_set_ui (mpc_imagref (z), 0, GMP_RNDN);
    146  1.1.1.1.8.2  tls     }
    147  1.1.1.1.8.2  tls   if (!mpfr_zero_p (mpc_realref (z)))
    148  1.1.1.1.8.2  tls     mpfr_set_exp (mpc_realref (z), (mpfr_exp_t) gmp_urandomm_ui (rands, range) + emin);
    149  1.1.1.1.8.2  tls 
    150  1.1.1.1.8.2  tls   if (!mpfr_zero_p (mpc_imagref (z)))
    151  1.1.1.1.8.2  tls     mpfr_set_exp (mpc_imagref (z), (mpfr_exp_t) gmp_urandomm_ui (rands, range) + emin);
    152  1.1.1.1.8.2  tls 
    153  1.1.1.1.8.2  tls   if (negative_probability > 256)
    154  1.1.1.1.8.2  tls     negative_probability = 256;
    155  1.1.1.1.8.2  tls   r = gmp_urandomb_ui (rands, 16);
    156  1.1.1.1.8.2  tls   if ((r & 0xFF) < negative_probability)
    157  1.1.1.1.8.2  tls     mpfr_neg (mpc_realref (z), mpc_realref (z), GMP_RNDN);
    158  1.1.1.1.8.2  tls   if (((r>>8) & 0xFF) < negative_probability)
    159  1.1.1.1.8.2  tls     mpfr_neg (mpc_imagref (z), mpc_imagref (z), GMP_RNDN);
    160  1.1.1.1.8.2  tls }
    161