[BACK]Return to gen.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / tests / rand

Annotation of OpenXM_contrib/gmp/tests/rand/gen.c, Revision 1.1.1.1

1.1       maekawa     1: /* gen.c -- Generate pseudorandom numbers. */
                      2:
                      3: /*
                      4: Copyright (C) 1999, 2000 Free Software Foundation, Inc.
                      5:
                      6: This file is part of the GNU MP Library.
                      7:
                      8: The GNU MP Library is free software; you can redistribute it and/or modify
                      9: it under the terms of the GNU Lesser General Public License as published by
                     10: the Free Software Foundation; either version 2.1 of the License, or (at your
                     11: option) any later version.
                     12:
                     13: The GNU MP Library is distributed in the hope that it will be useful, but
                     14: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
                     16: License for more details.
                     17:
                     18: You should have received a copy of the GNU Lesser General Public License
                     19: along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
                     20: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
                     21: MA 02111-1307, USA.
                     22: */
                     23:
                     24: /* Examples:
                     25:
                     26:   $ gen 10
                     27: 10 integers 0 <= X < 2^32 generated by mpz_urandomb()
                     28:
                     29:   $ gen -f mpf_urandomb 10
                     30: 10 real numbers 0 <= X < 1
                     31:
                     32:   $ gen -z 127 10
                     33: 10 integers 0 <= X < 2^127
                     34:
                     35:   $ gen -f mpf_urandomb -x .9,1 10
                     36: 10 real numbers 0 <= X < .9
                     37:
                     38:   $ gen -s 1 10
                     39: 10 integers, sequence seeded with 1
                     40:
                     41: */
                     42:
                     43: #include <stdio.h>
                     44: #include <stdlib.h>
                     45: #include <unistd.h>
                     46: #include <limits.h>
                     47: #include <errno.h>
                     48: #include <time.h>
                     49: #include <string.h>
                     50:
                     51: #if !HAVE_DECL_OPTARG
                     52: extern char *optarg;
                     53: extern int optind, opterr;
                     54: #endif
                     55:
                     56: #include "gmp.h"
                     57: #include "gmp-impl.h"
                     58:
                     59: int main (argc, argv)
                     60:      int argc;
                     61:      char *argv[];
                     62: {
                     63:   const char usage[] =
                     64:     "usage: gen [-bhpq] [-a n] [-c a,c,m2exp] [-C a,c,m] [-f func] [-g alg] [-m n] [-s n] " \
                     65:     "[-x f,t] [-z n] [n]\n" \
                     66:     "  n        number of random numbers to generate\n" \
                     67:     "  -a n     ASCII output in radix n (default, with n=10)\n" \
                     68:     "  -b       binary output\n" \
                     69:     "  -c a,c,m2exp use supplied LC scheme\n" \
                     70:     "  -C a,c,m     use supplied LC scheme\n" \
                     71:     "  -f func  random function, one of\n" \
                     72:     "           mpz_urandomb (default), mpz_urandomm, mpf_urandomb, rand, random\n" \
                     73:     "  -g alg   algorithm, one of lc (default), bbs\n" \
                     74:     "  -h       print this text and exit\n" \
                     75:     "  -m n     maximum size of generated number plus 1 (0<= X < n) for mpz_urandomm\n" \
                     76:     "  -p       print used seed on stderr\n" \
                     77:     "  -q      quiet, no output\n" \
                     78:     "  -s n     initial seed (default: output from time(3))\n" \
                     79:     "  -x f,t   exclude all numbers f <= x <= t\n" \
                     80:     "  -z n     size in bits of generated numbers (0<= X <2^n) (default 32)\n" \
                     81:     "";
                     82:
                     83:   unsigned long int f;
                     84:   unsigned long int n = 0;
                     85:   unsigned long int seed;
                     86:   unsigned long int m2exp = 0;
                     87:   unsigned int size = 32;
                     88:   int seed_from_user = 0;
                     89:   int ascout = 1, binout = 0, printseed = 0;
                     90:   int output_radix = 10;
                     91:   int lc_scheme_from_user = 0;
                     92:   int quiet_flag = 0;
                     93:   mpz_t z_seed;
                     94:   mpz_t z1;
                     95:   mpf_t f1;
                     96:   gmp_randstate_t rstate;
                     97:   int c, i;
                     98:   double drand;
                     99:   long lrand;
                    100:   int do_exclude = 0;
                    101:   mpf_t f_xf, f_xt;            /* numbers to exclude from sequence */
                    102:   char *str_xf, *str_xt;       /* numbers to exclude from sequence */
                    103:   char *str_a, *str_adder, *str_m;
                    104:   mpz_t z_a, z_m, z_mmax;
                    105:   unsigned long int ul_adder;
                    106:
                    107:   enum
                    108:   {
                    109:     RFUNC_mpz_urandomb = 0,
                    110:     RFUNC_mpz_urandomm,
                    111:     RFUNC_mpf_urandomb,
                    112:     RFUNC_rand,
                    113:     RFUNC_random,
                    114:   } rfunc = RFUNC_mpz_urandomb;
                    115:   char *rfunc_str[] =  { "mpz_urandomb", "mpz_urandomm", "mpf_urandomb",
                    116:                         "rand", "random" };
                    117:   gmp_randalg_t ralg = GMP_RAND_ALG_DEFAULT;
                    118:   char *ralg_str[] = { "lc", "bbs" };
                    119:
                    120:   mpf_init (f_xf);
                    121:   mpf_init (f_xt);
                    122:   mpf_init (f1);
                    123:   mpz_init (z1);
                    124:   mpz_init (z_seed);
                    125:   mpz_init_set_ui (z_mmax, 0);
                    126:
                    127:
                    128:   while ((c = getopt (argc, argv, "a:bc:C:f:g:hm:n:pqs:z:x:")) != -1)
                    129:     switch (c)
                    130:       {
                    131:       case 'a':
                    132:        ascout = 1;
                    133:        binout = 0;
                    134:        output_radix = atoi (optarg);
                    135:        break;
                    136:
                    137:       case 'b':
                    138:        ascout = 0;
                    139:        binout = 1;
                    140:        break;
                    141:
                    142:       case 'c':                        /* User supplied LC scheme: a,c,m2exp */
                    143:       case 'C':                        /* User supplied LC scheme: a,c,m */
                    144:        if (NULL == (str_a = strtok (optarg, ","))
                    145:            || NULL == (str_adder = strtok (NULL, ","))
                    146:            || NULL == (str_m = strtok (NULL, ",")))
                    147:          {
                    148:            fprintf (stderr, "gen: bad LC scheme parameters: %s\n", optarg);
                    149:            exit (1);
                    150:          }
                    151: #ifdef HAVE_STRTOUL
                    152:        ul_adder = strtoul (str_adder, NULL, 0);
                    153: #elif HAVE_STRTOL
                    154:        ul_adder = (unsigned long int) strtol (str_adder, NULL, 0);
                    155: #else
                    156:        ul_adder = (unsigned long int) atoi (str_adder);
                    157: #endif
                    158:
                    159:        if (mpz_init_set_str (z_a, str_a, 0))
                    160:          {
                    161:            fprintf (stderr, "gen: bad LC scheme parameter `a': %s\n", str_a);
                    162:            exit (1);
                    163:          }
                    164:        if (ULONG_MAX == ul_adder)
                    165:          {
                    166:            fprintf (stderr, "gen: bad LC scheme parameter `c': %s\n",
                    167:                     str_adder);
                    168:            exit (1);
                    169:          }
                    170:        if (c == 'c')
                    171:          m2exp = atol (str_m);
                    172:        else
                    173:          mpz_init_set_str (z_m, str_m, 0);
                    174:
                    175:        lc_scheme_from_user = 1;
                    176:        break;
                    177:
                    178:
                    179:       case 'f':
                    180:        rfunc = -1;
                    181:        for (f = 0; f < sizeof (rfunc_str) / sizeof (*rfunc_str); f++)
                    182:            if (!strcmp (optarg, rfunc_str[f]))
                    183:              {
                    184:                rfunc = f;
                    185:                break;
                    186:              }
                    187:        if (rfunc == -1)
                    188:          {
                    189:            fputs (usage, stderr);
                    190:            exit (1);
                    191:          }
                    192:        break;
                    193:
                    194:       case 'g':                        /* algorithm */
                    195:        ralg = -1;
                    196:        for (f = 0; f < sizeof (ralg_str) / sizeof (*ralg_str); f++)
                    197:            if (!strcmp (optarg, ralg_str[f]))
                    198:              {
                    199:                ralg = f;
                    200:                break;
                    201:              }
                    202:        if (ralg == -1)
                    203:          {
                    204:            fputs (usage, stderr);
                    205:            exit (1);
                    206:          }
                    207:        break;
                    208:
                    209:       case 'm':                        /* max for mpz_urandomm() */
                    210:        if (mpz_set_str (z_mmax, optarg, 0))
                    211:          {
                    212:            fprintf (stderr, "gen: bad max value: %s\n", optarg);
                    213:            exit (1);
                    214:          }
                    215:        break;
                    216:
                    217:       case 'p':                        /* print seed on stderr */
                    218:        printseed = 1;
                    219:        break;
                    220:
                    221:       case 'q':                        /* quiet */
                    222:        quiet_flag = 1;
                    223:        break;
                    224:
                    225:       case 's':                        /* user provided seed */
                    226:        if (mpz_set_str (z_seed, optarg, 0))
                    227:          {
                    228:            fprintf (stderr, "gen: bad seed argument %s\n", optarg);
                    229:            exit (1);
                    230:          }
                    231:        seed_from_user = 1;
                    232:        break;
                    233:
                    234:       case 'z':
                    235:        size = atoi (optarg);
                    236:        if (size < 1)
                    237:          {
                    238:            fprintf (stderr, "gen: bad size argument (-z %u)\n", size);
                    239:            exit (1);
                    240:          }
                    241:        break;
                    242:
                    243:       case 'x':                        /* Exclude. from,to */
                    244:        str_xf = optarg;
                    245:        str_xt = strchr (optarg, ',');
                    246:        if (NULL == str_xt)
                    247:          {
                    248:            fprintf (stderr, "gen: bad exclusion parameters: %s\n", optarg);
                    249:            exit (1);
                    250:          }
                    251:        *str_xt++ = '\0';
                    252:        do_exclude = 1;
                    253:        break;
                    254:
                    255:       case 'h':
                    256:       case '?':
                    257:       default:
                    258:        fputs (usage, stderr);
                    259:        exit (1);
                    260:       }
                    261:   argc -= optind;
                    262:   argv += optind;
                    263:
                    264:   if (! seed_from_user)
                    265:     mpz_set_ui (z_seed, (unsigned long int) time (NULL));
                    266:   seed = mpz_get_ui (z_seed);
                    267:   if (printseed)
                    268:     {
                    269:       fprintf (stderr, "gen: seed used: ");
                    270:       mpz_out_str (stderr, output_radix, z_seed);
                    271:       fprintf (stderr, "\n");
                    272:     }
                    273:
                    274:   mpf_set_prec (f1, size);
                    275:
                    276:   /* init random state and plant seed */
                    277:   switch (rfunc)
                    278:     {
                    279:     case RFUNC_mpf_urandomb:
                    280: #if 0
                    281:       /* Don't init a too small generator.  */
                    282:       size = PREC (f1) * BITS_PER_MP_LIMB;
                    283:       /* Fall through.  */
                    284: #endif
                    285:     case RFUNC_mpz_urandomb:
                    286:     case RFUNC_mpz_urandomm:
                    287:       if (! lc_scheme_from_user)
                    288:        {
                    289:          gmp_randinit (rstate, ralg, MIN (128, size));
                    290:        }
                    291:       else
                    292:        {
                    293:          if (m2exp != 0)
                    294:            gmp_randinit_lc_2exp (rstate, z_a, ul_adder, m2exp);
                    295:          else
                    296:            gmp_randinit_lc (rstate, z_a, ul_adder, z_m);
                    297:        }
                    298:
                    299:       if (gmp_errno != GMP_ERROR_NONE)
                    300:        {
                    301:          if (gmp_errno & GMP_ERROR_INVALID_ARGUMENT)
                    302:            fprintf (stderr, "gen: asking for too big random state\n");
                    303:          if (gmp_errno & GMP_ERROR_UNSUPPORTED_ARGUMENT)
                    304:            fprintf (stderr, "gen: unsupported algorithm\n");
                    305:          exit (1);
                    306:        }
                    307:       gmp_randseed (rstate, z_seed);
                    308:       break;
                    309:
                    310:     case RFUNC_rand:
                    311:       srand (seed);
                    312:       break;
                    313:
                    314:     case RFUNC_random:
                    315: #ifdef __FreeBSD__             /* FIXME */
                    316:       if (seed_from_user)
                    317:        srandom (seed);
                    318:       else
                    319:        srandomdev ();
                    320: #else
                    321:       fprintf (stderr, "gen: unsupported algorithm\n");
                    322: #endif
                    323:       break;
                    324:
                    325:     default:
                    326:       fprintf (stderr, "gen: random function not implemented\n");
                    327:       exit (1);
                    328:     }
                    329:
                    330:   /* set up excludes */
                    331:   if (do_exclude)
                    332:     switch (rfunc)
                    333:       {
                    334:       case RFUNC_mpf_urandomb:
                    335:
                    336:        if (mpf_set_str (f_xf, str_xf, 10) ||
                    337:            mpf_set_str (f_xt, str_xt, 10))
                    338:          {
                    339:            fprintf (stderr, "gen: bad exclusion-from (\"%s\") " \
                    340:                     "or exclusion-to (\"%s\") string.  no exclusion done.\n",
                    341:                     str_xf, str_xt);
                    342:            do_exclude = 0;
                    343:          }
                    344:        break;
                    345:
                    346:       default:
                    347:        fprintf (stderr, "gen: exclusion not implemented for chosen " \
                    348:                 "randomization function.  all numbers included in sequence.\n");
                    349:       }
                    350:
                    351:   /* generate and print */
                    352:   if (argc > 0)
                    353:     {
                    354: #if HAVE_STRTOUL
                    355:       n = strtoul (argv[0], (char **) NULL, 10);
                    356: #elif HAVE_STRTOL
                    357:       n = (unsigned long int) strtol (argv[0], (char **) NULL, 10);
                    358: #else
                    359:       n = (unsigned long int) atoi (argv[0]);
                    360: #endif
                    361:     }
                    362:
                    363:   for (f = 0; n == 0 || f < n; f++)
                    364:     {
                    365:       switch (rfunc)
                    366:        {
                    367:        case RFUNC_mpz_urandomb:
                    368:          mpz_urandomb (z1, rstate, size);
                    369:          if (quiet_flag)
                    370:            break;
                    371:          if (binout)
                    372:            {
                    373:              /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/
                    374:              fprintf (stderr, "gen: binary output for mpz_urandom* is broken\n");
                    375:              exit (1);
                    376:            }
                    377:          else
                    378:            {
                    379:              mpz_out_str (stdout, output_radix, z1);
                    380:              puts ("");
                    381:            }
                    382:          break;
                    383:
                    384:        case RFUNC_mpz_urandomm:
                    385:          mpz_urandomm (z1, rstate, z_mmax);
                    386:          if (quiet_flag)
                    387:            break;
                    388:          if (binout)
                    389:            {
                    390:              /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/
                    391:              fprintf (stderr, "gen: binary output for mpz_urandom* is broken\n");
                    392:              exit (1);
                    393:            }
                    394:          else
                    395:            {
                    396:              mpz_out_str (stdout, output_radix, z1);
                    397:              puts ("");
                    398:            }
                    399:          break;
                    400:
                    401:        case RFUNC_mpf_urandomb:
                    402:          mpf_urandomb (f1, rstate, size);
                    403:          if (do_exclude)
                    404:            if (mpf_cmp (f1, f_xf) >= 0 && mpf_cmp (f1, f_xt) <= 0)
                    405:                break;
                    406:          if (quiet_flag)
                    407:            break;
                    408:          if (binout)
                    409:            {
                    410:              fprintf (stderr, "gen: binary output for floating point numbers "\
                    411:                       "not implemented\n");
                    412:              exit (1);
                    413:            }
                    414:          else
                    415:            {
                    416:              mpf_out_str (stdout, output_radix, 0, f1);
                    417:              puts ("");
                    418:            }
                    419:          break;
                    420:
                    421:        case RFUNC_rand:
                    422:          i = rand ();
                    423: #ifdef FLOAT_OUTPUT
                    424:          if (i)
                    425:            drand = (double) i / (double) RAND_MAX;
                    426:          else
                    427:            drand = 0.0;
                    428:          if (quiet_flag)
                    429:            break;
                    430:          if (binout)
                    431:            fwrite (&drand, sizeof (drand), 1, stdout);
                    432:          else
                    433:            printf ("%e\n", drand);
                    434: #else
                    435:          if (quiet_flag)
                    436:            break;
                    437:          if (binout)
                    438:            fwrite (&i, sizeof (i), 1, stdout);
                    439:          else
                    440:            printf ("%d\n", i);
                    441: #endif
                    442:          break;
                    443:
                    444:        case RFUNC_random:
                    445:          lrand = random ();
                    446:          if (lrand)
                    447:            drand = (double) lrand / (double) 0x7fffffff;
                    448:          else
                    449:            drand = 0;
                    450:          if (quiet_flag)
                    451:            break;
                    452:          if (binout)
                    453:            fwrite (&drand, sizeof (drand), 1, stdout);
                    454:          else
                    455:            printf ("%e\n", drand);
                    456:          break;
                    457:
                    458:        default:
                    459:          fprintf (stderr, "gen: random function not implemented\n");
                    460:          exit (1);
                    461:        }
                    462:
                    463:     }
                    464:
                    465:   /* clean up */
                    466:   switch (rfunc)
                    467:     {
                    468:     case RFUNC_mpz_urandomb:
                    469:     case RFUNC_mpf_urandomb:
                    470:       gmp_randclear (rstate);
                    471:       break;
                    472:     default:
                    473:       break;
                    474:     }
                    475:   mpf_clear (f1);
                    476:   mpf_clear (f_xf);
                    477:   mpf_clear (f_xt);
                    478:   mpz_clear (z1);
                    479:   mpz_clear (z_seed);
                    480:
                    481:   return 0;
                    482: }
                    483:
                    484: static void *debug_dummyz = mpz_dump;
                    485: static void *debug_dummyf = mpf_dump;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>