random_variable 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
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
+ }