## 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] */