2 Last changed Time-stamp: <2011-03-10 18:02:10 ivo>
3 c Christoph Flamm and Ivo L Hofacker
4 {xtof,ivo}@tbi.univie.ac.at
6 $Id: nachbar.c,v 1.8 2008/06/03 21:55:11 ivo Exp $
15 #include "fold_vars.h"
16 #include "energy_const.h"
18 #include "cache_util.h"
21 static char UNUSED rcsid[]="$Id: nachbar.c,v 1.8 2008/06/03 21:55:11 ivo Exp $";
24 static short *neighbor_list=NULL;
25 static float *bmf=NULL; /* boltzmann weight of structure */
26 static const char *costring(const char *str);
28 /* globals for laplace stuff */
29 static double L = 0.0;
30 static double D = 0.0;
31 static double sumT = 0.0;
32 static double sumK = 0.0;
33 static double sumKK = 0.0;
34 static double sumD = 0.0;
35 static double *energies=NULL; /* energies of neighbors */
38 /* static double highestE = -1000.0; */
39 /* static double OhighestE = -1000.0; */
40 /* static char *highestS, *OhighestS; */
43 static int is_from_cache = 0;
44 /* static double meanE = 0.0; */
45 static double totalflux = 0.0;
46 static double Zeit = 0.0;
47 static double zeitInc = 0.0;
48 static double _RT = 0.6;
50 /* public functiones */
51 void ini_nbList(int chords);
52 void update_nbList(int i, int j, int iE);
54 void clean_up_nbList(void);
55 extern void update_tree(int i, int j);
57 /* privat functiones */
58 static void reset_nbList(void);
59 static void grow_chain(void);
60 static FILE *logFP=NULL;
63 void ini_nbList(int chords) {
66 _RT = (((temperature + K0) * GASCONST) / 1000.0);
67 if (neighbor_list!=NULL) return;
70 make room for 2*chords neighbors (safe bet)
72 if (chords == 0) chords = 1;
73 neighbor_list = (short *)calloc(4*chords, sizeof(short));
74 assert(neighbor_list != NULL);
76 list for Boltzmann-factors
78 bmf = (float *)calloc(2*chords, sizeof(double));
81 /* list of neighbor energies */
82 energies = (double*)calloc(2*chords, sizeof(double));
83 assert(energies != NULL);
86 logFP = fopen(strcat(strcpy(logFN, GAV.BaseName), ".log"), "a+");
87 assert(logFP != NULL);
89 /* log initial condition */
90 log_prog_params(logFP);
91 log_start_stop(logFP);
95 void update_nbList(int i, int j, int iE) {
99 neighbor_list[2*top] = (short )i;
100 neighbor_list[2*top+1] = (short )j;
102 /* compute rates and some statistics */
110 /* fprintf(stderr, ">>%g %g<<\n", L, D); */
113 /* metropolis rule */
115 else p = exp(-(dE / _RT*GSV.phi));
117 else /* kawasaki rule */
118 p = exp(-0.5 * (dE / _RT*GSV.phi));
121 bmf[top++] = (float )p;
122 if (dE < 0) lmin = 0;
123 if ((dE == 0) && (lmin==1)) lmin = 2;
127 void get_from_cache(cache_entry *c) {
130 GSV.currE = c->energy;
132 memcpy(neighbor_list, c->neighbors, 2*top*sizeof(short));
133 memcpy(bmf, c->rates, top*sizeof(float));
134 memcpy(energies, c->energies, top*sizeof(double));
139 void put_in_cache(void) {
142 if ((c = (cache_entry *) malloc(sizeof(cache_entry)))==NULL) {
143 fprintf(stderr, "out of memory\n"); exit(255);
145 /* c->structure = strdup(GAV.currform); */
146 c->structure = (char *) calloc(GSV.len+1, sizeof(char));
147 strcpy(c->structure, GAV.currform);
148 c->neighbors = (short *) malloc(top*2*sizeof(short));
149 memcpy(c->neighbors,neighbor_list,top*2*sizeof(short));
150 c->rates = (float *) malloc(top*sizeof(float));
151 memcpy(c->rates, bmf, top*sizeof(float));
152 c->energies = (double*)malloc(top*sizeof(double));
153 memcpy(c->energies, energies, top*sizeof(double));
157 c->energy = GSV.currE;
167 double pegel = 0.0, schwelle = 0.0, zufall = 0.0;
170 /* before we select a move, store current conformation in cache */
171 /* ... unless it just came from there */
172 if ( !is_from_cache ) put_in_cache();
175 for (i=0; i<top; i++) {
176 L += (GSV.currE - energies[i]);
181 /* draw 2 different a random number */
183 while ( zufall==0 ) zufall = urn();
185 /* advance internal clock */
187 zeitInc = (log(1. / zufall) / totalflux);
189 if (GSV.grow>0) zeitInc=GSV.grow;
190 else zeitInc = GSV.time;
197 sumKK += L*L*zeitInc;
200 if (GSV.grow>0 && GSV.len < strlen(GAV.farbe_full)) grow_chain();
202 /* meanE /= (double)top; */
204 /* normalize boltzmann weights */
205 schwelle *=totalflux;
207 /* and choose a neighbour structure next */
208 for (next = 0; next < top; next++) {
210 if (pegel > schwelle) break;
213 /* in case of rounding errors */
214 if (next==top) next=top-1;
217 process termination contitiones
219 /* is current structure identical to a stop structure ?*/
220 for (found_stop = 0, s = GAV.stopform; *s; s++) {
221 if (strcmp(*s, GAV.currform) == 0) {
222 found_stop = (s - GAV.stopform) + 1;
227 if ( ((found_stop > 0) && (GTV.fpt == 1)) || (Zeit > GSV.time) ) {
228 /* met condition to stop simulation */
231 double K, KK, N, sigma;
235 /* graph Laplacian is - Laplace-Beltrami operator */
236 sigma = -1.0*sqrt((KK-K*K)/N)/(K/N);
238 /* this goes to stdout */
240 printf("%s %6.2f %10.3f", costring(GAV.currform), GSV.currE, Zeit);
243 if (GTV.phi) printf(" %8.3f %8.3f %3g", zeitInc, L, D);
245 if (GTV.verbose) printf(" %4d _ %d", top, lmin);
246 if (found_stop) printf(" X%d\n", found_stop);/* found a stop structure */
247 else printf(" O\n"); /* time for simulation is exceeded */
250 if (GTV.phi) printf("Curvature fluctuation sigma = %7.5f\n", sigma);
255 /* this goes to log */
256 /* comment log steps of simulation as well !!! %6.2f round */
258 fprintf(logFP," X%02d %12.3f", found_stop, Zeit);
261 if (GTV.phi) fprintf(logFP, " %3g %7.5f", GSV.phi, sigma);
266 fprintf(logFP," O %12.3f", Zeit);
269 if (GTV.phi) fprintf(logFP, " %3g %7.5f", GSV.phi, sigma);
271 fprintf(logFP," %d %s\n", lmin, costring(GAV.currform));
273 GAV.subi[0] = xsubi[0];
274 GAV.subi[1] = xsubi[1];
275 GAV.subi[2] = xsubi[2];
276 fprintf(logFP, "(%5hu %5hu %5hu)", GAV.subi[0], GAV.subi[1], GAV.subi[2]);
281 /* reset laplace stuff for next trajectory */
289 /* highestE = OhighestE = -1000.0; */
295 /* continue simulation */
297 if( (!GTV.silent) && (GSV.currE <= GSV.stopE+GSV.cut) ) {
299 if (!GTV.lmin || (lmin==1 && strcmp(GAV.prevform, GAV.currform) != 0)) {
302 sprintf(format, "%%-%ds %%6.2f %%10.3f", strlen(GAV.farbe_full)+1);
303 printf(format, costring(GAV.currform), GSV.currE, Zeit);
308 printf(" %8.3f %8.3f %3g", zeitInc, L, D);
309 L = D = 0.0; /* reset L and D for next structure */
312 if ( flag && GTV.verbose ) {
314 if (next<0) trans='g'; /* growth */
316 ii = neighbor_list[2*next];
317 jj = neighbor_list[2*next+1];
318 if (abs(ii) < GSV.len) {
319 if ((ii > 0) && (jj > 0)) trans = 'i';
320 else if ((ii < 0) && (jj < 0)) trans = 'd';
321 else if ((ii > 0) && (jj < 0)) trans = 's';
324 if ((ii > 0) && (jj > 0)) trans = 'I';
328 printf(" %4d %c %d", top, trans, lmin);
330 if (flag) printf("\n");
335 /* store last lmin seen, so we can avoid printing the same lmin twice */
337 strcpy(GAV.prevform, GAV.currform);
341 /* went back to previous lmin */
342 if (strcmp(GAV.prevform, GAV.currform) == 0) {
343 if (OhighestE < highestE) {
344 highestE = OhighestE; /* delete loop */
345 strcpy(highestS, OhighestS);
348 strcpy(GAV.prevform, GAV.currform);
353 if ( strcmp(GAV.currform, GAV.startform)==0 ) {
354 OhighestE = highestE = -1000.;
358 /* log highes energy */
359 if (GSV.currE > highestE) {
360 OhighestE = highestE;
361 highestE = GSV.currE;
362 strcpy(OhighestS, highestS);
363 strcpy(highestS, GAV.currform);
367 if (next>=0) update_tree(neighbor_list[2*next], neighbor_list[2*next+1]);
369 clean_up_rl(); ini_or_reset_rl();
376 /*==========================*/
377 static void reset_nbList(void) {
385 /*======================*/
386 void clean_up_nbList(void){
395 /*======================*/
396 static void grow_chain(void){
398 /* note Zeit=0 corresponds to chain length GSV.glen */
399 if (Zeit<(GSV.len+1-GSV.glen) * GSV.grow) return;
401 Zeit = (newl-GSV.glen) * GSV.grow;
402 top=0; /* prevent structure move in sel_nb */
405 strncpy(GAV.farbe, GAV.farbe_full, newl);
406 GAV.farbe[newl] = '\0';
407 strcpy(GAV.startform, GAV.currform);
408 strcat(GAV.startform, ".");
414 static const char *costring(const char *str) {
415 static char* buffer=NULL;
420 /* make it possible to free buffer */
422 size = 0; buffer = NULL;
429 buffer = realloc(buffer, size);
431 if ((cut_point>0)&&(cut_point<=n)) {
432 strncpy(buffer, str, cut_point-1);
433 buffer[cut_point-1] = '&';
434 strncpy(buffer+cut_point, str+cut_point-1, n-cut_point+1);
437 strncpy(buffer, str, n+1);