3 * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth
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 (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 /* Modified by: Brian Gough, 12/2000 */
23 /* This is an implementation of the adaptive Monte-Carlo algorithm
24 of G. P. Lepage, originally described in J. Comp. Phys. 27, 192(1978).
25 The current version of the algorithm was described in the Cornell
26 preprint CLNS-80/447 of March, 1980.
28 This code follows most closely the c version by D.R.Yennie, coded
31 The input coordinates are x[j], with upper and lower limits xu[j]
32 and xl[j]. The integration length in the j-th direction is
33 delx[j]. Each coordinate x[j] is rescaled to a variable y[j] in
34 the range 0 to 1. The range is divided into bins with boundaries
35 xi[i][j], where i=0 corresponds to y=0 and i=bins to y=1. The grid
36 is refined (ie, bins are adjusted) using d[i][j] which is some
37 variation on the squared sum. A third parameter used in defining
38 the real coordinate using random numbers is called z. It ranges
39 from 0 to bins. Its integer part gives the lower index of the bin
40 into which a call is to be placed, and the remainder gives the
41 location inside the bin.
43 When stratified sampling is used the bins are grouped into boxes,
44 and the algorithm allocates an equal number of function calls to
47 The variable alpha controls how "stiff" the rebinning algorithm is.
48 alpha = 0 means never change the grid. Alpha is typically set between
53 /* configuration headers */
56 /* standard headers */
61 #include <gsl/gsl_math.h>
62 #include <gsl/gsl_errno.h>
63 #include <gsl/gsl_rng.h>
64 #include <gsl/gsl_monte_vegas.h>
66 /* lib-specific headers */
67 #define BINS_MAX 50 /* even integer, will be divided by two */
69 /* A separable grid with coordinates and values */
70 #define COORD(s,i,j) ((s)->xi[(i)*(s)->dim + (j)])
71 #define NEW_COORD(s,i) ((s)->xin[(i)])
72 #define VALUE(s,i,j) ((s)->d[(i)*(s)->dim + (j)])
74 /* predeclare functions */
78 static void init_grid (gsl_monte_vegas_state * s, double xl[], double xu[],
80 static void reset_grid_values (gsl_monte_vegas_state * s);
81 static void init_box_coord (gsl_monte_vegas_state * s, coord box[]);
82 static int change_box_coord (gsl_monte_vegas_state * s, coord box[]);
83 static void accumulate_distribution (gsl_monte_vegas_state * s, coord bin[],
85 static void random_point (double x[], coord bin[], double *bin_vol,
87 const double xl[], const double xu[],
88 gsl_monte_vegas_state * s, gsl_rng * r);
89 static void resize_grid (gsl_monte_vegas_state * s, unsigned int bins);
90 static void refine_grid (gsl_monte_vegas_state * s);
92 static void print_lim (gsl_monte_vegas_state * state,
93 double xl[], double xu[], unsigned long dim);
94 static void print_head (gsl_monte_vegas_state * state,
95 unsigned long num_dim, unsigned long calls,
97 unsigned int bins, unsigned int boxes);
98 static void print_res (gsl_monte_vegas_state * state,
99 unsigned int itr, double res, double err,
100 double cum_res, double cum_err,
102 static void print_dist (gsl_monte_vegas_state * state, unsigned long dim);
103 static void print_grid (gsl_monte_vegas_state * state, unsigned long dim);
106 gsl_monte_vegas_integrate (gsl_monte_function * f,
107 double xl[], double xu[],
108 size_t dim, size_t calls,
110 gsl_monte_vegas_state * state,
111 double *result, double *abserr)
113 double cum_int, cum_sig;
116 if (dim != state->dim)
118 GSL_ERROR ("number of dimensions must match allocated size", GSL_EINVAL);
121 for (i = 0; i < dim; i++)
125 GSL_ERROR ("xu must be greater than xl", GSL_EINVAL);
128 if (xu[i] - xl[i] > GSL_DBL_MAX)
130 GSL_ERROR ("Range of integration is too large, please rescale",
135 if (state->stage == 0)
137 init_grid (state, xl, xu, dim);
139 if (state->verbose >= 0)
141 print_lim (state, xl, xu, dim);
145 if (state->stage <= 1)
147 state->wtd_int_sum = 0;
154 if (state->stage <= 2)
156 unsigned int bins = state->bins_max;
157 unsigned int boxes = 1;
159 if (state->mode != GSL_VEGAS_MODE_IMPORTANCE_ONLY)
161 /* shooting for 2 calls/box */
163 boxes = floor (pow (calls / 2.0, 1.0 / dim));
164 state->mode = GSL_VEGAS_MODE_IMPORTANCE;
166 if (2 * boxes >= state->bins_max)
168 /* if bins/box < 2 */
169 int box_per_bin = GSL_MAX (boxes / state->bins_max, 1);
171 bins = GSL_MIN(boxes / box_per_bin, state->bins_max);
172 boxes = box_per_bin * bins;
174 state->mode = GSL_VEGAS_MODE_STRATIFIED;
179 double tot_boxes = pow ((double) boxes, (double) dim);
180 state->calls_per_box = GSL_MAX (calls / tot_boxes, 2);
181 calls = state->calls_per_box * tot_boxes;
184 /* total volume of x-space/(avg num of calls/bin) */
185 state->jac = state->vol * pow ((double) bins, (double) dim) / calls;
187 state->boxes = boxes;
189 /* If the number of bins changes from the previous invocation, bins
190 are expanded or contracted accordingly, while preserving bin
193 if (bins != state->bins)
195 resize_grid (state, bins);
197 if (state->verbose > 1)
199 print_grid (state, dim);
203 if (state->verbose >= 0)
206 dim, calls, state->it_num, state->bins, state->boxes);
210 state->it_start = state->it_num;
217 for (it = 0; it < state->iterations; it++)
219 double intgrl = 0.0, intgrl_sq = 0.0;
222 size_t calls_per_box = state->calls_per_box;
223 double jacbin = state->jac;
224 double *x = state->x;
225 coord *bin = state->bin;
227 state->it_num = state->it_start + it;
229 reset_grid_values (state);
230 init_box_coord (state, state->box);
235 double f_sq_sum = 0.0;
237 for (k = 0; k < calls_per_box; k++)
239 double fval, bin_vol;
241 random_point (x, bin, &bin_vol, state->box, xl, xu, state, r);
243 fval = jacbin * bin_vol * GSL_MONTE_FN_EVAL (f, x);
245 /* recurrence for mean and variance */
250 q += d * d * (k / (k + 1.0));
253 if (state->mode != GSL_VEGAS_MODE_STRATIFIED)
255 double f_sq = fval * fval;
256 accumulate_distribution (state, bin, f_sq);
260 intgrl += m * calls_per_box;
262 f_sq_sum = q * calls_per_box ;
266 if (state->mode == GSL_VEGAS_MODE_STRATIFIED)
268 accumulate_distribution (state, bin, f_sq_sum);
271 while (change_box_coord (state, state->box));
273 /* Compute final results for this iteration */
275 sig = sig / (calls_per_box - 1.0) ;
281 else if (state->sum_wgts > 0)
283 wgt = state->sum_wgts / state->samples;
290 intgrl_sq = intgrl * intgrl;
292 state->result = intgrl;
293 state->sigma = sqrt(sig);
298 state->sum_wgts += wgt;
299 state->wtd_int_sum += intgrl * wgt;
300 state->chi_sum += intgrl_sq * wgt;
302 cum_int = state->wtd_int_sum / state->sum_wgts;
303 cum_sig = sqrt (1 / state->sum_wgts);
305 if (state->samples > 1)
307 state->chisq = (state->chi_sum - state->wtd_int_sum * cum_int) /
308 (state->samples - 1.0);
313 cum_int += (intgrl - cum_int) / (it + 1.0);
318 if (state->verbose >= 0)
321 state->it_num, intgrl, sqrt (sig), cum_int, cum_sig,
323 if (it + 1 == state->iterations && state->verbose > 0)
325 print_grid (state, dim);
329 if (state->verbose > 1)
331 print_dist (state, dim);
336 if (state->verbose > 1)
338 print_grid (state, dim);
343 /* By setting stage to 1 further calls will generate independent
344 estimates based on the same grid, although it may be rebinned. */
356 gsl_monte_vegas_state *
357 gsl_monte_vegas_alloc (size_t dim)
359 gsl_monte_vegas_state *s =
360 (gsl_monte_vegas_state *) malloc (sizeof (gsl_monte_vegas_state));
364 GSL_ERROR_VAL ("failed to allocate space for vegas state struct",
368 s->delx = (double *) malloc (dim * sizeof (double));
373 GSL_ERROR_VAL ("failed to allocate space for delx", GSL_ENOMEM, 0);
376 s->d = (double *) malloc (BINS_MAX * dim * sizeof (double));
382 GSL_ERROR_VAL ("failed to allocate space for d", GSL_ENOMEM, 0);
385 s->xi = (double *) malloc ((BINS_MAX + 1) * dim * sizeof (double));
392 GSL_ERROR_VAL ("failed to allocate space for xi", GSL_ENOMEM, 0);
395 s->xin = (double *) malloc ((BINS_MAX + 1) * sizeof (double));
403 GSL_ERROR_VAL ("failed to allocate space for xin", GSL_ENOMEM, 0);
406 s->weight = (double *) malloc (BINS_MAX * sizeof (double));
415 GSL_ERROR_VAL ("failed to allocate space for xin", GSL_ENOMEM, 0);
418 s->box = (coord *) malloc (dim * sizeof (coord));
428 GSL_ERROR_VAL ("failed to allocate space for box", GSL_ENOMEM, 0);
431 s->bin = (coord *) malloc (dim * sizeof (coord));
442 GSL_ERROR_VAL ("failed to allocate space for bin", GSL_ENOMEM, 0);
445 s->x = (double *) malloc (dim * sizeof (double));
457 GSL_ERROR_VAL ("failed to allocate space for x", GSL_ENOMEM, 0);
461 s->bins_max = BINS_MAX;
463 gsl_monte_vegas_init (s);
468 /* Set some default values and whatever */
470 gsl_monte_vegas_init (gsl_monte_vegas_state * state)
475 state->iterations = 5;
476 state->mode = GSL_VEGAS_MODE_IMPORTANCE;
478 state->bins = state->bins_max;
479 state->ostream = stdout;
485 gsl_monte_vegas_free (gsl_monte_vegas_state * s)
499 init_box_coord (gsl_monte_vegas_state * s, coord box[])
505 for (i = 0; i < dim; i++)
511 /* change_box_coord steps through the box coord like
512 {0,0}, {0, 1}, {0, 2}, {0, 3}, {1, 0}, {1, 1}, {1, 2}, ...
515 change_box_coord (gsl_monte_vegas_state * s, coord box[])
523 box[j] = (box[j] + 1) % ng;
537 init_grid (gsl_monte_vegas_state * s, double xl[], double xu[], size_t dim)
545 for (j = 0; j < dim; j++)
547 double dx = xu[j] - xl[j];
551 COORD (s, 0, j) = 0.0;
552 COORD (s, 1, j) = 1.0;
560 reset_grid_values (gsl_monte_vegas_state * s)
565 size_t bins = s->bins;
567 for (i = 0; i < bins; i++)
569 for (j = 0; j < dim; j++)
571 VALUE (s, i, j) = 0.0;
577 accumulate_distribution (gsl_monte_vegas_state * s, coord bin[], double y)
582 for (j = 0; j < dim; j++)
585 VALUE (s, i, j) += y;
590 random_point (double x[], coord bin[], double *bin_vol,
591 const coord box[], const double xl[], const double xu[],
592 gsl_monte_vegas_state * s, gsl_rng * r)
594 /* Use the random number generator r to return a random position x
595 in a given box. The value of bin gives the bin location of the
596 random position (there may be several bins within a given box) */
603 size_t bins = s->bins;
604 size_t boxes = s->boxes;
606 DISCARD_POINTER(xu); /* prevent warning about unused parameter */
608 for (j = 0; j < dim; ++j)
610 /* box[j] + ran gives the position in the box units, while z
611 is the position in bin units. */
613 double z = ((box[j] + gsl_rng_uniform_pos (r)) / boxes) * bins;
623 bin_width = COORD (s, 1, j);
628 bin_width = COORD (s, k + 1, j) - COORD (s, k, j);
629 y = COORD (s, k, j) + (z - k) * bin_width;
632 x[j] = xl[j] + y * s->delx[j];
642 resize_grid (gsl_monte_vegas_state * s, unsigned int bins)
647 /* weight is ratio of bin sizes */
649 double pts_per_bin = (double) s->bins / (double) bins;
651 for (j = 0; j < dim; j++)
658 for (k = 1; k <= s->bins; k++)
662 xnew = COORD (s, k, j);
664 for (; dw > pts_per_bin; i++)
667 NEW_COORD (s, i) = xnew - (xnew - xold) * dw;
671 for (k = 1 ; k < bins; k++)
673 COORD(s, k, j) = NEW_COORD(s, k);
676 COORD (s, bins, j) = 1;
683 refine_grid (gsl_monte_vegas_state * s)
687 size_t bins = s->bins;
689 for (j = 0; j < dim; j++)
691 double grid_tot_j, tot_weight;
692 double * weight = s->weight;
694 double oldg = VALUE (s, 0, j);
695 double newg = VALUE (s, 1, j);
697 VALUE (s, 0, j) = (oldg + newg) / 2;
698 grid_tot_j = VALUE (s, 0, j);
700 /* This implements gs[i][j] = (gs[i-1][j]+gs[i][j]+gs[i+1][j])/3 */
702 for (i = 1; i < bins - 1; i++)
704 double rc = oldg + newg;
706 newg = VALUE (s, i + 1, j);
707 VALUE (s, i, j) = (rc + newg) / 3;
708 grid_tot_j += VALUE (s, i, j);
710 VALUE (s, bins - 1, j) = (newg + oldg) / 2;
712 grid_tot_j += VALUE (s, bins - 1, j);
716 for (i = 0; i < bins; i++)
720 if (VALUE (s, i, j) > 0)
722 oldg = grid_tot_j / VALUE (s, i, j);
724 weight[i] = pow (((oldg - 1) / oldg / log (oldg)), s->alpha);
727 tot_weight += weight[i];
730 printf("weight[%d] = %g\n", i, weight[i]);
735 double pts_per_bin = tot_weight / bins;
742 for (k = 0; k < bins; k++)
746 xnew = COORD (s, k + 1, j);
748 for (; dw > pts_per_bin; i++)
751 NEW_COORD (s, i) = xnew - (xnew - xold) * dw / weight[k];
755 for (k = 1 ; k < bins ; k++)
757 COORD(s, k, j) = NEW_COORD(s, k);
760 COORD (s, bins, j) = 1;
767 print_lim (gsl_monte_vegas_state * state,
768 double xl[], double xu[], unsigned long dim)
772 fprintf (state->ostream, "The limits of integration are:\n");
773 for (j = 0; j < dim; ++j)
774 fprintf (state->ostream, "\nxl[%lu]=%f xu[%lu]=%f", j, xl[j], j, xu[j]);
775 fprintf (state->ostream, "\n");
776 fflush (state->ostream);
780 print_head (gsl_monte_vegas_state * state,
781 unsigned long num_dim, unsigned long calls,
782 unsigned int it_num, unsigned int bins, unsigned int boxes)
784 fprintf (state->ostream,
785 "\nnum_dim=%lu, calls=%lu, it_num=%d, max_it_num=%d ",
786 num_dim, calls, it_num, state->iterations);
787 fprintf (state->ostream,
788 "verb=%d, alph=%.2f,\nmode=%d, bins=%d, boxes=%d\n",
789 state->verbose, state->alpha, state->mode, bins, boxes);
790 fprintf (state->ostream,
791 "\n single.......iteration ");
792 fprintf (state->ostream, "accumulated......results \n");
794 fprintf (state->ostream,
795 "iteration integral sigma integral ");
796 fprintf (state->ostream, " sigma chi-sq/it\n\n");
797 fflush (state->ostream);
802 print_res (gsl_monte_vegas_state * state,
804 double res, double err,
805 double cum_res, double cum_err,
808 fprintf (state->ostream,
809 "%4d %6.4e %10.2e %6.4e %8.2e %10.2e\n",
810 itr, res, err, cum_res, cum_err, chi_sq);
811 fflush (state->ostream);
815 print_dist (gsl_monte_vegas_state * state, unsigned long dim)
818 int p = state->verbose;
822 for (j = 0; j < dim; ++j)
824 fprintf (state->ostream, "\n axis %lu \n", j);
825 fprintf (state->ostream, " x g\n");
826 for (i = 0; i < state->bins; i++)
828 fprintf (state->ostream, "weight [%11.2e , %11.2e] = ",
829 COORD (state, i, j), COORD(state,i+1,j));
830 fprintf (state->ostream, " %11.2e\n", VALUE (state, i, j));
833 fprintf (state->ostream, "\n");
835 fprintf (state->ostream, "\n");
836 fflush (state->ostream);
841 print_grid (gsl_monte_vegas_state * state, unsigned long dim)
844 int p = state->verbose;
848 for (j = 0; j < dim; ++j)
850 fprintf (state->ostream, "\n axis %lu \n", j);
851 fprintf (state->ostream, " x \n");
852 for (i = 0; i <= state->bins; i++)
854 fprintf (state->ostream, "%11.2e", COORD (state, i, j));
856 fprintf (state->ostream, "\n");
858 fprintf (state->ostream, "\n");
860 fprintf (state->ostream, "\n");
861 fflush (state->ostream);