42 #ifndef O2SCL_MCARLO_MISER_H
43 #define O2SCL_MCARLO_MISER_H
50 #include <boost/numeric/ublas/vector.hpp>
52 #include <o2scl/misc.h>
53 #include <o2scl/mcarlo.h>
55 #include <gsl/gsl_math.h>
56 #include <gsl/gsl_monte.h>
57 #include <gsl/gsl_machine.h>
58 #include <gsl/gsl_monte_miser.h>
60 #ifndef DOXYGEN_NO_O2NS
93 class rng_t=int,
class rng_dist_t=rng_gsl>
208 #ifndef DOXYGEN_INTERNAL
257 const vec_t &xl,
const vec_t &xu,
258 size_t calls,
double &res,
266 for (i=0;i<
dim;i++) {
271 lsigma_l[i]=lsigma_r[i]=-1;
274 for (n=0;n<calls;n++) {
277 unsigned int j=(n/2) % dim;
278 unsigned int side=(n % 2);
280 for (i=0;i<
dim;i++) {
289 x[i]=xl[i]+z*(xu[i]-xl[i]);
292 x[i]=lxmid[i]+z*(xu[i]-lxmid[i]);
294 x[i]=xl[i]+z*(lxmid[i]-xl[i]);
309 for (i=0;i<
dim;i++) {
310 if (
x[i] <= lxmid[i]) {
322 for (i=0;i<
dim;i++) {
323 double fraction_l=(lxmid[i]-xl[i])/(xu[i]-xl[i]);
328 lsigma_l[i]*=fraction_l*vol/
hits_l[i];
334 lsigma_r[i]*=(1-fraction_l)*vol/
hits_r[i];
343 err=vol*sqrt(q/(calls*(calls-1.0)));
412 const vec_t &xu,
size_t calls,
size_t level,
413 double &res,
double &err) {
416 O2SCL_ERR2(
"Variables min_calls or min_calls_per_bisection ",
417 "are zero in mcarlo_miser::miser_minteg_err().",
421 size_t n, estimate_calls, calls_l, calls_r;
426 double res_est=0, err_est=0;
427 double res_r=0, err_r=0, res_l=0, err_l=0;
428 double xbi_l, xbi_m, xbi_r, s;
431 double weight_l, weight_r;
433 for (i=0;i<
dim;i++) {
434 if (xu[i] <= xl[i]) {
435 std::string str=
"Upper limit, "+
dtos(xu[i])+
", must be greater "+
436 "than lower limit, "+
dtos(xl[i])+
", in mcarlo_miser::"+
437 "miser_minteg_err().";
440 if (xu[i]-xl[i]>GSL_DBL_MAX) {
441 O2SCL_ERR2(
"Range of integration is too large ",
442 "in mcarlo_miser::miser_minteg_err().",
exc_einval);
447 std::string str=
"Parameter alpha, "+
dtos(
alpha)+
", must be non-"+
448 "negative in mcarlo_miser::mister_minteg_err().";
456 for (i=0;i<
dim;i++) {
464 O2SCL_ERR2(
"Insufficient calls for subvolume ",
465 "in mcarlo_miser::miser_minteg_err().",
exc_einval);
468 for (n=0;n<calls;n++) {
471 for (i=0;i<
dim;i++) {
479 x[i]=xl[i]+rdn*(xu[i]-xl[i]);
496 err=vol*sqrt(q/(calls*(calls-1.0)));
506 if (estimate_calls<4*dim) {
507 O2SCL_ERR2(
"Insufficient calls to sample all halfspaces ",
508 "in mcarlo_miser::miser_minteg_err().",
exc_esanity);
513 for (i=0;i<
dim;i++) {
515 xmid[i]=(0.5+s)*xl[i]+(0.5-s)*xu[i];
530 calls -= estimate_calls;
535 double best_var=GSL_DBL_MAX;
536 double beta=2.0/(1.0+
alpha);
539 weight_l=weight_r=1.0;
541 for (i=0;i<
dim;i++) {
546 if (var <= best_var) {
550 weight_l=pow (
sigma_l[i], beta);
551 weight_r=pow (
sigma_r[i], beta);
552 if (weight_l==0 && weight_r==0) {
560 "in mcarlo_miser::miser_minteg_err().",
565 "in mcarlo_miser::miser_minteg_err().",
575 i_bisect=((int)(this->
rng_dist(this->
rng)*(dim-1.0e-10)));
583 xbi_m=
xmid[i_bisect];
589 double fraction_l=fabs ((xbi_m-xbi_l)/(xbi_r-xbi_l));
590 double fraction_r=1-fraction_l;
592 double a=fraction_l*weight_l;
593 double b=fraction_r*weight_r;
600 std::cout <<
"mcarlo_miser: level,calls_l,calls_r,calls,min_calls_pb: "
601 << level <<
" " << calls_l <<
" " << calls_r <<
" " << calls <<
" "
603 std::cout <<
"\tres,err: " << res_est <<
" " << err_est << std::endl;
605 std::cout <<
"\ti,left,mid,right: " << i_bisect <<
" "
606 << xbi_l <<
" " << xbi_m <<
" " << xbi_r << std::endl;
607 for(
size_t j=0;j<
dim;j++) {
608 std::cout <<
"\t\ti,low,high: " << j <<
" " << xl[j] <<
" " << xu[j]
628 for (i=0;i<
dim;i++) {
632 xu_tmp[i_bisect]=xbi_m;
649 for (i=0;i<
dim;i++) {
653 xl_tmp[i_bisect]=xbi_m;
664 err=sqrt(err_l*err_l+err_r*err_r);
676 virtual int minteg_err(func_t &func,
size_t ndim,
const vec_t &a,
677 const vec_t &b,
double &res,
double &err) {
699 virtual double minteg(func_t &func,
size_t ndim,
const vec_t &a,
707 virtual const char *
type() {
return "mcarlo_miser"; }
711 #ifndef DOXYGEN_NO_O2NS
ubvector_size_t hits_r
The number of evaluation points in the right half.
size_t calls_per_dim
Number of calls per dimension (default 16)
size_t bisection_ratio
Factor to set min_calls_per_bisection (default 32)
ubvector_size_t hits_l
The number of evaluation points in the left half.
rng_dist_t rng_dist
The random number distribution.
sanity check failed - shouldn't happen
invalid argument supplied by user
size_t dim
The number of dimensions of memory allocated.
unsigned long n_points
Number of integration points (default 1000)
ubvector fmin_l
The minimum function value in the left half.
ubvector sigma_r
The right variance.
size_t min_calls
Minimum number of calls to estimate the variance.
virtual int estimate_corrmc(func_t &func, size_t ndim, const vec_t &xl, const vec_t &xu, size_t calls, double &res, double &err, const ubvector &lxmid, ubvector &lsigma_l, ubvector &lsigma_r)
Estimate the variance.
ubvector fmax_l
The maximum function value in the left half.
double estimate_frac
Specify fraction of function calls for estimating variance (default 0.1)
ubvector xmid
The current midpoint.
int set_min_calls_per_bisection(size_t &mcb)
Minimum number of calls required to proceed with bisection.
double alpha
How estimated variances for two sub-regions are combined (default 2.0)
ubvector sigma_l
The left variance.
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.
rng_t rng
The random number generator.
ubvector fsum2_l
The sum of the squares in the left half.
virtual const char * type()
Return string denoting type ("mcarlo_miser")
vec_t x
The most recent integration point.
#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.
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
Monte-Carlo integration [abstract base].
ubvector fsum2_r
The sum of the squares in the right half.
size_t min_calls_per_bisection
Minimum number of calls required to proceed with bisection.
ubvector fsum_l
The sum in the left half.
virtual int allocate(size_t ldim)
Allocate memory.
ubvector fmin_r
The minimum function value in the right half.
size_t n_levels_out
The number of recursive levels to output when verbose is greater than zero (default 5) ...
double interror
The uncertainty for the last integration computation.
Multidimensional integration using the MISER Monte Carlo algorithm (GSL)
int set_min_calls(size_t &mc)
Minimum number of calls to estimate the variance.
ubvector fsum_r
The sum in the right half.
std::function< double(size_t, const boost::numeric::ublas::vector< double > &)> multi_funct11
Multi-dimensional function typedef.
virtual int miser_minteg_err(func_t &func, size_t ndim, const vec_t &xl, const vec_t &xu, size_t calls, size_t level, double &res, double &err)
Integrate function func over the hypercube from to for ndim-1.
ubvector fmax_r
The maximum function value in the right half.
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.
double dither
Introduce random variation into bisection (default 0.0)