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