Rev 288 | Rev 290 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 288 | Rev 289 | ||
---|---|---|---|
Line 171... | Line 171... | ||
171 | /* dif(a,b) Absolute value of the difference of a and b */ |
171 | /* dif(a,b) Absolute value of the difference of a and b */ |
172 | value_type ff_dif(value_type a,value_type b){ |
172 | value_type ff_dif(value_type a,value_type b){ |
173 | return abs(a-b); |
173 | return abs(a-b); |
174 | } |
174 | } |
175 | 175 | ||
176 | uint16_t gFactoryRndIndexCounter = 0; |
176 | uint16_t gFactoryRndIndexCounter1 = 0; |
- | 177 | uint16_t gFactoryRndIndexCounter2 = 31; |
|
177 | uint32_t gFactoryRndLookup[56]; |
178 | uint32_t gFactoryRndLookup[56]; |
178 | uint32_t gFactoryRndSeed; |
179 | uint32_t gFactoryRndSeed; |
179 | uint32_t gFactoryRndSeedSave; |
180 | uint32_t gFactoryRndSeedSave; |
180 | 181 | ||
181 | void factory_fill_rnd_lookup(uint32_t seed); |
182 | void factory_fill_rnd_lookup(uint32_t seed); |
182 | 183 | ||
183 | uint32_t factory_rnd(uint32_t a, uint32_t b) { |
184 | uint32_t factory_rnd(uint32_t a, uint32_t b) { |
184 | uint16_t rndCounterA, rndCounterB; |
185 | uint32_t mj; // Note: This must be "uint32_t". With "long" (as described by Knuth), it won't match FilterFactory's algorithm |
185 | uint32_t result; |
- | |
186 | int32_t range; |
186 | int range; |
187 | 187 | ||
188 | if (gFactoryRndSeed != gFactoryRndSeedSave) { |
188 | if (gFactoryRndSeed != gFactoryRndSeedSave) { |
189 | // (Intentional) behavior of Filter Foundry |
189 | // (Intentional) behavior of Filter Foundry |
190 | factory_fill_rnd_lookup(gFactoryRndSeed); |
190 | factory_fill_rnd_lookup(gFactoryRndSeed); |
191 | gFactoryRndIndexCounter = 0; |
191 | gFactoryRndIndexCounter1 = 0; |
- | 192 | gFactoryRndIndexCounter2 = 31; |
|
192 | } |
193 | } |
193 | 194 | ||
194 | // Algorithm of Filter Factory |
195 | // Algorithm of Filter Factory |
- | 196 | // Filter Factory uses Donald E.Knuth's subtractive |
|
- | 197 | // random number generator algorithm ("ran3"), which has been published |
|
- | 198 | // in Page 283 of "The Art of Computer Programming, volume 2: Seminumerical Algorithms", |
|
- | 199 | // Addison-Wesley, Reading, MA, second edition, 1981. |
|
- | 200 | // https://www.cec.uchile.cl/cinetica/pcordero/MC_libros/NumericalRecipesinC.pdf (PDF Page 307) |
|
195 | 201 | ||
196 | rndCounterA = gFactoryRndIndexCounter % 55 + 1; |
202 | if (++gFactoryRndIndexCounter1 == 56) gFactoryRndIndexCounter1 = 1; |
197 | rndCounterB = (gFactoryRndIndexCounter + 31) % 55 + 1; |
- | |
198 | gFactoryRndIndexCounter = rndCounterA; |
203 | if (++gFactoryRndIndexCounter2 == 56) gFactoryRndIndexCounter2 = 1; |
199 | 204 | ||
- | 205 | mj = gFactoryRndLookup[gFactoryRndIndexCounter1] - |
|
200 | result = gFactoryRndLookup[rndCounterA] - gFactoryRndLookup[rndCounterB]; |
206 | gFactoryRndLookup[gFactoryRndIndexCounter2]; |
201 | gFactoryRndLookup[rndCounterA] = result; |
207 | gFactoryRndLookup[gFactoryRndIndexCounter1] = mj; |
202 | 208 | ||
- | 209 | // This is Filter Factory specific: |
|
203 | // Scale result to interval [a..b] |
210 | // Squeeze result into interval [a..b] |
- | 211 | if (a == 0) { |
|
- | 212 | // This part is optional; it is intended to increase the |
|
- | 213 | // performance by avoiding modulo/divide if possible. |
|
- | 214 | switch (b) { |
|
- | 215 | case 255: |
|
- | 216 | return mj & 0xFF; |
|
- | 217 | case 127: |
|
- | 218 | return mj & 0x7F; |
|
- | 219 | case 63: |
|
- | 220 | return mj & 0x3F; |
|
- | 221 | case 31: |
|
- | 222 | return mj & 0x1F; |
|
- | 223 | case 15: |
|
- | 224 | return mj & 0xF; |
|
- | 225 | case 7: |
|
- | 226 | return mj & 0x7; |
|
- | 227 | case 3: |
|
- | 228 | return mj & 0x3; |
|
- | 229 | case 1: |
|
- | 230 | return mj & 0x1; |
|
- | 231 | } |
|
- | 232 | } |
|
204 | range = b - a; |
233 | range = b - a; |
205 | if (range < 0) return 0; |
234 | if (range < 0) return 0; |
206 | return a + (result % (range + 1)); |
235 | return a + (mj % (range + 1)); |
207 | } |
236 | } |
208 | 237 | ||
209 | void factory_fill_rnd_lookup(uint32_t seed) { |
238 | void factory_fill_rnd_lookup(uint32_t seed) { |
210 | // Algorithm of Filter Factory |
239 | // Algorithm of Filter Factory |
- | 240 | // Filter Factory uses Donald E.Knuth's subtractive |
|
- | 241 | // random number generator algorithm ("ran3"), which has been published |
|
- | 242 | // in Page 283 of "The Art of Computer Programming, volume 2: Seminumerical Algorithms", |
|
- | 243 | // Addison-Wesley, Reading, MA, second edition, 1981. |
|
- | 244 | // https://www.cec.uchile.cl/cinetica/pcordero/MC_libros/NumericalRecipesinC.pdf (PDF Page 307) |
|
211 | 245 | ||
212 | uint32_t i, j; |
246 | long mj, mk; |
213 | uint32_t v1, v2, v3; |
247 | int i, ii, k; |
214 | 248 | ||
215 | // 161803398 = 1.61803398 * 10^8 ~= phi * 10^8 |
249 | // 161803398 = 1.61803398 * 10^8 ~= phi * 10^8 |
216 | v2 = 161803398 - (seed & 0x7fff); |
250 | mj = 161803398 - (seed & 0x7fff); |
217 | gFactoryRndLookup[55] = v2; |
251 | gFactoryRndLookup[55] = mj; |
218 | 252 | ||
219 | v3 = 1; |
253 | mk = 1; |
220 | for (i=1; i<55; ++i) { |
254 | for (i=1; i<=54; ++i) { |
221 | v1 = v3; |
255 | ii = (21 * i) % 55; |
222 | gFactoryRndLookup[(i * 21) % 55] = v1; |
256 | gFactoryRndLookup[ii] = mk; |
223 | v3 = v2 - v1; |
257 | mk = mj - mk; |
224 | v2 = v1; |
258 | mj = gFactoryRndLookup[ii]; |
225 | } |
259 | } |
226 | 260 | ||
227 | for (i=0; i<4; ++i) { |
261 | for (k=1; k<=4; ++k) { |
228 | for (j=1; j<=55;) { |
262 | for (i=1; i<=55; ++i) { |
229 | gFactoryRndLookup[j++] = gFactoryRndLookup[j] - gFactoryRndLookup[((j + 30) % 55) + 1]; |
263 | gFactoryRndLookup[i] -= gFactoryRndLookup[1+(i + 30) % 55]; |
230 | } |
264 | } |
231 | } |
265 | } |
232 | 266 | ||
233 | gFactoryRndSeedSave = seed; |
267 | gFactoryRndSeedSave = seed; |
234 | 268 |