Annotation of OpenXM_contrib/gmp/tests/rand/findlc.c, Revision 1.1
1.1 ! maekawa 1: /*
! 2: Copyright (C) 2000 Free Software Foundation, Inc.
! 3:
! 4: This file is part of the GNU MP Library.
! 5:
! 6: The GNU MP Library is free software; you can redistribute it and/or modify
! 7: it under the terms of the GNU Lesser General Public License as published by
! 8: the Free Software Foundation; either version 2.1 of the License, or (at your
! 9: option) any later version.
! 10:
! 11: The GNU MP Library is distributed in the hope that it will be useful, but
! 12: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 13: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
! 14: License for more details.
! 15:
! 16: You should have received a copy of the GNU Lesser General Public License
! 17: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! 18: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
! 19: MA 02111-1307, USA.
! 20: */
! 21:
! 22: #include <stdio.h>
! 23: #include <stdlib.h>
! 24: #include <unistd.h>
! 25: #include <signal.h>
! 26: #include <math.h>
! 27: #include "gmp.h"
! 28: #include "gmpstat.h"
! 29:
! 30: #define RCSID(msg) \
! 31: static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
! 32:
! 33: RCSID("$Id: findlc.c,v 1.3 2000/07/24 17:04:39 tege Exp $");
! 34:
! 35: int g_debug = 0;
! 36:
! 37: static mpz_t a;
! 38:
! 39: static void
! 40: sh_status (int sig)
! 41: {
! 42: printf ("sh_status: signal %d caught. dumping status.\n", sig);
! 43:
! 44: printf (" a = ");
! 45: mpz_out_str (stdout, 10, a);
! 46: printf ("\n");
! 47: fflush (stdout);
! 48:
! 49: if (SIGSEGV == sig) /* remove SEGV handler */
! 50: signal (SIGSEGV, SIG_DFL);
! 51: }
! 52:
! 53: /* Input is a modulus (m). We shall find multiplyer (a) and adder (c)
! 54: conforming to the rules found in the first comment block in file
! 55: mpz/urandom.c.
! 56:
! 57: Then run a spectral test on the generator and discard any
! 58: multipliers not passing. */
! 59:
! 60: /* TODO:
! 61:
! 62: . find a better algorithm than a+=8; bigger jumps perhaps?
! 63:
! 64: */
! 65:
! 66: void
! 67: mpz_true_random (mpz_t s, unsigned long int nbits)
! 68: {
! 69: #if __FreeBSD__
! 70: FILE *fs;
! 71: char c[1];
! 72: int i;
! 73:
! 74: mpz_set_ui (s, 0);
! 75: for (i = 0; i < nbits; i += 8)
! 76: {
! 77: for (;;)
! 78: {
! 79: int nread;
! 80: fs = fopen ("/dev/random", "r");
! 81: nread = fread (c, 1, 1, fs);
! 82: fclose (fs);
! 83: if (nread != 0)
! 84: break;
! 85: sleep (1);
! 86: }
! 87: mpz_mul_2exp (s, s, 8);
! 88: mpz_add_ui (s, s, ((unsigned long int) c[0]) & 0xff);
! 89: printf ("%d random bits\n", i + 8);
! 90: }
! 91: if (nbits % 8 != 0)
! 92: mpz_mod_2exp (s, s, nbits);
! 93: #endif
! 94: }
! 95:
! 96: int
! 97: main (int argc, char *argv[])
! 98: {
! 99: const char usage[] = "usage: findlc [-dv] m2exp [low_merit [high_merit]]\n";
! 100: int f;
! 101: int v_lose, m_lose, v_best, m_best;
! 102: int c;
! 103: int debug = 1;
! 104: int cnt_high_merit;
! 105: mpz_t m;
! 106: unsigned long int m2exp;
! 107: #define DIMS 6 /* dimensions run in spectral test */
! 108: mpf_t v[DIMS-1]; /* spectral test result (there's no v
! 109: for 1st dimension */
! 110: mpf_t f_merit, low_merit, high_merit;
! 111: mpz_t acc, minus8;
! 112: mpz_t min, max;
! 113: mpz_t s;
! 114:
! 115:
! 116: mpz_init (m);
! 117: mpz_init (a);
! 118: for (f = 0; f < DIMS-1; f++)
! 119: mpf_init (v[f]);
! 120: mpf_init (f_merit);
! 121: mpf_init_set_d (low_merit, .1);
! 122: mpf_init_set_d (high_merit, .1);
! 123:
! 124: while ((c = getopt (argc, argv, "a:di:hv")) != -1)
! 125: switch (c)
! 126: {
! 127: case 'd': /* debug */
! 128: g_debug++;
! 129: break;
! 130:
! 131: case 'v': /* print version */
! 132: puts (rcsid[1]);
! 133: exit (0);
! 134:
! 135: case 'h':
! 136: case '?':
! 137: default:
! 138: fputs (usage, stderr);
! 139: exit (1);
! 140: }
! 141:
! 142: argc -= optind;
! 143: argv += optind;
! 144:
! 145: if (argc < 1)
! 146: {
! 147: fputs (usage, stderr);
! 148: exit (1);
! 149: }
! 150:
! 151: /* Install signal handler. */
! 152: if (SIG_ERR == signal (SIGSEGV, sh_status))
! 153: {
! 154: perror ("signal (SIGSEGV)");
! 155: exit (1);
! 156: }
! 157: if (SIG_ERR == signal (SIGHUP, sh_status))
! 158: {
! 159: perror ("signal (SIGHUP)");
! 160: exit (1);
! 161: }
! 162:
! 163: printf ("findlc: version: %s\n", rcsid[1]);
! 164: m2exp = atol (argv[0]);
! 165: mpz_init_set_ui (m, 1);
! 166: mpz_mul_2exp (m, m, m2exp);
! 167: printf ("m = 0x");
! 168: mpz_out_str (stdout, 16, m);
! 169: puts ("");
! 170:
! 171: if (argc > 1) /* have low_merit */
! 172: mpf_set_str (low_merit, argv[1], 0);
! 173: if (argc > 2) /* have high_merit */
! 174: mpf_set_str (high_merit, argv[2], 0);
! 175:
! 176: if (debug)
! 177: {
! 178: fprintf (stderr, "low_merit = ");
! 179: mpf_out_str (stderr, 10, 2, low_merit);
! 180: fprintf (stderr, "; high_merit = ");
! 181: mpf_out_str (stderr, 10, 2, high_merit);
! 182: fputs ("\n", stderr);
! 183: }
! 184:
! 185: mpz_init (minus8);
! 186: mpz_set_si (minus8, -8L);
! 187: mpz_init_set_ui (acc, 0);
! 188: mpz_init (s);
! 189: mpz_init_set_d (min, 0.01 * pow (2.0, (double) m2exp));
! 190: mpz_init_set_d (max, 0.99 * pow (2.0, (double) m2exp));
! 191:
! 192: mpz_true_random (s, m2exp); /* Start. */
! 193: mpz_setbit (s, 0); /* Make it odd. */
! 194:
! 195: v_best = m_best = 2*(DIMS-1);
! 196: for (;;)
! 197: {
! 198: mpz_add (acc, acc, s);
! 199: mpz_mod_2exp (acc, acc, m2exp);
! 200: #if later
! 201: mpz_and_si (a, acc, -8L);
! 202: #else
! 203: mpz_and (a, acc, minus8);
! 204: #endif
! 205: mpz_add_ui (a, a, 5);
! 206: if (mpz_cmp (a, min) <= 0 || mpz_cmp (a, max) >= 0)
! 207: continue;
! 208:
! 209: spectral_test (v, DIMS, a, m);
! 210: for (f = 0, v_lose = m_lose = 0, cnt_high_merit = DIMS-1;
! 211: f < DIMS-1; f++)
! 212: {
! 213: merit (f_merit, f + 2, v[f], m);
! 214:
! 215: if (mpf_cmp_ui (v[f], 1 << (30 / (f + 2) + (f == 2))) < 0)
! 216: v_lose++;
! 217:
! 218: if (mpf_cmp (f_merit, low_merit) < 0)
! 219: m_lose++;
! 220:
! 221: if (mpf_cmp (f_merit, high_merit) >= 0)
! 222: cnt_high_merit--;
! 223: }
! 224:
! 225: if (0 == v_lose && 0 == m_lose)
! 226: {
! 227: mpz_out_str (stdout, 10, a); puts (""); fflush (stdout);
! 228: if (0 == cnt_high_merit)
! 229: break; /* leave loop */
! 230: }
! 231: if (v_lose < v_best)
! 232: {
! 233: v_best = v_lose;
! 234: printf ("best (v_lose=%d; m_lose=%d): ", v_lose, m_lose);
! 235: mpz_out_str (stdout, 10, a); puts (""); fflush (stdout);
! 236: }
! 237: if (m_lose < m_best)
! 238: {
! 239: m_best = m_lose;
! 240: printf ("best (v_lose=%d; m_lose=%d): ", v_lose, m_lose);
! 241: mpz_out_str (stdout, 10, a); puts (""); fflush (stdout);
! 242: }
! 243: }
! 244:
! 245: mpz_clear (m);
! 246: mpz_clear (a);
! 247: for (f = 0; f < DIMS-1; f++)
! 248: mpf_clear (v[f]);
! 249: mpf_clear (f_merit);
! 250: mpf_clear (low_merit);
! 251: mpf_clear (high_merit);
! 252:
! 253: printf ("done.\n");
! 254: return 0;
! 255: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>