gsl_monte__miser.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. /* monte/miser.c
  2. *
  3. * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. /* MISER. Based on the algorithm described in the following article,
  20. W.H. Press, G.R. Farrar, "Recursive Stratified Sampling for
  21. Multidimensional Monte Carlo Integration", Computers in Physics,
  22. v4 (1990), pp190-195.
  23. */
  24. /* Author: MJB */
  25. /* Modified by Brian Gough 12/2000 */
  26. #include "gsl__config.h"
  27. #include <math.h>
  28. #include <stdlib.h>
  29. #include "gsl_math.h"
  30. #include "gsl_errno.h"
  31. #include "gsl_rng.h"
  32. #include "gsl_monte.h"
  33. #include "gsl_monte_miser.h"
  34. static int
  35. estimate_corrmc (gsl_monte_function * f,
  36. const double xl[], const double xu[],
  37. size_t dim, size_t calls,
  38. gsl_rng * r,
  39. gsl_monte_miser_state * state,
  40. double *result, double *abserr,
  41. const double xmid[], double sigma_l[], double sigma_r[]);
  42. int
  43. gsl_monte_miser_integrate (gsl_monte_function * f,
  44. const double xl[], const double xu[],
  45. size_t dim, size_t calls,
  46. gsl_rng * r,
  47. gsl_monte_miser_state * state,
  48. double *result, double *abserr)
  49. {
  50. size_t n, estimate_calls, calls_l, calls_r;
  51. const size_t min_calls = state->min_calls;
  52. size_t i;
  53. size_t i_bisect;
  54. int found_best;
  55. double res_est = 0, err_est = 0;
  56. double res_r = 0, err_r = 0, res_l = 0, err_l = 0;
  57. double xbi_l, xbi_m, xbi_r, s;
  58. double vol;
  59. double weight_l, weight_r;
  60. double *x = state->x;
  61. double *xmid = state->xmid;
  62. double *sigma_l = state->sigma_l, *sigma_r = state->sigma_r;
  63. if (dim != state->dim)
  64. {
  65. GSL_ERROR ("number of dimensions must match allocated size", GSL_EINVAL);
  66. }
  67. for (i = 0; i < dim; i++)
  68. {
  69. if (xu[i] <= xl[i])
  70. {
  71. GSL_ERROR ("xu must be greater than xl", GSL_EINVAL);
  72. }
  73. if (xu[i] - xl[i] > GSL_DBL_MAX)
  74. {
  75. GSL_ERROR ("Range of integration is too large, please rescale",
  76. GSL_EINVAL);
  77. }
  78. }
  79. if (state->alpha < 0)
  80. {
  81. GSL_ERROR ("alpha must be non-negative", GSL_EINVAL);
  82. }
  83. /* Compute volume */
  84. vol = 1;
  85. for (i = 0; i < dim; i++)
  86. {
  87. vol *= xu[i] - xl[i];
  88. }
  89. if (calls < state->min_calls_per_bisection)
  90. {
  91. double m = 0.0, q = 0.0;
  92. if (calls < 2)
  93. {
  94. GSL_ERROR ("insufficient calls for subvolume", GSL_EFAILED);
  95. }
  96. for (n = 0; n < calls; n++)
  97. {
  98. /* Choose a random point in the integration region */
  99. for (i = 0; i < dim; i++)
  100. {
  101. x[i] = xl[i] + gsl_rng_uniform_pos (r) * (xu[i] - xl[i]);
  102. }
  103. {
  104. double fval = GSL_MONTE_FN_EVAL (f, x);
  105. /* recurrence for mean and variance */
  106. double d = fval - m;
  107. m += d / (n + 1.0);
  108. q += d * d * (n / (n + 1.0));
  109. }
  110. }
  111. *result = vol * m;
  112. *abserr = vol * sqrt (q / (calls * (calls - 1.0)));
  113. return GSL_SUCCESS;
  114. }
  115. estimate_calls = GSL_MAX (min_calls, calls * (state->estimate_frac));
  116. if (estimate_calls < 4 * dim)
  117. {
  118. GSL_ERROR ("insufficient calls to sample all halfspaces", GSL_ESANITY);
  119. }
  120. /* Flip coins to bisect the integration region with some fuzz */
  121. for (i = 0; i < dim; i++)
  122. {
  123. s = (gsl_rng_uniform (r) - 0.5) >= 0.0 ? state->dither : -state->dither;
  124. state->xmid[i] = (0.5 + s) * xl[i] + (0.5 - s) * xu[i];
  125. }
  126. /* The idea is to chose the direction to bisect based on which will
  127. give the smallest total variance. We could (and may do so later)
  128. use MC to compute these variances. But the NR guys simply estimate
  129. the variances by finding the min and max function values
  130. for each half-region for each bisection. */
  131. estimate_corrmc (f, xl, xu, dim, estimate_calls,
  132. r, state, &res_est, &err_est, xmid, sigma_l, sigma_r);
  133. /* We have now used up some calls for the estimation */
  134. calls -= estimate_calls;
  135. /* Now find direction with the smallest total "variance" */
  136. {
  137. double best_var = GSL_DBL_MAX;
  138. double beta = 2.0 / (1.0 + state->alpha);
  139. found_best = 0;
  140. i_bisect = 0;
  141. weight_l = weight_r = 1.0;
  142. for (i = 0; i < dim; i++)
  143. {
  144. if (sigma_l[i] >= 0 && sigma_r[i] >= 0)
  145. {
  146. /* estimates are okay */
  147. double var = pow (sigma_l[i], beta) + pow (sigma_r[i], beta);
  148. if (var <= best_var)
  149. {
  150. found_best = 1;
  151. best_var = var;
  152. i_bisect = i;
  153. weight_l = pow (sigma_l[i], beta);
  154. weight_r = pow (sigma_r[i], beta);
  155. }
  156. }
  157. else
  158. {
  159. if (sigma_l[i] < 0)
  160. {
  161. GSL_ERROR ("no points in left-half space!", GSL_ESANITY);
  162. }
  163. if (sigma_r[i] < 0)
  164. {
  165. GSL_ERROR ("no points in right-half space!", GSL_ESANITY);
  166. }
  167. }
  168. }
  169. }
  170. if (!found_best)
  171. {
  172. /* All estimates were the same, so chose a direction at random */
  173. i_bisect = gsl_rng_uniform_int (r, dim);
  174. }
  175. xbi_l = xl[i_bisect];
  176. xbi_m = xmid[i_bisect];
  177. xbi_r = xu[i_bisect];
  178. /* Get the actual fractional sizes of the two "halves", and
  179. distribute the remaining calls among them */
  180. {
  181. double fraction_l = fabs ((xbi_m - xbi_l) / (xbi_r - xbi_l));
  182. double fraction_r = 1 - fraction_l;
  183. double a = fraction_l * weight_l;
  184. double b = fraction_r * weight_r;
  185. calls_l = min_calls + (calls - 2 * min_calls) * a / (a + b);
  186. calls_r = min_calls + (calls - 2 * min_calls) * b / (a + b);
  187. }
  188. /* Compute the integral for the left hand side of the bisection */
  189. /* Due to the recursive nature of the algorithm we must allocate
  190. some new memory for each recursive call */
  191. {
  192. int status;
  193. double *xu_tmp = (double *) malloc (dim * sizeof (double));
  194. if (xu_tmp == 0)
  195. {
  196. GSL_ERROR_VAL ("out of memory for left workspace", GSL_ENOMEM, 0);
  197. }
  198. for (i = 0; i < dim; i++)
  199. {
  200. xu_tmp[i] = xu[i];
  201. }
  202. xu_tmp[i_bisect] = xbi_m;
  203. status = gsl_monte_miser_integrate (f, xl, xu_tmp,
  204. dim, calls_l, r, state,
  205. &res_l, &err_l);
  206. free (xu_tmp);
  207. if (status != GSL_SUCCESS)
  208. {
  209. return status;
  210. }
  211. }
  212. /* Compute the integral for the right hand side of the bisection */
  213. {
  214. int status;
  215. double *xl_tmp = (double *) malloc (dim * sizeof (double));
  216. if (xl_tmp == 0)
  217. {
  218. GSL_ERROR_VAL ("out of memory for right workspace", GSL_ENOMEM, 0);
  219. }
  220. for (i = 0; i < dim; i++)
  221. {
  222. xl_tmp[i] = xl[i];
  223. }
  224. xl_tmp[i_bisect] = xbi_m;
  225. status = gsl_monte_miser_integrate (f, xl_tmp, xu,
  226. dim, calls_r, r, state,
  227. &res_r, &err_r);
  228. free (xl_tmp);
  229. if (status != GSL_SUCCESS)
  230. {
  231. return status;
  232. }
  233. }
  234. *result = res_l + res_r;
  235. *abserr = sqrt (err_l * err_l + err_r * err_r);
  236. return GSL_SUCCESS;
  237. }
  238. gsl_monte_miser_state *
  239. gsl_monte_miser_alloc (size_t dim)
  240. {
  241. gsl_monte_miser_state *s =
  242. (gsl_monte_miser_state *) malloc (sizeof (gsl_monte_miser_state));
  243. if (s == 0)
  244. {
  245. GSL_ERROR_VAL ("failed to allocate space for miser state struct",
  246. GSL_ENOMEM, 0);
  247. }
  248. s->x = (double *) malloc (dim * sizeof (double));
  249. if (s->x == 0)
  250. {
  251. free (s);
  252. GSL_ERROR_VAL ("failed to allocate space for x", GSL_ENOMEM, 0);
  253. }
  254. s->xmid = (double *) malloc (dim * sizeof (double));
  255. if (s->xmid == 0)
  256. {
  257. free (s->x);
  258. free (s);
  259. GSL_ERROR_VAL ("failed to allocate space for xmid", GSL_ENOMEM, 0);
  260. }
  261. s->sigma_l = (double *) malloc (dim * sizeof (double));
  262. if (s->sigma_l == 0)
  263. {
  264. free (s->xmid);
  265. free (s->x);
  266. free (s);
  267. GSL_ERROR_VAL ("failed to allocate space for sigma_l", GSL_ENOMEM, 0);
  268. }
  269. s->sigma_r = (double *) malloc (dim * sizeof (double));
  270. if (s->sigma_r == 0)
  271. {
  272. free (s->sigma_l);
  273. free (s->xmid);
  274. free (s->x);
  275. free (s);
  276. GSL_ERROR_VAL ("failed to allocate space for sigma_r", GSL_ENOMEM, 0);
  277. }
  278. s->fmax_l = (double *) malloc (dim * sizeof (double));
  279. if (s->fmax_l == 0)
  280. {
  281. free (s->sigma_r);
  282. free (s->sigma_l);
  283. free (s->xmid);
  284. free (s->x);
  285. free (s);
  286. GSL_ERROR_VAL ("failed to allocate space for fmax_l", GSL_ENOMEM, 0);
  287. }
  288. s->fmax_r = (double *) malloc (dim * sizeof (double));
  289. if (s->fmax_r == 0)
  290. {
  291. free (s->fmax_l);
  292. free (s->sigma_r);
  293. free (s->sigma_l);
  294. free (s->xmid);
  295. free (s->x);
  296. free (s);
  297. GSL_ERROR_VAL ("failed to allocate space for fmax_r", GSL_ENOMEM, 0);
  298. }
  299. s->fmin_l = (double *) malloc (dim * sizeof (double));
  300. if (s->fmin_l == 0)
  301. {
  302. free (s->fmax_r);
  303. free (s->fmax_l);
  304. free (s->sigma_r);
  305. free (s->sigma_l);
  306. free (s->xmid);
  307. free (s->x);
  308. free (s);
  309. GSL_ERROR_VAL ("failed to allocate space for fmin_l", GSL_ENOMEM, 0);
  310. }
  311. s->fmin_r = (double *) malloc (dim * sizeof (double));
  312. if (s->fmin_r == 0)
  313. {
  314. free (s->fmin_l);
  315. free (s->fmax_r);
  316. free (s->fmax_l);
  317. free (s->sigma_r);
  318. free (s->sigma_l);
  319. free (s->xmid);
  320. free (s->x);
  321. free (s);
  322. GSL_ERROR_VAL ("failed to allocate space for fmin_r", GSL_ENOMEM, 0);
  323. }
  324. s->fsum_l = (double *) malloc (dim * sizeof (double));
  325. if (s->fsum_l == 0)
  326. {
  327. free (s->fmin_r);
  328. free (s->fmin_l);
  329. free (s->fmax_r);
  330. free (s->fmax_l);
  331. free (s->sigma_r);
  332. free (s->sigma_l);
  333. free (s->xmid);
  334. free (s->x);
  335. free (s);
  336. GSL_ERROR_VAL ("failed to allocate space for fsum_l", GSL_ENOMEM, 0);
  337. }
  338. s->fsum_r = (double *) malloc (dim * sizeof (double));
  339. if (s->fsum_r == 0)
  340. {
  341. free (s->fsum_l);
  342. free (s->fmin_r);
  343. free (s->fmin_l);
  344. free (s->fmax_r);
  345. free (s->fmax_l);
  346. free (s->sigma_r);
  347. free (s->sigma_l);
  348. free (s->xmid);
  349. free (s->x);
  350. free (s);
  351. GSL_ERROR_VAL ("failed to allocate space for fsum_r", GSL_ENOMEM, 0);
  352. }
  353. s->fsum2_l = (double *) malloc (dim * sizeof (double));
  354. if (s->fsum2_l == 0)
  355. {
  356. free (s->fsum_r);
  357. free (s->fsum_l);
  358. free (s->fmin_r);
  359. free (s->fmin_l);
  360. free (s->fmax_r);
  361. free (s->fmax_l);
  362. free (s->sigma_r);
  363. free (s->sigma_l);
  364. free (s->xmid);
  365. free (s->x);
  366. free (s);
  367. GSL_ERROR_VAL ("failed to allocate space for fsum2_l", GSL_ENOMEM, 0);
  368. }
  369. s->fsum2_r = (double *) malloc (dim * sizeof (double));
  370. if (s->fsum2_r == 0)
  371. {
  372. free (s->fsum2_l);
  373. free (s->fsum_r);
  374. free (s->fsum_l);
  375. free (s->fmin_r);
  376. free (s->fmin_l);
  377. free (s->fmax_r);
  378. free (s->fmax_l);
  379. free (s->sigma_r);
  380. free (s->sigma_l);
  381. free (s->xmid);
  382. free (s->x);
  383. free (s);
  384. GSL_ERROR_VAL ("failed to allocate space for fsum2_r", GSL_ENOMEM, 0);
  385. }
  386. s->hits_r = (size_t *) malloc (dim * sizeof (size_t));
  387. if (s->hits_r == 0)
  388. {
  389. free (s->fsum2_r);
  390. free (s->fsum2_l);
  391. free (s->fsum_r);
  392. free (s->fsum_l);
  393. free (s->fmin_r);
  394. free (s->fmin_l);
  395. free (s->fmax_r);
  396. free (s->fmax_l);
  397. free (s->sigma_r);
  398. free (s->sigma_l);
  399. free (s->xmid);
  400. free (s->x);
  401. free (s);
  402. GSL_ERROR_VAL ("failed to allocate space for fsum2_r", GSL_ENOMEM, 0);
  403. }
  404. s->hits_l = (size_t *) malloc (dim * sizeof (size_t));
  405. if (s->hits_l == 0)
  406. {
  407. free (s->hits_r);
  408. free (s->fsum2_r);
  409. free (s->fsum2_l);
  410. free (s->fsum_r);
  411. free (s->fsum_l);
  412. free (s->fmin_r);
  413. free (s->fmin_l);
  414. free (s->fmax_r);
  415. free (s->fmax_l);
  416. free (s->sigma_r);
  417. free (s->sigma_l);
  418. free (s->xmid);
  419. free (s->x);
  420. free (s);
  421. GSL_ERROR_VAL ("failed to allocate space for fsum2_r", GSL_ENOMEM, 0);
  422. }
  423. s->dim = dim;
  424. gsl_monte_miser_init (s);
  425. return s;
  426. }
  427. int
  428. gsl_monte_miser_init (gsl_monte_miser_state * s)
  429. {
  430. /* We use 8 points in each halfspace to estimate the variance. There are
  431. 2*dim halfspaces. A variance estimate requires a minimum of 2 points. */
  432. s->min_calls = 16 * s->dim;
  433. s->min_calls_per_bisection = 32 * s->min_calls;
  434. s->estimate_frac = 0.1;
  435. s->alpha = 2.0;
  436. s->dither = 0.0;
  437. return GSL_SUCCESS;
  438. }
  439. void
  440. gsl_monte_miser_free (gsl_monte_miser_state * s)
  441. {
  442. free (s->hits_r);
  443. free (s->hits_l);
  444. free (s->fsum2_r);
  445. free (s->fsum2_l);
  446. free (s->fsum_r);
  447. free (s->fsum_l);
  448. free (s->fmin_r);
  449. free (s->fmin_l);
  450. free (s->fmax_r);
  451. free (s->fmax_l);
  452. free (s->sigma_r);
  453. free (s->sigma_l);
  454. free (s->xmid);
  455. free (s->x);
  456. free (s);
  457. }
  458. static int
  459. estimate_corrmc (gsl_monte_function * f,
  460. const double xl[], const double xu[],
  461. size_t dim, size_t calls,
  462. gsl_rng * r,
  463. gsl_monte_miser_state * state,
  464. double *result, double *abserr,
  465. const double xmid[], double sigma_l[], double sigma_r[])
  466. {
  467. size_t i, n;
  468. double *x = state->x;
  469. double *fsum_l = state->fsum_l;
  470. double *fsum_r = state->fsum_r;
  471. double *fsum2_l = state->fsum2_l;
  472. double *fsum2_r = state->fsum2_r;
  473. size_t *hits_l = state->hits_l;
  474. size_t *hits_r = state->hits_r;
  475. double m = 0.0, q = 0.0;
  476. double vol = 1.0;
  477. for (i = 0; i < dim; i++)
  478. {
  479. vol *= xu[i] - xl[i];
  480. hits_l[i] = hits_r[i] = 0;
  481. fsum_l[i] = fsum_r[i] = 0.0;
  482. fsum2_l[i] = fsum2_r[i] = 0.0;
  483. sigma_l[i] = sigma_r[i] = -1;
  484. }
  485. for (n = 0; n < calls; n++)
  486. {
  487. double fval;
  488. unsigned int j = (n/2) % dim;
  489. unsigned int side = (n % 2);
  490. for (i = 0; i < dim; i++)
  491. {
  492. double z = gsl_rng_uniform_pos (r) ;
  493. if (i != j)
  494. {
  495. x[i] = xl[i] + z * (xu[i] - xl[i]);
  496. }
  497. else
  498. {
  499. if (side == 0)
  500. {
  501. x[i] = xmid[i] + z * (xu[i] - xmid[i]);
  502. }
  503. else
  504. {
  505. x[i] = xl[i] + z * (xmid[i] - xl[i]);
  506. }
  507. }
  508. }
  509. fval = GSL_MONTE_FN_EVAL (f, x);
  510. /* recurrence for mean and variance */
  511. {
  512. double d = fval - m;
  513. m += d / (n + 1.0);
  514. q += d * d * (n / (n + 1.0));
  515. }
  516. /* compute the variances on each side of the bisection */
  517. for (i = 0; i < dim; i++)
  518. {
  519. if (x[i] <= xmid[i])
  520. {
  521. fsum_l[i] += fval;
  522. fsum2_l[i] += fval * fval;
  523. hits_l[i]++;
  524. }
  525. else
  526. {
  527. fsum_r[i] += fval;
  528. fsum2_r[i] += fval * fval;
  529. hits_r[i]++;
  530. }
  531. }
  532. }
  533. for (i = 0; i < dim; i++)
  534. {
  535. double fraction_l = (xmid[i] - xl[i]) / (xu[i] - xl[i]);
  536. if (hits_l[i] > 0)
  537. {
  538. fsum_l[i] /= hits_l[i];
  539. sigma_l[i] = sqrt (fsum2_l[i] - fsum_l[i] * fsum_l[i] / hits_l[i]);
  540. sigma_l[i] *= fraction_l * vol / hits_l[i];
  541. }
  542. if (hits_r[i] > 0)
  543. {
  544. fsum_r[i] /= hits_r[i];
  545. sigma_r[i] = sqrt (fsum2_r[i] - fsum_r[i] * fsum_r[i] / hits_r[i]);
  546. sigma_r[i] *= (1 - fraction_l) * vol / hits_r[i];
  547. }
  548. }
  549. *result = vol * m;
  550. if (calls < 2)
  551. {
  552. *abserr = GSL_POSINF;
  553. }
  554. else
  555. {
  556. *abserr = vol * sqrt (q / (calls * (calls - 1.0)));
  557. }
  558. return GSL_SUCCESS;
  559. }