1
1
/*
2
2
wanglandau.c : main computation routines for Wang-Landau sampling
3
- Last changed Time-stamp: <2014-07-03 00:27:55 mtw>
3
+ Last changed Time-stamp: <2014-07-03 18:08:12 mtw>
4
4
5
5
Literature:
6
6
Landau, PD and Tsai, S-H and Exler, M (2004) Am. J. Phys. 72:(10) 1294-1302
7
7
A new approach to Monte Carlo simulations in statistical physics:
8
8
Wang-Landau sampling
9
9
*/
10
10
11
+
12
+ /*
13
+ TODO
14
+
15
+ - output_dos fertig machen
16
+
17
+ - output current DOS estimation after 1 million * 10^(1/4) steps until
18
+ 100 million steps are reached (do not stop at f=1e-8)
19
+
20
+ - relative error (siehe original-Paper) einbauen und fuer jede Ausgabe
21
+ der geschaetzten DOS ausgeben
22
+
23
+ */
24
+
11
25
#include <stdio.h>
12
26
#include <stdlib.h>
13
27
#include <string.h>
@@ -31,19 +45,19 @@ static void wl_montecarlo(char *);
31
45
static void scale_normalize_DOS (void );
32
46
static void output_dos (double * dos , char T );
33
47
static short histogram_is_flat (const gsl_histogram * );
34
- static gsl_histogram * ini_histogram (const int ,const double ,const double );
48
+ static gsl_histogram * ini_histogram_uniform (const int ,const double ,const double );
35
49
36
50
/* variables */
37
- static int iterations = 0 ; /* # of iterations (modifications with f) */
38
- static int maxbin = -1 ; /* index of highest bin */
39
- static unsigned long steps = 0 ; /* # of WL steps */
40
- static unsigned long seed ; /* random seed */
41
- static gsl_rng * r = NULL ; /* GSL random number generator */
42
- static struct timespec ts ; /* timespec struct needed for random seed */
43
- static double rnum ; /* random number */
51
+ static int iterations = 0 ; /* #iterations (modifications with f) */
52
+ static int maxbin = -1 ; /* index of highest bin */
53
+ static unsigned long steps = 0 ; /* # of WL steps */
54
+ static unsigned long seed ; /* random seed */
55
+ static gsl_rng * r = NULL ; /* GSL random number generator */
56
+ static struct timespec ts ; /* timespec struct for random seed */
57
+ static double rnum ; /* random number */
44
58
45
59
/* arrays */
46
- gsl_histogram * g = NULL ; /* DoS histogram */
60
+ static gsl_histogram * g = NULL ; /* DoS histogram */
47
61
static char * out_prefix = NULL ; /* prefix for output */
48
62
49
63
/* ==== */
@@ -70,7 +84,7 @@ static void
70
84
initialize_wl (void )
71
85
{
72
86
int bins ;
73
- double low ,high ,lo ,hi ,hmin ,hmax ,erange ;
87
+ double low ,high ,lo ,hi ,hmin ,hmax ,erange , * range = NULL ;
74
88
75
89
srand (time (NULL ));
76
90
if (wanglandau_opt .verbose ){
@@ -80,36 +94,58 @@ initialize_wl(void)
80
94
initialize_model = initialize_RNA ; /* for RNA */
81
95
pre_process_model = pre_process_RNA ;
82
96
post_process_model = post_process_RNA ;
83
-
84
- initialize_model (wanglandau_opt .sequence ); /* set energy paramters for
85
- current model; get mfe */
86
- //hmin=floor(mfe);
87
- hmin = mfe - 0.10001 ;
88
- hmax = 5 * fabs (mfe );
89
- /*printf ("-> mfe is %4.2f | hmin is %4.2f | hmax is %4.2f <-\n",
90
- mfe,hmin,hmax); */
91
-
92
- /* prepare histogram h (holds energy levels seen in the current
93
- iteration) */
94
- h = ini_histogram (wanglandau_opt .bins ,(int )hmin ,hmax );
95
- bins = gsl_histogram_bins (h );
96
- if (wanglandau_opt .verbose ){
97
- fprintf (stderr , "histogram h allocated with %zu bins\n" ,bins );
98
- }
99
-
100
- /* prepare histogram g (holds estimation for DOS */
101
- g = ini_histogram (wanglandau_opt .bins ,(int )hmin ,hmax );
102
- bins = gsl_histogram_bins (g );
103
- if (wanglandau_opt .verbose ){
104
- fprintf (stderr , "histogram g allocated with %d bins\n" ,bins );
97
+
98
+ /* set energy paramters for current model; compute mfe */
99
+ initialize_model (wanglandau_opt .sequence );
100
+
101
+ range = (double * )calloc ((wanglandau_opt .bins + 1 ), sizeof (double ));
102
+ assert (range != NULL );
103
+
104
+ /* initialize histograms */
105
+ hmin = mfe ;
106
+ if (wanglandau_opt .res_given ){ /* determine histogram ranges manually */
107
+ int i ;
108
+ range [0 ]= mfe ;
109
+ for (i = 1 ;i <=wanglandau_opt .bins ;i ++ ){
110
+ range [i ]= range [i - 1 ]+ wanglandau_opt .res ;
111
+ }
112
+ /* info output */
113
+ fprintf (stderr ,"#allocating %lu bins of width %g\n" ,
114
+ wanglandau_opt .bins ,wanglandau_opt .res );
115
+ fprintf (stderr ,"#histogram ranges:\n" );
116
+ for (i = 0 ;i <=wanglandau_opt .bins ;i ++ ){
117
+ fprintf (stderr , "%6.2f " ,range [i ]);
118
+ }
119
+ fprintf (stderr ,"\n" );
120
+
121
+
122
+ if (wanglandau_opt .max_given ){
123
+ hmax = wanglandau_opt .max ;
124
+ }
125
+ else {
126
+ wanglandau_opt .max = range [wanglandau_opt .bins ]; /* the last element */
127
+ hmax = wanglandau_opt .max ;
128
+ }
129
+ h = gsl_histogram_alloc (wanglandau_opt .bins );
130
+ g = gsl_histogram_alloc (wanglandau_opt .bins );
131
+ s = gsl_histogram_alloc (wanglandau_opt .bins );
132
+ gsl_histogram_set_ranges (h ,range ,(wanglandau_opt .bins + 1 ));
133
+ gsl_histogram_set_ranges (g ,range ,(wanglandau_opt .bins + 1 ));
134
+ gsl_histogram_set_ranges (s ,range ,(wanglandau_opt .bins + 1 ));
105
135
}
106
-
107
- /* prepare histogram s (required for normalization) */
108
- s = ini_histogram (wanglandau_opt .bins ,(int )hmin ,hmax );
109
- bins = gsl_histogram_bins (s );
110
- if (wanglandau_opt .verbose ){
111
- fprintf (stderr , "histogram s allocated with %d bins\n" ,bins );
136
+ else { /* determine histogram ranges automatically */
137
+ if (wanglandau_opt .max_given ){
138
+ hmax = wanglandau_opt .max ;
139
+ }
140
+ else {
141
+ hmax = 20 * fabs (mfe );
142
+ }
143
+ h = ini_histogram_uniform (wanglandau_opt .bins ,hmin ,hmax );
144
+ g = ini_histogram_uniform (wanglandau_opt .bins ,hmin ,hmax );
145
+ s = ini_histogram_uniform (wanglandau_opt .bins ,hmin ,hmax );
112
146
}
147
+ fprintf (stderr , "# sampling energy range is %6.2f - %6.2f\n" ,
148
+ hmin ,hmax );
113
149
114
150
dos = (double * )calloc (wanglandau_opt .bins ,sizeof (double ));
115
151
assert (dos != NULL );
@@ -141,18 +177,21 @@ initialize_wl(void)
141
177
r = gsl_rng_alloc (gsl_rng_mt19937 );
142
178
gsl_rng_set ( r , seed );
143
179
180
+ free (range );
144
181
return ;
145
182
}
146
183
147
184
/* ==== */
148
185
static void
149
186
wl_montecarlo (char * struc )
150
187
{
188
+ move_str m ;
151
189
short * pt = NULL ;
152
190
int e ,enew ,emove ,eval_me ,status ,debug = 1 ;
153
- double g_b1 ,g_b2 ,prob ,lnf = 1 ; /* logarithmic modification parameter f */
154
- size_t b1 ,b2 ; /* indices in g/h corresponding to old/new energies */
155
- move_str m ;
191
+ double g_b1 ,g_b2 ,prob ,lnf = 1. ; /* log modification parameter f */
192
+ size_t b1 ,b2 ; /* indices in g/h corresponding to
193
+ old/new energies */
194
+
156
195
157
196
eval_me = 1 ; /* paranoid checking of neighbors against RNAeval */
158
197
if (wanglandau_opt .verbose ){
@@ -174,17 +213,37 @@ wl_montecarlo(char *struc)
174
213
exit (EXIT_FAILURE );
175
214
}
176
215
printf ("%s\n" , wanglandau_opt .sequence );
177
- print_str (stdout ,pt );printf (" %6.2f bin:%d\n" ,(float )e /100 ,b1 );
216
+ print_str (stdout ,pt );printf ("( %6.2f) bin:%d\n" ,(float )e /100 ,b1 );
178
217
if (wanglandau_opt .verbose ){
179
- fprintf (stderr ,"Starting MC loop ...\n" );
218
+ fprintf (stderr ,"\nStarting MC loop ...\n" );
180
219
}
181
220
while (lnf > wanglandau_opt .ffinal ) {
221
+ if (wanglandau_opt .debug ){
222
+ fprintf (stderr ,"==================\n" );
223
+ fprintf (stderr ,"in while: lnf=%8.6f\n" ,lnf );
224
+ print_str (stdout ,pt );printf (" (%6.2f) bin:%d\n" ,(float )e /100 ,b1 );
225
+ mtw_dump_pt (pt );
226
+ }
182
227
/* make a random move */
183
- m = get_random_move_pt (wanglandau_opt .sequence ,pt , wanglandau_opt . verbose );
228
+ m = get_random_move_pt (wanglandau_opt .sequence ,pt );
184
229
/* compute energy difference for this move */
185
230
emove = vrna_eval_move_pt (pt ,s0 ,s1 ,m .left ,m .right ,P );
186
231
/* evaluate energy of the new structure */
187
232
enew = e + emove ;
233
+ if (wanglandau_opt .debug ){
234
+ fprintf (stderr ,
235
+ "random move: left %i right %i enew(%6.4f)=e(%6.4f)+emove(%6.4f)\n" ,
236
+ m .left ,m .right ,(float )enew /100 ,(float )e /100 ,(float )emove /100 );
237
+ }
238
+
239
+ /* ensure the new energy is ithin our sampling region */
240
+ if ((float )enew /100 >= wanglandau_opt .max ){
241
+ fprintf (stderr ,
242
+ "New structure has energy %6.2f >= %6.2f (upper energy bound)\n" ,
243
+ (float )enew /100 ,wanglandau_opt .max );
244
+ fprintf (stderr ,"Please increase --bins or adjust --max! Exiting ...\n" );
245
+ exit (EXIT_FAILURE );
246
+ }
188
247
/* determine bin where the new structure goes */
189
248
status = gsl_histogram_find (g ,(float )enew /100 ,& b2 );
190
249
if (status ) {
@@ -194,35 +253,51 @@ wl_montecarlo(char *struc)
194
253
else {fprintf (stderr , "GSL error: gsl_errno=%d\n" ,status );}
195
254
exit (EXIT_FAILURE );
196
255
}
256
+
257
+ if (wanglandau_opt .debug ){
258
+ fprintf (stderr ,"steps: %d\n" ,steps );
259
+ }
197
260
steps ++ ; /* # of MC steps performed so far */
261
+
262
+ if (steps == 5000000 ){
263
+ gsl_histogram_fprintf (stderr ,g ,"%6.2f" ,"%30.6f" );
264
+ exit (100 );
265
+
266
+ }
198
267
/* lookup current values for bins b1 and b2 */
199
- if (debug == 1 ){
200
- fprintf (stderr ,"================== \n" );
201
- gsl_histogram_fprintf (stderr ,g ,"%6.3g " ,"%8.6g " );
268
+ if (wanglandau_opt . debug ){
269
+ fprintf (stderr ,"current histogram g: \n" );
270
+ gsl_histogram_fprintf (stderr ,g ,"%6.2f " ,"30.6f " );
202
271
fprintf (stderr ,"\n" );
203
272
}
204
273
g_b1 = gsl_histogram_get (g ,b1 );
205
274
g_b2 = gsl_histogram_get (g ,b2 );
206
- if (debug == 1 ){
275
+ /*
276
+ if(debug ==1){
207
277
fprintf(stderr,"b1=%i g_b1: %6.2f | b2=%i g_b2: %6.2f\n",b1,g_b1,b2,g_b2);
208
- }
278
+ }
279
+ */
209
280
210
281
/* core MC steps */
211
282
prob = MIN2 (exp (g_b1 - g_b2 ), 1.0 );
212
283
rnum = gsl_rng_uniform (r );
213
284
/* if(wanglandau_opt.verbose){ printf ("rnum is %.5f\n", rnum); }*/
214
285
215
- if ((prob == 1 || (rnum <= prob )) ) { /* accept the move */
216
- /* apply the move */
286
+ if ((prob == 1 || (rnum <= prob )) ) { /* accept & apply the move */
217
287
apply_move_pt (pt ,m );
218
- /* fprintf(stderr, "accepting %s %6.4f\n", neighbor, e); */
219
- //mtw_dump_pt(pt);
288
+ if (wanglandau_opt .debug ){
289
+ print_str (stdout ,pt );printf (" %6.2f bin:%d [A]\n" ,(float )enew /100 ,b2 );
290
+ }
220
291
b1 = b2 ;
221
292
e = enew ;
222
293
}
223
294
else { /* reject the move */
224
- ;
295
+ if (wanglandau_opt .debug ){
296
+ print_str (stdout ,pt );printf (" %6.2f bin:%d [R]\n" ,(float )enew /100 ,b2 );
297
+ }
298
+
225
299
}
300
+
226
301
/* update histogram h */
227
302
status = gsl_histogram_increment (h ,(float )e /100 );
228
303
if (status ) {
@@ -261,6 +336,8 @@ wl_montecarlo(char *struc)
261
336
if ( histogram_is_flat (h ) ) {
262
337
lnf /= 2 ;
263
338
fprintf (stderr ,"# histogram is flat f=%12g steps=%20li\n" ,lnf ,steps );
339
+ fprintf (stderr ,"estimated g\n" );
340
+ gsl_histogram_fprintf (stderr ,g ,"%6.2f" ,"%20.6f" );
264
341
gsl_histogram_reset (h );
265
342
}
266
343
else {
@@ -275,9 +352,9 @@ wl_montecarlo(char *struc)
275
352
276
353
/* ==== */
277
354
static gsl_histogram *
278
- ini_histogram (const int n ,
279
- const double min ,
280
- const double max )
355
+ ini_histogram_uniform (const int n ,
356
+ const double min ,
357
+ const double max )
281
358
{
282
359
gsl_histogram * a = gsl_histogram_alloc (n );
283
360
gsl_histogram_set_ranges_uniform (a ,min ,max );
@@ -354,7 +431,7 @@ scale_normalize_DOS(void)
354
431
factor += val ;
355
432
}
356
433
/* subtract g[0] from each entry to get smaller numbers */
357
- gsl_histogram_shift (g ,(-1 * GZero ));
434
+ // gsl_histogram_shift(g,(-1*GZero));
358
435
359
436
for (i = 0 ;i < wanglandau_opt .norm ;i ++ ){
360
437
double val = gsl_histogram_get (g ,i );
@@ -374,7 +451,7 @@ scale_normalize_DOS(void)
374
451
fprintf(stderr, %6.2
375
452
}
376
453
*/
377
- gsl_histogram_fprintf (stderr ,g ,"%6.3g " ,"%6g " );
454
+ gsl_histogram_fprintf (stderr ,g ,"%6.2f " ,"%30.6f " );
378
455
379
456
/* SECOND: normalize g */
380
457
}
0 commit comments