New restartable interface to Maurer testing.
[u/mdw/catacomb] / rspit.c
diff --git a/rspit.c b/rspit.c
index 01ebf4d..4622d90 100644 (file)
--- a/rspit.c
+++ b/rspit.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: rspit.c,v 1.9 2000/08/04 23:24:15 mdw Exp $
+ * $Id: rspit.c,v 1.10 2000/08/11 21:34:59 mdw Exp $
  *
  * Spit out random numbers
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: rspit.c,v $
+ * Revision 1.10  2000/08/11 21:34:59  mdw
+ * New restartable interface to Maurer testing.
+ *
  * Revision 1.9  2000/08/04 23:24:15  mdw
  * Add a timer and a discard option.
  *
@@ -373,7 +376,7 @@ static int opt(void)
          char *p;
          unsigned long lo, hi;
          lo = strtoul(optarg, &p, 0);
-         if (*p == '-')
+         if (*p == '-' || *p == ',')
            hi = strtoul(p + 1, &p, 0);
          else
            hi = lo;
@@ -1119,6 +1122,21 @@ static int genbuf(const void *buf, size_t sz, void *p)
   return (0);
 }
 
+typedef struct genmaurer_ctx {
+  size_t n;
+  maurer_ctx *m;
+} genmaurer_ctx;
+
+static int genmaurer(const void *buf, size_t sz, void *p)
+{
+  genmaurer_ctx *g = p;
+  size_t i;
+
+  for (i = 0; i < g->n; i++)
+    maurer_test(&g->m[i], buf, sz);
+  return (0);
+}
+
 static int generate(grand *r, size_t outsz,
                    int (*func)(const void *buf, size_t sz, void *p),
                    void *p)
@@ -1236,14 +1254,17 @@ static int generate(grand *r, size_t outsz,
   if (flags & f_progress)
     fputc('\n', stderr);
   if (flags & f_timer) {
-    double sec = (double)clk/CLOCKS_PER_SEC;
-    double bps = (outsz << 3)/sec;
-    char *kk;
-
-    for (kk = kmg; bps > 1024 && kk[1]; kk++, bps /= 1024)
-      ;
-    fprintf(stderr, "generated %lu bytes in %g secs (%g %cb/s)\n",
-           (unsigned long)outsz, sec, bps, *kk);
+    fprintf(stderr, "generated %lu bytes ", (unsigned long)outsz);
+    if (!clk)
+      fputs("too quickly to measure\n", stderr);
+    else {
+      char *kk;
+      double sec = (double)clk/CLOCKS_PER_SEC;
+      double bps = (outsz << 3)/sec;
+      for (kk = kmg; bps > 1024 && kk[1]; kk++, bps /= 1024)
+       ;
+      fprintf(stderr, "in %g secs (%g %cb/s)\n", sec, bps, *kk);
+    }
   }
   return (0);
 }
@@ -1330,13 +1351,10 @@ int main(int ac, char *av[])
   /* --- Do Maurer's test --- */
 
   if (flags & f_maurer) {
-    octet *buf;
     size_t bufsz;
     unsigned i;
     unsigned rc = 0;
-    unsigned f = 0, jj = 0;
-    double maxz = 0;
-    octet *p;
+    genmaurer_ctx g;
 
     static struct { double x; const char *sig; } sigtab[] = {
       { 3.2905, "1e-3" },
@@ -1346,24 +1364,21 @@ int main(int ac, char *av[])
       { 0     , 0      }
     };
 
+    g.n = maurer_hi - maurer_lo + 1;
+    g.m = xmalloc(g.n * sizeof(maurer_ctx));
+    for (i = 0; i < g.n; i++)
+      maurer_init(&g.m[i], i + maurer_lo);
     bufsz = (100 * maurer_hi) << maurer_hi;
-    if ((buf = a_alloc(arena_global, bufsz)) == 0)
-      die(EXIT_FAILURE, "not enough memory for data buffer");
-    p = buf;
-    generate(r, bufsz, genbuf, &p);
+
+    generate(r, bufsz, genmaurer, &g);
 
     for (i = maurer_lo; i <= maurer_hi; i++) {
-      double z = maurer(buf, bufsz, i);
+      double z = maurer_done(&g.m[i - maurer_lo]);
       double zz = fabs(z);
       unsigned j;
 
       for (j = 0; sigtab[j].sig; j++) {
        if (zz > sigtab[j].x) {
-         if (zz > fabs(maxz)) {
-           maxz = z;
-           f = i;
-           jj = j;
-         }
          rc = EXIT_FAILURE;
          moan("failed, bits = %u, sig = %s, Z_u = %g",
               i, sigtab[j].sig, z);
@@ -1374,6 +1389,7 @@ int main(int ac, char *av[])
        fprintf(stderr, "bits = %u, Z_u = %g\n", i, z);
     }
 
+    xfree(g.m);
     return (rc);
   }