1 /*
2  *  gretl -- Gnu Regression, Econometrics and Time-series Library
3  *  Copyright (C) 2001 Allin Cottrell and Riccardo "Jack" Lucchetti
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 /* random.c for gretl: RNGs */
21 
22 #include "libgretl.h"
23 #include <time.h>
24 
25 #ifdef HAVE_MPI
26 # include "gretl_mpi.h"
27 #endif
28 
29 #if defined(USE_AVX) || defined(USE_SSE2)
30 # define HAVE_SSE2
31 #else
32 # ifdef HAVE_SSE2
33 #  undef HAVE_SSE2
34 # endif
35 #endif
36 
37 #if defined(_OPENMP) && !defined(OS_OSX)
38 # include <omp.h>
39 #endif
40 
41 /* For optimizing the Ziggurat */
42 #if defined(i386) || defined (__i386__)
43 # define HAVE_X86_32 1
44 # define UMASK 0x80000000UL /* most significant w-r bits */
45 #else
46 # define HAVE_X86_32 0
47 #endif
48 
49 #define SFMT_MEXP 19937
50 
51 #include "../../rng/SFMT.c"
52 #include "../../dcmt/dc.h"
53 
54 /**
55  * SECTION:random
56  * @short_description: generate pseudo-random values
57  * @title: PRNG
58  * @include: libgretl.h
59  *
60  * Libgretl uses the Mersenne Twister as its underlying engine
61  * for uniform random values, but offers added value in
62  * the form of generators for several distributions commonly
63  * used in econometrics.
64  *
65  * Note that before using the libgretl PRNG you must call
66  * either libgretl_init() or the specific initialization
67  * function shown below, gretl_rand_init(). And once you're
68  * finished with it, you may call gretl_rand_free() or the
69  * global libgretl function libgretl_cleanup().
70  */
71 
72 static sfmt_t gretl_sfmt;
73 static guint32 sfmt_seed;
74 
75 /* alternate SFMT */
76 static sfmt_t gretl_alt_sfmt;
77 static guint32 alt_sfmt_seed;
78 
79 #define sfmt_rand32() sfmt_genrand_uint32(&gretl_sfmt)
80 #define sfmt_alt_rand32() sfmt_genrand_uint32(&gretl_alt_sfmt)
81 
82 /* Find n independent "small" Mersenne Twisters with period 2^521-1;
83    set the one corresponding to @self as the one to use
84 */
85 
86 static mt_struct *dcmt;
87 static guint32 dcmt_seed;
88 static int use_dcmt = 0;
89 
90 #define dcmt_rand32() genrand_mt(dcmt)
91 
set_up_dcmt(int n,int self,unsigned int seed)92 static int set_up_dcmt (int n, int self, unsigned int seed)
93 {
94     mt_struct **mtss;
95     int w = 32;
96     int p = 521; /* period = 2^521-1 =~ 6.9e+156 */
97     int dseed = 4172;
98     int i, count = 0;
99 
100     mtss = get_mt_parameters_st(w, p, 0, n - 1, dseed, &count);
101     if (mtss == NULL) {
102         fprintf(stderr, "Couldn't get MT parameters\n");
103         return E_DATA;
104     }
105 
106 #if 0
107     fprintf(stderr, "set_up_dcmt: set up %d MTs, self = %d\n", n, self);
108 #endif
109 
110     use_dcmt = 1;
111     dcmt_seed = seed != 0 ? seed : time(NULL);
112 
113     for (i=0; i<count; i++) {
114 	if (i == self) {
115 	    dcmt = mtss[i];
116 	    sgenrand_mt(dcmt_seed, dcmt);
117 	} else {
118 	    free_mt_struct(mtss[i]);
119 	}
120     }
121 
122     free(mtss);
123 
124     return 0;
125 }
126 
127 #ifdef HAVE_MPI
128 
dcmt_late_start(void)129 static int dcmt_late_start (void)
130 {
131     int np = gretl_mpi_n_processes();
132     int self = gretl_mpi_rank();
133     int err = 0;
134 
135     if (np > 0 && self >= 0 && self < np) {
136 	set_up_dcmt(np, self, 0);
137     } else {
138 	err = E_DATA;
139     }
140 
141     return err;
142 }
143 
144 #endif
145 
gretl_rand_set_dcmt(int s)146 int gretl_rand_set_dcmt (int s)
147 {
148     int err = 0;
149 
150     if (s == use_dcmt) {
151 	/* no-op */
152 	return 0;
153     }
154 
155     if (s) {
156 	/* sfmt in use, dcmt requested */
157 	if (dcmt == NULL) {
158 	    /* dcmt not set up already */
159 #ifdef HAVE_MPI
160 	    err = dcmt_late_start();
161 #else
162 	    err = E_DATA;
163 #endif
164 	} else {
165 	    /* reset seed */
166 	    dcmt_seed = time(NULL);
167 	    sgenrand_mt(dcmt_seed, dcmt);
168 	}
169     } else {
170 	/* dcmt in use, sfmt requested */
171 	gretl_rand_init();
172     }
173 
174     if (err) {
175 	gretl_errmsg_set("dcmt: not available");
176     } else {
177 	use_dcmt = s;
178     }
179 
180     return err;
181 }
182 
gretl_rand_get_dcmt(void)183 int gretl_rand_get_dcmt (void)
184 {
185     return use_dcmt;
186 }
187 
188 /**
189  * gretl_rand_init:
190  *
191  * Initialize gretl's PRNG, using the system time as seed.
192  * Default version, as opposed to DCMT.
193  */
194 
gretl_rand_init(void)195 void gretl_rand_init (void)
196 {
197     char *fseed = getenv("GRETL_FORCE_SEED");
198 
199     if (fseed != NULL) {
200 	sfmt_seed = atoi(fseed);
201     } else {
202 	sfmt_seed = time(NULL);
203     }
204 
205     sfmt_init_gen_rand(&gretl_sfmt, sfmt_seed);
206 }
207 
208 /**
209  * gretl_dcmt_init:
210  *
211  * Initialize DCMT, if needed.
212  */
213 
gretl_dcmt_init(int n,int self,unsigned int seed)214 void gretl_dcmt_init (int n, int self, unsigned int seed)
215 {
216     if (n > 0 && self >= 0 && self < n) {
217 	set_up_dcmt(n, self, seed);
218     }
219 }
220 
221 /**
222  * gretl_rand_free:
223  *
224  * Free the gretl_rand structure (may be called at program exit).
225  */
226 
gretl_rand_free(void)227 void gretl_rand_free (void)
228 {
229     if (dcmt != NULL) {
230 	free_mt_struct(dcmt);
231 	dcmt = NULL;
232     }
233 }
234 
235 /**
236  * gretl_rand_get_seed:
237  *
238  * Returns: the value of the seed for gretl's PRNG.
239  */
240 
gretl_rand_get_seed(void)241 unsigned int gretl_rand_get_seed (void)
242 {
243     if (use_dcmt) {
244 	return dcmt_seed;
245     } else {
246 	return sfmt_seed;
247     }
248 }
249 
gretl_dcmt_set_seed(unsigned int seed)250 static void gretl_dcmt_set_seed (unsigned int seed)
251 {
252     dcmt_seed = seed;
253     sgenrand_mt(dcmt_seed, dcmt);
254 }
255 
gretl_sfmt_set_seed(unsigned int seed)256 static void gretl_sfmt_set_seed (unsigned int seed)
257 {
258     sfmt_seed = seed;
259     sfmt_init_gen_rand(&gretl_sfmt, sfmt_seed);
260 }
261 
gretl_alt_sfmt_set_seed(unsigned int seed)262 static void gretl_alt_sfmt_set_seed (unsigned int seed)
263 {
264     alt_sfmt_seed = seed;
265     sfmt_init_gen_rand(&gretl_alt_sfmt, alt_sfmt_seed);
266 }
267 
268 /**
269  * gretl_rand_set_seed:
270  * @seed: the chosen seed value.
271  *
272  * Set a specific (and hence reproducible) seed for gretl's PRNG.
273  * But if the value 0 is given for @seed, set the seed using
274  * the system time (which is the default when libgretl is
275  * initialized).
276  */
277 
gretl_rand_set_seed(unsigned int seed)278 void gretl_rand_set_seed (unsigned int seed)
279 {
280     seed = (seed == 0)? time(NULL) : seed;
281 
282     if (use_dcmt) {
283 	gretl_dcmt_set_seed(seed);
284     } else {
285 	gretl_sfmt_set_seed(seed);
286     }
287 }
288 
gretl_alt_rand_set_seed(unsigned int seed)289 void gretl_alt_rand_set_seed (unsigned int seed)
290 {
291     seed = (seed == 0)? time(NULL) : seed;
292 
293     gretl_alt_sfmt_set_seed(seed);
294 }
295 
296 /**
297  * gretl_rand_01:
298  *
299  * Returns: the next random double, equally distributed over
300  * the range [0, 1).
301  */
302 
gretl_rand_01(void)303 double gretl_rand_01 (void)
304 {
305     if (use_dcmt) {
306 	return sfmt_to_real2(dcmt_rand32());
307     } else {
308 	return sfmt_to_real2(sfmt_rand32());
309     }
310 }
311 
312 /* Select which 32 bit generator to use for Ziggurat */
313 
randi32(void)314 static inline uint32_t randi32 (void)
315 {
316     if (use_dcmt) {
317 	return genrand_mt(dcmt);
318     } else {
319 	return sfmt_genrand_uint32(&gretl_sfmt);
320     }
321 }
322 
323 #if !(HAVE_X86_32)
324 
325 /* 53 bits for mantissa + 1 bit sign */
326 
randi54(void)327 static uint64_t randi54 (void)
328 {
329     const uint32_t lo = randi32();
330     const uint32_t hi = randi32() & 0x3FFFFF;
331 
332     return (((uint64_t) (hi) << 32) | lo);
333 }
334 
335 #endif
336 
337 /* generates a uniform random double on (0,1) with 53-bit resolution */
338 
randu53(void)339 static double randu53 (void)
340 {
341     const uint32_t a = randi32() >> 5;
342     const uint32_t b = randi32() >> 6;
343 
344     return (a*67108864.0+b+0.4) * (1.0/9007199254740992.0);
345 }
346 
347 /* Ziggurat normal generator: this Ziggurat code here is shamelessly
348    filched from GNU Octave (with minor modifications), since it turned
349    out to be faster than what we had (until 2016-10-08), with no loss
350    in quality of the random normal variates (in fact, perhaps a gain).
351 
352    See randmtzig.c in the Octave code-base. It appears that David
353    Bateman was the main author; anyway, thanks to whoever wrote the
354    implementation!
355 */
356 
357 #define ZIGGURAT_TABLE_SIZE 256
358 #define ZIGGURAT_NOR_R 3.6541528853610088
359 #define ZIGGURAT_NOR_INV_R 0.27366123732975828
360 #define NOR_SECTION_AREA 0.00492867323399
361 
362 #define ZIGINT uint64_t
363 #define NMANTISSA 9007199254740992.0  /* 53 bit mantissa */
364 
365 static ZIGINT ki[ZIGGURAT_TABLE_SIZE];
366 static double wi[ZIGGURAT_TABLE_SIZE];
367 static double fi[ZIGGURAT_TABLE_SIZE];
368 
369 static int initt = 1;
370 
create_ziggurat_tables(void)371 static void create_ziggurat_tables (void)
372 {
373     int i;
374     double x, x1;
375 
376     x1 = ZIGGURAT_NOR_R;
377     wi[255] = x1 / NMANTISSA;
378     fi[255] = exp(-0.5 * x1 * x1);
379 
380     /* Index zero is special for tail strip, where Marsaglia and Tsang
381        defines this as:
382        k_0 = 2^31 * r * f(r) / v, w_0 = 0.5^31 * v / f(r), f_0 = 1,
383        where v is the area of each strip of the ziggurat.
384     */
385     ki[0] = (ZIGINT) (x1 * fi[255] / NOR_SECTION_AREA * NMANTISSA);
386     wi[0] = NOR_SECTION_AREA / fi[255] / NMANTISSA;
387     fi[0] = 1.;
388 
389     for (i = 254; i > 0; i--) {
390 	/* New x is given by x = f^{-1}(v/x_{i+1} + f(x_{i+1})), thus
391 	   need inverse operator of y = exp(-0.5*x*x) -> x = sqrt(-2*ln(y))
392 	*/
393 	x = sqrt (-2. * log(NOR_SECTION_AREA / x1 + fi[i+1]));
394 	ki[i+1] = (ZIGINT) (x / x1 * NMANTISSA);
395 	wi[i] = x / NMANTISSA;
396 	fi[i] = exp(-0.5 * x * x);
397 	x1 = x;
398     }
399 
400     ki[1] = 0;
401 
402     initt = 0;
403 }
404 
405 /**
406  * gretl_one_snormal:
407  *
408  * Returns: a single drawing from the standard normal distribution.
409  */
410 
gretl_one_snormal(void)411 double gretl_one_snormal (void)
412 {
413     if (initt) {
414 	create_ziggurat_tables();
415     }
416 
417     while (1) {
418 #if HAVE_X86_32
419 	/* Specialized for x86 32-bit architecture: 53-bit mantissa,
420 	   1-bit sign
421 	*/
422 	double x;
423 	int si, idx;
424 	uint32_t lo, hi;
425 	int64_t rabs;
426 	uint32_t *p = (uint32_t *) &rabs;
427 
428 	lo = randi32();
429 	idx = lo & 0xFF;
430 	hi = randi32();
431 	si = hi & UMASK;
432 	p[0] = lo;
433 	p[1] = hi & 0x1FFFFF;
434 	x = (si ? -rabs : rabs) * wi[idx];
435 #else
436 	const uint64_t r = randi54();
437 	const int64_t rabs = r >> 1;
438 	const int idx = (int) (rabs & 0xFF);
439 	const double x = ((r & 1) ? -rabs : rabs) * wi[idx];
440 #endif
441 
442 	if (rabs < (int64_t) (ki[idx])) {
443 	    return x; /* 99.3% of the time we return here 1st try */
444 	} else if (idx == 0) {
445 	    /* As stated in Marsaglia and Tsang:
446 	       For the normal tail, the method of Marsaglia provides:
447 	       generate x = -ln(U_1)/r, y = -ln(U_2), until y+y > x*x,
448 	       then return r+x. Except that r+x is always in the positive
449 	       tail. Anything random might be used to determine the
450 	       sign, but as we already have r we might as well use it.
451 	    */
452 	    double xx, yy;
453 
454 	    do {
455 		xx = - ZIGGURAT_NOR_INV_R * log(randu53());
456 		yy = - log(randu53());
457             } while (yy+yy <= xx*xx);
458 	    return (rabs & 0x100) ? -ZIGGURAT_NOR_R-xx : ZIGGURAT_NOR_R+xx;
459         } else if ((fi[idx-1] - fi[idx]) * randu53() + fi[idx] < exp(-0.5*x*x)) {
460 	    return x;
461 	}
462     }
463 }
464 
465 /**
466  * gretl_rand_normal:
467  * @a: target array
468  * @t1: start of the fill range
469  * @t2: end of the fill range
470  *
471  * Fill the selected range of array @a with pseudo-random drawings
472  * from the standard normal distribution, using the Mersenne Twister
473  * for uniform input and the Ziggurat method for converting to the
474  * normal distribution.
475  */
476 
gretl_rand_normal(double * a,int t1,int t2)477 void gretl_rand_normal (double *a, int t1, int t2)
478 {
479     int t;
480 
481     for (t=t1; t<=t2; t++) {
482 	a[t] = gretl_one_snormal();
483     }
484 }
485 
486 /**
487  * gretl_rand_normal_full:
488  * @a: target array
489  * @t1: start of the fill range
490  * @t2: end of the fill range
491  * @mean: mean of the distribution
492  * @sd: standard deviation
493  *
494  * Fill the selected range of array @a with pseudo-random drawings
495  * from the normal distribution with the given mean and standard
496  * deviation, using the Mersenne Twister for uniform input and
497  * the Ziggurat method for converting to the normal distribution.
498  *
499  * Returns: 0 on success, 1 on invalid input.
500  */
501 
gretl_rand_normal_full(double * a,int t1,int t2,double mean,double sd)502 int gretl_rand_normal_full (double *a, int t1, int t2,
503 			    double mean, double sd)
504 {
505     int t;
506 
507     if (na(mean) && na(sd)) {
508 	mean = 0.0;
509 	sd = 1.0;
510     } else if (na(mean) || na(sd) || sd <= 0.0) {
511 	return E_INVARG;
512     }
513 
514     gretl_rand_normal(a, t1, t2);
515 
516     if (mean != 0.0 || sd != 1.0) {
517 	for (t=t1; t<=t2; t++) {
518 	    a[t] = mean + a[t] * sd;
519 	}
520     }
521 
522     return 0;
523 }
524 
mt_int_range(guint32 begin,guint32 end,int alt)525 static guint32 mt_int_range (guint32 begin,
526 			     guint32 end,
527 			     int alt)
528 {
529     guint32 dist = end - begin;
530     guint32 rval = 0;
531 
532     if (dist > 0) {
533 	/* maxval is set to the predecessor of the greatest
534 	   multiple of dist less than or equal to 2^32
535 	*/
536 	guint32 maxval;
537 
538 	if (dist <= 0x80000000u) { /* 2^31 */
539 	    /* maxval = 2^32 - 1 - (2^32 % dist) */
540 	    guint32 rem = (0x80000000u % dist) * 2;
541 
542 	    if (rem >= dist) rem -= dist;
543 	    maxval = 0xffffffffu - rem;
544 	} else {
545 	    maxval = dist - 1;
546 	}
547 
548 	if (use_dcmt) {
549 	    do {
550 		rval = dcmt_rand32();
551 	    } while (rval > maxval);
552 	} else if (alt) {
553 	    do {
554 		rval = sfmt_alt_rand32();
555 	    } while (rval > maxval);
556 	} else {
557 	    do {
558 		rval = sfmt_rand32();
559 	    } while (rval > maxval);
560 	}
561 
562 	rval %= dist;
563     }
564 
565     return begin + rval;
566 }
567 
568 /**
569  * gretl_rand_uniform_minmax:
570  * @a: target array.
571  * @t1: start of the fill range.
572  * @t2: end of the fill range.
573  * @min: lower bound of range.
574  * @max: upper bound of range.
575  *
576  * Fill the selected subset of array @a with pseudo-random drawings
577  * from the uniform distribution on @min to @max, using the Mersenne
578  * Twister.
579  *
580  * Returns: 0 on success, 1 on invalid input.
581  */
582 
gretl_rand_uniform_minmax(double * a,int t1,int t2,double min,double max)583 int gretl_rand_uniform_minmax (double *a, int t1, int t2,
584 			       double min, double max)
585 {
586     int t;
587 
588     if (na(min) && na(max)) {
589 	min = 0.0;
590 	max = 1.0;
591     } else if (na(min) || na(max) || max <= min) {
592 	return E_INVARG;
593     }
594 
595     for (t=t1; t<=t2; t++) {
596 	if (use_dcmt) {
597 	    a[t] = sfmt_to_real2(dcmt_rand32()) * (max - min) + min;
598 	} else {
599 	    a[t] = sfmt_to_real2(sfmt_rand32()) * (max - min) + min;
600 	}
601     }
602 
603     return 0;
604 }
605 
real_gretl_rand_int_minmax(int * a,int n,int min,int max,int alt)606 static int real_gretl_rand_int_minmax (int *a, int n,
607 				       int min, int max,
608 				       int alt)
609 {
610     int i, err = 0;
611 
612     if (max < min) {
613 	err = E_INVARG;
614     } else if (min == max) {
615 	for (i=0; i<n; i++) {
616 	    a[i] = min;
617 	}
618     } else {
619 	int offset = 0;
620 
621 	if (min < 0) {
622 	    offset = -min;
623 	    max += offset;
624 	    min += offset;
625 	}
626 
627 	for (i=0; i<n; i++) {
628 	    a[i] = mt_int_range(min, max + 1, alt) - offset;
629 	}
630     }
631 
632     return err;
633 }
634 
635 /**
636  * gretl_rand_int_minmax:
637  * @a: target array.
638  * @n: length of array.
639  * @min: lower closed bound of range.
640  * @max: upper closed bound of range.
641  *
642  * Fill array @a of length @n with pseudo-random drawings
643  * from the uniform distribution on [@min, @max], using the
644  * Mersenne Twister.
645  *
646  * Returns: 0 on success, 1 on invalid input.
647  */
648 
gretl_rand_int_minmax(int * a,int n,int min,int max)649 int gretl_rand_int_minmax (int *a, int n, int min, int max)
650 {
651     return real_gretl_rand_int_minmax(a, n, min, max, 0);
652 }
653 
654 /**
655  * gretl_alt_rand_int_minmax:
656  * @a: target array.
657  * @n: length of array.
658  * @min: lower closed bound of range.
659  * @max: upper closed bound of range.
660  *
661  * Fill array @a of length @n with pseudo-random drawings
662  * from the uniform distribution on [@min, @max], using a
663  * Mersenne Twister which is independent of the main one
664  * employed by libgretl.
665  *
666  * Returns: 0 on success, 1 on invalid input.
667  */
668 
gretl_alt_rand_int_minmax(int * a,int n,int min,int max)669 int gretl_alt_rand_int_minmax (int *a, int n, int min, int max)
670 {
671     return real_gretl_rand_int_minmax(a, n, min, max, 1);
672 }
673 
already_selected(double * a,int n,double val,int offset)674 static int already_selected (double *a, int n, double val,
675 			     int offset)
676 {
677     int i;
678 
679     for (i=0; i<n; i++) {
680 	if (offset > 0) {
681 	    if (a[i] == val - offset) {
682 		return 1;
683 	    }
684 	} else if (a[i] == val) {
685 	    return 1;
686 	}
687     }
688 
689     return 0;
690 }
691 
692 /**
693  * gretl_rand_uniform_int_minmax:
694  * @a: target array.
695  * @t1: start of the fill range.
696  * @t2: end of the fill range.
697  * @min: lower closed bound of range.
698  * @max: upper closed bound of range.
699  * @opt: include OPT_O for sampling without replacement.
700  *
701  * Fill the selected subset of array @a with pseudo-random drawings
702  * from the uniform distribution on [@min, @max], using the
703  * Mersenne Twister.
704  *
705  * Returns: 0 on success, 1 on invalid input.
706  */
707 
gretl_rand_uniform_int_minmax(double * a,int t1,int t2,int min,int max,gretlopt opt)708 int gretl_rand_uniform_int_minmax (double *a, int t1, int t2,
709 				   int min, int max,
710 				   gretlopt opt)
711 {
712     int t, err = 0;
713 
714     if (max < min) {
715 	err = E_INVARG;
716     } else if (max == min) {
717 	for (t=t1; t<=t2; t++) {
718 	    a[t] = min;
719 	}
720     } else {
721 	int i = 0, offset = 0;
722 	double x;
723 
724 	if (min < 0) {
725 	    offset = -min;
726 	    max += offset;
727 	    min += offset;
728 	}
729 
730 	for (t=t1; t<=t2; t++) {
731 	    x = mt_int_range(min, max + 1, 0);
732 	    if (opt & OPT_O) {
733 		while (already_selected(a, i, x, offset)) {
734 		    x = mt_int_range(min, max + 1, 0);
735 		}
736 	    }
737 	    a[t] = x - offset;
738 	    i++;
739 	}
740     }
741 
742     return err;
743 }
744 
745 /**
746  * gretl_rand_uniform:
747  * @a: target array
748  * @t1: start of the fill range
749  * @t2: end of the fill range
750  *
751  * Fill the selected range of array @a with pseudo-random drawings
752  * from the uniform distribution on [0-1), using the Mersenne
753  * Twister.
754  */
755 
gretl_rand_uniform(double * a,int t1,int t2)756 void gretl_rand_uniform (double *a, int t1, int t2)
757 {
758     int t;
759 
760     if (use_dcmt) {
761 	for (t=t1; t<=t2; t++) {
762 	   a[t] = sfmt_to_real2(dcmt_rand32());
763 	}
764     } else {
765 	for (t=t1; t<=t2; t++) {
766 	   a[t] = sfmt_to_real2(sfmt_rand32());
767 	}
768     }
769 }
770 
gretl_rand_uniform_one(void)771 static double gretl_rand_uniform_one (void)
772 {
773     if (use_dcmt) {
774 	return sfmt_to_real2(dcmt_rand32());
775     } else {
776 	return sfmt_to_real2(sfmt_rand32());
777     }
778 }
779 
gretl_rand_gamma_one(double shape,double scale)780 double gretl_rand_gamma_one (double shape, double scale)
781 {
782     double k = shape;
783     double d, c, x, v, u, dv;
784 
785     if (shape <= 0 || scale <= 0) {
786 	return NADBL;
787     }
788 
789     if (shape < 1) {
790 	k = shape + 1.0;
791     }
792 
793     d = k - 1.0/3;
794     c = 1.0 / sqrt(9*d);
795 
796     while (1) {
797 	x = gretl_one_snormal();
798 	v = pow(1 + c*x, 3);
799 	if (v > 0.0) {
800 	    dv = d * v;
801 	    u = gretl_rand_01();
802 	    /* apply squeeze */
803 	    if (u < 1 - 0.0331 * pow(x, 4) ||
804 		log(u) < 0.5*x*x + d*(1-v+log(v))) {
805 		break;
806 	    }
807 	}
808     }
809     if (shape < 1) {
810 	u = gretl_rand_01();
811 	dv *= pow(u, 1/shape);
812     }
813 
814     return dv * scale;
815 }
816 
817 /* Marsaglia-Tsang, "A Simple Method for Generating Gamma Variables",
818    ACM Transactions on Mathematical Software, Vol. 26, No. 3,
819    September 2000, Pages 363­372.
820 
821    (1) Setup: d=a-1/3, c=1/sqrt(9*d).
822    (2) Generate v=(1+c*x)^3 with x normal; repeat if v <= 0.
823    (3) Generate uniform U.
824    (4) If U < 1-0.0331*x^4 return d*v.
825    (5) If log(U) < 0.5*x^2+d*(1-v+log(v)) return d*v.
826    (6) Go to step 2.
827 */
828 
829 /**
830  * gretl_rand_gamma:
831  * @a: target array.
832  * @t1: start of the fill range.
833  * @t2: end of the fill range.
834  * @shape: shape parameter.
835  * @scale: scale parameter.
836  *
837  * Fill the selected range of array @a with pseudo-random drawings
838  * from the specified gamma distribution.
839  *
840  * Returns: 0 on success, non-zero on error.
841  */
842 
gretl_rand_gamma(double * a,int t1,int t2,double shape,double scale)843 int gretl_rand_gamma (double *a, int t1, int t2,
844 		      double shape, double scale)
845 {
846     double k = shape;
847     double d, c, x, v, u, dv;
848     int t;
849 
850     if (shape <= 0 || scale <= 0) {
851 	return E_DATA;
852     }
853 
854     if (shape < 1) {
855 	k = shape + 1.0;
856     }
857 
858     d = k - 1.0/3;
859     c = 1.0 / sqrt(9*d);
860 
861     for (t=t1; t<=t2; t++) {
862 	while (1) {
863 	    x = gretl_one_snormal();
864 	    v = pow(1 + c*x, 3);
865 	    if (v > 0.0) {
866 		dv = d * v;
867 		u = gretl_rand_01();
868 		/* apply squeeze */
869 		if (u < 1 - 0.0331 * pow(x, 4) ||
870 		    log(u) < 0.5*x*x + d*(1-v+log(v))) {
871 		    break;
872 		}
873 	    }
874 	}
875 	if (shape < 1) {
876 	    u = gretl_rand_01();
877 	    dv *= pow(u, 1/shape);
878 	}
879 	a[t] = dv * scale;
880     }
881 
882     return 0;
883 }
884 
885 /**
886  * gretl_rand_chisq:
887  * @a: target array.
888  * @t1: start of the fill range.
889  * @t2: end of the fill range.
890  * @v: degrees of freedom.
891  *
892  * Fill the selected range of array @a with pseudo-random drawings
893  * from the Chi-squared distribution with @v degrees of freedom,
894  * using the gamma r.v. generator.
895  *
896  * Returns: 0 on success, non-zero on error.
897  */
898 
gretl_rand_chisq(double * a,int t1,int t2,int v)899 int gretl_rand_chisq (double *a, int t1, int t2, int v)
900 {
901     return gretl_rand_gamma(a, t1, t2, 0.5*v, 2);
902 }
903 
904 /**
905  * gretl_rand_student:
906  * @a: target array.
907  * @t1: start of the fill range.
908  * @t2: end of the fill range.
909  * @v: degrees of freedom.
910  *
911  * Fill the selected range of array @a with pseudo-random drawings
912  * from the Student t distribution with @v degrees of freedom,
913  * using the Mersenne Twister for uniform input and the ziggurat
914  * method for converting to the normal distribution.
915  *
916  * Returns: 0 on success, non-zero on error.
917  */
918 
gretl_rand_student(double * a,int t1,int t2,double v)919 int gretl_rand_student (double *a, int t1, int t2, double v)
920 {
921     double *X2 = NULL;
922     int T = t2 - t1 + 1;
923     int t;
924 
925     if (v <= 0) {
926 	return E_INVARG;
927     }
928 
929     X2 = malloc(T * sizeof *X2);
930     if (X2 == NULL) {
931 	return E_ALLOC;
932     }
933 
934     gretl_rand_normal(a, t1, t2);
935     gretl_rand_gamma(X2, 0, T-1, 0.5*v, 2);
936 
937     for (t=0; t<T; t++) {
938 	a[t + t1] /= sqrt(X2[t] / v);
939     }
940 
941     free(X2);
942 
943     return 0;
944 }
945 
946 /**
947  * gretl_rand_F:
948  * @a: target array.
949  * @t1: start of the fill range.
950  * @t2: end of the fill range.
951  * @v1: numerator degrees of freedom.
952  * @v2: denominator degrees of freedom.
953  *
954  * Fill the selected range of array @a with pseudo-random drawings
955  * from the F distribution with @v1 and @v2 degrees of freedom,
956  * using the Mersenne Twister for uniform input and the Ziggurat
957  * method for converting to the normal distribution.
958  *
959  * Returns: 0 on success, non-zero on error.
960  */
961 
gretl_rand_F(double * a,int t1,int t2,int v1,int v2)962 int gretl_rand_F (double *a, int t1, int t2, int v1, int v2)
963 {
964     double *b = NULL;
965     int T = t2 - t1 + 1;
966     int s, t;
967 
968     if (v1 < 1 || v2 < 1) {
969 	return E_INVARG;
970     }
971 
972     b = malloc(T * sizeof *b);
973     if (b == NULL) {
974 	return E_ALLOC;
975     }
976 
977     gretl_rand_chisq(a, t1, t2, v1);
978     gretl_rand_chisq(b, 0, T-1, v2);
979 
980     for (t=0; t<T; t++) {
981 	s = t + t1;
982 	a[s] = (a[s]/v1) / (b[t]/v2);
983     }
984 
985     free(b);
986 
987     return 0;
988 }
989 
990 /**
991  * gretl_rand_binomial:
992  * @a: target array.
993  * @t1: start of the fill range.
994  * @t2: end of the fill range.
995  * @n: number of trials.
996  * @p: success probability per trial.
997  *
998  * Fill the selected range of array @a with pseudo-random drawings
999  * from the binomial distribution with parameters @n and @p.
1000  *
1001  * Returns: 0 on success, non-zero on error.
1002  */
1003 
gretl_rand_binomial(double * a,int t1,int t2,int n,double p)1004 int gretl_rand_binomial (double *a, int t1, int t2, int n, double p)
1005 {
1006     int t;
1007 
1008     if (n < 0 || p < 0 || p > 1) {
1009 	return E_INVARG;
1010     }
1011 
1012     if (n == 0 || p == 0.0) {
1013 	for (t=t1; t<=t2; t++) {
1014 	    a[t] = 0.0;
1015 	}
1016     } else if (p == 1.0) {
1017 	for (t=t1; t<=t2; t++) {
1018 	    a[t] = n;
1019 	}
1020     } else {
1021 	double *b = malloc(n * sizeof *b);
1022 	int i;
1023 
1024 	if (b == NULL) {
1025 	    return E_ALLOC;
1026 	}
1027 
1028 	for (t=t1; t<=t2; t++) {
1029 	    a[t] = 0.0;
1030 	    gretl_rand_uniform(b, 0, n - 1);
1031 	    for (i=0; i<n; i++) {
1032 		if (b[i] <= p) {
1033 		    a[t] += 1;
1034 		}
1035 	    }
1036 	}
1037 
1038 	free(b);
1039     }
1040 
1041     return 0;
1042 }
1043 
gretl_rand_binomial_one(int n,double p,double * b)1044 static double gretl_rand_binomial_one (int n, double p,
1045 				       double *b)
1046 {
1047     double ret;
1048 
1049     if (n < 0 || p < 0 || p > 1) {
1050 	return NADBL;
1051     }
1052 
1053     if (n == 0 || p == 0.0) {
1054 	ret = 0.0;
1055     } else if (p == 1.0) {
1056 	ret = n;
1057     } else {
1058 	int i;
1059 
1060 	ret = 0.0;
1061 	gretl_rand_uniform(b, 0, n - 1);
1062 	for (i=0; i<n; i++) {
1063 	    if (b[i] <= p) {
1064 		ret += 1;
1065 	    }
1066 	}
1067     }
1068 
1069     return ret;
1070 }
1071 
1072 /* Poisson rv with mean m */
1073 
genpois(const double m)1074 static double genpois (const double m)
1075 {
1076     double x;
1077 
1078     if (m > 200) {
1079 	x = (m + 0.5) + sqrt(m) * gretl_one_snormal();
1080 	x = floor(x);
1081     } else {
1082 	int y = 0;
1083 
1084 	x = exp(m) * gretl_rand_01();
1085 	while (x > 1) {
1086 	    y++;
1087 	    x *= gretl_rand_01();
1088 	}
1089 	x = (double) y;
1090     }
1091 
1092     return x;
1093 }
1094 
1095 /**
1096  * gretl_rand_poisson:
1097  * @a: target array.
1098  * @t1: start of the fill range.
1099  * @t2: end of the fill range.
1100  * @m: mean (see below).
1101  * @vec: should be 1 if @m is an array, else 0.
1102  *
1103  * Fill the selected range of array @a with pseudo-random drawings
1104  * from the Poisson distribution with a mean determined by
1105  * @m, which can either be a pointer to a scalar, or an array
1106  * of length greater than or equal to @t2 + 1.
1107  *
1108  * Returns: 0 on success, non-zero on error.
1109  */
1110 
gretl_rand_poisson(double * a,int t1,int t2,const double * m,int vec)1111 int gretl_rand_poisson (double *a, int t1, int t2, const double *m,
1112 			int vec)
1113 {
1114     double mt;
1115     int t;
1116 
1117     for (t=t1; t<=t2; t++) {
1118 	mt = (vec)? m[t] : *m;
1119 	a[t] = (mt <= 0)? NADBL : genpois(mt);
1120     }
1121 
1122     return 0;
1123 }
1124 
1125 /* f(x; k, \lambda) = (k/\lambda) (x/\lambda)^{k-1} e^{-(x/\lambda)^k} */
1126 
1127 /**
1128  * gretl_rand_weibull:
1129  * @a: target array.
1130  * @t1: start of the fill range.
1131  * @t2: end of the fill range.
1132  * @shape: shape parameter > 0.
1133  * @scale: scale parameter > 0.
1134  *
1135  * Fill the selected range of array @a with pseudo-random drawings
1136  * from the Weibull distribution with shape @k and scale @lambda.
1137  *
1138  * Returns: 0 on success, non-zero if either parameter is out of
1139  * bounds.
1140  */
1141 
gretl_rand_weibull(double * a,int t1,int t2,double shape,double scale)1142 int gretl_rand_weibull (double *a, int t1, int t2, double shape,
1143 			double scale)
1144 {
1145     int err = 0;
1146 
1147     if (shape <= 0 || scale <= 0) {
1148 	err = E_DATA;
1149     } else {
1150 	double u, kinv = 1.0 / shape;
1151 	int t;
1152 
1153 	for (t=t1; t<=t2; t++) {
1154 	    u = gretl_rand_01();
1155 	    while (u == 0.0) {
1156 		u = gretl_rand_01();
1157 	    }
1158 	    a[t] = scale * pow(-log(u), kinv);
1159 	}
1160     }
1161 
1162     return err;
1163 }
1164 
1165 /**
1166  * gretl_rand_exponential:
1167  * @a: target array.
1168  * @t1: start of the fill range.
1169  * @t2: end of the fill range.
1170  * @mu: scale parameter > 0.
1171  *
1172  * Fill the selected range of array @a with pseudo-random drawings
1173  * from the exponential distribution with scale @mu.
1174  *
1175  * Returns: 0 on success, non-zero if @mu is out of
1176  * bounds.
1177  */
1178 
gretl_rand_exponential(double * a,int t1,int t2,double mu)1179 int gretl_rand_exponential (double *a, int t1, int t2, double mu)
1180 {
1181     int err = 0;
1182 
1183     if (mu <= 0) {
1184 	err = E_DATA;
1185     } else {
1186 	double u;
1187 	int t;
1188 
1189 	for (t=t1; t<=t2; t++) {
1190 	    u = gretl_rand_01();
1191 	    while (u == 0.0) {
1192 		u = gretl_rand_01();
1193 	    }
1194 	    a[t] = -mu * log(u);
1195 	}
1196     }
1197 
1198     return err;
1199 }
1200 
1201 /**
1202  * gretl_rand_logistic:
1203  * @a: target array.
1204  * @t1: start of the fill range.
1205  * @t2: end of the fill range.
1206  * @loc: location parameter.
1207  * @scale: scale parameter > 0.
1208  *
1209  * Fill the selected range of array @a with pseudo-random drawings
1210  * from the logistic distribution with location @loc and scale @scale.
1211  *
1212  * Returns: 0 on success, non-zero if @scale is out of
1213  * bounds.
1214  */
1215 
gretl_rand_logistic(double * a,int t1,int t2,double loc,double scale)1216 int gretl_rand_logistic (double *a, int t1, int t2,
1217 			 double loc, double scale)
1218 {
1219     int err = 0;
1220 
1221     if (scale <= 0) {
1222 	err = E_DATA;
1223     } else {
1224 	double u;
1225 	int t;
1226 
1227 	for (t=t1; t<=t2; t++) {
1228 	    u = gretl_rand_01();
1229 	    while (u == 0.0) {
1230 		u = gretl_rand_01();
1231 	    }
1232 	    a[t] = loc + scale * log(u / (1 - u));
1233 	}
1234     }
1235 
1236     return err;
1237 }
1238 
1239 /**
1240  * gretl_rand_GED:
1241  * @a: target array.
1242  * @t1: start of the fill range.
1243  * @t2: end of the fill range.
1244  * @nu: shape parameter > 0.
1245  *
1246  * Fill the selected range of array @a with pseudo-random drawings
1247  * from the GED distribution with shape @nu. We exploit the fact that
1248  * if x ~ GED(n), then |x/k|^n is a Gamma rv.
1249  *
1250  * Returns: 0 on success, non-zero if @nu is out of bounds.
1251  */
1252 
gretl_rand_GED(double * a,int t1,int t2,double nu)1253 int gretl_rand_GED (double *a, int t1, int t2, double nu)
1254 {
1255     int err, t;
1256     double p, scale;
1257 
1258     if (nu < 0) {
1259 	return E_INVARG;
1260     }
1261 
1262     p = 1.0/nu;
1263     scale = pow(0.5, p) * sqrt(gammafun(p) / gammafun(3.0*p));
1264     err = gretl_rand_gamma(a, t1, t2, p, 2);
1265 
1266     if (!err) {
1267 	for (t=t1; t<=t2; t++) {
1268 	    a[t] = scale * pow(a[t], p);
1269 	    if (gretl_rand_01() < 0.5) {
1270 		a[t] = -a[t];
1271 	    }
1272 	}
1273     }
1274 
1275     return err;
1276 }
1277 
1278 /**
1279  * gretl_rand_laplace:
1280  * @a: target array.
1281  * @t1: start of the fill range.
1282  * @t2: end of the fill range.
1283  * @mu: mean.
1284  * @b: shape parameter > 0.
1285  *
1286  * Fill the selected range of array @a with pseudo-random drawings
1287  * from the Laplace distribution with mean @mu and scale @b.
1288  *
1289  * Returns: 0 on success, non-zero if @b is out of bounds.
1290  */
1291 
gretl_rand_laplace(double * a,int t1,int t2,double mu,double b)1292 int gretl_rand_laplace (double *a, int t1, int t2,
1293 			double mu, double b)
1294 {
1295     int t, sgn;
1296     double U;
1297 
1298     if (b < 0) {
1299 	return E_INVARG;
1300     }
1301 
1302     /* uniform on [0,1) */
1303     gretl_rand_uniform(a, t1, t2);
1304 
1305     for (t=t1; t<=t2; t++) {
1306 	/* convert to (-1/2,1/2] */
1307 	U = 0.5 - a[t];
1308 	sgn = U < 0 ? -1 : 1;
1309 	a[t] = mu - b*sgn * log(1 - 2*fabs(U));
1310     }
1311 
1312     return 0;
1313 }
1314 
1315 /**
1316  * gretl_rand_beta:
1317  * @x: target array.
1318  * @t1: start of the fill range.
1319  * @t2: end of the fill range.
1320  * @s1: shape parameter > 0.
1321  * @s2: shape parameter > 0.
1322  *
1323  * Fill the selected range of array @a with pseudo-random drawings
1324  * from the beta distribution with shape parameters @s1 and @s2.
1325  * The code here is adapted from http://www.netlib.org/random/random.f90
1326  * which implements the method of R.C.H. Cheng, "Generating beta
1327  * variates with nonintegral shape parameters", Communications of the
1328  * ACM, 21(4), April 1978.
1329  *
1330  * Returns: 0 on success, non-zero if @s1 or @s2 are out of bounds.
1331  */
1332 
gretl_rand_beta(double * x,int t1,int t2,double s1,double s2)1333 int gretl_rand_beta (double *x, int t1, int t2,
1334 		     double s1, double s2)
1335 {
1336     double aln4 = 1.3862944;
1337     double a, b, s, u, v, y, z;
1338     double d, f, h, u0, c;
1339     int t, j, swap;
1340     double val;
1341 
1342     if (s1 <= 0 || s2 <= 0) {
1343 	return E_DATA;
1344     }
1345 
1346     /* initialization */
1347     a = s1;
1348     b = s2;
1349     swap = b > a;
1350     if (swap) {
1351 	f = b;
1352 	b = a;
1353 	a = f;
1354     }
1355     d = a/b;
1356     f = a+b;
1357     if (b > 1) {
1358 	h = sqrt((2*a*b - f)/(f - 2.0));
1359 	u0 = 1.0;
1360     } else {
1361 	h = b;
1362 	u0 = 1.0/(1.0 + pow(a/(DBL_MAX*b), b));
1363     }
1364     c = a+h;
1365 
1366     /* generation */
1367     for (t=t1; t<=t2; t++) {
1368 	for (j=0; ; j++) {
1369 	    u = gretl_rand_uniform_one();
1370 	    v = gretl_rand_uniform_one();
1371 	    s = u * u * v;
1372 	    if (u < DBL_MIN || s <= 0) continue;
1373 	    if (u < u0) {
1374 		v = log(u/(1.0 - u))/h;
1375 		y = d*exp(v);
1376 		z = c*v + f*log((1.0 + d)/(1.0 + y)) - aln4;
1377 		if (s - 1.0 > z) {
1378 		    if (s - s*z > 1.0) continue;
1379 		    if (log(s) > z) continue;
1380 		}
1381 		val = y/(1.0 + y);
1382 	    } else {
1383 		if (4.0*s > pow(1.0 + 1.0/d, f)) continue;
1384 		val = 1.0;
1385 	    }
1386 	    break;
1387 	}
1388 
1389 	x[t] = swap ? (1.0 - val) : val;
1390     }
1391 
1392     return 0;
1393 }
1394 
1395 /**
1396  * gretl_rand_beta_binomial:
1397  * @x: target array.
1398  * @t1: start of the fill range.
1399  * @t2: end of the fill range.
1400  * @n: number of trials.
1401  * @s1: beta shape parameter > 0.
1402  * @s2: beta shape parameter > 0.
1403  *
1404  * Fill the selected range of array @x with pseudo-random drawings
1405  * from the binomial distribution with @n trials and success
1406  * probability distributed according to the beta distribution with
1407  * shape parameters @s1 and @s2.
1408  *
1409  * Returns: 0 on success, non-zero if @n, @s1 or @s2 are out of bounds.
1410  */
1411 
gretl_rand_beta_binomial(double * x,int t1,int t2,int n,double s1,double s2)1412 int gretl_rand_beta_binomial (double *x, int t1, int t2,
1413 			      int n, double s1, double s2)
1414 {
1415     int t, err;
1416 
1417     err = gretl_rand_beta(x, t1, t2, s1, s2);
1418 
1419     if (!err) {
1420 	double *b = malloc(n * sizeof *b);
1421 
1422 	if (b == NULL) {
1423 	    return E_ALLOC;
1424 	} else {
1425 	    for (t=t1; t<=t2; t++) {
1426 		x[t] = gretl_rand_binomial_one(n, x[t], b);
1427 	    }
1428 	    free(b);
1429 	}
1430     }
1431 
1432     return err;
1433 }
1434 
1435 /**
1436  * gretl_rand_int_max:
1437  * @max: the maximum value (open)
1438  *
1439  * Returns: a pseudo-random unsigned int in the interval
1440  * [0, max-1] using the Mersenne Twister.
1441  */
1442 
gretl_rand_int_max(unsigned int max)1443 unsigned int gretl_rand_int_max (unsigned int max)
1444 {
1445     return mt_int_range(0, max, 0);
1446 }
1447 
1448 /**
1449  * gretl_rand_int:
1450  *
1451  * Returns: a pseudo-random unsigned int on the interval
1452  * [0, 2^32-1] using the Mersenne Twister.
1453  */
1454 
gretl_rand_int(void)1455 unsigned int gretl_rand_int (void)
1456 {
1457     if (use_dcmt) {
1458 	return dcmt_rand32();
1459     } else {
1460 	return sfmt_rand32();
1461     }
1462 }
1463 
gretl_alt_rand_int(void)1464 unsigned int gretl_alt_rand_int (void)
1465 {
1466     return sfmt_alt_rand32();
1467 }
1468 
halton(int i,int base)1469 static double halton (int i, int base)
1470 {
1471     double f = 1.0 / base;
1472     double h = 0.0;
1473 
1474     while (i > 0) {
1475 	h += f * (i % base);
1476 	i = floor(i / base);
1477 	f /= base;
1478     }
1479 
1480     return h;
1481 }
1482 
1483 /**
1484  * halton_matrix:
1485  * @m: number of rows (sequences); the maximum is 40.
1486  * @r: number of columns (elements in each sequence).
1487  * @offset: the number of initial values to discard.
1488  * @err: location to receive error code.
1489  *
1490  * Returns: an @m x @r matrix containing @m Halton
1491  * sequences. The sequences are contructed using the first
1492  * @m primes, and the first @offset elements of each sequence
1493  * are discarded.
1494  */
1495 
halton_matrix(int m,int r,int offset,int * err)1496 gretl_matrix *halton_matrix (int m, int r, int offset, int *err)
1497 {
1498     const int bases[] = {
1499 	2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
1500 	37, 41, 43, 47, 53, 59, 61, 67, 71, 73,
1501 	79, 83, 89, 97, 101, 103, 107, 109, 113,
1502 	127, 131, 137, 139, 149, 151, 157, 163,
1503 	167, 173, 179, 181
1504     };
1505     gretl_matrix *H;
1506     double hij;
1507     int i, j, k, n;
1508 
1509     if (m > 40 || offset < 0 || m <= 0 || r <= 0) {
1510 	*err = E_DATA;
1511 	return NULL;
1512     }
1513 
1514     H = gretl_matrix_alloc(m, r);
1515     if (H == NULL) {
1516 	*err = E_ALLOC;
1517 	return NULL;
1518     }
1519 
1520     /* we'll discard the first @offset elements */
1521     n = r + offset;
1522 
1523     for (i=0; i<m; i++) {
1524 	j = 0;
1525 	for (k=1; k<n; k++) {
1526 	    hij = halton(k, bases[i]);
1527 	    if (k >= offset) {
1528 		gretl_matrix_set(H, i, j++, hij);
1529 	    }
1530 	}
1531     }
1532 
1533     return H;
1534 }
1535 
1536 static gretl_matrix *
cholesky_factor_of_inverse(const gretl_matrix * S,int * err)1537 cholesky_factor_of_inverse (const gretl_matrix *S, int *err)
1538 {
1539     gretl_matrix *C = gretl_matrix_copy(S);
1540 
1541     if (C == NULL) {
1542 	*err = E_ALLOC;
1543     } else {
1544 	*err = gretl_invert_symmetric_matrix(C);
1545 	if (!*err) {
1546 	    *err = gretl_matrix_cholesky_decomp(C);
1547 	}
1548     }
1549 
1550     return C;
1551 }
1552 
wishart_workspace(gretl_matrix ** pW,gretl_matrix ** pB,double ** pZ,int p)1553 static int wishart_workspace (gretl_matrix **pW,
1554 			      gretl_matrix **pB,
1555 			      double **pZ,
1556 			      int p)
1557 {
1558     int err = 0;
1559 
1560     *pW = gretl_matrix_alloc(p, p);
1561 
1562     if (*pW == NULL) {
1563 	return E_ALLOC;
1564     }
1565 
1566     *pB = gretl_matrix_alloc(p, p);
1567 
1568     if (*pB == NULL) {
1569 	err = E_ALLOC;
1570     } else {
1571 	int n = p * (p + 1) / 2;
1572 
1573 	*pZ = malloc(n * sizeof **pZ);
1574 	if (*pZ == NULL) {
1575 	    err = E_ALLOC;
1576 	} else {
1577 	    gretl_rand_normal(*pZ, 0, n - 1);
1578 	}
1579     }
1580 
1581     if (err) {
1582 	gretl_matrix_free(*pW);
1583 	gretl_matrix_free(*pB);
1584     }
1585 
1586     return err;
1587 }
1588 
wishart_inverse_finalize(const gretl_matrix * C,gretl_matrix * B,gretl_matrix * W)1589 static int wishart_inverse_finalize (const gretl_matrix *C,
1590 				     gretl_matrix *B,
1591 				     gretl_matrix *W)
1592 {
1593     gretl_matrix_qform(C, GRETL_MOD_NONE,
1594 		       W, B, GRETL_MOD_NONE);
1595     gretl_matrix_copy_values(W, B);
1596 
1597     return gretl_invert_symmetric_matrix(W);
1598 }
1599 
odell_feiveson_compute(gretl_matrix * W,double * Z,int v)1600 static void odell_feiveson_compute (gretl_matrix *W,
1601 				    double *Z,
1602 				    int v)
1603 {
1604     double Xi, Zri, Zrj;
1605     double wii, wij;
1606     int p = W->rows;
1607     int i, j, r;
1608 
1609     for (i=0; i<p; i++) {
1610 	gretl_rand_chisq(&Xi, 0, 0, v - i);
1611 	wii = Xi;
1612 	for (r=0; r<i; r++) {
1613 	    Zri = Z[ijton(r, i, p)];
1614 	    wii += Zri * Zri;
1615 	}
1616 	gretl_matrix_set(W, i, i, wii);
1617 	for (j=i+1; j<p; j++) {
1618 	    wij = Z[ijton(i, j, p)] * sqrt(Xi);
1619 	    for (r=0; r<i; r++) {
1620 		Zri = Z[ijton(r, i, p)];
1621 		Zrj = Z[ijton(r, j, p)];
1622 		wij += Zri * Zrj;
1623 	    }
1624 	    gretl_matrix_set(W, i, j, wij);
1625 	    gretl_matrix_set(W, j, i, wij);
1626 	}
1627     }
1628 }
1629 
1630 /**
1631  * inverse_wishart_matrix:
1632  * @S: p x p positive definite scale matrix.
1633  * @v: degrees of freedom.
1634  * @err: location to receive error code.
1635  *
1636  * Computes a draw from the Inverse Wishart distribution
1637  * with @v degrees of freedom, using the method of Odell and
1638  * Feiveson, "A numerical procedure to generate a sample
1639  * covariance matrix", JASA 61, pp. 199­203, 1966.
1640  *
1641  * Returns: a p x p Inverse Wishart matrix, or NULL on error.
1642  */
1643 
inverse_wishart_matrix(const gretl_matrix * S,int v,int * err)1644 gretl_matrix *inverse_wishart_matrix (const gretl_matrix *S,
1645 				      int v, int *err)
1646 {
1647     gretl_matrix *C, *B = NULL, *W = NULL;
1648     double *Z = NULL;
1649 
1650     if (S == NULL || S->cols != S->rows || v < S->rows) {
1651 	*err = E_INVARG;
1652 	return NULL;
1653     }
1654 
1655     *err = 0;
1656 
1657     /* copy, invert and decompose S */
1658     C = cholesky_factor_of_inverse(S, err);
1659 
1660     if (!*err) {
1661 	*err = wishart_workspace(&W, &B, &Z, S->rows);
1662     }
1663 
1664     if (*err) {
1665 	gretl_matrix_free(C);
1666 	return NULL;
1667     }
1668 
1669     odell_feiveson_compute(W, Z, v);
1670     *err = wishart_inverse_finalize(C, B, W);
1671 
1672     if (*err) {
1673 	gretl_matrix_free(W);
1674 	W = NULL;
1675     }
1676 
1677     gretl_matrix_free(B);
1678     gretl_matrix_free(C);
1679     free(Z);
1680 
1681     return W;
1682 }
1683 
vech_into_row(gretl_matrix * targ,int row,const gretl_matrix * m)1684 static void vech_into_row (gretl_matrix *targ, int row,
1685 			   const gretl_matrix *m)
1686 {
1687     double mij;
1688     int n = m->rows;
1689     int i, j, jj = 0;
1690 
1691     for (i=0; i<n; i++) {
1692 	for (j=i; j<n; j++) {
1693 	    mij = gretl_matrix_get(m, i, j);
1694 	    gretl_matrix_set(targ, row, jj++, mij);
1695 	}
1696     }
1697 }
1698 
inverse_wishart_sequence(const gretl_matrix * S,int v,int replics,int * err)1699 gretl_matrix *inverse_wishart_sequence (const gretl_matrix *S,
1700 					int v, int replics,
1701 					int *err)
1702 {
1703     gretl_matrix *C, *B = NULL, *W = NULL;
1704     gretl_matrix *Seq = NULL;
1705     double *Z = NULL;
1706     int k, np = 0;
1707 
1708     if (S == NULL || S->cols != S->rows || v < S->rows) {
1709 	*err = E_INVARG;
1710 	return NULL;
1711     }
1712 
1713     if (replics < 1) {
1714 	*err = E_INVARG;
1715 	return NULL;
1716     }
1717 
1718     *err = 0;
1719 
1720     /* copy, invert and decompose S */
1721     C = cholesky_factor_of_inverse(S, err);
1722 
1723     if (!*err) {
1724 	*err = wishart_workspace(&W, &B, &Z, S->rows);
1725     }
1726 
1727     if (!*err) {
1728 	int p = S->rows;
1729 
1730 	np = p * (p + 1) / 2;
1731 	Seq = gretl_matrix_alloc(replics, np);
1732 	if (Seq == NULL) {
1733 	    *err = E_ALLOC;
1734 	}
1735     }
1736 
1737     for (k=0; k<replics && !*err; k++) {
1738 	odell_feiveson_compute(W, Z, v);
1739 	*err = wishart_inverse_finalize(C, B, W);
1740         if (!*err) {
1741 	    /* write vech of W into row k of Seq */
1742 	    vech_into_row(Seq, k, W);
1743 	    if (k < replics - 1) {
1744 		/* refresh Normal draws */
1745 		gretl_rand_normal(Z, 0, np - 1);
1746 	    }
1747 	}
1748     }
1749 
1750     gretl_matrix_free(C);
1751     gretl_matrix_free(W);
1752     gretl_matrix_free(B);
1753     free(Z);
1754 
1755     if (*err && Seq != NULL) {
1756 	gretl_matrix_free(Seq);
1757 	Seq = NULL;
1758     }
1759 
1760     return Seq;
1761 }
1762