![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006-2012, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 /* monte/vegas.c 00024 * 00025 * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth 00026 * 00027 * This program is free software; you can redistribute it and/or modify 00028 * it under the terms of the GNU General Public License as published by 00029 * the Free Software Foundation; either version 3 of the License, or (at 00030 * your option) any later version. 00031 * 00032 * This program is distributed in the hope that it will be useful, but 00033 * WITHOUT ANY WARRANTY; without even the implied warranty of 00034 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00035 * General Public License for more details. 00036 * 00037 * You should have received a copy of the GNU General Public License 00038 * along with this program; if not, write to the Free Software 00039 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00040 * 02110-1301, USA. 00041 */ 00042 00043 #ifndef O2SCL_GSL_VEGAS_H 00044 #define O2SCL_GSL_VEGAS_H 00045 00046 #include <iostream> 00047 #include <o2scl/mcarlo_inte.h> 00048 #include <o2scl/gsl_rnga.h> 00049 #include <gsl/gsl_math.h> 00050 #include <gsl/gsl_monte.h> 00051 #include <gsl/gsl_machine.h> 00052 #include <gsl/gsl_monte_vegas.h> 00053 00054 #ifndef DOXYGENP 00055 namespace o2scl { 00056 #endif 00057 00058 /** \brief Multidimensional integration using Vegas Monte Carlo (GSL) 00059 00060 The output options are a little different than the original GSL 00061 routine. The default setting of \ref mcarlo_inte::verbose is 0, 00062 which turns off all output. A verbose value of 1 prints summary 00063 information about the weighted average and final result, while a 00064 value of 2 also displays the grid coordinates. A value of 3 00065 prints information from the rebinning procedure for each 00066 iteration. 00067 00068 Some original documentation from GSL: 00069 00070 \verbatim 00071 The input coordinates are x[j], with upper and lower limits 00072 xu[j] and xl[j]. The integration length in the j-th direction is 00073 delx[j]. Each coordinate x[j] is rescaled to a variable y[j] in 00074 the range 0 to 1. The range is divided into bins with boundaries 00075 xi[i][j], where i=0 corresponds to y=0 and i=bins to y=1. The 00076 grid is refined (ie, bins are adjusted) using d[i][j] which is 00077 some variation on the squared sum. A third parameter used in 00078 defining the real coordinate using random numbers is called z. 00079 It ranges from 0 to bins. Its integer part gives the lower index 00080 of the bin into which a call is to be placed, and the remainder 00081 gives the location inside the bin. 00082 00083 When stratified sampling is used the bins are grouped into 00084 boxes, and the algorithm allocates an equal number of function 00085 calls to each box. 00086 00087 The variable alpha controls how "stiff" the rebinning algorithm 00088 is. alpha = 0 means never change the grid. Alpha is typically 00089 set between 1 and 2. 00090 \endverbatim 00091 00092 \todo Mode = importance only doesn't give the same answer 00093 as GSL yet. 00094 00095 \future Prettify the verbose output 00096 00097 \future Allow the user to get information about the how 00098 the sampling was done, possibly by converting the bins 00099 and boxes into a structure or class. 00100 00101 \future Allow the user to change the maximum number of bins. 00102 00103 Based on \ref Lepage78 . The current version of the algorithm 00104 was described in the Cornell preprint CLNS-80/447 of March, 00105 1980. The GSL code follows most closely the C version by D. R. 00106 Yennie, coded in 1984. 00107 */ 00108 template<class func_t=multi_funct<>, class rng_t=gsl_rnga, 00109 class vec_t=ovector_base, class alloc_vec_t=ovector, 00110 class alloc_t=ovector_alloc> class gsl_vegas : 00111 public mcarlo_inte<func_t,rng_t,vec_t> { 00112 00113 public: 00114 00115 /// \name Integration mode (default is mode_importance) 00116 //@{ 00117 int mode; 00118 static const int mode_importance=1; 00119 static const int mode_importance_only=0; 00120 static const int mode_stratified=-1; 00121 //@} 00122 00123 /// Result from last iteration 00124 double result; 00125 00126 /// Uncertainty from last iteration 00127 double sigma; 00128 00129 /** \brief The stiffness of the rebinning algorithm (default 1.5) 00130 00131 This usual range is between 1 and 2. 00132 */ 00133 double alpha; 00134 00135 /// Set the number of iterations (default 5) 00136 unsigned int iterations; 00137 00138 /** \brief The chi-squared per degree of freedom for the weighted 00139 estimate of the integral 00140 00141 After an integration, this should be close to 1. If it is not, 00142 then this indicates that the values of the integral from 00143 different iterations are inconsistent, and the error may be 00144 underestimated. Further iterations of the algorithm may enable 00145 one to obtain more reliable results. 00146 */ 00147 double chisq; 00148 00149 /// The output stream to send output information (default \c std::cout) 00150 std::ostream *outs; 00151 00152 #ifndef DOXYGEN_INTERNAL 00153 00154 protected: 00155 00156 /// Maximum number of bins 00157 static const size_t bins_max=50; 00158 00159 /// Number of dimensions 00160 size_t dim; 00161 /// Number of bins 00162 unsigned int bins; 00163 /// Number of boxes 00164 unsigned int boxes; 00165 /// Boundaries for each bin 00166 uvector xi; 00167 /// Storage for grid refinement 00168 uvector xin; 00169 /// The iteration length in each direction 00170 uvector delx; 00171 /// The weight for each bin 00172 uvector weight; 00173 /// The volume of the current bin 00174 double vol; 00175 00176 /// The bins for each direction 00177 uvector_int bin; 00178 /// The boxes for each direction 00179 uvector_int box; 00180 00181 /// Distribution 00182 uvector d; 00183 00184 /** \name Scratch variables preserved between calls to 00185 vegas_minteg_err() 00186 */ 00187 //@{ 00188 double jac; 00189 double wtd_int_sum; 00190 double sum_wgts; 00191 double chi_sum; 00192 //@} 00193 00194 /// The starting iteration number 00195 unsigned int it_start; 00196 /// The total number of iterations 00197 unsigned int it_num; 00198 /// Number of samples for computing chi squared 00199 unsigned int samples; 00200 /// Number of function calls per box 00201 unsigned int calls_per_box; 00202 00203 /// Initialize box coordinates 00204 virtual void init_box_coord(uvector_int &boxt) { 00205 size_t i; 00206 for (i=0;i<dim;i++) { 00207 boxt[i]=0; 00208 } 00209 return; 00210 } 00211 00212 /** \brief Change box coordinates 00213 00214 Steps through the box coordinates, e.g. 00215 \verbatim 00216 {0,0}, {0,1}, {0,2}, {0,3}, {1,0}, {1,1}, {1,2}, ... 00217 \endverbatim 00218 00219 This is among the member functions that is not virtual 00220 because it is part of the innermost loop. 00221 */ 00222 int change_box_coord(uvector_int &boxt) { 00223 int j=dim-1; 00224 int ng=boxes; 00225 00226 while (j >= 0) { 00227 00228 boxt[j]=(boxt[j]+1) % ng; 00229 if (boxt[j] != 0) { 00230 return 1; 00231 } 00232 j--; 00233 00234 } 00235 00236 return 0; 00237 } 00238 00239 /// Initialize grid 00240 virtual void init_grid(const vec_t &xl, const vec_t &xu, size_t ldim) { 00241 size_t j; 00242 vol=1.0; 00243 bins=1; 00244 00245 for (j=0;j<ldim;j++) { 00246 double dx=xu[j]-xl[j]; 00247 delx[j]=dx; 00248 vol *= dx; 00249 00250 xi[j]=0.0; 00251 xi[dim+j]=1.0; 00252 } 00253 00254 return; 00255 } 00256 00257 /// Reset grid values 00258 virtual void reset_grid_values() { 00259 size_t i, j; 00260 00261 for (i=0;i<bins;i++) { 00262 for (j=0;j<dim;j++) { 00263 d[i*dim+j]=0.0; 00264 } 00265 } 00266 return; 00267 } 00268 00269 /** \brief Add the most recently generated result to the distribution 00270 00271 This is among the member functions that is not virtual 00272 because it is part of the innermost loop. 00273 */ 00274 void accumulate_distribution(uvector_int &lbin, double y) { 00275 size_t j; 00276 00277 for (j=0;j<dim;j++) { 00278 int i=lbin[j]; 00279 d[i*dim+j]+=y; 00280 } 00281 return; 00282 } 00283 00284 /** \brief Generate a random position in a given box 00285 00286 Use the random number generator \ref mcarlo_inte::def_rng to 00287 return a random position x in a given box. The value of bin 00288 gives the bin location of the random position (there may be 00289 several bins within a given box) 00290 00291 This is among the member functions that is not virtual 00292 because it is part of the innermost loop. 00293 */ 00294 void random_point(vec_t &lx, uvector_int &lbin, double &bin_vol, 00295 const uvector_int &lbox, const vec_t &xl, 00296 const vec_t &xu) { 00297 00298 double lvol=1.0; 00299 00300 size_t j; 00301 00302 for (j=0;j<dim;++j) { 00303 00304 // The equivalent of gsl_rng_uniform_pos() 00305 double rdn; 00306 do { rdn=this->def_rng.random(); } while (rdn==0); 00307 00308 /* lbox[j] + ran gives the position in the box units, while z 00309 is the position in bin units. */ 00310 double z=((lbox[j]+rdn)/boxes)*bins; 00311 00312 int k=(int)z; 00313 00314 double y, bin_width; 00315 00316 lbin[j]=k; 00317 00318 if (k == 0) { 00319 bin_width=xi[dim+j]; 00320 y=z*bin_width; 00321 } else { 00322 bin_width=xi[(k+1)*dim+j]-xi[k*dim+j]; 00323 y=xi[k*dim+j]+(z-k)*bin_width; 00324 } 00325 00326 lx[j]=xl[j]+y*delx[j]; 00327 00328 lvol *= bin_width; 00329 } 00330 00331 bin_vol=lvol; 00332 00333 return; 00334 } 00335 00336 /// Resize the grid 00337 virtual void resize_grid(unsigned int lbins) { 00338 size_t j, k; 00339 00340 /* weight is ratio of bin sizes */ 00341 00342 double pts_per_bin=(double) bins/(double) lbins; 00343 00344 for (j=0;j<dim;j++) { 00345 double xold; 00346 double xnew=0; 00347 double dw=0; 00348 int i=1; 00349 00350 for (k=1;k <= bins;k++) { 00351 dw+=1.0; 00352 xold=xnew; 00353 xnew=xi[k*dim+j]; 00354 00355 for (;dw > pts_per_bin;i++) { 00356 dw -= pts_per_bin; 00357 (xin[i])=xnew-(xnew-xold)*dw; 00358 } 00359 } 00360 00361 for (k=1 ;k<lbins;k++) { 00362 xi[k*dim+j]=xin[k]; 00363 } 00364 00365 xi[lbins*dim+j]=1; 00366 } 00367 00368 bins=lbins; 00369 00370 return; 00371 } 00372 00373 /// Refine the grid 00374 virtual void refine_grid() { 00375 00376 size_t i, j, k; 00377 00378 for (j=0;j<dim;j++) { 00379 double grid_tot_j, tot_weight; 00380 00381 double oldg=d[j]; 00382 double newg=d[dim+j]; 00383 00384 d[j]=(oldg+newg)/2; 00385 grid_tot_j=d[j]; 00386 00387 /* This implements gs[i][j]=(gs[i-1][j]+gs[i][j]+gs[i+1][j])/3 */ 00388 00389 for (i=1;i<bins-1;i++) { 00390 double rc=oldg+newg; 00391 oldg=newg; 00392 newg=d[(i+1)*dim+j]; 00393 d[i*dim+j]=(rc+newg)/3; 00394 grid_tot_j+=d[i*dim+j]; 00395 } 00396 d[(bins-1)*dim+j]=(newg+oldg)/2; 00397 00398 grid_tot_j+=d[(bins-1)*dim+j]; 00399 00400 tot_weight=0; 00401 00402 for (i=0;i<bins;i++) { 00403 weight[i]=0; 00404 00405 if (d[i*dim+j] > 0) { 00406 oldg=grid_tot_j/d[i*dim+j]; 00407 /* damped change */ 00408 weight[i]=pow (((oldg-1)/oldg/log (oldg)), alpha); 00409 } 00410 00411 tot_weight+=weight[i]; 00412 } 00413 00414 { 00415 double pts_per_bin=tot_weight/bins; 00416 00417 double xold; 00418 double xnew=0; 00419 double dw=0; 00420 i=1; 00421 00422 for (k=0;k<bins;k++) { 00423 dw+=weight[k]; 00424 xold=xnew; 00425 xnew=xi[(k+1)*dim+j]; 00426 00427 for (;dw > pts_per_bin;i++) { 00428 dw -= pts_per_bin; 00429 (xin[i])=xnew-(xnew-xold)*dw/weight[k]; 00430 } 00431 } 00432 00433 for (k=1 ;k<bins ;k++) { 00434 xi[k*dim+j]=xin[k]; 00435 } 00436 00437 xi[bins*dim+j]=1; 00438 } 00439 } 00440 return; 00441 } 00442 00443 /// Print limits of integration 00444 virtual void print_lim(const vec_t &xl, const vec_t &xu, 00445 unsigned long ldim) { 00446 00447 unsigned long j; 00448 00449 (*outs) << "The limits of integration are:\n" << std::endl; 00450 for (j=0;j<ldim;++j) { 00451 (*outs) << "xl[" << j << "]=" << xl[j] << " xu[" << j 00452 << "]=" << xu[j] << std::endl; 00453 } 00454 (*outs) << std::endl; 00455 00456 return; 00457 } 00458 00459 /// Print header 00460 virtual void print_head(unsigned long num_dim, unsigned long calls, 00461 unsigned int lit_num, unsigned int lbins, 00462 unsigned int lboxes) { 00463 00464 (*outs) << "num_dim=" << num_dim << ", calls=" << calls 00465 << ", it_num=" << lit_num << ", max_it_num=" 00466 << iterations << ", verb=" << this->verbose << ", alph=" << alpha 00467 << ",\n mode=" << mode << ", boxes=" << lboxes 00468 << "\n\n single.......iteration " 00469 << "accumulated......results\n" 00470 << "iter integral sigma integral " 00471 << " sigma chi-sq/it" << std::endl; 00472 00473 return; 00474 } 00475 00476 /// Print results 00477 virtual void print_res(unsigned int itr, double res, 00478 double err, double cum_res, double cum_err, 00479 double chi_sq) { 00480 (*outs).precision(5); 00481 (*outs) << itr << " "; 00482 outs->setf(std::ios::showpos); 00483 (*outs) << res << " "; 00484 outs->unsetf(std::ios::showpos); 00485 (*outs) << err << " "; 00486 outs->setf(std::ios::showpos); 00487 (*outs) << cum_res << " "; 00488 outs->unsetf(std::ios::showpos); 00489 (*outs) << cum_err << " " << chi_sq << std::endl; 00490 (*outs).precision(6); 00491 return; 00492 } 00493 00494 /// Print distribution 00495 virtual void print_dist(unsigned long ldim) { 00496 unsigned long i, j; 00497 00498 if (this->verbose<2) { 00499 return; 00500 } 00501 00502 for (j=0;j<ldim;++j) { 00503 (*outs) << "\n Axis " << j << std::endl; 00504 (*outs) << " x g" << std::endl; 00505 outs->setf(std::ios::showpos); 00506 for (i=0;i<bins;i++) { 00507 (*outs) << "weight [ " << (xi[(i)*dim+(j)]) << " , " 00508 << xi[(i+1)*dim+j] << " ] = "; 00509 (*outs) << " " << (d[(i)*dim+(j)]) << std::endl; 00510 } 00511 outs->unsetf(std::ios::showpos); 00512 (*outs) << std::endl; 00513 } 00514 (*outs) << std::endl; 00515 return; 00516 } 00517 00518 /// Print grid 00519 virtual void print_grid(unsigned long ldim) { 00520 00521 if (this->verbose<2) { 00522 return; 00523 } 00524 00525 unsigned long i, j; 00526 for (j=0;j<ldim;++j) { 00527 (*outs) << "\n Axis " << j << std::endl; 00528 (*outs) << " x " << std::endl; 00529 outs->setf(std::ios::showpos); 00530 for (i=0;i <= bins;i++) { 00531 (*outs) << (xi[(i)*dim+(j)]) << " "; 00532 if (i % 5 == 4) { 00533 (*outs) << std::endl; 00534 } 00535 } 00536 (*outs) << std::endl; 00537 outs->unsetf(std::ios::showpos); 00538 } 00539 (*outs) << std::endl; 00540 return; 00541 } 00542 00543 /// Memory allocation object 00544 alloc_t ao; 00545 00546 /// Point for function evaluation 00547 alloc_vec_t x; 00548 00549 #endif 00550 00551 public: 00552 00553 gsl_vegas() { 00554 this->verbose=0; 00555 outs=&std::cout; 00556 alpha=1.5; 00557 iterations=5; 00558 mode=mode_importance; 00559 chisq=0; 00560 bins=bins_max; 00561 dim=0; 00562 } 00563 00564 /// Allocate memory 00565 virtual int allocate(size_t ldim) { 00566 00567 delx.allocate(ldim); 00568 d.allocate(bins_max*ldim); 00569 xi.allocate((bins_max+1)*ldim); 00570 xin.allocate(bins_max+1); 00571 weight.allocate(bins_max); 00572 box.allocate(ldim); 00573 bin.allocate(ldim); 00574 ao.allocate(x,ldim); 00575 00576 dim=ldim; 00577 00578 return 0; 00579 } 00580 00581 /// Free allocated memory 00582 virtual int free() { 00583 if (dim>0) { 00584 delx.free(); 00585 d.free(); 00586 xi.free(); 00587 xin.free(); 00588 weight.free(); 00589 box.free(); 00590 bin.free(); 00591 ao.free(x); 00592 dim=0; 00593 } 00594 return 0; 00595 } 00596 00597 /** \brief Integrate function \c func from x=a to x=b. 00598 00599 Original documentation from GSL: 00600 00601 Normally, <tt>stage = 0</tt> which begins with a new uniform 00602 grid and empty weighted average. Calling vegas with <tt>stage 00603 = 1</tt> retains the grid from the previous run but discards 00604 the weighted average, so that one can "tune" the grid using a 00605 relatively small number of points and then do a large run with 00606 <tt>stage = 1</tt> on the optimized grid. Setting <tt>stage = 00607 2</tt> keeps the grid and the weighted average from the 00608 previous run, but may increase (or decrease) the number of 00609 histogram bins in the grid depending on the number of calls 00610 available. Choosing <tt>stage = 3</tt> enters at the main 00611 loop, so that nothing is changed, and is equivalent to 00612 performing additional iterations in a previous call. 00613 00614 \todo Should stage be passed by reference? 00615 \todo There was an update between gsl-1.12 and 1.15 which 00616 has not been implemented here yet. 00617 */ 00618 virtual int vegas_minteg_err(int stage, func_t &func, size_t ndim, 00619 const vec_t &xl, const vec_t &xu, 00620 double &res, double &err) { 00621 00622 size_t calls=this->n_points; 00623 00624 double cum_int, cum_sig; 00625 size_t i, k, it; 00626 00627 for (i=0;i<dim;i++) { 00628 if (xu[i] <= xl[i]) { 00629 std::string serr="Upper limit, "+dtos(xu[i])+", must be greater "+ 00630 "than lower limit, "+dtos(xl[i])+", in gsl_vegas::"+ 00631 "vegas_minteg_err()."; 00632 O2SCL_ERR_RET(serr.c_str(),gsl_einval); 00633 } 00634 00635 if (xu[i]-xl[i] > GSL_DBL_MAX) { 00636 O2SCL_ERR2_RET("Range of integration is too large, please rescale ", 00637 "in gsl_vegas::vegas_minteg_err().",gsl_einval); 00638 } 00639 } 00640 00641 if (stage == 0) { 00642 init_grid(xl,xu,dim); 00643 if (this->verbose>=1) { 00644 print_lim(xl,xu,dim); 00645 } 00646 } 00647 00648 if (stage<=1) { 00649 wtd_int_sum=0; 00650 sum_wgts=0; 00651 chi_sum=0; 00652 it_num=1; 00653 samples=0; 00654 chisq=0; 00655 } 00656 00657 if (stage <= 2) { 00658 00659 unsigned int lbins=bins_max; 00660 unsigned int lboxes=1; 00661 00662 if (mode != mode_importance_only) { 00663 00664 /* shooting for 2 calls/box */ 00665 00666 // The original GSL code was: 00667 // boxes=floor (pow (calls/2.0, 1.0/dim)); 00668 // but floor returns double on my machine, so 00669 // we explicitly typecast here 00670 00671 lboxes=((unsigned int)(floor(pow(calls/2.0,1.0/dim)))); 00672 mode=mode_importance; 00673 00674 if (2*lboxes >= bins_max) { 00675 /* if bins/box < 2 */ 00676 int box_per_bin=GSL_MAX(lboxes/bins_max,1); 00677 00678 lbins=GSL_MIN(lboxes/box_per_bin,bins_max); 00679 lboxes=box_per_bin*lbins; 00680 00681 mode=mode_stratified; 00682 } 00683 00684 } 00685 00686 //double tot_boxes=gsl_pow_int((double)boxes,dim); 00687 double tot_boxes=pow((double)lboxes,(double)dim); 00688 calls_per_box=((unsigned int)(GSL_MAX(calls/tot_boxes,2))); 00689 calls=((size_t)( calls_per_box*tot_boxes)); 00690 00691 /* total volume of x-space/(avg num of calls/bin) */ 00692 jac=vol*pow((double) lbins, (double) dim)/calls; 00693 00694 boxes=lboxes; 00695 00696 /* If the number of bins changes from the previous invocation, bins 00697 are expanded or contracted accordingly, while preserving bin 00698 density */ 00699 00700 if (lbins!=bins) { 00701 resize_grid(lbins); 00702 if (this->verbose > 2) print_grid(dim); 00703 } 00704 if (this->verbose >= 1) { 00705 print_head(dim,calls,it_num,bins,boxes); 00706 } 00707 } 00708 00709 it_start=it_num; 00710 00711 cum_int=0.0; 00712 cum_sig=0.0; 00713 00714 for (it=0;it<iterations;it++) { 00715 00716 double intgrl=0.0, intgrl_sq=0.0; 00717 double tss=0.0; 00718 double wgt, var, sig; 00719 size_t lcalls_per_box=calls_per_box; 00720 double jacbin=jac; 00721 00722 it_num=it_start+it; 00723 00724 reset_grid_values(); 00725 init_box_coord(box); 00726 00727 do { 00728 volatile double m=0, q=0; 00729 double f_sq_sum=0.0; 00730 00731 for (k=0;k<lcalls_per_box;k++) { 00732 double fval, bin_vol; 00733 00734 random_point(x,bin,bin_vol,box,xl,xu); 00735 00736 fval=func(dim,x); 00737 fval*=jacbin*bin_vol; 00738 00739 /* recurrence for mean and variance (sum of squares) */ 00740 00741 { 00742 double dt=fval-m; 00743 m+=dt/(k+1.0); 00744 q+=dt*dt*(k/(k+1.0)); 00745 } 00746 00747 if (mode != mode_stratified) { 00748 double f_sq=fval*fval; 00749 accumulate_distribution(bin,f_sq); 00750 } 00751 } 00752 00753 intgrl+=m*lcalls_per_box; 00754 00755 f_sq_sum=q*lcalls_per_box; 00756 00757 tss+=f_sq_sum; 00758 00759 if (mode == mode_stratified) { 00760 accumulate_distribution (bin, f_sq_sum); 00761 } 00762 00763 } while (change_box_coord(box)); 00764 00765 /* Compute final results for this iteration */ 00766 00767 var=tss/(lcalls_per_box-1.0); 00768 00769 if (var>0) { 00770 wgt=1.0/var; 00771 } else if (sum_wgts>0) { 00772 wgt=sum_wgts/samples; 00773 } else { 00774 wgt=0.0; 00775 } 00776 00777 intgrl_sq=intgrl*intgrl; 00778 00779 sig=sqrt(var); 00780 00781 result=intgrl; 00782 sigma=sig; 00783 00784 if (wgt > 0.0) { 00785 double lsum_wgts=sum_wgts; 00786 double m=(sum_wgts > 0) ? (wtd_int_sum/sum_wgts) : 0; 00787 double q=intgrl-m; 00788 00789 samples++; 00790 sum_wgts+=wgt; 00791 wtd_int_sum+=intgrl*wgt; 00792 chi_sum+=intgrl_sq*wgt; 00793 00794 cum_int= wtd_int_sum/sum_wgts; 00795 cum_sig=sqrt(1/sum_wgts); 00796 00797 /* The original chisq formula from the Lepage paper is 00798 00799 if ( samples > 1) { 00800 chisq=(chi_sum-wtd_int_sum*cum_int)/(samples-1.0); 00801 } 00802 00803 This can suffer from cancellations and return a negative 00804 value of chi squared. We use the new formula from 00805 GSL-1.12 instead 00806 */ 00807 if (samples==1) { 00808 chisq=0; 00809 } else { 00810 chisq*=(samples-2.0); 00811 chisq+=(wgt/(1+(wgt/lsum_wgts)))*q*q; 00812 chisq/=(samples-1.0); 00813 } 00814 00815 } else { 00816 cum_int+=(intgrl-cum_int)/(it+1.0); 00817 cum_sig=0.0; 00818 } 00819 00820 if (this->verbose >= 1) { 00821 print_res(it_num,intgrl,sig,cum_int,cum_sig,chisq); 00822 if (it+1 == iterations && this->verbose > 1) { 00823 print_grid(dim); 00824 } 00825 } 00826 00827 if (this->verbose > 2) { 00828 print_dist(dim); 00829 } 00830 00831 refine_grid (); 00832 00833 if (this->verbose > 2) { 00834 print_grid(dim); 00835 } 00836 00837 } 00838 00839 /* 00840 By setting stage to 1 further calls will generate independent 00841 estimates based on the same grid, although it may be rebinned. 00842 */ 00843 stage=1; 00844 00845 res=cum_int; 00846 err=cum_sig; 00847 00848 return GSL_SUCCESS; 00849 } 00850 00851 virtual ~gsl_vegas() {} 00852 00853 /// Integrate function \c func from x=a to x=b. 00854 virtual int minteg_err(func_t &func, size_t ndim, const vec_t &a, 00855 const vec_t &b, double &res, double &err) { 00856 allocate(ndim); 00857 chisq=0; 00858 bins=bins_max; 00859 int ret=vegas_minteg_err(0,func,ndim,a,b,res,err); 00860 free(); 00861 return ret; 00862 } 00863 00864 /** \brief Integrate function \c func over the hypercube from 00865 \f$ x_i=a_i \f$ to \f$ x_i=b_i \f$ for 00866 \f$ 0<i< \f$ ndim-1 00867 */ 00868 virtual double minteg(func_t &func, size_t ndim, const vec_t &a, 00869 const vec_t &b) { 00870 double res; 00871 minteg_err(func,ndim,a,b,res,this->interror); 00872 return res; 00873 } 00874 00875 /// Return string denoting type ("gsl_vegas") 00876 virtual const char *type() { return "gsl_vegas"; } 00877 00878 }; 00879 00880 #ifndef DOXYGENP 00881 } 00882 #endif 00883 00884 #endif 00885
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).