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