Skip to content

Commit a07ec60

Browse files
committed
added lots of goodies, eg an option for setting histogram bin width
1 parent 3c8be6d commit a07ec60

File tree

9 files changed

+336
-133
lines changed

9 files changed

+336
-133
lines changed

moves.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <assert.h>
55
#include <math.h>
66
#include "globals.h"
7+
#include "wl_options.h"
78
#include "moves.h"
89
#include <ViennaRNA/move_set.h>
910

@@ -20,21 +21,17 @@ void mtw_dump_pt(const short*);
2021
returns move operations to be applied to pt in order to perform the move
2122
*/
2223
move_str
23-
get_random_move_pt(const char *seq, const short int *pt,int verbose)
24+
get_random_move_pt(const char *seq, const short int *pt)
2425
{
2526
move_str r,*mvs=NULL;
26-
int i,count,debug=0;
27+
int i,count;
2728

2829
count = construct_moves_new((const char *)seq,pt,1,&mvs);
29-
30-
if (debug==1){
31-
/*
30+
/*
3231
for (i = 0; i<count; i++) {
33-
printf("%d %d\n", mvs[i].left, mvs[i].right);
32+
printf("%d %d\n", mvs[i].left, mvs[i].right);
3433
}
35-
*/
36-
printf ("++ applying move: left %i right %i\n",mvs[0].left,mvs[0].right);
37-
}
34+
*/
3835

3936
r.left = mvs[0].left;
4037
r.right = mvs[0].right;

moves.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Last changed Time-stamp: <2014-05-09 23:43:06 mtw> */
1+
/* Last changed Time-stamp: <2014-07-03 09:43:27 mtw> */
22

33
#ifndef __MOVES__
44
#define __MOVES__
@@ -8,7 +8,7 @@ typedef struct move_str {
88
int right;
99
} move_str;
1010

11-
move_str get_random_move_pt(const char *,const short int*,int);
11+
move_str get_random_move_pt(const char *,const short int*);
1212
void apply_move_pt(short int *,const move_str);
1313

1414
#endif

wanglandau.c

Lines changed: 137 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
11
/*
22
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>
44
55
Literature:
66
Landau, PD and Tsai, S-H and Exler, M (2004) Am. J. Phys. 72:(10) 1294-1302
77
A new approach to Monte Carlo simulations in statistical physics:
88
Wang-Landau sampling
99
*/
1010

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+
1125
#include <stdio.h>
1226
#include <stdlib.h>
1327
#include <string.h>
@@ -31,19 +45,19 @@ static void wl_montecarlo(char *);
3145
static void scale_normalize_DOS(void);
3246
static void output_dos(double *dos, char T);
3347
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);
3549

3650
/* 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 */
4458

4559
/* arrays */
46-
gsl_histogram *g = NULL; /* DoS histogram */
60+
static gsl_histogram *g = NULL; /* DoS histogram */
4761
static char *out_prefix=NULL; /* prefix for output */
4862

4963
/* ==== */
@@ -70,7 +84,7 @@ static void
7084
initialize_wl(void)
7185
{
7286
int bins;
73-
double low,high,lo,hi,hmin,hmax,erange;
87+
double low,high,lo,hi,hmin,hmax,erange,*range = NULL;
7488

7589
srand(time(NULL));
7690
if(wanglandau_opt.verbose){
@@ -80,36 +94,58 @@ initialize_wl(void)
8094
initialize_model = initialize_RNA; /* for RNA */
8195
pre_process_model = pre_process_RNA;
8296
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));
105135
}
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);
112146
}
147+
fprintf (stderr, "# sampling energy range is %6.2f - %6.2f\n",
148+
hmin,hmax);
113149

114150
dos = (double*)calloc(wanglandau_opt.bins,sizeof(double));
115151
assert(dos != NULL);
@@ -141,18 +177,21 @@ initialize_wl(void)
141177
r = gsl_rng_alloc (gsl_rng_mt19937);
142178
gsl_rng_set( r, seed );
143179

180+
free(range);
144181
return;
145182
}
146183

147184
/* ==== */
148185
static void
149186
wl_montecarlo(char *struc)
150187
{
188+
move_str m;
151189
short *pt=NULL;
152190
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+
156195

157196
eval_me = 1; /* paranoid checking of neighbors against RNAeval */
158197
if (wanglandau_opt.verbose){
@@ -174,17 +213,37 @@ wl_montecarlo(char *struc)
174213
exit(EXIT_FAILURE);
175214
}
176215
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);
178217
if (wanglandau_opt.verbose){
179-
fprintf(stderr,"Starting MC loop ...\n");
218+
fprintf(stderr,"\nStarting MC loop ...\n");
180219
}
181220
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+
}
182227
/* 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);
184229
/* compute energy difference for this move */
185230
emove = vrna_eval_move_pt(pt,s0,s1,m.left,m.right,P);
186231
/* evaluate energy of the new structure */
187232
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+
}
188247
/* determine bin where the new structure goes */
189248
status = gsl_histogram_find(g,(float)enew/100,&b2);
190249
if (status) {
@@ -194,35 +253,51 @@ wl_montecarlo(char *struc)
194253
else {fprintf(stderr, "GSL error: gsl_errno=%d\n",status);}
195254
exit(EXIT_FAILURE);
196255
}
256+
257+
if(wanglandau_opt.debug){
258+
fprintf(stderr,"steps: %d\n",steps);
259+
}
197260
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+
}
198267
/* 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");
202271
fprintf(stderr,"\n");
203272
}
204273
g_b1 = gsl_histogram_get(g,b1);
205274
g_b2 = gsl_histogram_get(g,b2);
206-
if(debug ==1){
275+
/*
276+
if(debug ==1){
207277
fprintf(stderr,"b1=%i g_b1: %6.2f | b2=%i g_b2: %6.2f\n",b1,g_b1,b2,g_b2);
208-
}
278+
}
279+
*/
209280

210281
/* core MC steps */
211282
prob = MIN2(exp(g_b1 - g_b2), 1.0);
212283
rnum = gsl_rng_uniform (r);
213284
/* if(wanglandau_opt.verbose){ printf ("rnum is %.5f\n", rnum); }*/
214285

215-
if ((prob == 1 || (rnum <= prob)) ) { /* accept the move */
216-
/* apply the move */
286+
if ((prob == 1 || (rnum <= prob)) ) { /* accept & apply the move */
217287
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+
}
220291
b1 = b2;
221292
e = enew;
222293
}
223294
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+
225299
}
300+
226301
/* update histogram h */
227302
status = gsl_histogram_increment(h,(float)e/100);
228303
if (status) {
@@ -261,6 +336,8 @@ wl_montecarlo(char *struc)
261336
if( histogram_is_flat(h) ) {
262337
lnf /= 2;
263338
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");
264341
gsl_histogram_reset(h);
265342
}
266343
else {
@@ -275,9 +352,9 @@ wl_montecarlo(char *struc)
275352

276353
/* ==== */
277354
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)
281358
{
282359
gsl_histogram *a = gsl_histogram_alloc(n);
283360
gsl_histogram_set_ranges_uniform(a,min,max);
@@ -354,7 +431,7 @@ scale_normalize_DOS(void)
354431
factor += val;
355432
}
356433
/* subtract g[0] from each entry to get smaller numbers */
357-
gsl_histogram_shift(g,(-1*GZero));
434+
// gsl_histogram_shift(g,(-1*GZero));
358435

359436
for(i=0;i<wanglandau_opt.norm;i++){
360437
double val = gsl_histogram_get(g,i);
@@ -374,7 +451,7 @@ scale_normalize_DOS(void)
374451
fprintf(stderr, %6.2
375452
}
376453
*/
377-
gsl_histogram_fprintf(stderr,g,"%6.3g","%6g");
454+
gsl_histogram_fprintf(stderr,g,"%6.2f","%30.6f");
378455

379456
/* SECOND: normalize g */
380457
}

wanglandau.ggo

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1-
purpose "Estimate the Density of States by a Wang-Landau MC simulation"
1+
purpose "Sample the Density of States by a Wang-Landau MC simulation"
22
args "--file-name=wl_cmdline --unamed-opts"
33
section "General options"
44
option "bins" b "Number of (equidistant) histogram bins" int optional
5-
option "emax" - "Upper energy bound for sampling" double optional
5+
option "elow" - "Lower limit of sampling window (currently n/a)" double optional
6+
option "ehigh" - "Upper limit of sampling window (currently n/a)" double optional
67
option "flat" l "Flatness criterion for the histogram" float optional
78
option "info" - "Show settings" flag off
9+
option "max" m "Upper energy bound for sampling" double optional
810
option "mod" f "Final value of Wang-Landau modification factor" double optional
911
option "norm" n "Number of bins used for normalization" int optional
12+
option "resolution" r "Sampling resolution (histogram bin width)" double default="0.5" optional
1013
option "steps" s "Number of Wang-Landau steps before histogram is checked for flatness" longlong optional
1114
option "seed" S "Seed for random number generation" long optional
1215
option "Temp" T "Temperatur in Celsius" float no
1316
option "verbose" v "Verbose output" flag off
17+
option "debug" d "Debugging output" flag off
1418

1519

1620

0 commit comments

Comments
 (0)