root/trunk/random/quasi.lisp

Revision 34, 4.9 kB (checked in by lhealy, 9 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;; Quasi-random sequences in arbitrary dimensions.
2;; Liam Healy, Sun Jul 16 2006 - 15:54
3;; Time-stamp: <2008-03-09 19:29:16EDT quasi.lisp>
4;; $Id$
5
6(in-package :gsl)
7
8(defclass quasi-random-number-generator (gsl-random)
9  ((dimension :initarg :dimension :accessor qr-dimension))
10  (:documentation "A generator of quasi-random numbers."))
11
12(defparameter *default-quasi-random-number-generator* nil)
13
14(defgo-s (quasi-random-number-generator dimension type)
15         make-quasi-random-number-generator free nil 2)
16
17(defun make-quasi-random-number-generator
18    (dimension
19     &optional (type *default-quasi-random-number-generator*)
20     (generator t))
21  "Make a random number generator; by default it is allocated on creation."
22  (let ((instance
23         (make-instance
24          'quasi-random-number-generator
25          :type type
26          :dimension dimension
27          :generator generator)))
28    (if (eq generator t) (alloc instance) instance)))
29
30(defmfun alloc ((generator quasi-random-number-generator))
31  "gsl_qrng_alloc"
32  (((rng-type generator) :pointer) ((qr-dimension generator) :uint))
33  :type :method
34  :c-return (ptr :pointer)
35  :return ((progn (setf (generator generator) ptr) generator))
36  :documentation                        ; FDL
37  "Instatiate a random number generator of specified type.
38   For example, create an instance of the Tausworthe
39   generator: (rng-alloc *taus*).
40   The generator is automatically initialized with the default seed,
41   *default-seed*.  This is zero by default but can be changed
42   either directly or by using the environment variable GSL_RNG_SEED.")
43
44(defmfun free ((generator quasi-random-number-generator))
45  "gsl_qrng_free" (((generator generator) :pointer))
46  :type :method
47  :c-return :void
48  :after ((setf (generator generator) nil))
49  :documentation                        ; FDL
50  "Free all the memory associated with the generator.")
51
52(defmfun init (generator)
53  "gsl_qrng_init" (((generator generator) :pointer))
54  :c-return :void
55  :documentation                        ; FDL
56  "Reinitializes the generator q to its starting point.
57   Note that quasi-random sequences do not use a seed and always produce
58   the same set of values.")
59
60(defmfun qrng-get (generator return-vector)
61  "gsl_qrng_get"
62  (((generator generator) :pointer) ((gsl-array return-vector) :pointer))
63  :documentation                        ; FDL
64  "Store the next point from the sequence generator q
65   in the array x.  The space available for x must match the
66   dimension of the generator.  The point x will lie in the range
67   0 < x_i < 1 for each x_i."
68  :invalidate (return-vector))
69
70(defmfun rng-name ((instance quasi-random-number-generator))
71  "gsl_qrng_name" (((generator instance) :pointer))
72  :type :method
73  :c-return :string)
74
75(defmfun rng-state ((instance quasi-random-number-generator))
76  "gsl_qrng_state" (((generator instance) :pointer))
77  :c-return :pointer
78  :type :method
79  :export nil
80  :index gsl-random-state)
81
82(defmfun rng-size ((instance quasi-random-number-generator))
83  "gsl_qrng_size" (((generator instance) :pointer))
84  :c-return size
85  :type :method
86  :export nil
87  :index gsl-random-state)
88
89(defmfun copy
90    ((destination quasi-random-number-generator)
91     (source quasi-random-number-generator))
92  "gsl_qrng_memcpy"
93  (((generator destination) :pointer) ((generator source) :pointer))
94  :type :method
95  :documentation                        ; FDL
96  "Copy the quasi-random sequence generator src into the
97   pre-existing generator dest, making dest into an exact copy
98   of src.  The two generators must be of the same type.")
99
100(defmfun clone-generator ((instance quasi-random-number-generator))
101  "gsl_qrng_clone" (((generator instance) :pointer))
102  :c-return :pointer
103  :type :method
104  :documentation                        ; FDL
105  "Create a new generator which is an exact copy of the original.
106   Don't use; use #'make-random-number-generator, #'copy instead.")
107
108(def-rng-type *niederreiter2*
109    ;; FDL
110    "Described in Bratley, Fox, Niederreiter,
111     ACM Trans. Model. Comp. Sim. 2, 195 (1992). It is
112     valid up to 12 dimensions."
113  "gsl_qrng_niederreiter_2")
114
115(eval-when (:load-toplevel :execute)
116 (setf *default-quasi-random-number-generator*
117       (make-quasi-random-number-generator 2 *niederreiter2*)))
118
119(def-rng-type *sobol*
120    ;; FDL
121    "This generator uses the Sobol sequence described in Antonov, Saleev,
122    USSR Comput. Maths. Math. Phys. 19, 252 (1980). It is valid up to
123    40 dimensions."
124  "gsl_qrng_sobol")
125
126;;; Examples and unit test
127#|
128(make-tests quasi-random-number-generators
129  ;; This example is given in the GSL documentation
130  (letm ((gen (quasi-random-number-generator 2 *sobol*))
131          (vec (vector-double-float 2)))
132     (loop repeat 5
133           do (qrng-get gen vec)
134           append (coerce (data vec) 'list))))
135|#
136
137(LISP-UNIT:DEFINE-TEST QUASI-RANDOM-NUMBER-GENERATORS
138  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
139   (LIST
140    (LIST 0.5d0 0.5d0 0.75d0 0.25d0 0.25d0 0.75d0 0.375d0
141          0.375d0 0.875d0 0.875d0))
142   (MULTIPLE-VALUE-LIST
143    (LETM
144        ((GEN (QUASI-RANDOM-NUMBER-GENERATOR 2 *SOBOL*))
145         (VEC (VECTOR-DOUBLE-FLOAT 2)))
146      (LOOP REPEAT 5 DO (QRNG-GET GEN VEC) APPEND
147            (COERCE (DATA VEC) 'LIST))))))
148
Note: See TracBrowser for help on using the browser.