modules/up/src/Core/gnu/ACG.cc

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. LCG
  2. ACG
  3. reset
  4. ACG
  5. asLong

   1 // This may look like C code, but it is really -*- C++ -*-
   2 /* 
   3 Copyright (C) 1989 Free Software Foundation
   4 
   5 This file is part of the GNU C++ Library.  This library is free
   6 software; you can redistribute it and/or modify it under the terms of
   7 the GNU Library General Public License as published by the Free
   8 Software Foundation; either version 2 of the License, or (at your
   9 option) any later version.  This library is distributed in the hope
  10 that it will be useful, but WITHOUT ANY WARRANTY; without even the
  11 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12 PURPOSE.  See the GNU Library General Public License for more details.
  13 You should have received a copy of the GNU Library General Public
  14 License along with this library; if not, write to the Free Software
  15 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16 */
  17 
  18 #ifdef __GNUG__
  19 #pragma implementation
  20 #endif
  21 #include "gnu/ACG.h"
  22 #include <assert.h>
  23 
  24 //
  25 //      This is an extension of the older implementation of Algorithm M
  26 //      which I previously supplied. The main difference between this
  27 //      version and the old code are:
  28 //
  29 //              + Andres searched high & low for good constants for
  30 //                the LCG.
  31 //
  32 //              + theres more bit chopping going on.
  33 //
  34 //      The following contains his comments.
  35 //
  36 //      agn@UNH.CS.CMU.EDU sez..
  37 //      
  38 //      The generator below is based on 2 well known
  39 //      methods: Linear Congruential (LCGs) and Additive
  40 //      Congruential generators (ACGs).
  41 //      
  42 //      The LCG produces the longest possible sequence
  43 //      of 32 bit random numbers, each being unique in
  44 //      that sequence (it has only 32 bits of state).
  45 //      It suffers from 2 problems: a) Independence
  46 //      isnt great, that is the (n+1)th number is
  47 //      somewhat related to the preceding one, unlike
  48 //      flipping a coin where knowing the past outcomes
  49 //      dont help to predict the next result.  b)
  50 //      Taking parts of a LCG generated number can be
  51 //      quite non-random: for example, looking at only
  52 //      the least significant byte gives a permuted
  53 //      8-bit counter (that has a period length of only
  54 //      256).  The advantage of an LCA is that it is
  55 //      perfectly uniform when run for the entire period
  56 //      length (and very uniform for smaller sequences
  57 //      too, if the parameters are chosen carefully).
  58 //      
  59 //      ACGs have extremly long period lengths and
  60 //      provide good independence.  Unfortunately,
  61 //      uniformity isnt not too great. Furthermore, I
  62 //      didnt find any theoretically analysis of ACGs
  63 //      that addresses uniformity.
  64 //      
  65 //      The RNG given below will return numbers
  66 //      generated by an LCA that are permuted under
  67 //      control of a ACG. 2 permutations take place: the
  68 //      4 bytes of one LCG generated number are
  69 //      subjected to one of 16 permutations selected by
  70 //      4 bits of the ACG. The permutation a such that
  71 //      byte of the result may come from each byte of
  72 //      the LCG number. This effectively destroys the
  73 //      structure within a word. Finally, the sequence
  74 //      of such numbers is permuted within a range of
  75 //      256 numbers. This greatly improves independence.
  76 //      
  77 //
  78 //  Algorithm M as describes in Knuths "Art of Computer Programming",
  79 //      Vol 2. 1969
  80 //  is used with a linear congruential generator (to get a good uniform
  81 //  distribution) that is permuted with a Fibonacci additive congruential
  82 //  generator to get good independence.
  83 //
  84 //  Bit, byte, and word distributions were extensively tested and pass
  85 //  Chi-squared test near perfect scores (>7E8 numbers tested, Uniformity
  86 //  assumption holds with probability > 0.999)
  87 //
  88 //  Run-up tests for on 7E8 numbers confirm independence with
  89 //  probability > 0.97.
  90 //
  91 //  Plotting random points in 2d reveals no apparent structure.
  92 //
  93 //  Autocorrelation on sequences of 5E5 numbers (A(i) = SUM X(n)*X(n-i),
  94 //      i=1..512)
  95 //  results in no obvious structure (A(i) ~ const).
  96 //
  97 //  Except for speed and memory requirements, this generator outperforms
  98 //  random() for all tests. (random() scored rather low on uniformity tests,
  99 //  while independence test differences were less dramatic).
 100 //
 101 //  AGN would like to..
 102 //  thanks to M.Mauldin, H.Walker, J.Saxe and M.Molloy for inspiration & help.
 103 //
 104 //  And I would (DGC) would like to thank Donald Kunth for AGN for letting me
 105 //  use his extensions in this implementation.
 106 //
 107 
 108 //
 109 //      Part of the table on page 28 of Knuth, vol II. This allows us
 110 //      to adjust the size of the table at the expense of shorter sequences.
 111 //
 112 
 113 static int randomStateTable[][3] = {
 114 {3,7,16}, {4,9, 32}, {3,10, 32}, {1,11, 32}, {1,15,64}, {3,17,128},
 115 {7,18,128}, {3,20,128}, {2,21, 128}, {1,22, 128}, {5,23, 128}, {3,25, 128},
 116 {2,29, 128}, {3,31, 128}, {13,33, 256}, {2,35, 256}, {11,36, 256},
 117 {14,39,256}, {3,41,256}, {9,49,256}, {3,52,256}, {24,55,256}, {7,57, 256},
 118 {19,58,256}, {38,89,512}, {17,95,512}, {6,97,512}, {11,98,512}, {-1,-1,-1} };
 119 
 120 //
 121 // spatial permutation table
 122 //      RANDOM_PERM_SIZE must be a power of two
 123 //
 124 
 125 #define RANDOM_PERM_SIZE 64
 126 _G_uint32_t randomPermutations[RANDOM_PERM_SIZE] = {
 127 0xffffffff, 0x00000000,  0x00000000,  0x00000000,  // 3210
 128 0x0000ffff, 0x00ff0000,  0x00000000,  0xff000000,  // 2310
 129 0xff0000ff, 0x0000ff00,  0x00000000,  0x00ff0000,  // 3120
 130 0x00ff00ff, 0x00000000,  0xff00ff00,  0x00000000,  // 1230
 131 
 132 0xffff0000, 0x000000ff,  0x00000000,  0x0000ff00,  // 3201
 133 0x00000000, 0x00ff00ff,  0x00000000,  0xff00ff00,  // 2301
 134 0xff000000, 0x00000000,  0x000000ff,  0x00ffff00,  // 3102
 135 0x00000000, 0x00000000,  0x00000000,  0xffffffff,  // 2103
 136 
 137 0xff00ff00, 0x00000000,  0x00ff00ff,  0x00000000,  // 3012
 138 0x0000ff00, 0x00000000,  0x00ff0000,  0xff0000ff,  // 2013
 139 0x00000000, 0x00000000,  0xffffffff,  0x00000000,  // 1032
 140 0x00000000, 0x0000ff00,  0xffff0000,  0x000000ff,  // 1023
 141 
 142 0x00000000, 0xffffffff,  0x00000000,  0x00000000,  // 0321
 143 0x00ffff00, 0xff000000,  0x00000000,  0x000000ff,  // 0213
 144 0x00000000, 0xff000000,  0x0000ffff,  0x00ff0000,  // 0132
 145 0x00000000, 0xff00ff00,  0x00000000,  0x00ff00ff   // 0123
 146 };
 147 
 148 //
 149 //      SEED_TABLE_SIZE must be a power of 2
 150 //
 151 #define SEED_TABLE_SIZE 32
 152 static _G_uint32_t seedTable[SEED_TABLE_SIZE] = {
 153 0xbdcc47e5, 0x54aea45d, 0xec0df859, 0xda84637b,
 154 0xc8c6cb4f, 0x35574b01, 0x28260b7d, 0x0d07fdbf,
 155 0x9faaeeb0, 0x613dd169, 0x5ce2d818, 0x85b9e706,
 156 0xab2469db, 0xda02b0dc, 0x45c60d6e, 0xffe49d10,
 157 0x7224fea3, 0xf9684fc9, 0xfc7ee074, 0x326ce92a,
 158 0x366d13b5, 0x17aaa731, 0xeb83a675, 0x7781cb32,
 159 0x4ec7c92d, 0x7f187521, 0x2cf346b4, 0xad13310f,
 160 0xb89cff2b, 0x12164de1, 0xa865168d, 0x32b56cdf
 161 };
 162 
 163 //
 164 //      The LCG used to scramble the ACG
 165 //
 166 //
 167 // LC-parameter selection follows recommendations in 
 168 // "Handbook of Mathematical Functions" by Abramowitz & Stegun 10th, edi.
 169 //
 170 // LC_A = 251^2, ~= sqrt(2^32) = 66049
 171 // LC_C = result of a long trial & error series = 3907864577
 172 //
 173 
 174 static const _G_uint32_t LC_A = 66049;
 175 static const _G_uint32_t LC_C = 3907864577u;
 176 static inline _G_uint32_t LCG(_G_uint32_t x)
     /* [<][>][^][v][top][bottom][index][help] */
 177 {
 178     return( x * LC_A + LC_C );
 179 }
 180 
 181 
 182 ACG::ACG(_G_uint32_t seed, int size)
     /* [<][>][^][v][top][bottom][index][help] */
 183 {
 184     register int l;
 185     initialSeed = seed;
 186     
 187     //
 188     //  Determine the size of the state table
 189     //
 190     
 191     for (l = 0;
 192          randomStateTable[l][0] != -1 && randomStateTable[l][1] < size;
 193          l++);
 194     
 195     if (randomStateTable[l][1] == -1) {
 196         l--;
 197     }
 198 
 199     initialTableEntry = l;
 200     
 201     stateSize = randomStateTable[ initialTableEntry ][ 1 ];
 202     auxSize = randomStateTable[ initialTableEntry ][ 2 ];
 203     
 204     //
 205     //  Allocate the state table & the auxillary table in a single malloc
 206     //
 207     
 208     state = new _G_uint32_t[stateSize + auxSize];
 209     auxState = &state[stateSize];
 210 
 211     reset();
 212 }
 213 
 214 //
 215 //      Initialize the state
 216 //
 217 void
 218 ACG::reset()
     /* [<][>][^][v][top][bottom][index][help] */
 219 {
 220     register _G_uint32_t u;
 221 
 222     if (initialSeed < SEED_TABLE_SIZE) {
 223         u = seedTable[ initialSeed ];
 224     } else {
 225         u = initialSeed ^ seedTable[ initialSeed & (SEED_TABLE_SIZE-1) ];
 226     }
 227 
 228 
 229     j = randomStateTable[ initialTableEntry ][ 0 ] - 1;
 230     k = randomStateTable[ initialTableEntry ][ 1 ] - 1;
 231 
 232     register int i;
 233     for(i = 0; i < stateSize; i++) {
 234         state[i] = u = LCG(u);
 235     }
 236     
 237     for (i = 0; i < auxSize; i++) {
 238         auxState[i] = u = LCG(u);
 239     }
 240     
 241     k = u % stateSize;
 242     int tailBehind = (stateSize - randomStateTable[ initialTableEntry ][ 0 ]);
 243     j = k - tailBehind;
 244     if (j < 0) {
 245         j += stateSize;
 246     }
 247     
 248     lcgRecurr = u;
 249     
 250     assert(sizeof(double) == 2 * sizeof(_G_int32_t));
 251 }
 252 
 253 ACG::~ACG()
     /* [<][>][^][v][top][bottom][index][help] */
 254 {
 255     if (state) delete state;
 256     state = 0;
 257     // don't delete auxState, it's really an alias for state.
 258 }
 259 
 260 //
 261 //      Returns 32 bits of random information.
 262 //
 263 
 264 _G_uint32_t
 265 ACG::asLong()
     /* [<][>][^][v][top][bottom][index][help] */
 266 {
 267     _G_uint32_t result = state[k] + state[j];
 268     state[k] = result;
 269     j = (j <= 0) ? (stateSize-1) : (j-1);
 270     k = (k <= 0) ? (stateSize-1) : (k-1);
 271     
 272     short int auxIndex = (result >> 24) & (auxSize - 1);
 273     register _G_uint32_t auxACG = auxState[auxIndex];
 274     auxState[auxIndex] = lcgRecurr = LCG(lcgRecurr);
 275     
 276     //
 277     // 3c is a magic number. We are doing four masks here, so we
 278     // do not want to run off the end of the permutation table.
 279     // This insures that we have always got four entries left.
 280     //
 281     register _G_uint32_t *perm = & randomPermutations[result & 0x3c];
 282     
 283     result =  *(perm++) & auxACG;
 284     result |= *(perm++) & ((auxACG << 24)
 285                            | ((auxACG >> 8)& 0xffffff));
 286     result |= *(perm++) & ((auxACG << 16)
 287                            | ((auxACG >> 16) & 0xffff));
 288     result |= *(perm++) & ((auxACG <<  8)
 289                            | ((auxACG >> 24) &   0xff));
 290     
 291     return(result);
 292 }

/* [<][>][^][v][top][bottom][index][help] */