| 1 | /* |
|---|
| 2 | * |
|---|
| 3 | * Rand.c |
|---|
| 4 | * |
|---|
| 5 | * - linear and additive congruential random number generators |
|---|
| 6 | * (see R. Sedgewick, Algorithms, Chapter 35) |
|---|
| 7 | * |
|---|
| 8 | * Implementation: R. Fuchs, EMBL Data Library, 1991 |
|---|
| 9 | * |
|---|
| 10 | */ |
|---|
| 11 | #include <stdio.h> |
|---|
| 12 | |
|---|
| 13 | unsigned long linrand(unsigned long r); |
|---|
| 14 | unsigned long addrand(unsigned long r); |
|---|
| 15 | void addrandinit(unsigned long s); |
|---|
| 16 | |
|---|
| 17 | static unsigned long mult(unsigned long p,unsigned long q); |
|---|
| 18 | |
|---|
| 19 | |
|---|
| 20 | #define m1 10000 |
|---|
| 21 | #define m 100000000 |
|---|
| 22 | |
|---|
| 23 | static unsigned long mult(unsigned long p, unsigned long q); |
|---|
| 24 | |
|---|
| 25 | /* linear congruential method |
|---|
| 26 | * |
|---|
| 27 | * linrand() returns an unsigned long random number in the range 0 to r-1 |
|---|
| 28 | */ |
|---|
| 29 | |
|---|
| 30 | |
|---|
| 31 | unsigned long linrand(unsigned long r) |
|---|
| 32 | { |
|---|
| 33 | static unsigned long a=1234567; |
|---|
| 34 | |
|---|
| 35 | a = (mult(a,31415821)+1) % m; |
|---|
| 36 | return( ( (a / m1) * r) / m1 ); |
|---|
| 37 | } |
|---|
| 38 | |
|---|
| 39 | static unsigned long mult(unsigned long p, unsigned long q) |
|---|
| 40 | { |
|---|
| 41 | unsigned long p1,p0,q1,q0; |
|---|
| 42 | |
|---|
| 43 | p1 = p/m1; p0 = p % m1; |
|---|
| 44 | q1 = q/m1; q0 = q % m1; |
|---|
| 45 | return((((p0*q1 + p1*q0) % m1) * m1 + p0*q0) % m); |
|---|
| 46 | } |
|---|
| 47 | |
|---|
| 48 | |
|---|
| 49 | /* additive congruential method |
|---|
| 50 | * |
|---|
| 51 | * addrand() returns an unsigned long random number in the range 0 to r-1 |
|---|
| 52 | * The random number generator is initialized by addrandinit() |
|---|
| 53 | */ |
|---|
| 54 | |
|---|
| 55 | static unsigned long j; |
|---|
| 56 | static unsigned long a[55]; |
|---|
| 57 | |
|---|
| 58 | unsigned long addrand(unsigned long r) |
|---|
| 59 | { |
|---|
| 60 | int x,y; |
|---|
| 61 | /* fprintf(stdout,"\n j = %d",j); */ |
|---|
| 62 | j = (j + 1) % 55; |
|---|
| 63 | /* fprintf(stdout,"\n j = %d",j); */ |
|---|
| 64 | x = (j+23)%55; |
|---|
| 65 | y = (j+54)%55; |
|---|
| 66 | a[j] = (a[x] + a[y]) % m; |
|---|
| 67 | /* a[j] = (a[(j+23)%55] + a[(j+54)%55]) % m; */ |
|---|
| 68 | /* fprintf(stdout,"\n a[j] = %d",a[j]); */ |
|---|
| 69 | return( ((a[j] / m1) * r) / m1 ); |
|---|
| 70 | } |
|---|
| 71 | |
|---|
| 72 | void addrandinit(unsigned long s) |
|---|
| 73 | { |
|---|
| 74 | a[0] = s; |
|---|
| 75 | j = 0; |
|---|
| 76 | do { |
|---|
| 77 | ++j; |
|---|
| 78 | a[j] = (mult(31,a[j-1]) + 1) % m; |
|---|
| 79 | } while (j<54); |
|---|
| 80 | } |
|---|
| 81 | |
|---|