[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     ! 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>