random_variable 0.0.1.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/ext/com.c ADDED
@@ -0,0 +1,373 @@
1
+ #include "randlib.h"
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+ static long Xm1,Xm2,Xa1,Xa2,Xcg1[32],Xcg2[32],Xa1w,Xa2w,Xig1[32],Xig2[32],
5
+ Xlg1[32],Xlg2[32],Xa1vw,Xa2vw;
6
+ static long Xqanti[32];
7
+ void advnst(long k)
8
+ /*
9
+ **********************************************************************
10
+ void advnst(long k)
11
+ ADV-a-N-ce ST-ate
12
+ Advances the state of the current generator by 2^K values and
13
+ resets the initial seed to that value.
14
+ This is a transcription from Pascal to Fortran of routine
15
+ Advance_State from the paper
16
+ L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
17
+ with Splitting Facilities." ACM Transactions on Mathematical
18
+ Software, 17:98-111 (1991)
19
+ Arguments
20
+ k -> The generator is advanced by2^K values
21
+ **********************************************************************
22
+ */
23
+ {
24
+ #define numg 32L
25
+ extern void gsrgs(long getset,long *qvalue);
26
+ extern void gscgn(long getset,long *g);
27
+ extern long Xm1,Xm2,Xa1,Xa2,Xcg1[],Xcg2[];
28
+ static long g,i,ib1,ib2;
29
+ static long qrgnin;
30
+ /*
31
+ Abort unless random number generator initialized
32
+ */
33
+ gsrgs(0L,&qrgnin);
34
+ if(qrgnin) goto S10;
35
+ fputs(" ADVNST called before random generator initialized - ABORT\n",
36
+ stderr);
37
+ exit(1);
38
+ S10:
39
+ gscgn(0L,&g);
40
+ ib1 = Xa1;
41
+ ib2 = Xa2;
42
+ for(i=1; i<=k; i++) {
43
+ ib1 = mltmod(ib1,ib1,Xm1);
44
+ ib2 = mltmod(ib2,ib2,Xm2);
45
+ }
46
+ setsd(mltmod(ib1,*(Xcg1+g-1),Xm1),mltmod(ib2,*(Xcg2+g-1),Xm2));
47
+ /*
48
+ NOW, IB1 = A1**K AND IB2 = A2**K
49
+ */
50
+ #undef numg
51
+ }
52
+ void getsd(long *iseed1,long *iseed2)
53
+ /*
54
+ **********************************************************************
55
+ void getsd(long *iseed1,long *iseed2)
56
+ GET SeeD
57
+ Returns the value of two integer seeds of the current generator
58
+ This is a transcription from Pascal to Fortran of routine
59
+ Get_State from the paper
60
+ L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
61
+ with Splitting Facilities." ACM Transactions on Mathematical
62
+ Software, 17:98-111 (1991)
63
+ Arguments
64
+ iseed1 <- First integer seed of generator G
65
+ iseed2 <- Second integer seed of generator G
66
+ **********************************************************************
67
+ */
68
+ {
69
+ #define numg 32L
70
+ extern void gsrgs(long getset,long *qvalue);
71
+ extern void gscgn(long getset,long *g);
72
+ extern long Xcg1[],Xcg2[];
73
+ static long g;
74
+ static long qrgnin;
75
+ /*
76
+ Abort unless random number generator initialized
77
+ */
78
+ gsrgs(0L,&qrgnin);
79
+ if(qrgnin) goto S10;
80
+ fprintf(stderr,"%s\n",
81
+ " GETSD called before random number generator initialized -- abort!");
82
+ exit(0);
83
+ S10:
84
+ gscgn(0L,&g);
85
+ *iseed1 = *(Xcg1+g-1);
86
+ *iseed2 = *(Xcg2+g-1);
87
+ #undef numg
88
+ }
89
+ long ignlgi(void)
90
+ /*
91
+ **********************************************************************
92
+ long ignlgi(void)
93
+ GeNerate LarGe Integer
94
+ Returns a random integer following a uniform distribution over
95
+ (1, 2147483562) using the current generator.
96
+ This is a transcription from Pascal to Fortran of routine
97
+ Random from the paper
98
+ L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
99
+ with Splitting Facilities." ACM Transactions on Mathematical
100
+ Software, 17:98-111 (1991)
101
+ **********************************************************************
102
+ */
103
+ {
104
+ #define numg 32L
105
+ extern void gsrgs(long getset,long *qvalue);
106
+ extern void gssst(long getset,long *qset);
107
+ extern void gscgn(long getset,long *g);
108
+ extern void inrgcm(void);
109
+ extern long Xm1,Xm2,Xa1,Xa2,Xcg1[],Xcg2[];
110
+ extern long Xqanti[];
111
+ static long ignlgi,curntg,k,s1,s2,z;
112
+ static long qqssd,qrgnin;
113
+ /*
114
+ IF THE RANDOM NUMBER PACKAGE HAS NOT BEEN INITIALIZED YET, DO SO.
115
+ IT CAN BE INITIALIZED IN ONE OF TWO WAYS : 1) THE FIRST CALL TO
116
+ THIS ROUTINE 2) A CALL TO SETALL.
117
+ */
118
+ gsrgs(0L,&qrgnin);
119
+ if(!qrgnin) inrgcm();
120
+ gssst(0,&qqssd);
121
+ if(!qqssd) setall(1234567890L,123456789L);
122
+ /*
123
+ Get Current Generator
124
+ */
125
+ gscgn(0L,&curntg);
126
+ s1 = *(Xcg1+curntg-1);
127
+ s2 = *(Xcg2+curntg-1);
128
+ k = s1/53668L;
129
+ s1 = Xa1*(s1-k*53668L)-k*12211;
130
+ if(s1 < 0) s1 += Xm1;
131
+ k = s2/52774L;
132
+ s2 = Xa2*(s2-k*52774L)-k*3791;
133
+ if(s2 < 0) s2 += Xm2;
134
+ *(Xcg1+curntg-1) = s1;
135
+ *(Xcg2+curntg-1) = s2;
136
+ z = s1-s2;
137
+ if(z < 1) z += (Xm1-1);
138
+ if(*(Xqanti+curntg-1)) z = Xm1-z;
139
+ ignlgi = z;
140
+ return ignlgi;
141
+ #undef numg
142
+ }
143
+ void initgn(long isdtyp)
144
+ /*
145
+ **********************************************************************
146
+ void initgn(long isdtyp)
147
+ INIT-ialize current G-e-N-erator
148
+ Reinitializes the state of the current generator
149
+ This is a transcription from Pascal to C of routine
150
+ Init_Generator from the paper
151
+ L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
152
+ with Splitting Facilities." ACM Transactions on Mathematical
153
+ Software, 17:98-111 (1991)
154
+ Arguments
155
+ isdtyp -> The state to which the generator is to be set
156
+ isdtyp = -1 => sets the seeds to their initial value
157
+ isdtyp = 0 => sets the seeds to the first value of
158
+ the current block
159
+ isdtyp = 1 => sets the seeds to the first value of
160
+ the next block
161
+ WGR, 12/19/00: replaced S10, S20, etc. with C blocks {} per
162
+ original paper.
163
+ **********************************************************************
164
+ */
165
+ {
166
+ #define numg 32L
167
+ extern void gsrgs(long getset,long *qvalue);
168
+ extern void gscgn(long getset,long *g);
169
+ extern long Xm1,Xm2,Xa1w,Xa2w,Xig1[],Xig2[],Xlg1[],Xlg2[],Xcg1[],Xcg2[];
170
+ static long g;
171
+ static long qrgnin;
172
+ /*
173
+ Abort unless random number generator initialized
174
+ */
175
+ gsrgs(0L,&qrgnin);
176
+ if (! qrgnin) {
177
+ fprintf(stderr,"%s\n",
178
+ " INITGN called before random number generator initialized -- abort!");
179
+ exit(1);
180
+ }
181
+
182
+ gscgn(0L,&g);
183
+ if(isdtyp == -1) { /* Initial seed */
184
+ *(Xlg1+g-1) = *(Xig1+g-1);
185
+ *(Xlg2+g-1) = *(Xig2+g-1);
186
+ }
187
+ else if (isdtyp == 0) { ; } /* Last seed */
188
+ else if (isdtyp == 1) { /* New seed */
189
+ *(Xlg1+g-1) = mltmod(Xa1w,*(Xlg1+g-1),Xm1);
190
+ *(Xlg2+g-1) = mltmod(Xa2w,*(Xlg2+g-1),Xm2);
191
+ } else {
192
+ fprintf(stderr,"%s\n","isdtyp not in range in INITGN");
193
+ exit(1);
194
+ }
195
+
196
+ *(Xcg1+g-1) = *(Xlg1+g-1);
197
+ *(Xcg2+g-1) = *(Xlg2+g-1);
198
+ #undef numg
199
+ }
200
+
201
+ void inrgcm(void)
202
+ /*
203
+ **********************************************************************
204
+ void inrgcm(void)
205
+ INitialize Random number Generator CoMmon
206
+ Function
207
+ Initializes common area for random number generator. This saves
208
+ the nuisance of a BLOCK DATA routine and the difficulty of
209
+ assuring that the routine is loaded with the other routines.
210
+ **********************************************************************
211
+ */
212
+ {
213
+ #define numg 32L
214
+ extern void gsrgs(long getset,long *qvalue);
215
+ extern long Xm1,Xm2,Xa1,Xa2,Xa1w,Xa2w,Xa1vw,Xa2vw;
216
+ extern long Xqanti[];
217
+ static long T1;
218
+ static long i;
219
+ /*
220
+ V=20; W=30;
221
+ A1W = MOD(A1**(2**W),M1) A2W = MOD(A2**(2**W),M2)
222
+ A1VW = MOD(A1**(2**(V+W)),M1) A2VW = MOD(A2**(2**(V+W)),M2)
223
+ If V or W is changed A1W, A2W, A1VW, and A2VW need to be recomputed.
224
+ An efficient way to precompute a**(2*j) MOD m is to start with
225
+ a and square it j times modulo m using the function MLTMOD.
226
+ */
227
+ Xm1 = 2147483563L;
228
+ Xm2 = 2147483399L;
229
+ Xa1 = 40014L;
230
+ Xa2 = 40692L;
231
+ Xa1w = 1033780774L;
232
+ Xa2w = 1494757890L;
233
+ Xa1vw = 2082007225L;
234
+ Xa2vw = 784306273L;
235
+ for(i=0; i<numg; i++) *(Xqanti+i) = 0;
236
+ T1 = 1;
237
+ /*
238
+ Tell the world that common has been initialized
239
+ */
240
+ gsrgs(1L,&T1);
241
+ #undef numg
242
+ }
243
+ void setall(long iseed1,long iseed2)
244
+ /*
245
+ **********************************************************************
246
+ void setall(long iseed1,long iseed2)
247
+ SET ALL random number generators
248
+ Sets the initial seed of generator 1 to ISEED1 and ISEED2. The
249
+ initial seeds of the other generators are set accordingly, and
250
+ all generators states are set to these seeds.
251
+ This is a transcription from Pascal to Fortran of routine
252
+ Set_Initial_Seed from the paper
253
+ L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
254
+ with Splitting Facilities." ACM Transactions on Mathematical
255
+ Software, 17:98-111 (1991)
256
+ Arguments
257
+ iseed1 -> First of two integer seeds
258
+ iseed2 -> Second of two integer seeds
259
+ **********************************************************************
260
+ */
261
+ {
262
+ #define numg 32L
263
+ extern void gsrgs(long getset,long *qvalue);
264
+ extern void gssst(long getset,long *qset);
265
+ extern void gscgn(long getset,long *g);
266
+ extern long Xm1,Xm2,Xa1vw,Xa2vw,Xig1[],Xig2[];
267
+ static long T1;
268
+ static long g,ocgn;
269
+ static long qrgnin;
270
+ T1 = 1;
271
+ /*
272
+ TELL IGNLGI, THE ACTUAL NUMBER GENERATOR, THAT THIS ROUTINE
273
+ HAS BEEN CALLED.
274
+ */
275
+ gssst(1,&T1);
276
+ gscgn(0L,&ocgn);
277
+ /*
278
+ Initialize Common Block if Necessary
279
+ */
280
+ gsrgs(0L,&qrgnin);
281
+ if(!qrgnin) inrgcm();
282
+ *Xig1 = iseed1;
283
+ *Xig2 = iseed2;
284
+ initgn(-1L);
285
+ for(g=2; g<=numg; g++) {
286
+ *(Xig1+g-1) = mltmod(Xa1vw,*(Xig1+g-2),Xm1);
287
+ *(Xig2+g-1) = mltmod(Xa2vw,*(Xig2+g-2),Xm2);
288
+ gscgn(1L,&g);
289
+ initgn(-1L);
290
+ }
291
+ gscgn(1L,&ocgn);
292
+ #undef numg
293
+ }
294
+ void setant(long qvalue)
295
+ /*
296
+ **********************************************************************
297
+ void setant(long qvalue)
298
+ SET ANTithetic
299
+ Sets whether the current generator produces antithetic values. If
300
+ X is the value normally returned from a uniform [0,1] random
301
+ number generator then 1 - X is the antithetic value. If X is the
302
+ value normally returned from a uniform [0,N] random number
303
+ generator then N - 1 - X is the antithetic value.
304
+ All generators are initialized to NOT generate antithetic values.
305
+ This is a transcription from Pascal to Fortran of routine
306
+ Set_Antithetic from the paper
307
+ L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
308
+ with Splitting Facilities." ACM Transactions on Mathematical
309
+ Software, 17:98-111 (1991)
310
+ Arguments
311
+ qvalue -> nonzero if generator G is to generating antithetic
312
+ values, otherwise zero
313
+ **********************************************************************
314
+ */
315
+ {
316
+ #define numg 32L
317
+ extern void gsrgs(long getset,long *qvalue);
318
+ extern void gscgn(long getset,long *g);
319
+ extern long Xqanti[];
320
+ static long g;
321
+ static long qrgnin;
322
+ /*
323
+ Abort unless random number generator initialized
324
+ */
325
+ gsrgs(0L,&qrgnin);
326
+ if(qrgnin) goto S10;
327
+ fprintf(stderr,"%s\n",
328
+ " SETANT called before random number generator initialized -- abort!");
329
+ exit(1);
330
+ S10:
331
+ gscgn(0L,&g);
332
+ Xqanti[g-1] = qvalue;
333
+ #undef numg
334
+ }
335
+ void setsd(long iseed1,long iseed2)
336
+ /*
337
+ **********************************************************************
338
+ void setsd(long iseed1,long iseed2)
339
+ SET S-ee-D of current generator
340
+ Resets the initial seed of the current generator to ISEED1 and
341
+ ISEED2. The seeds of the other generators remain unchanged.
342
+ This is a transcription from Pascal to Fortran of routine
343
+ Set_Seed from the paper
344
+ L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
345
+ with Splitting Facilities." ACM Transactions on Mathematical
346
+ Software, 17:98-111 (1991)
347
+ Arguments
348
+ iseed1 -> First integer seed
349
+ iseed2 -> Second integer seed
350
+ **********************************************************************
351
+ */
352
+ {
353
+ #define numg 32L
354
+ extern void gsrgs(long getset,long *qvalue);
355
+ extern void gscgn(long getset,long *g);
356
+ extern long Xig1[],Xig2[];
357
+ static long g;
358
+ static long qrgnin;
359
+ /*
360
+ Abort unless random number generator initialized
361
+ */
362
+ gsrgs(0L,&qrgnin);
363
+ if(qrgnin) goto S10;
364
+ fprintf(stderr,"%s\n",
365
+ " SETSD called before random number generator initialized -- abort!");
366
+ exit(1);
367
+ S10:
368
+ gscgn(0L,&g);
369
+ *(Xig1+g-1) = iseed1;
370
+ *(Xig2+g-1) = iseed2;
371
+ initgn(-1L);
372
+ #undef numg
373
+ }
@@ -0,0 +1,7 @@
1
+ require 'mkmf'
2
+
3
+ extension_name = 'random_variable'
4
+ have_header 'ruby.h'
5
+ have_header 'math.h'
6
+ have_header 'limits.h'
7
+ create_makefile 'random_variable'
data/lib/ext/linpack.c ADDED
@@ -0,0 +1,91 @@
1
+ #include <math.h>
2
+ double sdot(long n,double *sx,long incx,double *sy,long incy)
3
+ {
4
+ static long i,ix,iy,m,mp1;
5
+ static double sdot,stemp;
6
+ stemp = sdot = 0.0;
7
+ if(n <= 0) return sdot;
8
+ if(incx == 1 && incy == 1) goto S20;
9
+ ix = iy = 1;
10
+ if(incx < 0) ix = (-n+1)*incx+1;
11
+ if(incy < 0) iy = (-n+1)*incy+1;
12
+ for(i=1; i<=n; i++) {
13
+ stemp += (*(sx+ix-1)**(sy+iy-1));
14
+ ix += incx;
15
+ iy += incy;
16
+ }
17
+ sdot = stemp;
18
+ return sdot;
19
+ S20:
20
+ m = n % 5L;
21
+ if(m == 0) goto S40;
22
+ for(i=0; i<m; i++) stemp += (*(sx+i)**(sy+i));
23
+ if(n < 5) goto S60;
24
+ S40:
25
+ mp1 = m+1;
26
+ for(i=mp1; i<=n; i+=5) stemp += (*(sx+i-1)**(sy+i-1)+*(sx+i)**(sy+i)+*(sx+i
27
+ +1)**(sy+i+1)+*(sx+i+2)**(sy+i+2)+*(sx+i+3)**(sy+i+3));
28
+ S60:
29
+ sdot = stemp;
30
+ return sdot;
31
+ }
32
+ void spofa(double *a,long lda,long n,long *info)
33
+ /*
34
+ SPOFA FACTORS A REAL SYMMETRIC POSITIVE DEFINITE MATRIX.
35
+ SPOFA IS USUALLY CALLED BY SPOCO, BUT IT CAN BE CALLED
36
+ DIRECTLY WITH A SAVING IN TIME IF RCOND IS NOT NEEDED.
37
+ (TIME FOR SPOCO) = (1 + 18/N)*(TIME FOR SPOFA) .
38
+ ON ENTRY
39
+ A REAL(LDA, N)
40
+ THE SYMMETRIC MATRIX TO BE FACTORED. ONLY THE
41
+ DIAGONAL AND UPPER TRIANGLE ARE USED.
42
+ LDA INTEGER
43
+ THE LEADING DIMENSION OF THE ARRAY A .
44
+ N INTEGER
45
+ THE ORDER OF THE MATRIX A .
46
+ ON RETURN
47
+ A AN UPPER TRIANGULAR MATRIX R SO THAT A = TRANS(R)*R
48
+ WHERE TRANS(R) IS THE TRANSPOSE.
49
+ THE STRICT LOWER TRIANGLE IS UNALTERED.
50
+ IF INFO .NE. 0 , THE FACTORIZATION IS NOT COMPLETE.
51
+ INFO INTEGER
52
+ = 0 FOR NORMAL RETURN.
53
+ = K SIGNALS AN ERROR CONDITION. THE LEADING MINOR
54
+ OF ORDER K IS NOT POSITIVE DEFINITE.
55
+ LINPACK. THIS VERSION DATED 08/14/78 .
56
+ CLEVE MOLER, UNIVERSITY OF NEW MEXICO, ARGONNE NATIONAL LAB.
57
+ SUBROUTINES AND FUNCTIONS
58
+ BLAS SDOT
59
+ FORTRAN SQRT
60
+ INTERNAL VARIABLES
61
+ */
62
+ {
63
+ extern double sdot(long n,double *sx,long incx,double *sy,long incy);
64
+ static long j,jm1,k;
65
+ static double t,s;
66
+ /*
67
+ BEGIN BLOCK WITH ...EXITS TO 40
68
+ */
69
+ for(j=1; j<=n; j++) {
70
+ *info = j;
71
+ s = 0.0;
72
+ jm1 = j-1;
73
+ if(jm1 < 1) goto S20;
74
+ for(k=0; k<jm1; k++) {
75
+ t = *(a+k+(j-1)*lda)-sdot(k,(a+k*lda),1L,(a+(j-1)*lda),1L);
76
+ t /= *(a+k+k*lda);
77
+ *(a+k+(j-1)*lda) = t;
78
+ s += (t*t);
79
+ }
80
+ S20:
81
+ s = *(a+j-1+(j-1)*lda)-s;
82
+ /*
83
+ ......EXIT
84
+ */
85
+ if(s <= 0.0) goto S40;
86
+ *(a+j-1+(j-1)*lda) = sqrt(s);
87
+ }
88
+ *info = 0;
89
+ S40:
90
+ return;
91
+ }