static void power_fit(int n,int nset,real **val,real *t) { real *x,*y,quality,a,b,r; int s,i; snew(x,n); snew(y,n); if (t[0]>0) { for(i=0; i<n; i++) if (t[0]>0) x[i] = log(t[i]); } else { fprintf(stdout,"First time is not larger than 0, using index number as time for power fit\n"); for(i=0; i<n; i++) x[i] = log(i+1); } for(s=0; s<nset; s++) { i=0; for(i=0; i<n && val[s][i]>=0; i++) y[i] = log(val[s][i]); if (i < n) fprintf(stdout,"Will power fit up to point %d, since it is not larger than 0\n",i); lsq_y_ax_b(i,x,y,&a,&b,&r,&quality); fprintf(stdout,"Power fit set %3d: error %.3f a %g b %g\n", s+1,quality,a,exp(b)); } sfree(y); sfree(x); }
static void regression_analysis(int n,bool bXYdy,real *x,real **val) { real S,chi2,a,b,da,db,r=0; printf("Fitting data to a function f(x) = ax + b\n"); printf("Minimizing residual chi2 = Sum_i w_i [f(x_i) - y_i]2\n"); printf("Error estimates will be given if w_i (sigma) values are given\n"); printf("(use option -xydy).\n\n"); if (bXYdy) lsq_y_ax_b_error(n,x,val[0],val[1],&a,&b,&da,&db,&r,&S); else lsq_y_ax_b(n,x,val[0],&a,&b,&r,&S); chi2 = sqr((n-2)*S); printf("Chi2 = %g\n",chi2); printf("S (Sqrt(Chi2/(n-2)) = %g\n",S); printf("Correlation coefficient = %.1f%%\n",100*r); printf("\n"); if (bXYdy) { printf("a = %g +/- %g\n",a,da); printf("b = %g +/- %g\n",b,db); } else { printf("a = %g\n",a); printf("b = %g\n",b); } }
static void dielectric(FILE *fmj, FILE *fmd, FILE *outf, FILE *fcur, FILE *mcor, FILE *fmjdsp, gmx_bool bNoJump, gmx_bool bACF, gmx_bool bINT, int ePBC, t_topology top, t_trxframe fr, real temp, real bfit, real efit, real bvit, real evit, t_trxstatus *status, int isize, int nmols, int nshift, int *index0, int indexm[], real mass2[], real qmol[], real eps_rf, const gmx_output_env_t *oenv) { int i, j; int valloc, nalloc, nfr, nvfr; int vshfr; real *xshfr = NULL; int *vfr = NULL; real refr = 0.0; real *cacf = NULL; real *time = NULL; real *djc = NULL; real corint = 0.0; real prefactorav = 0.0; real prefactor = 0.0; real volume; real volume_av = 0.0; real dk_s, dk_d, dk_f; real mj = 0.0; real mj2 = 0.0; real mjd = 0.0; real mjdav = 0.0; real md2 = 0.0; real mdav2 = 0.0; real sgk; rvec mja_tmp; rvec mjd_tmp; rvec mdvec; rvec *mu = NULL; rvec *xp = NULL; rvec *v0 = NULL; rvec *mjdsp = NULL; real *dsp2 = NULL; real t0; real rtmp; rvec tmp; rvec *mtrans = NULL; /* * Variables for the least-squares fit for Einstein-Helfand and Green-Kubo */ int bi, ei, ie, ii; real rest = 0.0; real sigma = 0.0; real malt = 0.0; real err = 0.0; real *xfit; real *yfit; gmx_rmpbc_t gpbc = NULL; /* * indices for EH */ ei = 0; bi = 0; /* * indices for GK */ ii = 0; ie = 0; t0 = 0; sgk = 0.0; /* This is the main loop over frames */ nfr = 0; nvfr = 0; vshfr = 0; nalloc = 0; valloc = 0; clear_rvec(mja_tmp); clear_rvec(mjd_tmp); clear_rvec(mdvec); clear_rvec(tmp); gpbc = gmx_rmpbc_init(&top.idef, ePBC, fr.natoms); do { refr = (nfr+1); if (nfr >= nalloc) { nalloc += 100; srenew(time, nalloc); srenew(mu, nalloc); srenew(mjdsp, nalloc); srenew(dsp2, nalloc); srenew(mtrans, nalloc); srenew(xshfr, nalloc); for (i = nfr; i < nalloc; i++) { clear_rvec(mjdsp[i]); clear_rvec(mu[i]); clear_rvec(mtrans[i]); dsp2[i] = 0.0; xshfr[i] = 0.0; } } GMX_RELEASE_ASSERT(time != NULL, "Memory not allocated correctly - time array is NULL"); if (nfr == 0) { t0 = fr.time; } time[nfr] = fr.time-t0; if (time[nfr] <= bfit) { bi = nfr; } if (time[nfr] <= efit) { ei = nfr; } if (bNoJump) { if (xp) { remove_jump(fr.box, fr.natoms, xp, fr.x); } else { snew(xp, fr.natoms); } for (i = 0; i < fr.natoms; i++) { copy_rvec(fr.x[i], xp[i]); } } gmx_rmpbc_trxfr(gpbc, &fr); calc_mj(top, ePBC, fr.box, bNoJump, nmols, indexm, fr.x, mtrans[nfr], mass2, qmol); for (i = 0; i < isize; i++) { j = index0[i]; svmul(top.atoms.atom[j].q, fr.x[j], fr.x[j]); rvec_inc(mu[nfr], fr.x[j]); } /*if(mod(nfr,nshift)==0){*/ if (nfr%nshift == 0) { for (j = nfr; j >= 0; j--) { rvec_sub(mtrans[nfr], mtrans[j], tmp); dsp2[nfr-j] += norm2(tmp); xshfr[nfr-j] += 1.0; } } if (fr.bV) { if (nvfr >= valloc) { valloc += 100; srenew(vfr, valloc); if (bINT) { srenew(djc, valloc); } srenew(v0, valloc); if (bACF) { srenew(cacf, valloc); } } if (time[nfr] <= bvit) { ii = nvfr; } if (time[nfr] <= evit) { ie = nvfr; } vfr[nvfr] = nfr; clear_rvec(v0[nvfr]); if (bACF) { cacf[nvfr] = 0.0; } if (bINT) { djc[nvfr] = 0.0; } for (i = 0; i < isize; i++) { j = index0[i]; svmul(mass2[j], fr.v[j], fr.v[j]); svmul(qmol[j], fr.v[j], fr.v[j]); rvec_inc(v0[nvfr], fr.v[j]); } fprintf(fcur, "%.3f\t%.6f\t%.6f\t%.6f\n", time[nfr], v0[nfr][XX], v0[nfr][YY], v0[nfr][ZZ]); if (bACF || bINT) { /*if(mod(nvfr,nshift)==0){*/ if (nvfr%nshift == 0) { for (j = nvfr; j >= 0; j--) { if (bACF) { cacf[nvfr-j] += iprod(v0[nvfr], v0[j]); } if (bINT) { djc[nvfr-j] += iprod(mu[vfr[j]], v0[nvfr]); } } vshfr++; } } nvfr++; } volume = det(fr.box); volume_av += volume; rvec_inc(mja_tmp, mtrans[nfr]); mjd += iprod(mu[nfr], mtrans[nfr]); rvec_inc(mdvec, mu[nfr]); mj2 += iprod(mtrans[nfr], mtrans[nfr]); md2 += iprod(mu[nfr], mu[nfr]); fprintf(fmj, "%.3f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\n", time[nfr], mtrans[nfr][XX], mtrans[nfr][YY], mtrans[nfr][ZZ], mj2/refr, norm(mja_tmp)/refr); fprintf(fmd, "%.3f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\t%8.5f\n", \ time[nfr], mu[nfr][XX], mu[nfr][YY], mu[nfr][ZZ], md2/refr, norm(mdvec)/refr); nfr++; } while (read_next_frame(oenv, status, &fr)); gmx_rmpbc_done(gpbc); volume_av /= refr; prefactor = 1.0; prefactor /= 3.0*EPSILON0*volume_av*BOLTZ*temp; prefactorav = E_CHARGE*E_CHARGE; prefactorav /= volume_av*BOLTZMANN*temp*NANO*6.0; fprintf(stderr, "Prefactor fit E-H: 1 / 6.0*V*k_B*T: %g\n", prefactorav); calc_mjdsp(fmjdsp, prefactorav, dsp2, time, nfr, xshfr); /* * Now we can average and calculate the correlation functions */ mj2 /= refr; mjd /= refr; md2 /= refr; svmul(1.0/refr, mdvec, mdvec); svmul(1.0/refr, mja_tmp, mja_tmp); mdav2 = norm2(mdvec); mj = norm2(mja_tmp); mjdav = iprod(mdvec, mja_tmp); printf("\n\nAverage translational dipole moment M_J [enm] after %d frames (|M|^2): %f %f %f (%f)\n", nfr, mja_tmp[XX], mja_tmp[YY], mja_tmp[ZZ], mj2); printf("\n\nAverage molecular dipole moment M_D [enm] after %d frames (|M|^2): %f %f %f (%f)\n", nfr, mdvec[XX], mdvec[YY], mdvec[ZZ], md2); if (v0 != NULL) { if (bINT) { printf("\nCalculating M_D - current correlation integral ... \n"); corint = calc_cacf(mcor, prefactorav/EPSI0, djc, time, nvfr, vfr, ie, nshift); } if (bACF) { printf("\nCalculating current autocorrelation ... \n"); sgk = calc_cacf(outf, prefactorav/PICO, cacf, time, nvfr, vfr, ie, nshift); if (ie > ii) { snew(xfit, ie-ii+1); snew(yfit, ie-ii+1); for (i = ii; i <= ie; i++) { xfit[i-ii] = std::log(time[vfr[i]]); rtmp = std::abs(cacf[i]); yfit[i-ii] = std::log(rtmp); } lsq_y_ax_b(ie-ii, xfit, yfit, &sigma, &malt, &err, &rest); malt = std::exp(malt); sigma += 1.0; malt *= prefactorav*2.0e12/sigma; sfree(xfit); sfree(yfit); } } } /* Calculation of the dielectric constant */ fprintf(stderr, "\n********************************************\n"); dk_s = calceps(prefactor, md2, mj2, mjd, eps_rf, FALSE); fprintf(stderr, "\nAbsolute values:\n epsilon=%f\n", dk_s); fprintf(stderr, " <M_D^2> , <M_J^2>, <(M_J*M_D)^2>: (%f, %f, %f)\n\n", md2, mj2, mjd); fprintf(stderr, "********************************************\n"); dk_f = calceps(prefactor, md2-mdav2, mj2-mj, mjd-mjdav, eps_rf, FALSE); fprintf(stderr, "\n\nFluctuations:\n epsilon=%f\n\n", dk_f); fprintf(stderr, "\n deltaM_D , deltaM_J, deltaM_JD: (%f, %f, %f)\n", md2-mdav2, mj2-mj, mjd-mjdav); fprintf(stderr, "\n********************************************\n"); if (bINT) { dk_d = calceps(prefactor, md2-mdav2, mj2-mj, corint, eps_rf, TRUE); fprintf(stderr, "\nStatic dielectric constant using integral and fluctuations: %f\n", dk_d); fprintf(stderr, "\n < M_JM_D > via integral: %.3f\n", -1.0*corint); } fprintf(stderr, "\n***************************************************"); fprintf(stderr, "\n\nAverage volume V=%f nm^3 at T=%f K\n", volume_av, temp); fprintf(stderr, "and corresponding refactor 1.0 / 3.0*V*k_B*T*EPSILON_0: %f \n", prefactor); if (bACF && (ii < nvfr)) { fprintf(stderr, "Integral and integrated fit to the current acf yields at t=%f:\n", time[vfr[ii]]); fprintf(stderr, "sigma=%8.3f (pure integral: %.3f)\n", sgk-malt*std::pow(time[vfr[ii]], sigma), sgk); } if (ei > bi) { fprintf(stderr, "\nStart fit at %f ps (%f).\n", time[bi], bfit); fprintf(stderr, "End fit at %f ps (%f).\n\n", time[ei], efit); snew(xfit, ei-bi+1); snew(yfit, ei-bi+1); for (i = bi; i <= ei; i++) { xfit[i-bi] = time[i]; yfit[i-bi] = dsp2[i]; } lsq_y_ax_b(ei-bi, xfit, yfit, &sigma, &malt, &err, &rest); sigma *= 1e12; dk_d = calceps(prefactor, md2, 0.5*malt/prefactorav, corint, eps_rf, TRUE); fprintf(stderr, "Einstein-Helfand fit to the MSD of the translational dipole moment yields:\n\n"); fprintf(stderr, "sigma=%.4f\n", sigma); fprintf(stderr, "translational fraction of M^2: %.4f\n", 0.5*malt/prefactorav); fprintf(stderr, "Dielectric constant using EH: %.4f\n", dk_d); sfree(xfit); sfree(yfit); } else { fprintf(stderr, "Too few points for a fit.\n"); } if (v0 != NULL) { sfree(v0); } if (bACF) { sfree(cacf); } if (bINT) { sfree(djc); } sfree(time); sfree(mjdsp); sfree(mu); }
static void regression_analysis(int n, gmx_bool bXYdy, real *x, int nset, real **val) { real S, chi2, a, b, da, db, r = 0; int ok; if (bXYdy || (nset == 1)) { printf("Fitting data to a function f(x) = ax + b\n"); printf("Minimizing residual chi2 = Sum_i w_i [f(x_i) - y_i]2\n"); printf("Error estimates will be given if w_i (sigma) values are given\n"); printf("(use option -xydy).\n\n"); if (bXYdy) { if ((ok = lsq_y_ax_b_error(n, x, val[0], val[1], &a, &b, &da, &db, &r, &S)) != estatsOK) { gmx_fatal(FARGS, "Error fitting the data: %s", gmx_stats_message(ok)); } } else { if ((ok = lsq_y_ax_b(n, x, val[0], &a, &b, &r, &S)) != estatsOK) { gmx_fatal(FARGS, "Error fitting the data: %s", gmx_stats_message(ok)); } } chi2 = sqr((n-2)*S); printf("Chi2 = %g\n", chi2); printf("S (Sqrt(Chi2/(n-2)) = %g\n", S); printf("Correlation coefficient = %.1f%%\n", 100*r); printf("\n"); if (bXYdy) { printf("a = %g +/- %g\n", a, da); printf("b = %g +/- %g\n", b, db); } else { printf("a = %g\n", a); printf("b = %g\n", b); } } else { double chi2, *a, **xx, *y; int i, j; snew(y, n); snew(xx, nset-1); for (j = 0; (j < nset-1); j++) { snew(xx[j], n); } for (i = 0; (i < n); i++) { y[i] = val[0][i]; for (j = 1; (j < nset); j++) { xx[j-1][i] = val[j][i]; } } snew(a, nset-1); chi2 = multi_regression(NULL, n, y, nset-1, xx, a); printf("Fitting %d data points in %d sets\n", n, nset-1); printf("chi2 = %g\n", chi2); printf("A ="); for (i = 0; (i < nset-1); i++) { printf(" %g", a[i]); sfree(xx[i]); } printf("\n"); sfree(xx); sfree(y); sfree(a); } }
void do_corr(const char *trx_file, const char *ndx_file, const char *msd_file, const char *mol_file, const char *pdb_file, real t_pdb, int nrgrp, t_topology *top, int ePBC, gmx_bool bTen, gmx_bool bMW, gmx_bool bRmCOMM, int type, real dim_factor, int axis, real dt, real beginfit, real endfit, const output_env_t oenv) { t_corr *msd; int *gnx; /* the selected groups' sizes */ atom_id **index; /* selected groups' indices */ char **grpname; int i, i0, i1, j, N, nat_trx; real *DD, *SigmaD, a, a2, b, r, chi2; rvec *x; matrix box; int *gnx_com = NULL; /* the COM removal group size */ atom_id **index_com = NULL; /* the COM removal group atom indices */ char **grpname_com = NULL; /* the COM removal group name */ snew(gnx, nrgrp); snew(index, nrgrp); snew(grpname, nrgrp); fprintf(stderr, "\nSelect a group to calculate mean squared displacement for:\n"); get_index(&top->atoms, ndx_file, nrgrp, gnx, index, grpname); if (bRmCOMM) { snew(gnx_com, 1); snew(index_com, 1); snew(grpname_com, 1); fprintf(stderr, "\nNow select a group for center of mass removal:\n"); get_index(&top->atoms, ndx_file, 1, gnx_com, index_com, grpname_com); } if (mol_file) { index_atom2mol(&gnx[0], index[0], &top->mols); } msd = init_corr(nrgrp, type, axis, dim_factor, mol_file == NULL ? 0 : gnx[0], bTen, bMW, dt, top, beginfit, endfit); nat_trx = corr_loop(msd, trx_file, top, ePBC, mol_file ? gnx[0] : 0, gnx, index, (mol_file != NULL) ? calc1_mol : (bMW ? calc1_mw : calc1_norm), bTen, gnx_com, index_com, dt, t_pdb, pdb_file ? &x : NULL, box, oenv); /* Correct for the number of points */ for (j = 0; (j < msd->ngrp); j++) { for (i = 0; (i < msd->nframes); i++) { msd->data[j][i] /= msd->ndata[j][i]; if (bTen) { msmul(msd->datam[j][i], 1.0/msd->ndata[j][i], msd->datam[j][i]); } } } if (mol_file) { if (pdb_file && x == NULL) { fprintf(stderr, "\nNo frame found need time tpdb = %g ps\n" "Can not write %s\n\n", t_pdb, pdb_file); } i = top->atoms.nr; top->atoms.nr = nat_trx; printmol(msd, mol_file, pdb_file, index[0], top, x, ePBC, box, oenv); top->atoms.nr = i; } DD = NULL; SigmaD = NULL; if (beginfit == -1) { i0 = static_cast<int>(0.1*(msd->nframes - 1) + 0.5); beginfit = msd->time[i0]; } else { for (i0 = 0; i0 < msd->nframes && msd->time[i0] < beginfit; i0++) { ; } } if (endfit == -1) { i1 = static_cast<int>(0.9*(msd->nframes - 1) + 0.5) + 1; endfit = msd->time[i1-1]; } else { for (i1 = i0; i1 < msd->nframes && msd->time[i1] <= endfit; i1++) { ; } } fprintf(stdout, "Fitting from %g to %g %s\n\n", beginfit, endfit, output_env_get_time_unit(oenv)); N = i1-i0; if (N <= 2) { fprintf(stdout, "Not enough points for fitting (%d).\n" "Can not determine the diffusion constant.\n", N); } else { snew(DD, msd->ngrp); snew(SigmaD, msd->ngrp); for (j = 0; j < msd->ngrp; j++) { if (N >= 4) { lsq_y_ax_b(N/2, &(msd->time[i0]), &(msd->data[j][i0]), &a, &b, &r, &chi2); lsq_y_ax_b(N/2, &(msd->time[i0+N/2]), &(msd->data[j][i0+N/2]), &a2, &b, &r, &chi2); SigmaD[j] = std::abs(a-a2); } else { SigmaD[j] = 0; } lsq_y_ax_b(N, &(msd->time[i0]), &(msd->data[j][i0]), &(DD[j]), &b, &r, &chi2); DD[j] *= FACTOR/msd->dim_factor; SigmaD[j] *= FACTOR/msd->dim_factor; if (DD[j] > 0.01 && DD[j] < 1e4) { fprintf(stdout, "D[%10s] %.4f (+/- %.4f) 1e-5 cm^2/s\n", grpname[j], DD[j], SigmaD[j]); } else { fprintf(stdout, "D[%10s] %.4g (+/- %.4g) 1e-5 cm^2/s\n", grpname[j], DD[j], SigmaD[j]); } } } /* Print mean square displacement */ corr_print(msd, bTen, msd_file, "Mean Square Displacement", "MSD (nm\\S2\\N)", msd->time[msd->nframes-1], beginfit, endfit, DD, SigmaD, grpname, oenv); }