root/trunk/monte-carlo.lisp

Revision 34, 11.1 kB (checked in by lhealy, 7 months ago)

The classes/types in the different contexts are now gathered together
in one place, in *type-names* for the types and in *data-class-name*
for data classes, populated by #'add-data-class. Both defdata and
defmfun-all use the table and so mapping between various names is
consistent. The data class names are now different, *-double-float
and *-single-float replaces *-double and *-single. The regression
tests give the same results as before.

  • Property svn:keywords set to Id
Line 
1;; Monte Carlo Integration
2;; Liam Healy Sat Feb  3 2007 - 17:42
3;; Time-stamp: <2008-03-09 19:29:43EDT monte-carlo.lisp>
4;; $Id$
5
6(in-package :gsl)
7
8;;;;****************************************************************************
9;;;; PLAIN Monte Carlo
10;;;;****************************************************************************
11
12(cffi:defcstruct plain-state
13  (dim size)
14  (x :pointer))
15
16(defgo-s (monte-carlo-plain dim) monte-carlo-plain-alloc monte-carlo-plain-free)
17
18(defmfun monte-carlo-plain-alloc (dim)
19  "gsl_monte_plain_alloc"
20  ((dim size))
21  :c-return :pointer
22  :export nil
23  :index (letm monte-carlo-plain)
24  :documentation                        ; FDL
25  "Allocate and initialize a workspace for Monte Carlo
26   integration in dim dimensions.")
27
28(defmfun monte-carlo-plain-init (integrator-state)
29  "gsl_monte_plain_init"
30  ((integrator-state :pointer))
31  :documentation                        ; FDL
32  "Initialize a previously allocated integration state.
33   This allows an existing workspace to be reused for different
34   integrations.")
35
36(defmfun monte-carlo-plain-free (integrator-state)
37  "gsl_monte_plain_free"
38  ((integrator-state :pointer))
39  :c-return :void
40  :export nil
41  :index (letm monte-carlo-plain)
42  :documentation                        ; FDL
43  "Frees the memory associated with the integrator.")
44
45(defmfun monte-carlo-integrate-plain
46    (function lower-limits upper-limits calls generator state)
47  "gsl_monte_plain_integrate"
48  ((function :pointer)
49   ((gsl-array lower-limits) :pointer) ((gsl-array upper-limits) :pointer)
50   ((dim0 lower-limits) size) (calls size)
51   ((generator generator) :pointer)
52   (state :pointer)
53   (result :double) (abserr :double))
54  :documentation                        ; FDL
55  "Uses the plain Monte Carlo algorithm to integrate the
56   function f over the hypercubic region defined by the
57   lower and upper limits in the arrays 'lower-limits and
58   'upper-limits, each a gsl-vector of length dim.
59   The integration uses a fixed number
60   of function calls calls, and obtains random sampling points using
61   the random number generator 'generator. A previously allocated workspace
62   'state must be supplied.  The result of the integration is returned
63   with an estimated absolute error.")
64
65;;;;****************************************************************************
66;;;; MISER
67;;;;****************************************************************************
68
69;;; The MISER algorithm of Press and Farrar is based on recursive
70;;; stratified sampling.  This technique aims to reduce the overall
71;;; integration error by concentrating integration points in the
72;;; regions of highest variance.
73
74(cffi:defcstruct miser-state
75  (min-calls size)
76  (min-calls-per-bisection size)
77  (dither :double)
78  (estimate-frac :double)
79  (alpha :double)
80  (dim size)
81  (estimate-style :int)
82  (depth :int)
83  (verbose :int)
84  (x :pointer)
85  (xmid :pointer)
86  (sigma-l :pointer)
87  (sigma-r :pointer)
88  (fmax-l :pointer)
89  (fmax-r :pointer)
90  (fmin-l :pointer)
91  (fmin-r :pointer)
92  (fsum-l :pointer)
93  (fsum-r :pointer)
94  (fsum2-l :pointer)
95  (fsum2-r :pointer)
96  (hits-l :pointer)
97  (hits-r :pointer))
98
99(defgo-s (monte-carlo-miser dim) monte-carlo-miser-alloc monte-carlo-miser-free)
100
101(defmfun monte-carlo-miser-alloc (dim)
102  "gsl_monte_miser_alloc"
103  ((dim size))
104  :c-return :pointer
105  :export nil
106  :index (letm monte-carlo-miser)
107  :documentation                        ; FDL
108  "Allocate and initialize a workspace for Monte Carlo integration in
109   dim dimensions.  The workspace is used to maintain
110   the state of the integration.  Returns a pointer to miser-state.")
111
112(defmfun monte-carlo-miser-init (integrator-state)
113  "gsl_monte_miser_init"
114  ((integrator-state :pointer))
115  :documentation                        ; FDL
116  "Initialize a previously allocated integration state.
117   This allows an existing workspace to be reused for different
118   integrations.")
119
120(defmfun monte-carlo-miser-free (integrator-state)
121  "gsl_monte_miser_free"
122  ((integrator-state :pointer))
123  :c-return :void
124  :export nil
125  :index (letm monte-carlo-miser)
126  :documentation                        ; FDL
127  "Frees the memory associated with the integrator.")
128
129(export 'miser-parameter)
130(defmacro miser-parameter (workspace parameter)
131  ;; FDL
132  "Get or set with setf the parameter value for the MISER Monte Carlo
133   integration method."
134  ;; (miser-parameter ws min-calls)
135  ;; (setf (miser-parameter ws min-calls) 300)
136 `(foreign-slot-value ,workspace 'miser-state ',parameter))
137
138(defmfun monte-carlo-integrate-miser
139    (function lower-limits upper-limits calls generator state)
140  "gsl_monte_miser_integrate"
141  ((function :pointer)
142   ((gsl-array lower-limits) :pointer) ((gsl-array upper-limits) :pointer)
143   ((dim0 lower-limits) size) (calls size)
144   ((generator generator) :pointer)
145   (state :pointer)
146   (result :double) (abserr :double))
147  :documentation                        ; FDL
148  "Uses the miser Monte Carlo algorithm to integrate the
149   function f over the hypercubic region defined by the
150   lower and upper limits in the arrays 'lower-limits and
151   'upper-limits, each a gsl-vector of the samelength
152   The integration uses a fixed number
153   of function calls calls, and obtains random sampling points using
154   the random number generator 'generator. A previously allocated workspace
155   'state must be supplied.  The result of the integration is returned
156   with an estimated absolute error.")
157
158;;;;****************************************************************************
159;;;; VEGAS
160;;;;****************************************************************************
161
162;;; The vegas algorithm of Lepage is based on importance sampling.  It
163;;; samples points from the probability distribution described by the
164;;; function |f|, so that the points are concentrated in the regions
165;;; that make the largest contribution to the integral.
166
167(cffi:defcstruct vegas-state
168  ;; grid
169  (dim size)
170  (bins-max size)
171  (bins :uint)                          ; uint
172  (boxes :uint)                ; these are both counted along the axes
173  (xi :pointer)
174  (xin :pointer)
175  (delx :pointer)
176  (weight :pointer)
177  (vol :double)
178  (x :pointer)
179  (bin :pointer)
180  (box :pointer)
181  (d :pointer)                          ; distribution
182  ;; control variables
183  (alpha :double)
184  (mode :int)
185  (verbose :int)
186  (iterations :uint)
187  (stage :int)
188  ;; scratch variables preserved between calls to vegas1/2/3
189  (jac :double)
190  (wtd-int-sum :double)
191  (sum-wgts :double)
192  (chi-sum :double)
193  (chisq :double)
194  (result :double)
195  (sigma :double)
196  (it-start :uint)
197  (it-num :uint)
198  (samples :uint)
199  (calls-per-box :uint)
200  (ostream :pointer))
201
202(defgo-s (monte-carlo-vegas dim) monte-carlo-vegas-alloc monte-carlo-vegas-free)
203
204(defmfun monte-carlo-vegas-alloc (dim)
205  "gsl_monte_vegas_alloc"
206  ((dim size))
207  :c-return :pointer
208  :export nil
209  :index (letm monte-carlo-vegas)
210  :documentation                        ; FDL
211  "Allocate and initialize a workspace for Monte Carlo integration in
212   dim dimensions.  The workspace is used to maintain
213   the state of the integration.  Returns a pointer to vegas-state.")
214
215(defmfun monte-carlo-vegas-init (integrator-state)
216  "gsl_monte_vegas_init"
217  ((integrator-state :pointer))
218  :documentation                        ; FDL
219  "Initialize a previously allocated integration state.
220   This allows an existing workspace to be reused for different
221   integrations.")
222
223(defmfun monte-carlo-vegas-free (integrator-state)
224  "gsl_monte_vegas_free"
225  ((integrator-state :pointer))
226  :c-return :void
227  :export nil
228  :index (letm monte-carlo-vegas)
229  :documentation                        ; FDL
230  "Frees the memory associated with the integrator.")
231
232(export 'vegas-parameter)
233(defmacro vegas-parameter (workspace parameter)
234  ;; FDL
235  "Get or set with setf the parameter value for the VEGAS Monte Carlo
236   integration method."
237  ;; (vegas-parameter ws bins-max)
238  ;; (setf (vegas-parameter ws bins-max) 300)
239 `(foreign-slot-value ,workspace 'vegas-state ',parameter))
240
241(defmfun monte-carlo-integrate-vegas
242    (function lower-limits upper-limits calls generator state)
243  "gsl_monte_vegas_integrate"
244  ((function :pointer)
245   ((gsl-array lower-limits) :pointer) ((gsl-array upper-limits) :pointer)
246   ((dim0 lower-limits) size) (calls size)
247   ((generator generator) :pointer)
248   (state :pointer)
249   (result :double) (abserr :double))
250  :documentation                        ; FDL
251  "Uses the vegas Monte Carlo algorithm to integrate the
252   function f over the dim-dimensional hypercubic region
253   defined by the lower and upper limits in the arrays x1 and
254   xu, each of size dim.  The integration uses a fixed number
255   of function calls calls, and obtains random sampling points using
256   the random number generator r.  A previously allocated workspace
257   s must be supplied.  The result of the integration is returned
258   with an estimated absolute error.  The result
259   and its error estimate are based on a weighted average of independent
260   samples. The chi-squared per degree of freedom for the weighted average
261   is returned via the state struct component, s->chisq, and must be
262   consistent with 1 for the weighted average to be reliable.")
263
264;;;;****************************************************************************
265;;;; Callback definition
266;;;;****************************************************************************
267
268(cffi:defcstruct monte-function
269  (function :pointer)
270  (dimensions size)
271  (parameters :pointer))
272
273(export 'def-mc-function)
274(defmacro def-mc-function (name dimensions)
275  `(def-single-function ,name :double :pointer monte-function
276    ((dimensions ,dimensions))))
277
278;;;;****************************************************************************
279;;;; Examples and unit test
280;;;;****************************************************************************
281
282;;; Example from Sec. 23.5
283;;; This is a function that occurs in random walk studies.
284
285(defun monte-carlo-g (arg)
286  (with-c-double (arg x y z)
287    (* (/ (expt pi 3))
288       (/ (- 1 (* (cos x) (cos y) (cos z)))))))
289
290(def-mc-function monte-carlo-g 3)
291
292(defun random-walk-plain-example (&optional (nsamples 500000))
293  (letm ((ws (monte-carlo-plain 3))
294         (lower (vector-double-float #(0.0d0 0.0d0 0.0d0)))
295         (upper (vector-double-float (vector pi pi pi)))
296         (rng (random-number-generator *mt19937* 0)))
297    (monte-carlo-integrate-plain monte-carlo-g lower upper nsamples rng ws)))
298
299(defun random-walk-miser-example (&optional (nsamples 500000))
300  (letm ((ws (monte-carlo-miser 3))
301         (lower (vector-double-float #(0.0d0 0.0d0 0.0d0)))
302         (upper (vector-double-float (vector pi pi pi)))
303         (rng (random-number-generator *mt19937* 0)))
304    (monte-carlo-integrate-miser monte-carlo-g lower upper nsamples rng ws)))
305
306(defun random-walk-vegas-example (&optional (nsamples 500000))
307  (letm ((ws (monte-carlo-vegas 3))
308         (lower (vector-double-float #(0.0d0 0.0d0 0.0d0)))
309         (upper (vector-double-float (vector pi pi pi)))
310         (rng (random-number-generator *mt19937* 0)))
311    (monte-carlo-integrate-vegas monte-carlo-g lower upper nsamples rng ws)))
312
313#|
314(make-tests monte-carlo
315  (random-walk-plain-example)
316  (random-walk-miser-example)
317  (random-walk-vegas-example))
318|#
319
320(LISP-UNIT:DEFINE-TEST MONTE-CARLO
321  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
322   (LIST 1.4122087033540667d0 0.013435861456267064d0)
323   (MULTIPLE-VALUE-LIST (RANDOM-WALK-PLAIN-EXAMPLE)))
324  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
325   (LIST 1.3895297058825096d0 0.0050106269732269415d0)
326   (MULTIPLE-VALUE-LIST (RANDOM-WALK-MISER-EXAMPLE)))
327  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
328   (LIST 1.3931632739551914d0 1.4981164744582692d-4)
329   (MULTIPLE-VALUE-LIST (RANDOM-WALK-VEGAS-EXAMPLE))))
330
Note: See TracBrowser for help on using the browser.