42 #ifndef O2SCL_MCARLO_VEGAS_H
43 #define O2SCL_MCARLO_VEGAS_H
51 #include <gsl/gsl_math.h>
52 #include <gsl/gsl_monte.h>
53 #include <gsl/gsl_machine.h>
54 #include <gsl/gsl_monte_vegas.h>
56 #include <o2scl/mcarlo.h>
58 #ifndef DOXYGEN_NO_O2NS
114 class rng_t=int,
class rng_dist_t=rng_gsl>
128 static const int mode_importance=1;
129 static const int mode_importance_only=0;
130 static const int mode_stratified=-1;
162 #ifndef DOXYGEN_INTERNAL
216 for (i=0;i<
dim;i++) {
238 boxt[j]=(boxt[j]+1) % ng;
250 virtual void init_grid(
const vec_t &xl,
const vec_t &xu,
size_t ldim) {
255 for (j=0;j<ldim;j++) {
256 double dx=xu[j]-xl[j];
271 for (i=0;i<
bins;i++) {
272 for (j=0;j<
dim;j++) {
287 for (j=0;j<
dim;j++) {
311 for (j=0;j<
dim;++j) {
333 bin_width=
xi[(k+1)*dim+j]-
xi[k*dim+j];
334 y=
xi[k*dim+j]+(z-k)*bin_width;
337 lx[j]=xl[j]+y*
delx[j];
353 double pts_per_bin=(double)
bins/(
double) lbins;
355 for (j=0;j<
dim;j++) {
361 for (k=1;k <=
bins;k++) {
366 for (;dw > pts_per_bin;i++) {
368 (
xin[i])=xnew-(xnew-xold)*dw;
372 for (k=1 ;k<lbins;k++) {
389 for (j=0;j<
dim;j++) {
390 double grid_tot_j, tot_weight;
393 double newg=
d[dim+j];
400 for (i=1;i<
bins-1;i++) {
404 d[i*dim+j]=(rc+newg)/3;
405 grid_tot_j+=d[i*dim+j];
407 d[(bins-1)*dim+j]=(newg+oldg)/2;
409 grid_tot_j+=
d[(bins-1)*dim+j];
413 for (i=0;i<
bins;i++) {
416 if (
d[i*dim+j] > 0) {
417 oldg=grid_tot_j/
d[i*dim+j];
426 double pts_per_bin=tot_weight/
bins;
433 for (k=0;k<
bins;k++) {
436 xnew=
xi[(k+1)*dim+j];
438 for (;dw > pts_per_bin;i++) {
444 for (k=1 ;k<
bins ;k++) {
455 virtual void print_lim(
const vec_t &xl,
const vec_t &xu,
456 unsigned long ldim) {
460 (*outs) <<
"The limits of integration are:\n" << std::endl;
461 for (j=0;j<ldim;++j) {
462 (*outs) <<
"xl[" << j <<
"]=" << xl[j] <<
" xu[" << j
463 <<
"]=" << xu[j] << std::endl;
465 (*outs) << std::endl;
471 virtual void print_head(
unsigned long num_dim,
unsigned long calls,
472 unsigned int lit_num,
unsigned int lbins,
473 unsigned int lboxes) {
475 (*outs) <<
"num_dim=" << num_dim <<
", calls=" << calls
476 <<
", it_num=" << lit_num <<
", max_it_num="
478 <<
",\n mode=" << mode <<
", boxes=" << lboxes
479 <<
"\n\n single.......iteration "
480 <<
"accumulated......results\n"
481 <<
"iter integral sigma integral "
482 <<
" sigma chi-sq/it" << std::endl;
489 double err,
double cum_res,
double cum_err,
491 (*outs).precision(5);
492 (*outs) << itr <<
" ";
493 outs->setf(std::ios::showpos);
494 (*outs) << res <<
" ";
495 outs->unsetf(std::ios::showpos);
496 (*outs) << err <<
" ";
497 outs->setf(std::ios::showpos);
498 (*outs) << cum_res <<
" ";
499 outs->unsetf(std::ios::showpos);
500 (*outs) << cum_err <<
" " << chi_sq << std::endl;
501 (*outs).precision(6);
513 for (j=0;j<ldim;++j) {
514 (*outs) <<
"\n Axis " << j << std::endl;
515 (*outs) <<
" x g" << std::endl;
516 outs->setf(std::ios::showpos);
517 for (i=0;i<
bins;i++) {
518 (*outs) <<
"weight [ " << (
xi[(i)*
dim+(j)]) <<
" , "
519 <<
xi[(i+1)*
dim+j] <<
" ] = ";
520 (*outs) <<
" " << (
d[(i)*
dim+(j)]) << std::endl;
522 outs->unsetf(std::ios::showpos);
523 (*outs) << std::endl;
525 (*outs) << std::endl;
537 for (j=0;j<ldim;++j) {
538 (*outs) <<
"\n Axis " << j << std::endl;
539 (*outs) <<
" x " << std::endl;
540 outs->setf(std::ios::showpos);
541 for (i=0;i <=
bins;i++) {
542 (*outs) << (
xi[(i)*
dim+(j)]) <<
" ";
544 (*outs) << std::endl;
547 (*outs) << std::endl;
548 outs->unsetf(std::ios::showpos);
550 (*outs) << std::endl;
566 mode=mode_importance;
611 const vec_t &xl,
const vec_t &xu,
612 double &res,
double &err) {
616 double cum_int, cum_sig;
619 for (i=0;i<
dim;i++) {
620 if (xu[i] <= xl[i]) {
621 std::string serr=
"Upper limit, "+
dtos(xu[i])+
", must be greater "+
622 "than lower limit, "+
dtos(xl[i])+
", in mcarlo_vegas::"+
623 "vegas_minteg_err().";
627 if (xu[i]-xl[i] > GSL_DBL_MAX) {
628 O2SCL_ERR2(
"Range of integration is too large, please rescale ",
629 "in mcarlo_vegas::vegas_minteg_err().",
exc_einval);
652 unsigned int lboxes=1;
654 if (mode != mode_importance_only) {
663 lboxes=((
unsigned int)(floor(pow(calls/2.0,1.0/dim))));
664 mode=mode_importance;
668 int box_per_bin=GSL_MAX(lboxes/
bins_max,1);
670 if (lboxes/box_per_bin<
bins_max) lbins=lboxes/box_per_bin;
672 lboxes=box_per_bin*lbins;
674 mode=mode_stratified;
680 double tot_boxes=pow((
double)lboxes,(
double)dim);
685 jac=
vol*pow((
double) lbins, (
double) dim)/calls;
709 double intgrl=0.0, intgrl_sq=0.0;
711 double wgt, var, sig;
721 volatile double m=0, q=0;
724 for (k=0;k<lcalls_per_box;k++) {
725 double fval, bin_vol;
730 fval*=jacbin*bin_vol;
737 q+=dt*dt*(k/(k+1.0));
740 if (mode != mode_stratified) {
741 double f_sq=fval*fval;
746 intgrl+=m*lcalls_per_box;
748 f_sq_sum=q*lcalls_per_box;
752 if (mode == mode_stratified) {
760 var=tss/(lcalls_per_box-1.0);
764 }
else if (sum_wgts>0) {
770 intgrl_sq=intgrl*intgrl;
778 double lsum_wgts=sum_wgts;
779 double m=(sum_wgts > 0) ? (wtd_int_sum/sum_wgts) : 0;
784 wtd_int_sum+=intgrl*wgt;
785 chi_sum+=intgrl_sq*wgt;
787 cum_int= wtd_int_sum/sum_wgts;
788 cum_sig=sqrt(1/sum_wgts);
804 chisq+=(wgt/(1+(wgt/lsum_wgts)))*q*q;
809 cum_int+=(intgrl-cum_int)/(it+1.0);
815 if (it+1 == iterations && this->
verbose > 1) {
847 virtual int minteg_err(func_t &func,
size_t ndim,
const vec_t &a,
848 const vec_t &b,
double &res,
double &err) {
860 virtual double minteg(func_t &func,
size_t ndim,
const vec_t &a,
868 virtual const char *
type() {
return "mcarlo_vegas"; }
872 #ifndef DOXYGEN_NO_O2NS
virtual int vegas_minteg_err(int stage, func_t &func, size_t ndim, const vec_t &xl, const vec_t &xu, double &res, double &err)
Integrate function func from x=a to x=b.
ubvector_int bin
The bins for each direction.
virtual void print_head(unsigned long num_dim, unsigned long calls, unsigned int lit_num, unsigned int lbins, unsigned int lboxes)
Print header.
rng_dist_t rng_dist
The random number distribution.
invalid argument supplied by user
vec_t x
Point for function evaluation.
unsigned long n_points
Number of integration points (default 1000)
virtual double minteg(func_t &func, size_t ndim, const vec_t &a, const vec_t &b)
Integrate function func over the hypercube from to for ndim-1.
virtual void resize_grid(unsigned int lbins)
Resize the grid.
size_t dim
Number of dimensions.
unsigned int it_num
The total number of iterations.
double alpha
The stiffness of the rebinning algorithm (default 1.5)
ubvector_int box
The boxes for each direction.
unsigned int calls_per_box
Number of function calls per box.
virtual const char * type()
Return string denoting type ("mcarlo_vegas")
unsigned int iterations
Set the number of iterations (default 5)
virtual void init_grid(const vec_t &xl, const vec_t &xu, size_t ldim)
Initialize grid.
rng_t rng
The random number generator.
virtual void print_res(unsigned int itr, double res, double err, double cum_res, double cum_err, double chi_sq)
Print results.
ubvector xin
Storage for grid refinement.
void random_point(vec_t &lx, ubvector_int &lbin, double &bin_vol, const ubvector_int &lbox, const vec_t &xl, const vec_t &xu)
Generate a random position in a given box.
virtual void print_grid(unsigned long ldim)
Print grid.
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
std::string dtos(double x, int prec=6, bool auto_prec=false)
Convert a double to a string.
unsigned int bins
Number of bins.
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
Monte-Carlo integration [abstract base].
double vol
The volume of the current bin.
ubvector weight
The weight for each bin.
virtual int minteg_err(func_t &func, size_t ndim, const vec_t &a, const vec_t &b, double &res, double &err)
Integrate function func from x=a to x=b.
ubvector delx
The iteration length in each direction.
ubvector xi
Boundaries for each bin.
std::ostream * outs
The output stream to send output information (default std::cout)
static const size_t bins_max
Maximum number of bins.
double sigma
Uncertainty from last iteration.
virtual void reset_grid_values()
Reset grid values.
double interror
The uncertainty for the last integration computation.
virtual void refine_grid()
Refine the grid.
Multidimensional integration using Vegas Monte Carlo (GSL)
unsigned int samples
Number of samples for computing chi squared.
virtual int allocate(size_t ldim)
Allocate memory.
unsigned int boxes
Number of boxes.
unsigned int it_start
The starting iteration number.
int change_box_coord(ubvector_int &boxt)
Change box coordinates.
virtual void print_dist(unsigned long ldim)
Print distribution.
virtual void print_lim(const vec_t &xl, const vec_t &xu, unsigned long ldim)
Print limits of integration.
void accumulate_distribution(ubvector_int &lbin, double y)
Add the most recently generated result to the distribution.
double chisq
The chi-squared per degree of freedom for the weighted estimate of the integral.
std::function< double(size_t, const boost::numeric::ublas::vector< double > &)> multi_funct11
Multi-dimensional function typedef.
virtual void init_box_coord(ubvector_int &boxt)
Initialize box coordinates.
double result
Result from last iteration.