root/trunk/simulated-annealing.lisp

Revision 38 (checked in by lhealy, 5 months ago)

Indicate in documentation.html that simulated annealing is being
rewritten in GSL.

  • Property svn:keywords set to Id
Line 
1 ;; Simulated Annealing
2 ;; Liam Healy Sun Feb 11 2007 - 17:23
3 ;; Time-stamp: <2008-03-15 23:10:25EDT simulated-annealing.lisp>
4 ;; $Id$
5
6 (in-package :gsl)
7
8 ;;; This does not work.
9 ;;; Step size passed to the step function is incorrect.
10 ;;; Print function is ignored, but probably couldn't work if it weren't.
11 ;;; Does not converge.
12
13
14 (cffi:defcstruct simulated-annealing-parameters
15   (n-tries :int)                ; how many points to try for each step
16   (iterations-fixed-T :int) ; how many iterations at each temperature?
17   (step-size :double)               ; max step size in the random walk
18   ;; The following parameters are for the Boltzmann distribution
19   (k :double)
20   (t-initial :double)
21   (mu-t :double)
22   (t-min :double))
23
24 (defmacro with-simulated-annealing-parameters
25     ((name number-of-tries iterations-per-temperature
26                       step-size &optional k t-initial mu-t t-min)
27      &body body)
28   `(cffi:with-foreign-object (,name 'simulated-annealing-parameters)
29     (setf
30      (cffi:foreign-slot-value
31       ,name 'simulated-annealing-parameters 'n-tries)
32      ,number-of-tries
33      (cffi:foreign-slot-value
34       ,name 'simulated-annealing-parameters 'iterations-fixed-T)
35      ,iterations-per-temperature
36      (cffi:foreign-slot-value
37       ,name 'simulated-annealing-parameters 'step-size)
38      ,step-size
39      ;; The following parameters are for the Boltzmann distribution
40      (cffi:foreign-slot-value
41       ,name 'simulated-annealing-parameters 'k)
42      ,k
43      (cffi:foreign-slot-value
44       ,name 'simulated-annealing-parameters 't-initial)
45      ,t-initial
46      (cffi:foreign-slot-value
47       ,name 'simulated-annealing-parameters 'mu-t)
48      ,mu-t
49      (cffi:foreign-slot-value
50       ,name 'simulated-annealing-parameters 't-min)
51      ,t-min)
52     ,@body))
53
54 (defmfun simulated-annealing
55     (generator x0-p
56                Ef take-step distance-function
57                 print-position
58                 ;; copy-function copy-constructor destructor
59                element-size parameters)
60   "gsl_siman_solve"
61   (((generator generator) :pointer) (x0-p :pointer)
62    ((cffi:get-callback Ef) :pointer)
63    ((cffi:get-callback take-step) :pointer)
64    ((cffi:get-callback distance-function) :pointer)
65    ((cffi:get-callback print-position) :pointer)
66    ((cffi:null-pointer) :pointer)
67    ((cffi:null-pointer) :pointer)
68    ((cffi:null-pointer) :pointer)
69    ;;((cffi:get-callback copy-function) :pointer)
70    ;;((cffi:get-callback copy-constructor) :pointer)
71    ;;((cffi:get-callback destructor) :pointer)
72    (element-size size) (parameters simulated-annealing-parameters))
73   :c-return :void
74   :documentation                        ; FDL
75   "Perform a simulated annealing search through a given
76    space.  The space is specified by providing the functions Ef and
77    distance.  The simulated annealing steps are generated using the
78    random number generator r and the function take-step.
79
80    The starting configuration of the system should be given by x0-p
81    The routine offers two modes for updating configurations, a fixed-size
82    mode and a variable-size mode.  In the fixed-size mode the configuration
83    is stored as a single block of memory of size element-size
84    The functions copy-function,
85    copy-constructor and destructor should be NIL in
86    fixed-size mode.  In the variable-size mode the functions
87    copy-function, copy-constructor and destructor are used to
88    create, copy and destroy configurations internally.  The variable
89    element-size should be zero in the variable-size mode.
90
91    The parameters structure (described below) controls the run by
92    providing the temperature schedule and other tunable parameters to the
93    algorithm.
94
95    On exit the best result achieved during the search is placed in
96    x0-p.  If the annealing process has been successful this
97    should be a good approximation to the optimal point in the space.
98
99    If the function pointer print-position is not null, a debugging
100    log will be printed to standard output with the following columns:
101    number_of_iterations temperature x x-x0p Ef(x)
102    and the output of the function print-position itself.  If
103    print-position is null then no information is printed.
104    The simulated annealing routines require several user-specified
105    functions to define the configuration space and energy function.")
106
107 (defmacro def-energy-function (name)
108   "Define an energy or distance fuction for simulated annealing."
109   `(def-single-function ,name :double :pointer nil))
110
111 (defmacro def-step-function (name)
112   "Define a step fuction for simulated annealing."
113   (let ((generator (gensym "GEN"))
114         (arguments (gensym "ARGS"))
115         (step-size (gensym "SS")))
116     `(cffi:defcallback ,name :void
117       ((,generator :pointer) (,arguments :pointer) (,step-size :double))
118       (,name ,generator ,arguments ,step-size))))
119
120 (defmacro def-distance-function (name)
121   "Define a metric distance fuction for simulated annealing."
122   (let ((x (gensym "X"))
123         (y (gensym "Y")))
124     `(cffi:defcallback ,name :double
125       ((,x :pointer) (,y :pointer))
126       (,name ,x ,y))))
127
128 (defmacro def-print-function (name)
129   "Define a print function for simulated annealing."
130   `(def-single-function ,name :int :pointer nil))
131
132 ;;;;****************************************************************************
133 ;;;; Example
134 ;;;;****************************************************************************
135
136 ;;; Trivial example, Sec. 24.3.1
137 ;;; This does not work.
138
139 (defun M2 (cx cy)
140   (with-c-double (cx x)
141     (with-c-double (cy y)
142       (abs (- x y)))))
143
144 (defvar *sa-function-calls*)
145
146 (defun E2 (arg)
147   (with-c-double (arg x)
148     (incf *sa-function-calls*)
149     (when (> *sa-function-calls* 100)
150       (error "too much"))
151     (* (exp (- (expt (1- x) 2))) (sin (* 8 x)))))
152
153 (defun S2 (generator parameters step-size)
154   (with-c-double (parameters x)
155     ;;(format t "~&~d ~d" x step-size)
156     (let ((step-size 10.0d0))           ; this is coming in wrong, so we fix it
157       (let ((rand (uniform generator)))
158         (setf x (+ x (- (* 2 rand step-size) step-size)))))))
159
160 (defparameter *sa-example-print* nil)
161
162 ;;; Print functions are a problem because it is likely that the C
163 ;;; stdout and the CL *standard-output* are not the same stream.
164 ;;; Also, it seems to ignore that a function is supplied, and avoids
165 ;;; printing anything.
166 (defun P2 (arg)
167   (with-c-double (arg x)
168     (when *sa-example-print*
169       (format T "~&from P2: ~a" x))))
170
171 (def-energy-function E2)
172 (def-distance-function M2)
173 (def-step-function S2)
174 (def-print-function P2)
175
176 (defun simulated-annealing-example ()
177   (let ((*sa-function-calls* 0))
178     (rng-environment-setup)
179     (cffi:with-foreign-object (initial :double)
180       (setf (dcref initial) 15.5d0)
181       (with-simulated-annealing-parameters
182           (params 200 10 10.0d0 1.0d0 0.002d0 1.005d0 2.0d-6)
183         (simulated-annealing
184          (make-random-number-generator) initial
185          'E2 'S2 'M2 'P2
186          (cffi:foreign-type-size :double)
187          params)))))
188
Note: See TracBrowser for help on using the browser.