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 206 #ifndef DOXYGEN_INTERNAL 255 const vec_t &xl,
const vec_t &xu,
256 size_t calls,
double &res,
257 double &err,
const ubvector &lxmid,
258 ubvector &lsigma_l, ubvector &lsigma_r) {
264 for (i=0;i<
dim;i++) {
266 hits_l[i]=hits_r[i]=0;
267 fsum_l[i]=fsum_r[i]=0.0;
268 fsum2_l[i]=fsum2_r[i]=0.0;
269 lsigma_l[i]=lsigma_r[i]=-1;
272 for (n=0;n<calls;n++) {
275 unsigned int j=(n/2) % dim;
276 unsigned int side=(n % 2);
278 for (i=0;i<
dim;i++) {
287 x[i]=xl[i]+z*(xu[i]-xl[i]);
290 x[i]=lxmid[i]+z*(xu[i]-lxmid[i]);
292 x[i]=xl[i]+z*(lxmid[i]-xl[i]);
307 for (i=0;i<
dim;i++) {
308 if (
x[i] <= lxmid[i]) {
310 fsum2_l[i]+=fval*fval;
314 fsum2_r[i]+=fval*fval;
320 for (i=0;i<
dim;i++) {
321 double fraction_l=(lxmid[i]-xl[i])/(xu[i]-xl[i]);
324 fsum_l[i] /= hits_l[i];
325 lsigma_l[i]=sqrt(fsum2_l[i]-fsum_l[i]*fsum_l[i]/hits_l[i]);
326 lsigma_l[i]*=fraction_l*vol/hits_l[i];
330 fsum_r[i] /= hits_r[i];
331 lsigma_r[i]=sqrt(fsum2_r[i]-fsum_r[i]*fsum_r[i]/hits_r[i]);
332 lsigma_r[i]*=(1-fraction_l)*vol/hits_r[i];
341 err=vol*sqrt(q/(calls*(calls-1.0)));
359 min_calls_per_bisection=3000;
380 sigma_l.resize(ldim);
381 sigma_r.resize(ldim);
388 fsum2_l.resize(ldim);
389 fsum2_r.resize(ldim);
410 const vec_t &xu,
size_t calls,
size_t level,
411 double &res,
double &err) {
413 if (min_calls==0 || min_calls_per_bisection==0) {
414 O2SCL_ERR2(
"Variables min_calls or min_calls_per_bisection ",
415 "are zero in mcarlo_miser::miser_minteg_err().",
419 size_t n, estimate_calls, calls_l, calls_r;
424 double res_est=0, err_est=0;
425 double res_r=0, err_r=0, res_l=0, err_l=0;
426 double xbi_l, xbi_m, xbi_r, s;
429 double weight_l, weight_r;
431 for (i=0;i<
dim;i++) {
432 if (xu[i] <= xl[i]) {
433 std::string str=
"Upper limit, "+
dtos(xu[i])+
", must be greater "+
434 "than lower limit, "+
dtos(xl[i])+
", in mcarlo_miser::"+
435 "miser_minteg_err().";
438 if (xu[i]-xl[i]>GSL_DBL_MAX) {
439 O2SCL_ERR2(
"Range of integration is too large ",
440 "in mcarlo_miser::miser_minteg_err().",
exc_einval);
445 std::string str=
"Parameter alpha, "+
dtos(alpha)+
", must be non-"+
446 "negative in mcarlo_miser::mister_minteg_err().";
454 for (i=0;i<
dim;i++) {
458 if (calls<min_calls_per_bisection) {
462 O2SCL_ERR2(
"Insufficient calls for subvolume ",
463 "in mcarlo_miser::miser_minteg_err().",
exc_einval);
466 for (n=0;n<calls;n++) {
469 for (i=0;i<
dim;i++) {
477 x[i]=xl[i]+rdn*(xu[i]-xl[i]);
494 err=vol*sqrt(q/(calls*(calls-1.0)));
502 estimate_calls=(min_calls > prod ?
min_calls : prod);
504 if (estimate_calls<4*dim) {
505 O2SCL_ERR2(
"Insufficient calls to sample all halfspaces ",
506 "in mcarlo_miser::miser_minteg_err().",
exc_esanity);
511 for (i=0;i<
dim;i++) {
513 xmid[i]=(0.5+s)*xl[i]+(0.5-s)*xu[i];
524 res_est,err_est,xmid,sigma_l,sigma_r);
528 calls -= estimate_calls;
533 double best_var=GSL_DBL_MAX;
534 double beta=2.0/(1.0+
alpha);
537 weight_l=weight_r=1.0;
539 for (i=0;i<
dim;i++) {
540 if (sigma_l[i] >= 0 && sigma_r[i] >= 0) {
542 double var=pow (sigma_l[i], beta)+pow (sigma_r[i], beta);
544 if (var <= best_var) {
548 weight_l=pow (sigma_l[i], beta);
549 weight_r=pow (sigma_r[i], beta);
550 if (weight_l==0 && weight_r==0) {
558 "in mcarlo_miser::miser_minteg_err().",
563 "in mcarlo_miser::miser_minteg_err().",
573 i_bisect=((int)(this->
rng_dist(this->
rng)*(dim-1.0e-10)));
581 xbi_m=xmid[i_bisect];
587 double fraction_l=fabs ((xbi_m-xbi_l)/(xbi_r-xbi_l));
588 double fraction_r=1-fraction_l;
590 double a=fraction_l*weight_l;
591 double b=fraction_r*weight_r;
593 calls_l=(size_t)(min_calls+(calls-2*min_calls)*a/(a+b));
594 calls_r=(size_t)(min_calls+(calls-2*min_calls)*b/(a+b));
597 if (this->
verbose>0 && level<n_levels_out) {
598 std::cout <<
"mcarlo_miser: level,calls_l,calls_r,calls,min_calls_pb: " 599 << level <<
" " << calls_l <<
" " << calls_r <<
" " << calls <<
" " 600 << min_calls_per_bisection << std::endl;
601 std::cout <<
"\tres,err: " << res_est <<
" " << err_est << std::endl;
603 std::cout <<
"\ti,left,mid,right: " << i_bisect <<
" " 604 << xbi_l <<
" " << xbi_m <<
" " << xbi_r << std::endl;
605 for(
size_t j=0;j<
dim;j++) {
606 std::cout <<
"\t\ti,low,high: " << j <<
" " << xl[j] <<
" " << xu[j]
626 for (i=0;i<
dim;i++) {
630 xu_tmp[i_bisect]=xbi_m;
647 for (i=0;i<
dim;i++) {
651 xl_tmp[i_bisect]=xbi_m;
662 err=sqrt(err_l*err_l+err_r*err_r);
674 virtual int minteg_err(func_t &func,
size_t ndim,
const vec_t &a,
675 const vec_t &b,
double &res,
double &err) {
677 min_calls=calls_per_dim*ndim;
678 min_calls_per_bisection=bisection_ratio*
min_calls;
684 min_calls_per_bisection=0;
697 virtual double minteg(func_t &func,
size_t ndim,
const vec_t &a,
705 virtual const char *
type() {
return "mcarlo_miser"; }
709 #ifndef DOXYGEN_NO_O2NS rng_gsl_uniform_real rng_dist
The random number distribution.
ubvector xmid
The current midpoint.
The main O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl names...
size_t bisection_ratio
Factor to set min_calls_per_bisection (default 32)
double dither
Introduce random variation into bisection (default 0.0)
sanity check failed - shouldn't happen
ubvector fsum2_l
The sum of the squares in the left half.
invalid argument supplied by user
int set_min_calls_per_bisection(size_t &mcb)
Minimum number of calls required to proceed with bisection.
int set_min_calls(size_t &mc)
Minimum number of calls to estimate the variance.
ubvector fmin_r
The minimum function value in the right half.
virtual const char * type()
Return string denoting type ("mcarlo_miser")
size_t calls_per_dim
Number of calls per dimension (default 16)
size_t min_calls
Minimum number of calls to estimate the variance.
#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.
ubvector sigma_r
The right variance.
virtual int allocate(size_t ldim)
Allocate memory.
unsigned long n_points
Number of integration points (default 1000)
vec_t x
The most recent integration point.
double alpha
How estimated variances for two sub-regions are combined (default 2.0)
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
Monte-Carlo integration [abstract base].
size_t n_levels_out
The number of recursive levels to output when verbose is greater than zero (default 5) ...
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.
ubvector fmin_l
The minimum function value in the left half.
ubvector_size_t hits_l
The number of evaluation points in the left half.
ubvector fsum2_r
The sum of the squares in the right half.
size_t dim
The number of dimensions of memory allocated.
double interror
The uncertainty for the last integration computation.
Multidimensional integration using the MISER Monte Carlo algorithm (GSL)
ubvector sigma_l
The left variance.
ubvector fsum_r
The sum in the right half.
ubvector fsum_l
The sum in the left half.
double estimate_frac
Specify fraction of function calls for estimating variance (default 0.1)
ubvector fmax_r
The maximum function value in the right half.
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.
size_t min_calls_per_bisection
Minimum number of calls required to proceed with bisection.
ubvector_size_t hits_r
The number of evaluation points in the right half.
std::function< double(size_t, const boost::numeric::ublas::vector< double > &)> multi_funct11
Multi-dimensional function typedef.
ubvector fmax_l
The maximum function value in the left half.
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.
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.