void low_do_autocorr(const char *fn,const output_env_t oenv,const char *title, int nframes,int nitem,int nout,real **c1, real dt,unsigned long mode,int nrestart, gmx_bool bAver,gmx_bool bNormalize, gmx_bool bVerbose,real tbeginfit,real tendfit, int eFitFn,int nskip) { FILE *fp,*gp=NULL; int i,k,nfour; real *csum; real *ctmp,*fit; real c0,sum,Ct2av,Ctav; gmx_bool bFour = acf.bFour; /* Check flags and parameters */ nout = get_acfnout(); if (nout == -1) nout = acf.nout = (nframes+1)/2; else if (nout > nframes) nout=nframes; if (MODE(eacCos) && MODE(eacVector)) gmx_fatal(FARGS,"Incompatible options bCos && bVector (%s, %d)", __FILE__,__LINE__); if ((MODE(eacP3) || MODE(eacRcross)) && bFour) { fprintf(stderr,"Can't combine mode %lu with FFT, turning off FFT\n",mode); bFour = FALSE; } if (MODE(eacNormal) && MODE(eacVector)) gmx_fatal(FARGS,"Incompatible mode bits: normal and vector (or Legendre)"); /* Print flags and parameters */ if (bVerbose) { printf("Will calculate %s of %d thingies for %d frames\n", title ? title : "autocorrelation",nitem,nframes); printf("bAver = %s, bFour = %s bNormalize= %s\n", bool_names[bAver],bool_names[bFour],bool_names[bNormalize]); printf("mode = %lu, dt = %g, nrestart = %d\n",mode,dt,nrestart); } if (bFour) { c0 = log((double)nframes)/log(2.0); k = c0; if (k < c0) k++; k++; nfour = 1<<k; if (debug) fprintf(debug,"Using FFT to calculate %s, #points for FFT = %d\n", title,nfour); /* Allocate temp arrays */ snew(csum,nfour); snew(ctmp,nfour); } else { nfour = 0; /* To keep the compiler happy */ snew(csum,nframes); snew(ctmp,nframes); } /* Loop over items (e.g. molecules or dihedrals) * In this loop the actual correlation functions are computed, but without * normalizing them. */ k = max(1,pow(10,(int)(log(nitem)/log(100)))); for(i=0; i<nitem; i++) { if (bVerbose && ((i%k==0 || i==nitem-1))) fprintf(stderr,"\rThingie %d",i+1); if (bFour) do_four_core(mode,nfour,nframes,nframes,c1[i],csum,ctmp); else do_ac_core(nframes,nout,ctmp,c1[i],nrestart,mode); } if (bVerbose) fprintf(stderr,"\n"); sfree(ctmp); sfree(csum); if (fn) { snew(fit,nout); fp=xvgropen(fn,title,"Time (ps)","C(t)",oenv); } else { fit = NULL; fp = NULL; } if (bAver) { if (nitem > 1) average_acf(bVerbose,nframes,nitem,c1); if (bNormalize) normalize_acf(nout,c1[0]); if (eFitFn != effnNONE) { fit_acf(nout,eFitFn,oenv,fn!=NULL,tbeginfit,tendfit,dt,c1[0],fit); sum = print_and_integrate(fp,nout,dt,c1[0],fit,1); } else { sum = print_and_integrate(fp,nout,dt,c1[0],NULL,1); if (bVerbose) printf("Correlation time (integral over corrfn): %g (ps)\n",sum); } } else { /* Not averaging. Normalize individual ACFs */ Ctav = Ct2av = 0; if (debug) gp = xvgropen("ct-distr.xvg","Correlation times","item","time (ps)",oenv); for(i=0; i<nitem; i++) { if (bNormalize) normalize_acf(nout,c1[i]); if (eFitFn != effnNONE) { fit_acf(nout,eFitFn,oenv,fn!=NULL,tbeginfit,tendfit,dt,c1[i],fit); sum = print_and_integrate(fp,nout,dt,c1[i],fit,1); } else { sum = print_and_integrate(fp,nout,dt,c1[i],NULL,1); if (debug) fprintf(debug, "CORRelation time (integral over corrfn %d): %g (ps)\n", i,sum); } Ctav += sum; Ct2av += sum*sum; if (debug) fprintf(gp,"%5d %.3f\n",i,sum); } if (debug) ffclose(gp); if (nitem > 1) { Ctav /= nitem; Ct2av /= nitem; printf("Average correlation time %.3f Std. Dev. %.3f Error %.3f (ps)\n", Ctav,sqrt((Ct2av - sqr(Ctav))), sqrt((Ct2av - sqr(Ctav))/(nitem-1))); } } if (fp) ffclose(fp); sfree(fit); }
int main(int argc,char *argv[]) { FILE *fp; const char *desc[] = { "testac tests the functioning of the GROMACS acf routines" }; static int nframes = 1024; static int datatp = 0; static real a=0.02*M_PI; output_env_t oenv; t_pargs pa[] = { { "-np", FALSE, etINT, &nframes, "Number of data points" }, { "-dtp",FALSE, etINT, &datatp, "Which data: 0=all 0.0, 1=all 1.0, 2=cos(a t), 3=random, 4=cos(a t)+random, 5=sin(a t)/(a t)" } }; static char *str[] = { "all 0.0", "all 1.0", "cos(a t)", "random", "cos(a t)+random", "sin(a t)/(a t)" }; t_filenm fnm[] = { { efXVG, "-d", "acf-data", ffWRITE }, { efXVG, "-c", "acf-corr", ffWRITE }, { efXVG, "-comb", "acf-comb.xvg", ffWRITE } }; #define NFILE asize(fnm) int npargs,i,nlag; int seed=1993; real *data,*data2,x; t_pargs *ppa; CopyRight(stderr,argv[0]); npargs = asize(pa); ppa = add_acf_pargs(&npargs,pa); parse_common_args_r(&argc,argv,PCA_CAN_TIME | PCA_CAN_VIEW | PCA_BE_NICE, NFILE,fnm,npargs,ppa,asize(desc),desc,0,NULL,&oenv); snew(data,nframes); snew(data2,nframes); fp = xvgropen(opt2fn("-d",NFILE,fnm),"testac","x","y",oenv); for(i=0; (i<nframes); i++) { x = a*i; switch (datatp) { case 1: data[i] = 1; break; case 2: data[i] = cos(x); break; case 3: data[i] = 2*rando(&seed)-1.0; break; case 4: data[i] = cos(x)+2*rando(&seed)-1.0; break; case 5: if (i==0) data[i] = 1; else data[i] = sin(x)/(x); default: /* Data remains 0.0 */ break; } fprintf(fp,"%10g %10g\n",x,data[i]); data2[i] = data[i]; } ffclose(fp); do_autocorr(opt2fn("-c",NFILE,fnm),oenv,str[datatp], nframes,1,&data,a,eacNormal,FALSE); nlag = get_acfnout(); fp = xvgropen(opt2fn("-comb",NFILE,fnm),"testac","x","y",oenv); for(i=0; (i<nlag); i++) { fprintf(fp,"%10g %10g %10g\n",a*i,data2[i],data[i]); } ffclose(fp); do_view(opt2fn("-c",NFILE,fnm),"-nxy"); thanx(stderr); return 0; }
void low_do_autocorr(const char *fn, const gmx_output_env_t *oenv, const char *title, int nframes, int nitem, int nout, real **c1, real dt, unsigned long mode, int nrestart, gmx_bool bAver, gmx_bool bNormalize, gmx_bool bVerbose, real tbeginfit, real tendfit, int eFitFn) { FILE *fp, *gp = NULL; int i; real *csum; real *ctmp, *fit; real sum, Ct2av, Ctav; gmx_bool bFour = acf.bFour; /* Check flags and parameters */ nout = get_acfnout(); if (nout == -1) { nout = acf.nout = (nframes+1)/2; } else if (nout > nframes) { nout = nframes; } if (MODE(eacCos) && MODE(eacVector)) { gmx_fatal(FARGS, "Incompatible options bCos && bVector (%s, %d)", __FILE__, __LINE__); } if ((MODE(eacP3) || MODE(eacRcross)) && bFour) { if (bVerbose) { fprintf(stderr, "Can't combine mode %lu with FFT, turning off FFT\n", mode); } bFour = FALSE; } if (MODE(eacNormal) && MODE(eacVector)) { gmx_fatal(FARGS, "Incompatible mode bits: normal and vector (or Legendre)"); } /* Print flags and parameters */ if (bVerbose) { printf("Will calculate %s of %d thingies for %d frames\n", title ? title : "autocorrelation", nitem, nframes); printf("bAver = %s, bFour = %s bNormalize= %s\n", gmx::boolToString(bAver), gmx::boolToString(bFour), gmx::boolToString(bNormalize)); printf("mode = %lu, dt = %g, nrestart = %d\n", mode, dt, nrestart); } /* Allocate temp arrays */ snew(csum, nframes); snew(ctmp, nframes); /* Loop over items (e.g. molecules or dihedrals) * In this loop the actual correlation functions are computed, but without * normalizing them. */ for (int i = 0; i < nitem; i++) { if (bVerbose && (((i % 100) == 0) || (i == nitem-1))) { fprintf(stderr, "\rThingie %d", i+1); fflush(stderr); } if (bFour) { do_four_core(mode, nframes, c1[i], csum, ctmp); } else { do_ac_core(nframes, nout, ctmp, c1[i], nrestart, mode); } } if (bVerbose) { fprintf(stderr, "\n"); } sfree(ctmp); sfree(csum); if (fn) { snew(fit, nout); fp = xvgropen(fn, title, "Time (ps)", "C(t)", oenv); } else { fit = NULL; fp = NULL; } if (bAver) { if (nitem > 1) { average_acf(bVerbose, nframes, nitem, c1); } if (bNormalize) { normalize_acf(nout, c1[0]); } if (eFitFn != effnNONE) { fit_acf(nout, eFitFn, oenv, fn != NULL, tbeginfit, tendfit, dt, c1[0], fit); sum = print_and_integrate(fp, nout, dt, c1[0], fit, 1); } else { sum = print_and_integrate(fp, nout, dt, c1[0], NULL, 1); } if (bVerbose) { printf("Correlation time (integral over corrfn): %g (ps)\n", sum); } } else { /* Not averaging. Normalize individual ACFs */ Ctav = Ct2av = 0; if (debug) { gp = xvgropen("ct-distr.xvg", "Correlation times", "item", "time (ps)", oenv); } for (i = 0; i < nitem; i++) { if (bNormalize) { normalize_acf(nout, c1[i]); } if (eFitFn != effnNONE) { fit_acf(nout, eFitFn, oenv, fn != NULL, tbeginfit, tendfit, dt, c1[i], fit); sum = print_and_integrate(fp, nout, dt, c1[i], fit, 1); } else { sum = print_and_integrate(fp, nout, dt, c1[i], NULL, 1); if (debug) { fprintf(debug, "CORRelation time (integral over corrfn %d): %g (ps)\n", i, sum); } } Ctav += sum; Ct2av += sum*sum; if (debug) { fprintf(gp, "%5d %.3f\n", i, sum); } } if (debug) { xvgrclose(gp); } if (nitem > 1) { Ctav /= nitem; Ct2av /= nitem; printf("Average correlation time %.3f Std. Dev. %.3f Error %.3f (ps)\n", Ctav, std::sqrt((Ct2av - gmx::square(Ctav))), std::sqrt((Ct2av - gmx::square(Ctav))/(nitem-1))); } } if (fp) { xvgrclose(fp); } sfree(fit); }