00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 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 #ifndef O2SCL_GSL_MISER_H 00024 #define O2SCL_GSL_MISER_H 00025 00026 #include <iostream> 00027 #include <o2scl/collection.h> 00028 #include <o2scl/mcarlo_inte.h> 00029 #include <o2scl/gsl_rnga.h> 00030 #include <gsl/gsl_math.h> 00031 #include <gsl/gsl_monte.h> 00032 #include <gsl/gsl_machine.h> 00033 #include <gsl/gsl_monte_miser.h> 00034 00035 #ifndef DOXYGENP 00036 namespace o2scl { 00037 #endif 00038 00039 /** 00040 \brief Multidimensional integration using Miser Miser Carlo (GSL) 00041 00042 \todo Document the fact that min_calls and 00043 min_calls_per_bisection need to be set beforehand 00044 */ 00045 template<class param_t, class func_t=multi_funct<param_t>, 00046 class rng_t=gsl_rnga, class vec_t=ovector_view, class alloc_vec_t=ovector, 00047 class alloc_t=ovector_alloc> class gsl_miser : 00048 public mcarlo_inte<param_t,func_t,rng_t,vec_t> { 00049 00050 public: 00051 00052 /** 00053 \brief Introduce random variation into bisection (default 0.0) 00054 00055 From GSL documentation: 00056 \verbatim 00057 This parameter introduces a random fractional variation of size 00058 DITHER into each bisection, which can be used to break the 00059 symmetry of integrands which are concentrated near the exact 00060 center of the hypercubic integration region. The default value of 00061 dither is zero, so no variation is introduced. If needed, a 00062 typical value of DITHER is 0.1. 00063 \endverbatim 00064 */ 00065 double dither; 00066 00067 /** 00068 \brief Specify fraction of function calls for estimating variance 00069 00070 From GSL documentation: 00071 \verbatim 00072 This parameter specifies the fraction of the currently available 00073 number of function calls which are allocated to estimating the 00074 variance at each recursive step. The default value is 0.1. 00075 \endverbatim 00076 */ 00077 double estimate_frac; 00078 00079 /** 00080 \brief How estimated variances for two sub-regions are combined 00081 00082 From GSL documentation: 00083 \verbatim 00084 This parameter controls how the estimated variances for the two 00085 sub-regions of a bisection are combined when allocating points. 00086 With recursive sampling the overall variance should scale better 00087 than 1/N, since the values from the sub-regions will be obtained 00088 using a procedure which explicitly minimizes their variance. To 00089 accommodate this behavior the MISER algorithm allows the total 00090 variance to depend on a scaling parameter \alpha, 00091 00092 \Var(f) = {\sigma_a \over N_a^\alpha} + {\sigma_b \over N_b^\alpha}. 00093 00094 The authors of the original paper describing MISER recommend the 00095 value \alpha = 2 as a good choice, obtained from numerical 00096 experiments, and this is used as the default value in this 00097 implementation. 00098 \endverbatim 00099 */ 00100 double alpha; 00101 00102 /** 00103 \brief Minimum number of calls to estimate the variance 00104 (default 100) 00105 00106 From GSL documentation: 00107 \verbatim 00108 This parameter specifies the minimum number of function calls 00109 required for each estimate of the variance. If the number of 00110 function calls allocated to the estimate using ESTIMATE_FRAC falls 00111 below MIN_CALLS then MIN_CALLS are used instead. This ensures 00112 that each estimate maintains a reasonable level of accuracy. The 00113 default value of MIN_CALLS is `16 * dim'. 00114 \endverbatim 00115 */ 00116 size_t min_calls; 00117 00118 /** 00119 \brief Minimum number of calls required to proceed with bisection 00120 (default 4000) 00121 00122 From GSL documentation: 00123 \verbatim 00124 This parameter specifies the minimum number of function calls 00125 required to proceed with a bisection step. When a recursive step 00126 has fewer calls available than MIN_CALLS_PER_BISECTION it performs 00127 a plain Monte Carlo estimate of the current sub-region and 00128 terminates its branch of the recursion. The default value of this 00129 parameter is `32 * min_calls'. 00130 \endverbatim 00131 */ 00132 size_t min_calls_per_bisection; 00133 00134 #ifndef DOXYGEN_INTERNAL 00135 00136 protected: 00137 00138 /// Desc 00139 size_t dim; 00140 /// Desc 00141 double *xmid; 00142 /// Desc 00143 double *sigma_l; 00144 /// Desc 00145 double *sigma_r; 00146 /// Desc 00147 double *fmax_l; 00148 /// Desc 00149 double *fmax_r; 00150 /// Desc 00151 double *fmin_l; 00152 /// Desc 00153 double *fmin_r; 00154 /// Desc 00155 double *fsum_l; 00156 /// Desc 00157 double *fsum_r; 00158 /// Desc 00159 double *fsum2_l; 00160 /// Desc 00161 double *fsum2_r; 00162 /// Desc 00163 size_t *hits_l; 00164 /// Desc 00165 size_t *hits_r; 00166 00167 /// Desc 00168 virtual int estimate_corrmc(func_t &func, size_t ndim, 00169 const vec_t &xl, const vec_t &xu, 00170 param_t &pa, size_t calls, double &res, 00171 double &err, const double lxmid[], 00172 double lsigma_l[], double lsigma_r[]) { 00173 size_t i, n; 00174 00175 double m = 0.0, q = 0.0; 00176 double vol = 1.0; 00177 00178 for (i = 0; i < dim; i++) { 00179 vol *= xu[i] - xl[i]; 00180 hits_l[i] = hits_r[i] = 0; 00181 fsum_l[i] = fsum_r[i] = 0.0; 00182 fsum2_l[i] = fsum2_r[i] = 0.0; 00183 lsigma_l[i] = lsigma_r[i] = -1; 00184 } 00185 00186 for (n = 0; n < calls; n++) { 00187 double fval; 00188 00189 unsigned int j = (n/2) % dim; 00190 unsigned int side = (n % 2); 00191 00192 for (i = 0; i < dim; i++) { 00193 00194 // The equivalent of gsl_rng_uniform_pos() 00195 double z; 00196 do { z=this->def_rng.random(); } while (z==0); 00197 00198 if (i != j) { 00199 x[i] = xl[i] + z * (xu[i] - xl[i]); 00200 } else { 00201 if (side == 0) { 00202 x[i] = lxmid[i] + z * (xu[i] - lxmid[i]); 00203 } else { 00204 x[i] = xl[i] + z * (lxmid[i] - xl[i]); 00205 } 00206 } 00207 } 00208 00209 func(ndim,x,fval,pa); 00210 00211 /* recurrence for mean and variance */ 00212 { 00213 double d = fval - m; 00214 m += d / (n + 1.0); 00215 q += d * d * (n / (n + 1.0)); 00216 } 00217 00218 /* compute the variances on each side of the bisection */ 00219 for (i = 0; i < dim; i++) { 00220 if (x[i] <= lxmid[i]) { 00221 fsum_l[i] += fval; 00222 fsum2_l[i] += fval * fval; 00223 hits_l[i]++; 00224 } else { 00225 fsum_r[i] += fval; 00226 fsum2_r[i] += fval * fval; 00227 hits_r[i]++; 00228 } 00229 } 00230 } 00231 00232 for (i = 0; i < dim; i++) { 00233 double fraction_l = (lxmid[i] - xl[i]) / (xu[i] - xl[i]); 00234 00235 if (hits_l[i] > 0) { 00236 fsum_l[i] /= hits_l[i]; 00237 lsigma_l[i] = sqrt (fsum2_l[i] - fsum_l[i] * fsum_l[i] / hits_l[i]); 00238 lsigma_l[i] *= fraction_l * vol / hits_l[i]; 00239 } 00240 00241 if (hits_r[i] > 0) { 00242 fsum_r[i] /= hits_r[i]; 00243 lsigma_r[i] = sqrt (fsum2_r[i] - fsum_r[i] * fsum_r[i] / hits_r[i]); 00244 lsigma_r[i] *= (1 - fraction_l) * vol / hits_r[i]; 00245 } 00246 } 00247 00248 res = vol * m; 00249 00250 if (calls < 2) { 00251 err = GSL_POSINF; 00252 } else { 00253 err = vol * sqrt (q / (calls * (calls - 1.0))); 00254 } 00255 00256 return gsl_success; 00257 } 00258 00259 /// Memory allocator 00260 alloc_t ao; 00261 00262 /// The most recent integration point 00263 alloc_vec_t x; 00264 00265 #endif 00266 00267 public: 00268 00269 gsl_miser() { 00270 estimate_frac=0.1; 00271 alpha=2.0; 00272 dither=0.0; 00273 min_calls=100; 00274 min_calls_per_bisection=4000; 00275 } 00276 00277 /// Allocate memory 00278 virtual int allocate(size_t ldim) { 00279 00280 ao.allocate(x,ldim); 00281 00282 xmid = (double *) malloc (ldim * sizeof (double)); 00283 if (xmid == 0) { 00284 ao.free(x); 00285 set_err2_ret("Failed to allocate space for xmid", 00286 " in gsl_miser::allocate().",gsl_enomem); 00287 } 00288 00289 sigma_l = (double *) malloc (ldim * sizeof (double)); 00290 if (sigma_l == 0) { 00291 std::free(xmid); 00292 ao.free(x); 00293 set_err2_ret("Failed to allocate space for sigma_l", 00294 " in gsl_miser::allocate().",gsl_enomem); 00295 } 00296 00297 sigma_r = (double *) malloc (ldim * sizeof (double)); 00298 if (sigma_r == 0) { 00299 std::free(sigma_l); 00300 std::free(xmid); 00301 ao.free(x); 00302 set_err2_ret("Failed to allocate space for sigma_r", 00303 " in gsl_miser::allocate().",gsl_enomem); 00304 } 00305 00306 fmax_l = (double *) malloc (ldim * sizeof (double)); 00307 if (fmax_l == 0) { 00308 std::free(sigma_r); 00309 std::free(sigma_l); 00310 std::free(xmid); 00311 ao.free(x); 00312 set_err2_ret("Failed to allocate space for fmax_l", 00313 " in gsl_miser::allocate().",gsl_enomem); 00314 } 00315 00316 fmax_r = (double *) malloc (ldim * sizeof (double)); 00317 if (fmax_r == 0) { 00318 std::free(fmax_l); 00319 std::free(sigma_r); 00320 std::free(sigma_l); 00321 std::free(xmid); 00322 ao.free(x); 00323 set_err2_ret("Failed to allocate space for fmax_r", 00324 " in gsl_miser::allocate().",gsl_enomem); 00325 } 00326 00327 fmin_l = (double *) malloc (ldim * sizeof (double)); 00328 if (fmin_l == 0) { 00329 std::free(fmax_r); 00330 std::free(fmax_l); 00331 std::free(sigma_r); 00332 std::free(sigma_l); 00333 std::free(xmid); 00334 ao.free(x); 00335 set_err2_ret("Failed to allocate space for fmin_l", 00336 " in gsl_miser::allocate().",gsl_enomem); 00337 } 00338 00339 fmin_r = (double *) malloc (ldim * sizeof (double)); 00340 if (fmin_r == 0) { 00341 std::free(fmin_l); 00342 std::free(fmax_r); 00343 std::free(fmax_l); 00344 std::free(sigma_r); 00345 std::free(sigma_l); 00346 std::free(xmid); 00347 ao.free(x); 00348 set_err2_ret("Failed to allocate space for fmin_r", 00349 " in gsl_miser::allocate().",gsl_enomem); 00350 } 00351 00352 fsum_l = (double *) malloc (ldim * sizeof (double)); 00353 if (fsum_l == 0) { 00354 std::free(fmin_r); 00355 std::free(fmin_l); 00356 std::free(fmax_r); 00357 std::free(fmax_l); 00358 std::free(sigma_r); 00359 std::free(sigma_l); 00360 std::free(xmid); 00361 ao.free(x); 00362 set_err2_ret("Failed to allocate space for fsum_l", 00363 " in gsl_miser::allocate().",gsl_enomem); 00364 } 00365 00366 fsum_r = (double *) malloc (ldim * sizeof (double)); 00367 if (fsum_r == 0) { 00368 std::free(fsum_l); 00369 std::free(fmin_r); 00370 std::free(fmin_l); 00371 std::free(fmax_r); 00372 std::free(fmax_l); 00373 std::free(sigma_r); 00374 std::free(sigma_l); 00375 std::free(xmid); 00376 ao.free(x); 00377 set_err2_ret("Failed to allocate space for fsum_r", 00378 " in gsl_miser::allocate().",gsl_enomem); 00379 } 00380 00381 fsum2_l = (double *) malloc (ldim * sizeof (double)); 00382 if (fsum2_l == 0) { 00383 std::free(fsum_r); 00384 std::free(fsum_l); 00385 std::free(fmin_r); 00386 std::free(fmin_l); 00387 std::free(fmax_r); 00388 std::free(fmax_l); 00389 std::free(sigma_r); 00390 std::free(sigma_l); 00391 std::free(xmid); 00392 ao.free(x); 00393 set_err2_ret("Failed to allocate space for fsum2_l", 00394 " in gsl_miser::allocate().",gsl_enomem); 00395 } 00396 00397 fsum2_r = (double *) malloc (ldim * sizeof (double)); 00398 if (fsum2_r == 0) { 00399 std::free(fsum2_l); 00400 std::free(fsum_r); 00401 std::free(fsum_l); 00402 std::free(fmin_r); 00403 std::free(fmin_l); 00404 std::free(fmax_r); 00405 std::free(fmax_l); 00406 std::free(sigma_r); 00407 std::free(sigma_l); 00408 std::free(xmid); 00409 ao.free(x); 00410 set_err2_ret("Failed to allocate space for fsum2_r", 00411 " in gsl_miser::allocate().",gsl_enomem); 00412 } 00413 00414 00415 hits_r = (size_t *) malloc (ldim * sizeof (size_t)); 00416 if (hits_r == 0) { 00417 std::free(fsum2_r); 00418 std::free(fsum2_l); 00419 std::free(fsum_r); 00420 std::free(fsum_l); 00421 std::free(fmin_r); 00422 std::free(fmin_l); 00423 std::free(fmax_r); 00424 std::free(fmax_l); 00425 std::free(sigma_r); 00426 std::free(sigma_l); 00427 std::free(xmid); 00428 ao.free(x); 00429 set_err2_ret("Failed to allocate space for fsum2_r", 00430 " in gsl_miser::allocate().",gsl_enomem); 00431 } 00432 00433 hits_l = (size_t *) malloc (ldim * sizeof (size_t)); 00434 if (hits_l == 0) { 00435 std::free(hits_r); 00436 std::free(fsum2_r); 00437 std::free(fsum2_l); 00438 std::free(fsum_r); 00439 std::free(fsum_l); 00440 std::free(fmin_r); 00441 std::free(fmin_l); 00442 std::free(fmax_r); 00443 std::free(fmax_l); 00444 std::free(sigma_r); 00445 std::free(sigma_l); 00446 std::free(xmid); 00447 ao.free(x); 00448 set_err2_ret("Failed to allocate space for fsum2_r", 00449 " in gsl_miser::allocate().",gsl_enomem); 00450 } 00451 00452 dim = ldim; 00453 00454 return 0; 00455 } 00456 00457 /// Free allocated memory 00458 virtual int free() { 00459 std::free(hits_r); 00460 std::free(hits_l); 00461 std::free(fsum2_r); 00462 std::free(fsum2_l); 00463 std::free(fsum_r); 00464 std::free(fsum_l); 00465 std::free(fmin_r); 00466 std::free(fmin_l); 00467 std::free(fmax_r); 00468 std::free(fmax_l); 00469 std::free(sigma_r); 00470 std::free(sigma_l); 00471 std::free(xmid); 00472 ao.free(x); 00473 return 0; 00474 } 00475 00476 /** \brief Integrate function \c func over the hypercube from 00477 \f$ x_i=\mathrm{xl}_i \f$ to \f$ x_i=\mathrm{xu}_i \f$ for 00478 \f$ 0<i< \f$ ndim-1 00479 */ 00480 virtual int miser_minteg_err(func_t &func, size_t ndim, const vec_t &xl, 00481 const vec_t &xu, size_t calls, param_t &pa, 00482 double &res, double &err) { 00483 00484 size_t n, estimate_calls, calls_l, calls_r; 00485 size_t i; 00486 size_t i_bisect; 00487 int found_best; 00488 00489 double res_est = 0, err_est = 0; 00490 double res_r = 0, err_r = 0, res_l = 0, err_l = 0; 00491 double xbi_l, xbi_m, xbi_r, s; 00492 00493 double vol; 00494 double weight_l, weight_r; 00495 00496 for (i = 0; i < dim; i++) { 00497 if (xu[i] <= xl[i]) { 00498 set_err2_ret("Upper limit must be greater than lower limit ", 00499 "in gsl_miser::miser_minteg_err().",gsl_einval); 00500 } 00501 if (xu[i] - xl[i] > GSL_DBL_MAX) { 00502 set_err2_ret("Range of integration is too large ", 00503 "in gsl_miser::miser_minteg_err().",gsl_einval); 00504 } 00505 } 00506 00507 if (alpha < 0) { 00508 set_err2_ret("Parameter 'alpha' must be non-negative ", 00509 "in gsl_miser::miser_minteg_err().",gsl_einval); 00510 } 00511 00512 /* Compute volume */ 00513 00514 vol = 1; 00515 00516 for (i = 0; i < dim; i++) { 00517 vol *= xu[i] - xl[i]; 00518 } 00519 00520 if (calls < min_calls_per_bisection) { 00521 double m = 0.0, q = 0.0; 00522 00523 if (calls < 2) { 00524 set_err2_ret("Insufficient calls for subvolume ", 00525 "in gsl_miser::miser_minteg_err().",gsl_einval); 00526 } 00527 00528 for (n = 0; n < calls; n++) { 00529 /* Choose a random point in the integration region */ 00530 00531 for (i = 0; i < dim; i++) { 00532 00533 // The equivalent of gsl_rng_uniform_pos() 00534 double rdn; 00535 do { rdn=this->def_rng.random(); } while (rdn==0); 00536 00537 x[i] = xl[i] + rdn * (xu[i] - xl[i]); 00538 } 00539 00540 { 00541 double fval; 00542 func(ndim,x,fval,pa); 00543 00544 /* recurrence for mean and variance */ 00545 00546 double d = fval - m; 00547 m += d / (n + 1.0); 00548 q += d * d * (n / (n + 1.0)); 00549 } 00550 } 00551 00552 res = vol * m; 00553 00554 err = vol * sqrt (q / (calls * (calls - 1.0))); 00555 00556 return gsl_success; 00557 } 00558 00559 // We explicitly make the typecast here 00560 estimate_calls=((size_t)GSL_MAX(min_calls,calls*(estimate_frac))); 00561 00562 if (estimate_calls < 4 * dim) { 00563 set_err2_ret("Insufficient calls to sample all halfspaces ", 00564 "in gsl_miser::miser_minteg_err().",gsl_esanity); 00565 } 00566 00567 /* Flip coins to bisect the integration region with some fuzz */ 00568 00569 for (i = 0; i < dim; i++) { 00570 s=(this->def_rng.random()-0.5) >= 0.0 ? dither : -dither; 00571 xmid[i] = (0.5 + s) * xl[i] + (0.5 - s) * xu[i]; 00572 } 00573 00574 /* 00575 The idea is to chose the direction to bisect based on which will 00576 give the smallest total variance. We could (and may do so later) 00577 use MC to compute these variances. But the NR guys simply estimate 00578 the variances by finding the min and max function values 00579 for each half-region for each bisection. 00580 */ 00581 00582 estimate_corrmc(func,dim,xl,xu,pa,estimate_calls, 00583 res_est,err_est,xmid,sigma_l,sigma_r); 00584 00585 /* We have now used up some calls for the estimation */ 00586 00587 calls -= estimate_calls; 00588 00589 /* Now find direction with the smallest total "variance" */ 00590 00591 { 00592 double best_var = GSL_DBL_MAX; 00593 double beta = 2.0 / (1.0 + alpha); 00594 found_best = 0; 00595 i_bisect = 0; 00596 weight_l = weight_r = 1.0; 00597 00598 for (i = 0; i < dim; i++) { 00599 if (sigma_l[i] >= 0 && sigma_r[i] >= 0) { 00600 /* estimates are okay */ 00601 double var = pow (sigma_l[i], beta) + pow (sigma_r[i], beta); 00602 00603 if (var <= best_var) { 00604 found_best = 1; 00605 best_var = var; 00606 i_bisect = i; 00607 weight_l = pow (sigma_l[i], beta); 00608 weight_r = pow (sigma_r[i], beta); 00609 } 00610 } else { 00611 if (sigma_l[i] < 0) { 00612 set_err2_ret("No points in left-half space ", 00613 "in gsl_miser::miser_minteg_err().",gsl_esanity); 00614 } 00615 if (sigma_r[i] < 0) { 00616 set_err2_ret("No points in right-half space ", 00617 "in gsl_miser::miser_minteg_err().",gsl_esanity); 00618 } 00619 } 00620 } 00621 } 00622 00623 if (!found_best) { 00624 /* All estimates were the same, so chose a direction at random */ 00625 00626 i_bisect = this->def_rng.random_int(dim); 00627 } 00628 00629 xbi_l = xl[i_bisect]; 00630 xbi_m = xmid[i_bisect]; 00631 xbi_r = xu[i_bisect]; 00632 00633 /* Get the actual fractional sizes of the two "halves", and 00634 distribute the remaining calls among them */ 00635 00636 { 00637 double fraction_l = fabs ((xbi_m - xbi_l) / (xbi_r - xbi_l)); 00638 double fraction_r = 1 - fraction_l; 00639 00640 double a = fraction_l * weight_l; 00641 double b = fraction_r * weight_r; 00642 00643 calls_l = (size_t)(min_calls + (calls - 2 * min_calls) * a / (a + b)); 00644 calls_r = (size_t)(min_calls + (calls - 2 * min_calls) * b / (a + b)); 00645 } 00646 00647 /* Compute the integral for the left hand side of the bisection */ 00648 00649 /* Due to the recursive nature of the algorithm we must allocate 00650 some new memory for the integration limits for each recursive call */ 00651 00652 { 00653 int status; 00654 00655 alloc_vec_t xu_tmp; 00656 ao.allocate(xu_tmp,dim); 00657 00658 for (i = 0; i < dim; i++) { 00659 xu_tmp[i] = xu[i]; 00660 } 00661 00662 xu_tmp[i_bisect] = xbi_m; 00663 00664 status=miser_minteg_err(func,dim,xl,xu_tmp,calls_l,pa,res_l,err_l); 00665 00666 ao.free(xu_tmp); 00667 00668 if (status != gsl_success) { 00669 return status; 00670 } 00671 } 00672 00673 /* Compute the integral for the right hand side of the bisection */ 00674 00675 { 00676 int status; 00677 00678 alloc_vec_t xl_tmp; 00679 ao.allocate(xl_tmp,dim); 00680 00681 for (i = 0; i < dim; i++) { 00682 xl_tmp[i] = xl[i]; 00683 } 00684 00685 xl_tmp[i_bisect] = xbi_m; 00686 00687 status=miser_minteg_err(func,dim,xl_tmp,xu,calls_r,pa,res_r,err_r); 00688 00689 ao.free(xl_tmp); 00690 00691 if (status != gsl_success) { 00692 return status; 00693 } 00694 } 00695 00696 res=res_l+res_r; 00697 err=sqrt(err_l*err_l+err_r*err_r); 00698 00699 return 0; 00700 } 00701 00702 virtual ~gsl_miser() {} 00703 00704 /// Integrate function \c func from x=a to x=b. 00705 virtual int minteg_err(func_t &func, size_t ndim, const vec_t &a, 00706 const vec_t &b, param_t &pa, double &res, 00707 double &err) { 00708 allocate(ndim); 00709 min_calls=16*ndim; 00710 min_calls_per_bisection=32*min_calls; 00711 int ret=miser_minteg_err(func,ndim,a,b,this->n_points,pa,res,err); 00712 free(); 00713 return ret; 00714 } 00715 00716 /** \brief Integrate function \c func over the hypercube from 00717 \f$ x_i=a_i \f$ to \f$ x_i=b_i \f$ for 00718 \f$ 0<i< \f$ ndim-1 00719 */ 00720 virtual double minteg(func_t &func, size_t ndim, const vec_t &a, 00721 const vec_t &b, param_t &pa) { 00722 double res; 00723 minteg_err(func,ndim,a,b,pa,res,this->interror); 00724 return res; 00725 } 00726 00727 /// Return string denoting type ("gsl_miser") 00728 virtual const char *type() { return "gsl_miser"; } 00729 00730 }; 00731 00732 #ifndef DOXYGENP 00733 } 00734 #endif 00735 00736 #endif 00737
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page