00001
00002 #include "ranlux.h"
00003 #include <stdlib.h>
00004 #include <stdio.h>
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 namespace siscone{
00038
00039 static const unsigned long int mask_lo = 0x00ffffffUL;
00040 static const unsigned long int mask_hi = ~0x00ffffffUL;
00041 static const unsigned long int two24 = 16777216;
00042
00043
00044
00045
00046 typedef struct {
00047 unsigned int i;
00048 unsigned int j;
00049 unsigned int n;
00050 unsigned int skip;
00051 unsigned int carry;
00052 unsigned long int u[24];
00053 } ranlux_state_t;
00054
00055
00056
00057
00058 ranlux_state_t local_ranlux_state;
00059
00060
00061
00062
00063 static inline unsigned long int increment_state(){
00064 unsigned int i = local_ranlux_state.i;
00065 unsigned int j = local_ranlux_state.j;
00066 long int delta = local_ranlux_state.u[j] - local_ranlux_state.u[i]
00067 - local_ranlux_state.carry;
00068
00069 if (delta & mask_hi){
00070 local_ranlux_state.carry = 1;
00071 delta &= mask_lo;
00072 } else {
00073 local_ranlux_state.carry = 0;
00074 }
00075
00076 local_ranlux_state.u[i] = delta;
00077
00078 if (i==0)
00079 i = 23;
00080 else
00081 i--;
00082
00083 local_ranlux_state.i = i;
00084
00085 if (j == 0)
00086 j = 23;
00087 else
00088 j--;
00089
00090 local_ranlux_state.j = j;
00091
00092 return delta;
00093 }
00094
00095
00096
00097
00098 static void ranlux_set(unsigned long int s){
00099 int i;
00100 long int seed;
00101
00102 if (s==0)
00103 s = 314159265;
00104
00105 seed = s;
00106
00107
00108
00109
00110 for (i=0;i<24;i++){
00111 unsigned long int k = seed/53668;
00112 seed = 40014*(seed-k*53668)-k*12211;
00113 if (seed<0){
00114 seed += 2147483563;
00115 }
00116 local_ranlux_state.u[i] = seed%two24;
00117 }
00118
00119 local_ranlux_state.i = 23;
00120 local_ranlux_state.j = 9;
00121 local_ranlux_state.n = 0;
00122 local_ranlux_state.skip = 389-24;
00123
00124 if (local_ranlux_state.u[23]&mask_hi){
00125 local_ranlux_state.carry = 1;
00126 } else {
00127 local_ranlux_state.carry = 0;
00128 }
00129 }
00130
00131
00132
00133
00134 void ranlux_init(){
00135
00136 ranlux_set(0);
00137 }
00138
00139
00140
00141
00142 unsigned long int ranlux_get(){
00143 const unsigned int skip = local_ranlux_state.skip;
00144 unsigned long int r = increment_state();
00145
00146 local_ranlux_state.n++;
00147
00148 if (local_ranlux_state.n == 24){
00149 unsigned int i;
00150 local_ranlux_state.n = 0;
00151 for (i = 0; i < skip; i++)
00152 increment_state();
00153 }
00154
00155 return r;
00156 }
00157
00158
00159
00160 void ranlux_print_state(){
00161 size_t i;
00162 unsigned char *p = (unsigned char *) (&local_ranlux_state);
00163 const size_t n = sizeof (ranlux_state_t);
00164
00165 for (i=0;i<n;i++){
00166
00167 printf("%.2x", *(p+i));
00168 }
00169 }
00170
00171 }