A freeze group can now be allowed to move rigidly in some dimension by using "freezed...
[gromacs/rigid-bodies.git] / src / kernel / repl_ex.c
blob8bff387895cd337026a1593f638e6f386ddea6df
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 3.2.0
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
33 * And Hey:
34 * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
40 #include <math.h>
41 #include "repl_ex.h"
42 #include "network.h"
43 #include "random.h"
44 #include "smalloc.h"
45 #include "physics.h"
46 #include "copyrite.h"
47 #include "macros.h"
48 #include "vec.h"
49 #include "names.h"
50 #include "mvdata.h"
51 #include "domdec.h"
52 #include "partdec.h"
54 typedef struct gmx_repl_ex
56 int repl;
57 int nrepl;
58 real temp;
59 int type;
60 real *q;
61 gmx_bool bNPT;
62 real *pres;
63 int *ind;
64 int nst;
65 int seed;
66 int nattempt[2];
67 real *prob_sum;
68 int *nexchange;
69 } t_gmx_repl_ex;
71 enum { ereTEMP, ereLAMBDA, ereNR };
72 const char *erename[ereNR] = { "temperature", "lambda" };
74 static void repl_quantity(FILE *fplog,const gmx_multisim_t *ms,
75 struct gmx_repl_ex *re,int ere,real q)
77 real *qall;
78 gmx_bool bDiff;
79 int s;
81 snew(qall,ms->nsim);
82 qall[re->repl] = q;
83 gmx_sum_sim(ms->nsim,qall,ms);
85 bDiff = FALSE;
86 for(s=1; s<ms->nsim; s++)
88 if (qall[s] != qall[0])
90 bDiff = TRUE;
93 if (bDiff)
95 if (re->type >= 0 && re->type < ereNR)
97 gmx_fatal(FARGS,"For replica exchange both %s and %s differ",
98 erename[re->type],erename[ere]);
100 else
102 /* Set the replica exchange type and quantities */
103 re->type = ere;
104 snew(re->q,re->nrepl);
105 for(s=0; s<ms->nsim; s++)
107 re->q[s] = qall[s];
113 sfree(qall);
116 gmx_repl_ex_t init_replica_exchange(FILE *fplog,
117 const gmx_multisim_t *ms,
118 const t_state *state,
119 const t_inputrec *ir,
120 int nst,int init_seed)
122 real temp,pres;
123 int i,j,k;
124 struct gmx_repl_ex *re;
126 fprintf(fplog,"\nInitializing Replica Exchange\n");
128 if (ms == NULL || ms->nsim == 1)
130 gmx_fatal(FARGS,"Nothing to exchange with only one replica, maybe you forgot to set the -multi option of mdrun?");
133 snew(re,1);
135 re->repl = ms->sim;
136 re->nrepl = ms->nsim;
138 fprintf(fplog,"Repl There are %d replicas:\n",re->nrepl);
140 check_multi_int(fplog,ms,state->natoms,"the number of atoms");
141 check_multi_int(fplog,ms,ir->eI,"the integrator");
142 check_multi_large_int(fplog,ms,ir->init_step+ir->nsteps,"init_step+nsteps");
143 check_multi_large_int(fplog,ms,(ir->init_step+nst-1)/nst,
144 "first exchange step: init_step/-replex");
145 check_multi_int(fplog,ms,ir->etc,"the temperature coupling");
146 check_multi_int(fplog,ms,ir->opts.ngtc,
147 "the number of temperature coupling groups");
148 check_multi_int(fplog,ms,ir->epc,"the pressure coupling");
149 check_multi_int(fplog,ms,ir->efep,"free energy");
151 re->temp = ir->opts.ref_t[0];
152 for(i=1; (i<ir->opts.ngtc); i++)
154 if (ir->opts.ref_t[i] != re->temp)
156 fprintf(fplog,"\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n");
157 fprintf(stderr,"\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n");
161 re->type = -1;
162 for(i=0; i<ereNR; i++)
164 switch (i)
166 case ereTEMP:
167 repl_quantity(fplog,ms,re,i,re->temp);
168 break;
169 case ereLAMBDA:
170 if (ir->efep != efepNO)
172 repl_quantity(fplog,ms,re,i,ir->init_lambda);
174 break;
175 default:
176 gmx_incons("Unknown replica exchange quantity");
179 if (re->type == -1)
181 gmx_fatal(FARGS,"The properties of the %d systems are all the same, there is nothing to exchange",re->nrepl);
184 switch (re->type)
186 case ereTEMP:
187 please_cite(fplog,"Hukushima96a");
188 if (ir->epc != epcNO)
190 re->bNPT = TRUE;
191 fprintf(fplog,"Repl Using Constant Pressure REMD.\n");
192 please_cite(fplog,"Okabe2001a");
194 if (ir->etc == etcBERENDSEN)
196 gmx_fatal(FARGS,"REMD with the %s thermostat does not produce correct potential energy distributions, consider using the %s thermostat instead",
197 ETCOUPLTYPE(ir->etc),ETCOUPLTYPE(etcVRESCALE));
199 break;
200 case ereLAMBDA:
201 if (ir->delta_lambda != 0)
203 gmx_fatal(FARGS,"delta_lambda is not zero");
205 break;
208 if (re->bNPT)
210 snew(re->pres,re->nrepl);
211 if (ir->epct == epctSURFACETENSION)
213 pres = ir->ref_p[ZZ][ZZ];
215 else
217 pres = 0;
218 j = 0;
219 for(i=0; i<DIM; i++)
221 if (ir->compress[i][i] != 0)
223 pres += ir->ref_p[i][i];
224 j++;
227 pres /= j;
229 re->pres[re->repl] = pres;
230 gmx_sum_sim(re->nrepl,re->pres,ms);
233 snew(re->ind,re->nrepl);
234 /* Make an index for increasing temperature order */
235 for(i=0; i<re->nrepl; i++)
237 re->ind[i] = i;
239 for(i=0; i<re->nrepl; i++)
241 for(j=i+1; j<re->nrepl; j++)
243 if (re->q[re->ind[j]] < re->q[re->ind[i]])
245 k = re->ind[i];
246 re->ind[i] = re->ind[j];
247 re->ind[j] = k;
249 else if (re->q[re->ind[j]] == re->q[re->ind[i]])
251 gmx_fatal(FARGS,"Two replicas have identical %ss",erename[re->type]);
255 fprintf(fplog,"Repl ");
256 for(i=0; i<re->nrepl; i++)
258 fprintf(fplog," %3d ",re->ind[i]);
260 switch (re->type)
262 case ereTEMP:
263 fprintf(fplog,"\nRepl T");
264 for(i=0; i<re->nrepl; i++)
266 fprintf(fplog," %5.1f",re->q[re->ind[i]]);
268 break;
269 case ereLAMBDA:
270 fprintf(fplog,"\nRepl l");
271 for(i=0; i<re->nrepl; i++)
273 fprintf(fplog," %5.3f",re->q[re->ind[i]]);
275 break;
276 default:
277 gmx_incons("Unknown replica exchange quantity");
279 if (re->bNPT)
281 fprintf(fplog,"\nRepl p");
282 for(i=0; i<re->nrepl; i++)
284 fprintf(fplog," %5.2f",re->pres[re->ind[i]]);
287 for(i=0; i<re->nrepl; i++)
289 if ((i > 0) && (re->pres[re->ind[i]] < re->pres[re->ind[i-1]]))
291 gmx_fatal(FARGS,"The reference pressure decreases with increasing temperature");
295 fprintf(fplog,"\nRepl ");
297 re->nst = nst;
298 if (init_seed == -1)
300 if (MASTERSIM(ms))
302 re->seed = make_seed();
304 else
306 re->seed = 0;
308 gmx_sumi_sim(1,&(re->seed),ms);
310 else
312 re->seed = init_seed;
314 fprintf(fplog,"\nRepl exchange interval: %d\n",re->nst);
315 fprintf(fplog,"\nRepl random seed: %d\n",re->seed);
317 re->nattempt[0] = 0;
318 re->nattempt[1] = 0;
319 snew(re->prob_sum,re->nrepl);
320 snew(re->nexchange,re->nrepl);
322 fprintf(fplog,"Repl below: x=exchange, pr=probability\n");
324 return re;
327 static void exchange_reals(const gmx_multisim_t *ms,int b,real *v,int n)
329 real *buf;
330 int i;
332 if (v)
334 snew(buf,n);
335 #ifdef GMX_MPI
337 MPI_Sendrecv(v, n*sizeof(real),MPI_BYTE,MSRANK(ms,b),0,
338 buf,n*sizeof(real),MPI_BYTE,MSRANK(ms,b),0,
339 ms->mpi_comm_masters,MPI_STATUS_IGNORE);
342 MPI_Request mpi_req;
344 MPI_Isend(v,n*sizeof(real),MPI_BYTE,MSRANK(ms,b),0,
345 ms->mpi_comm_masters,&mpi_req);
346 MPI_Recv(buf,n*sizeof(real),MPI_BYTE,MSRANK(ms,b),0,
347 ms->mpi_comm_masters,MPI_STATUS_IGNORE);
348 MPI_Wait(&mpi_req,MPI_STATUS_IGNORE);
350 #endif
351 for(i=0; i<n; i++)
353 v[i] = buf[i];
355 sfree(buf);
359 static void exchange_doubles(const gmx_multisim_t *ms,int b,double *v,int n)
361 double *buf;
362 int i;
364 if (v)
366 snew(buf,n);
367 #ifdef GMX_MPI
369 MPI_Sendrecv(v, n*sizeof(double),MPI_BYTE,MSRANK(ms,b),0,
370 buf,n*sizeof(double),MPI_BYTE,MSRANK(ms,b),0,
371 ms->mpi_comm_masters,MPI_STATUS_IGNORE);
374 MPI_Request mpi_req;
376 MPI_Isend(v,n*sizeof(double),MPI_BYTE,MSRANK(ms,b),0,
377 ms->mpi_comm_masters,&mpi_req);
378 MPI_Recv(buf,n*sizeof(double),MPI_BYTE,MSRANK(ms,b),0,
379 ms->mpi_comm_masters,MPI_STATUS_IGNORE);
380 MPI_Wait(&mpi_req,MPI_STATUS_IGNORE);
382 #endif
383 for(i=0; i<n; i++)
385 v[i] = buf[i];
387 sfree(buf);
391 static void exchange_rvecs(const gmx_multisim_t *ms,int b,rvec *v,int n)
393 rvec *buf;
394 int i;
396 if (v)
398 snew(buf,n);
399 #ifdef GMX_MPI
401 MPI_Sendrecv(v[0], n*sizeof(rvec),MPI_BYTE,MSRANK(ms,b),0,
402 buf[0],n*sizeof(rvec),MPI_BYTE,MSRANK(ms,b),0,
403 ms->mpi_comm_masters,MPI_STATUS_IGNORE);
406 MPI_Request mpi_req;
408 MPI_Isend(v[0],n*sizeof(rvec),MPI_BYTE,MSRANK(ms,b),0,
409 ms->mpi_comm_masters,&mpi_req);
410 MPI_Recv(buf[0],n*sizeof(rvec),MPI_BYTE,MSRANK(ms,b),0,
411 ms->mpi_comm_masters,MPI_STATUS_IGNORE);
412 MPI_Wait(&mpi_req,MPI_STATUS_IGNORE);
414 #endif
415 for(i=0; i<n; i++)
417 copy_rvec(buf[i],v[i]);
419 sfree(buf);
423 static void exchange_state(const gmx_multisim_t *ms,int b,t_state *state)
425 /* When t_state changes, this code should be updated. */
426 int ngtc,nnhpres;
427 ngtc = state->ngtc * state->nhchainlength;
428 nnhpres = state->nnhpres* state->nhchainlength;
429 exchange_rvecs(ms,b,state->box,DIM);
430 exchange_rvecs(ms,b,state->box_rel,DIM);
431 exchange_rvecs(ms,b,state->boxv,DIM);
432 exchange_reals(ms,b,&(state->veta),1);
433 exchange_reals(ms,b,&(state->vol0),1);
434 exchange_rvecs(ms,b,state->svir_prev,DIM);
435 exchange_rvecs(ms,b,state->fvir_prev,DIM);
436 exchange_rvecs(ms,b,state->pres_prev,DIM);
437 exchange_doubles(ms,b,state->nosehoover_xi,ngtc);
438 exchange_doubles(ms,b,state->nosehoover_vxi,ngtc);
439 exchange_doubles(ms,b,state->nhpres_xi,nnhpres);
440 exchange_doubles(ms,b,state->nhpres_vxi,nnhpres);
441 exchange_doubles(ms,b,state->therm_integral,state->ngtc);
442 exchange_rvecs(ms,b,state->x,state->natoms);
443 exchange_rvecs(ms,b,state->v,state->natoms);
444 exchange_rvecs(ms,b,state->sd_X,state->natoms);
447 static void copy_rvecs(rvec *s,rvec *d,int n)
449 int i;
451 if (d != NULL)
453 for(i=0; i<n; i++)
455 copy_rvec(s[i],d[i]);
460 static void copy_doubles(const double *s,double *d,int n)
462 int i;
464 if (d != NULL)
466 for(i=0; i<n; i++)
468 d[i] = s[i];
473 #define scopy_rvecs(v,n) copy_rvecs(state->v,state_local->v,n);
474 #define scopy_doubles(v,n) copy_doubles(state->v,state_local->v,n);
476 static void copy_state_nonatomdata(t_state *state,t_state *state_local)
478 /* When t_state changes, this code should be updated. */
479 int ngtc,nnhpres;
480 ngtc = state->ngtc * state->nhchainlength;
481 nnhpres = state->nnhpres* state->nhchainlength;
482 scopy_rvecs(box,DIM);
483 scopy_rvecs(box_rel,DIM);
484 scopy_rvecs(boxv,DIM);
485 state_local->veta = state->veta;
486 state_local->vol0 = state->vol0;
487 scopy_rvecs(svir_prev,DIM);
488 scopy_rvecs(fvir_prev,DIM);
489 scopy_rvecs(pres_prev,DIM);
490 scopy_doubles(nosehoover_xi,ngtc);
491 scopy_doubles(nosehoover_vxi,ngtc);
492 scopy_doubles(nhpres_xi,nnhpres);
493 scopy_doubles(nhpres_vxi,nnhpres);
494 scopy_doubles(therm_integral,state->ngtc);
495 scopy_rvecs(x,state->natoms);
496 scopy_rvecs(v,state->natoms);
497 scopy_rvecs(sd_X,state->natoms);
500 static void scale_velocities(t_state *state,real fac)
502 int i;
504 if (state->v)
506 for(i=0; i<state->natoms; i++)
508 svmul(fac,state->v[i],state->v[i]);
513 static void pd_collect_state(const t_commrec *cr,t_state *state)
515 int shift;
517 if (debug)
519 fprintf(debug,"Collecting state before exchange\n");
521 shift = cr->nnodes - cr->npmenodes - 1;
522 move_rvecs(cr,FALSE,FALSE,GMX_LEFT,GMX_RIGHT,state->x,NULL,shift,NULL);
523 if (state->v)
525 move_rvecs(cr,FALSE,FALSE,GMX_LEFT,GMX_RIGHT,state->v,NULL,shift,NULL);
527 if (state->sd_X)
529 move_rvecs(cr,FALSE,FALSE,GMX_LEFT,GMX_RIGHT,state->sd_X,NULL,shift,NULL);
533 static void print_ind(FILE *fplog,const char *leg,int n,int *ind,gmx_bool *bEx)
535 int i;
537 fprintf(fplog,"Repl %2s %2d",leg,ind[0]);
538 for(i=1; i<n; i++)
540 fprintf(fplog," %c %2d",(bEx!=0 && bEx[i]) ? 'x' : ' ',ind[i]);
542 fprintf(fplog,"\n");
545 static void print_prob(FILE *fplog,const char *leg,int n,real *prob)
547 int i;
548 char buf[8];
550 fprintf(fplog,"Repl %2s ",leg);
551 for(i=1; i<n; i++)
553 if (prob[i] >= 0)
555 sprintf(buf,"%4.2f",prob[i]);
556 fprintf(fplog," %3s",buf[0]=='1' ? "1.0" : buf+1);
558 else
560 fprintf(fplog," ");
563 fprintf(fplog,"\n");
566 static void print_count(FILE *fplog,const char *leg,int n,int *count)
568 int i;
570 fprintf(fplog,"Repl %2s ",leg);
571 for(i=1; i<n; i++)
573 fprintf(fplog," %4d",count[i]);
575 fprintf(fplog,"\n");
578 static int get_replica_exchange(FILE *fplog,const gmx_multisim_t *ms,
579 struct gmx_repl_ex *re,real *ener,real vol,
580 int step,real time)
582 int m,i,a,b;
583 real *Epot=NULL,*Vol=NULL,*dvdl=NULL,*prob;
584 real ediff=0,delta=0,dpV=0,betaA=0,betaB=0;
585 gmx_bool *bEx,bPrint;
586 int exchange;
588 fprintf(fplog,"Replica exchange at step %d time %g\n",step,time);
590 switch (re->type)
592 case ereTEMP:
593 snew(Epot,re->nrepl);
594 snew(Vol,re->nrepl);
595 Epot[re->repl] = ener[F_EPOT];
596 Vol[re->repl] = vol;
597 gmx_sum_sim(re->nrepl,Epot,ms);
598 gmx_sum_sim(re->nrepl,Vol,ms);
599 break;
600 case ereLAMBDA:
601 snew(dvdl,re->nrepl);
602 dvdl[re->repl] = ener[F_DVDL];
603 gmx_sum_sim(re->nrepl,dvdl,ms);
604 break;
607 snew(bEx,re->nrepl);
608 snew(prob,re->nrepl);
610 exchange = -1;
611 m = (step / re->nst) % 2;
612 for(i=1; i<re->nrepl; i++)
614 a = re->ind[i-1];
615 b = re->ind[i];
616 bPrint = (re->repl==a || re->repl==b);
617 if (i % 2 == m)
619 switch (re->type)
621 case ereTEMP:
622 /* Use equations from:
623 * Okabe et. al. Chem. Phys. Lett. 335 (2001) 435-439
625 ediff = Epot[b] - Epot[a];
626 betaA = 1.0/(re->q[a]*BOLTZ);
627 betaB = 1.0/(re->q[b]*BOLTZ);
628 delta = (betaA - betaB)*ediff;
629 break;
630 case ereLAMBDA:
631 /* Here we exchange based on a linear extrapolation of dV/dlambda.
632 * We would like to have the real energies
633 * from foreign lambda calculations.
635 ediff = (dvdl[a] - dvdl[b])*(re->q[b] - re->q[a]);
636 delta = ediff/(BOLTZ*re->temp);
637 break;
638 default:
639 gmx_incons("Unknown replica exchange quantity");
641 if (bPrint)
643 fprintf(fplog,"Repl %d <-> %d dE = %10.3e",a,b,delta);
645 if (re->bNPT)
647 dpV = (betaA*re->pres[a]-betaB*re->pres[b])*(Vol[b]-Vol[a])/PRESFAC;
648 if (bPrint)
650 fprintf(fplog," dpV = %10.3e d = %10.3e",dpV,delta + dpV);
652 delta += dpV;
654 if (bPrint)
656 fprintf(fplog,"\n");
658 if (delta <= 0)
660 prob[i] = 1;
661 bEx[i] = TRUE;
663 else
665 if (delta > 100)
667 prob[i] = 0;
669 else
671 prob[i] = exp(-delta);
673 bEx[i] = (rando(&(re->seed)) < prob[i]);
675 re->prob_sum[i] += prob[i];
676 if (bEx[i])
678 if (a == re->repl)
680 exchange = b;
682 else if (b == re->repl)
684 exchange = a;
686 re->nexchange[i]++;
689 else
691 prob[i] = -1;
692 bEx[i] = FALSE;
695 print_ind(fplog,"ex",re->nrepl,re->ind,bEx);
696 print_prob(fplog,"pr",re->nrepl,prob);
697 fprintf(fplog,"\n");
699 sfree(bEx);
700 sfree(prob);
701 sfree(Epot);
702 sfree(Vol);
703 sfree(dvdl);
705 re->nattempt[m]++;
707 return exchange;
710 static void write_debug_x(t_state *state)
712 int i;
714 if (debug)
716 for(i=0; i<state->natoms; i+=10)
718 fprintf(debug,"dx %5d %10.5f %10.5f %10.5f\n",i,state->x[i][XX],state->x[i][YY],state->x[i][ZZ]);
723 gmx_bool replica_exchange(FILE *fplog,const t_commrec *cr,struct gmx_repl_ex *re,
724 t_state *state,real *ener,
725 t_state *state_local,
726 int step,real time)
728 gmx_multisim_t *ms;
729 int exchange=-1,shift;
730 gmx_bool bExchanged=FALSE;
732 ms = cr->ms;
734 if (MASTER(cr))
736 exchange = get_replica_exchange(fplog,ms,re,ener,det(state->box),
737 step,time);
738 bExchanged = (exchange >= 0);
741 if (PAR(cr))
743 #ifdef GMX_MPI
744 MPI_Bcast(&bExchanged,sizeof(gmx_bool),MPI_BYTE,MASTERRANK(cr),
745 cr->mpi_comm_mygroup);
746 #endif
749 if (bExchanged)
751 /* Exchange the states */
753 if (PAR(cr))
755 /* Collect the global state on the master node */
756 if (DOMAINDECOMP(cr))
758 dd_collect_state(cr->dd,state_local,state);
760 else
762 pd_collect_state(cr,state);
766 if (MASTER(cr))
768 /* Exchange the global states between the master nodes */
769 if (debug)
771 fprintf(debug,"Exchanging %d with %d\n",ms->sim,exchange);
773 exchange_state(ms,exchange,state);
775 if (re->type == ereTEMP)
777 scale_velocities(state,sqrt(re->q[ms->sim]/re->q[exchange]));
781 /* With domain decomposition the global state is distributed later */
782 if (!DOMAINDECOMP(cr))
784 /* Copy the global state to the local state data structure */
785 copy_state_nonatomdata(state,state_local);
787 if (PAR(cr))
789 bcast_state(cr,state,FALSE);
794 return bExchanged;
797 void print_replica_exchange_statistics(FILE *fplog,struct gmx_repl_ex *re)
799 real *prob;
800 int i;
802 fprintf(fplog,"\nReplica exchange statistics\n");
803 fprintf(fplog,"Repl %d attempts, %d odd, %d even\n",
804 re->nattempt[0]+re->nattempt[1],re->nattempt[1],re->nattempt[0]);
806 snew(prob,re->nrepl);
808 fprintf(fplog,"Repl average probabilities:\n");
809 for(i=1; i<re->nrepl; i++)
811 if (re->nattempt[i%2] == 0)
813 prob[i] = 0;
815 else
817 prob[i] = re->prob_sum[i]/re->nattempt[i%2];
820 print_ind(fplog,"",re->nrepl,re->ind,NULL);
821 print_prob(fplog,"",re->nrepl,prob);
823 fprintf(fplog,"Repl number of exchanges:\n");
824 print_ind(fplog,"",re->nrepl,re->ind,NULL);
825 print_count(fplog,"",re->nrepl,re->nexchange);
827 fprintf(fplog,"Repl average number of exchanges:\n");
828 for(i=1; i<re->nrepl; i++)
830 if (re->nattempt[i%2] == 0)
832 prob[i] = 0;
834 else
836 prob[i] = ((real)re->nexchange[i])/re->nattempt[i%2];
839 print_ind(fplog,"",re->nrepl,re->ind,NULL);
840 print_prob(fplog,"",re->nrepl,prob);
842 sfree(prob);
844 fprintf(fplog,"\n");