X-shooter Pipeline Reference Manual 3.8.15
xsh_model_sa.c
Go to the documentation of this file.
1/* $Id: xsh_model_sa.c,v 1.8 2012-06-15 11:11:12 amodigli Exp $
2 *
3 *Not sure about the copyright stuff here!
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 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/*
21 * $Author: amodigli $
22 * $Date: 2012-06-15 11:11:12 $
23 * $Revision: 1.8 $
24 * $Name: not supported by cvs2svn $
25 */
26
27/* a collection of C routines for general purpose Simulated Annealing
28 intended to be the C equivalent of the C++ Simulated Annealing object
29 SimAnneal
30
31 Uses Cauchy training
32
33*/
34
35#ifdef HAVE_CONFIG_H
36#include <config.h>
37#endif
38/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
47/*-----------------------------------------------------------------------------
48 Includes
49 -----------------------------------------------------------------------------*/
50
51#include <cpl.h>
52
53#include "xsh_model_kernel.h"
54#include "xsh_model_metric.h"
55
56/*----------------------------------------------------------------------------*/
57
58//static char rcsid[] = "@(#)sa.c 1.2 15:54:31 3/30/93 EFC";
59
60#include <stdio.h>
61#include <math.h>
62#include <float.h>
63
64#include <stdlib.h> /* for malloc */
65
66/* #include <rands.h> */
67#include "xsh_model_r250.h"
68
69#include "xsh_model_sa.h"
70
71
72/* #define DEBUG */
73
74#ifdef _R250_H_
75#define uniform(a,b) ( a + (b - a) * xsh_dr250() )
76#endif
77
78#ifndef HUGE
79#define HUGE HUGE_VAL
80#endif
81
82#ifndef PI
83#define PI 3.1415626536
84#endif
85
86#ifndef PI2
87#define PI2 (PI/2.0)
88#endif
89
90typedef struct
91{
93 int dimension, maxit, dwell;
94 double *x, *xnew, *xbest;
95 float dt, c_jump, K, rho, t0, tscale, range;
96 double y, ybest;
97} SimAnneal;
98
99static SimAnneal s;
100
101/* iterate a few times at the present temperature */
102/* to get to thermal equilibrium */
103#ifdef NO_PROTO
104static int equilibrate(t, n)
105float t;
106int n;
107#else
108static int equilibrate(float t,int n)
109#endif
110{
111 int i, j, equil = 0;
112 float ynew, c, delta, tmpval;
113 double *xtmp;
114
115 delta = 1.0;
116 tmpval = s.rho * t;
117 for (i = 0; i < n; i++)
118 {
119 for (j = 0; j < s.dimension; j++)
120 {
121 s.xnew[j] = s.x[j] + (tmpval*tan ( uniform( -s.range, s.range ) ));
122 }
123 /* "energy" */
124 ynew = s.func( s.xnew );
125 c = ynew - s.y;
126
127 if (c < 0.0) /* keep xnew if energy is reduced */
128 {
129 xtmp = s.x;
130 s.x = s.xnew;
131 s.xnew = xtmp;
132
133 s.y = ynew;
134 if ( s.y < s.ybest )
135 {
136 for (j = 0; j < s.dimension; j++)
137 s.xbest[j] = s.x[j];
138 s.ybest = s.y;
139 }
140
141 delta = fabs( c );
142 delta = ( s.y != 0.0 ) ? delta / s.y : ( ynew != 0.0 ) ?
143 delta / ynew : delta;
144
145 /* equilibrium is defined as a 10% or smaller change
146 in 10 iterations */
147 if ( delta < 0.10 )
148 equil++;
149 else
150 equil = 0;
151
152
153 }
154 else
155 {
156 /* keep xnew with probability, p, if ynew is increased */
157/*
158 p = exp( - (ynew - s.y) / (s.K * t) );
159
160 if ( p > number(0.0, 1.0) )
161 {
162 xtmp = s.x;
163 s.x = s.xnew;
164 s.xnew = xtmp;
165 s.y = ynew;
166 equil = 0;
167 }
168 else
169*/
170
171 equil++;
172 }
173
174 if (equil > 9)
175 break;
176
177
178
179 }
180
181 return i + 1;
182}
183
184
185/* initialize internal variables and define the cost function */
186#ifdef NO_PROTO
187int xsh_SAInit(f, d)
189int d;
190#else
192#endif
193{
194 int space;
195
196 s.func = f;
197 s.dimension = d;
198 s.t0 = 0.0;
199 s.K = 1.0;
200 s.rho = 0.5;
201 s.dt = 0.1;
202 s.tscale = 0.1;
203 s.maxit = 1;
204 s.c_jump = 100.0;
205 s.range = PI2;
206 s.dwell = 20;
207
208 space = s.dimension * sizeof(double);
209
210 if ( (s.x = (double *)cpl_malloc( space )) == NULL )
211 return 0;
212 if ( (s.xnew = (double *)cpl_malloc( space )) == NULL )
213 return 0;
214 if ( (s.xbest = (double *)cpl_malloc( space )) == NULL )
215 return 0;
216
217 s.y = s.ybest = HUGE;
218
219#ifdef _R250_H_
220 xsh_r250_init( 15256 );
221#endif
222
223 return 1;
224
225}
226
227void xsh_SAfree(void)
228{
229 cpl_free( s.x );
230 cpl_free( s.xnew );
231 cpl_free( s.xbest );
232 s.dimension = 0;
233}
234
235#ifdef NO_PROTO
237int m;
238#else
240#endif
241{
242 if ( m > 0 )
243 s.maxit = m;
244
245 return s.maxit;
246}
247
248#ifdef NO_PROTO
249int xsh_SAdwell(m)
250int m;
251#else
253#endif
254{
255 if ( m > 0 )
256 s.dwell = m;
257
258 return s.dwell;
259}
260
261
262
263#ifdef NO_PROTO
264float xsh_SABoltzmann(k)
265float k;
266#else
267float xsh_SABoltzmann(float k)
268#endif
269{
270 if ( k > 0.0 )
271 s.K = k;
272
273 return s.K;
274}
275
276#ifdef NO_PROTO
277float xsh_SAtemperature(t)
278float t;
279#else
280float xsh_SAtemperature(float t)
281#endif
282{
283 if ( t > 0.0 )
284 s.t0 = t;
285
286 return s.t0;
287}
288
289#ifdef NO_PROTO
290float xsh_SAlearning_rate(r)
291float r;
292#else
294#endif
295{
296 if ( r > 0.0 )
297 s.rho = r;
298
299 return s.rho;
300}
301
302#ifdef NO_PROTO
303float xsh_SAjump(j)
304float j;
305#else
306float xsh_SAjump(float j)
307#endif
308{
309 if ( j > 0.0 )
310 s.c_jump = j;
311
312 return s.c_jump;
313}
314
315#ifdef NO_PROTO
316float xsh_SArange(r)
317float r;
318#else
319float xsh_SArange(float r)
320#endif
321{
322 if ( r > 0.0 )
323 s.range = r;
324
325 return s.range;
326}
327
328
329#ifdef NO_PROTO
330void xsh_SAinitial(xi)
331float* xi;
332#else
333void xsh_SAinitial(double* xi)
334#endif
335{
336 int k;
337 for (k = 0; k < s.dimension; k++)
338 s.x[k] = xi[k];
339}
340
341#ifdef NO_PROTO
342void xsh_SAcurrent(xc)
343float* xc;
344#else
345void xsh_SAcurrent(double* xc)
346#endif
347{
348 int k;
349
350 for (k = 0; k < s.dimension; k++)
351 xc[k] = s.x[k];
352}
353
354#ifdef NO_PROTO
355void xsh_SAoptimum(xb)
356float* xb;
357#else
358void xsh_SAoptimum(double* xb)
359#endif
360{
361 int k;
362
363 for (k = 0; k < s.dimension; k++)
364 xb[k] = s.xbest[k];
365}
366
367
368
369
370/* increase the temperature until the system "melts" */
371#ifdef NO_PROTO
372float xsh_SAmelt(iters)
373int iters;
374#else
375float xsh_SAmelt(int iters)
376#endif
377{
378 int i, j, ok = 0;
379 float ynew, t, cold = 0.0, c = 0.0, tmpval;
380
381 int n = iters;
382 if ( n < 1 )
383 n = s.maxit;
384
385 t = s.t0;
386
387 for (i = 0; i < n; i++)
388 {
389 if (i > 0 && c > 0.0)
390 {
391 cold = c;
392 ok = 1;
393 }
394
395 t += s.dt;
396
397 tmpval = s.rho*t;
398 for (j = 0; j < s.dimension; j++)
399 {
400 s.x[j] += tmpval * tan ( uniform( -s.range, s.range ) );
401 }
402
403 equilibrate( t, s.dwell);
404
405 /* "energy" */
406 ynew = s.func( s.x );
407 c = ynew - s.y;
408
409 if ( c < 0.0 && ynew < s.ybest)
410 {
411 for (j = 0; j < s.dimension; j++)
412 s.xbest[j] = s.x[j];
413 s.ybest = ynew;
414 }
415
416 s.y = ynew;
417
418 if ( ok && c > (s.c_jump * cold) ) /* phase transition */
419 break;
420
421 }
422
423 return s.t0 = t;
424
425}
426
427/* cool the system with annealing */
428#ifdef NO_PROTO
429float xsh_SAanneal(iters)
430#else
431float xsh_SAanneal(int iters)
432#endif
433{
434 int i, j;
435 float p, ynew, t=0.0, c, dt, told, tmpval;
436 double *xtmp;
437
438
439 int n = iters;
440 if ( n < 1 )
441 n = s.maxit;
442
443 equilibrate( s.t0, 10 * s.dwell );
444
445 told = s.t0;
446 for (i = 0; i < n; i++)
447 {
448 t = s.t0 /(1.0 + i * s.tscale);
449 dt = t - told;
450 told = t;
451
452 equilibrate(t, s.dwell);
453
454 tmpval = s.rho * t;
455 for (j = 0; j < s.dimension; j++)
456 {
457/* s.xnew[j] = s.x[j] + xc; */
458 s.xnew[j] = tmpval * tan ( uniform( -s.range, s.range ) );
459 }
460 /* "energy" */
461
462 ynew = s.func( s.xnew );
463 c = ynew - s.y;
464
465 if (ynew <= s.y) /* keep xnew if energy is reduced */
466 {
467 xtmp = s.x;
468 s.x = s.xnew;
469 s.xnew = xtmp;
470 s.y = ynew;
471
472 if ( s.y < s.ybest )
473 {
474 for (j = 0; j < s.dimension; j++)
475 s.xbest[j] = s.x[j];
476 s.ybest = s.y;
477 }
478 continue;
479 }
480 else
481 {
482 /* keep xnew with probability, p, if ynew is increased */
483 p = exp( - (ynew - s.y) / (s.K * t) );
484
485 if ( p > uniform(0.0, 1.0) )
486 {
487 xtmp = s.x;
488 s.x = s.xnew;
489 s.xnew = xtmp;
490 s.y = ynew;
491 }
492 }
493
494 }
495
496 equilibrate( t, 10 * s.dwell );
497
498 return s.t0 = t;
499}
500
float xsh_SAanneal(int iters)
Definition: xsh_model_sa.c:431
#define PI2
Definition: xsh_model_sa.c:87
void xsh_SAinitial(double *xi)
Definition: xsh_model_sa.c:333
void xsh_SAoptimum(double *xb)
Definition: xsh_model_sa.c:358
void xsh_SAfree(void)
Definition: xsh_model_sa.c:227
#define uniform(a, b)
Definition: xsh_model_sa.c:75
#define HUGE
Definition: xsh_model_sa.c:79
static int equilibrate(float t, int n)
Definition: xsh_model_sa.c:108
void xsh_SAcurrent(double *xc)
Definition: xsh_model_sa.c:345
int xsh_SAdwell(int m)
Definition: xsh_model_sa.c:252
float xsh_SABoltzmann(float k)
Definition: xsh_model_sa.c:267
float xsh_SAmelt(int iters)
Definition: xsh_model_sa.c:375
float xsh_SAtemperature(float t)
Definition: xsh_model_sa.c:280
void xsh_r250_init(int sd)
float xsh_SAjump(float j)
Definition: xsh_model_sa.c:306
int xsh_SAiterations(int m)
Definition: xsh_model_sa.c:239
float xsh_SArange(float r)
Definition: xsh_model_sa.c:319
float xsh_SAlearning_rate(float r)
Definition: xsh_model_sa.c:293
int xsh_SAInit(CostFunction f, int d)
Definition: xsh_model_sa.c:191
static SimAnneal s
Definition: xsh_model_sa.c:99
double * xnew
Definition: xsh_model_sa.c:94
float rho
Definition: xsh_model_sa.c:95
float range
Definition: xsh_model_sa.c:95
int dimension
Definition: xsh_model_sa.c:93
double ybest
Definition: xsh_model_sa.c:96
double y
Definition: xsh_model_sa.c:96
double * xbest
Definition: xsh_model_sa.c:94
float dt
Definition: xsh_model_sa.c:95
double * x
Definition: xsh_model_sa.c:94
float tscale
Definition: xsh_model_sa.c:95
float c_jump
Definition: xsh_model_sa.c:95
float t0
Definition: xsh_model_sa.c:95
CostFunction func
Definition: xsh_model_sa.c:92
int m
Definition: xsh_detmon_lg.c:91
int n
Definition: xsh_detmon_lg.c:92
float(* CostFunction)(double *)
Definition: xsh_model_sa.h:29