int main(void) { int test; calc_com(); scanf("%d", &test); while (test--) { LL n,k; scanf("%lld%lld", &n, &k); LL ans[MAXK]; ans[0]=n%mod; ans[1]=n*(n+1)/2%mod; for (int i=2; i<=k; i++) { LL ret = power(n,i+1); for (int j=2; j<=i+1; j++) { if (j&1) ret=(ret-C[i+1][j]*ans[i+1-j]%mod+mod)%mod; else ret=(ret+C[i+1][j]*ans[i+1-j]%mod+mod)%mod; } LL a=C[i+1][1], b=ret, x, y; ext_gcd(a, mod, x, y); x=(x%mod+mod)%mod; ans[i]=(x*b+mod)%mod; } printf("%lld\n", ans[k]); } return 0; }
/// /// @par Detailed description /// ... /// @param [in, out] (param1) ... /// @return ... /// @note ... float sascalc::Prop:: calc_rg(int &frame){ std::vector<float> com = calc_com(frame) ; float rgx = ((_x().col(frame) - com[0]).pow(2.0)).sum() ; float rgy = ((_y().col(frame) - com[1]).pow(2.0)).sum() ; float rgz = ((_z().col(frame) - com[2]).pow(2.0)).sum() ; float rg = sqrt((rgx + rgy + rgz) / _natoms()) ; return rg ; }
/// /// @par Detailed description /// ... /// @param [in, out] (param1) ... /// @return ... /// @note ... void sascalc::Prop:: calc_pmi(int &frame) { std::vector<float> com = calc_com(frame) ; _x().col(frame) -= com[0] ; _y().col(frame) -= com[1] ; _z().col(frame) -= com[2] ; float Ixx = (_atom_mass()*(_y().col(frame)*_y().col(frame) + _z().col(frame)*_z().col(frame))).sum() ; float Iyy = (_atom_mass()*(_x().col(frame)*_x().col(frame) + _z().col(frame)*_z().col(frame))).sum() ; float Izz = (_atom_mass()*(_x().col(frame)*_x().col(frame) + _y().col(frame)*_y().col(frame))).sum() ; float Ixy = (-_atom_mass()*(_x().col(frame)*_y().col(frame))).sum() ; float Ixz = (-_atom_mass()*(_x().col(frame)*_z().col(frame))).sum() ; float Iyz = (-_atom_mass()*(_y().col(frame)*_z().col(frame))).sum() ; float Iyx = (-_atom_mass()*(_y().col(frame)*_x().col(frame))).sum() ; float Izx = (-_atom_mass()*(_z().col(frame)*_x().col(frame))).sum() ; float Izy = (-_atom_mass()*(_z().col(frame)*_y().col(frame))).sum() ; Eigen::Matrix3f I ; I << Ixx, Ixy, Ixz, Iyx, Iyy, Iyz, Izx, Izy, Izz; Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigensolver(I); if (eigensolver.info() != Eigen::Success) { std::cout << "PMI calculation failed" << std::endl ; return ; } _uk() = eigensolver.eigenvalues() ; // .col(0) ; _ak() = eigensolver.eigenvectors() ; // std::cout << "The eigenvalues of I are:\n" << eigensolver.eigenvalues() << std::endl; // std::cout << "Here's a matrix whose columns are eigenvectors of I \n" // << "corresponding to these eigenvalues:\n" // << eigensolver.eigenvectors() << std::endl; _x().col(frame) += com[0] ; _y().col(frame) += com[1] ; _z().col(frame) += com[2] ; return ; }
/* this is the main loop for the correlation type functions * fx and nx are file pointers to things like read_first_x and * read_next_x */ int corr_loop(t_corr *curr, const char *fn, t_topology *top, int ePBC, gmx_bool bMol, int gnx[], atom_id *index[], t_calc_func *calc1, gmx_bool bTen, int *gnx_com, atom_id *index_com[], real dt, real t_pdb, rvec **x_pdb, matrix box_pdb, const output_env_t oenv) { rvec *x[2]; /* the coordinates to read */ rvec *xa[2]; /* the coordinates to calculate displacements for */ rvec com = {0}; real t, t_prev = 0; int natoms, i, j, cur = 0, maxframes = 0; t_trxstatus *status; #define prev (1-cur) matrix box; gmx_bool bFirst; gmx_rmpbc_t gpbc = NULL; natoms = read_first_x(oenv, &status, fn, &curr->t0, &(x[cur]), box); #ifdef DEBUG fprintf(stderr, "Read %d atoms for first frame\n", natoms); #endif if ((gnx_com != NULL) && natoms < top->atoms.nr) { fprintf(stderr, "WARNING: The trajectory only contains part of the system (%d of %d atoms) and therefore the COM motion of only this part of the system will be removed\n", natoms, top->atoms.nr); } snew(x[prev], natoms); if (bMol) { curr->ncoords = curr->nmol; snew(xa[0], curr->ncoords); snew(xa[1], curr->ncoords); } else { curr->ncoords = natoms; xa[0] = x[0]; xa[1] = x[1]; } bFirst = TRUE; t = curr->t0; if (x_pdb) { *x_pdb = NULL; } if (bMol) { gpbc = gmx_rmpbc_init(&top->idef, ePBC, natoms); } /* the loop over all frames */ do { if (x_pdb && ((bFirst && t_pdb < t) || (!bFirst && t_pdb > t - 0.5*(t - t_prev) && t_pdb < t + 0.5*(t - t_prev)))) { if (*x_pdb == NULL) { snew(*x_pdb, natoms); } for (i = 0; i < natoms; i++) { copy_rvec(x[cur][i], (*x_pdb)[i]); } copy_mat(box, box_pdb); } /* check whether we've reached a restart point */ if (bRmod(t, curr->t0, dt)) { curr->nrestart++; srenew(curr->x0, curr->nrestart); snew(curr->x0[curr->nrestart-1], curr->ncoords); srenew(curr->com, curr->nrestart); srenew(curr->n_offs, curr->nrestart); srenew(curr->lsq, curr->nrestart); snew(curr->lsq[curr->nrestart-1], curr->nmol); for (i = 0; i < curr->nmol; i++) { curr->lsq[curr->nrestart-1][i] = gmx_stats_init(); } if (debug) { fprintf(debug, "Extended data structures because of new restart %d\n", curr->nrestart); } } /* create or extend the frame-based arrays */ if (curr->nframes >= maxframes-1) { if (maxframes == 0) { for (i = 0; (i < curr->ngrp); i++) { curr->ndata[i] = NULL; curr->data[i] = NULL; if (bTen) { curr->datam[i] = NULL; } } curr->time = NULL; } maxframes += 10; for (i = 0; (i < curr->ngrp); i++) { srenew(curr->ndata[i], maxframes); srenew(curr->data[i], maxframes); if (bTen) { srenew(curr->datam[i], maxframes); } for (j = maxframes-10; j < maxframes; j++) { curr->ndata[i][j] = 0; curr->data[i][j] = 0; if (bTen) { clear_mat(curr->datam[i][j]); } } } srenew(curr->time, maxframes); } /* set the time */ curr->time[curr->nframes] = t - curr->t0; /* for the first frame, the previous frame is a copy of the first frame */ if (bFirst) { std::memcpy(xa[prev], xa[cur], curr->ncoords*sizeof(xa[prev][0])); bFirst = FALSE; } /* make the molecules whole */ if (bMol) { gmx_rmpbc(gpbc, natoms, box, x[cur]); } /* calculate the molecules' centers of masses and put them into xa */ if (bMol) { calc_mol_com(gnx[0], index[0], &top->mols, &top->atoms, x[cur], xa[cur]); } /* first remove the periodic boundary condition crossings */ for (i = 0; i < curr->ngrp; i++) { prep_data(bMol, gnx[i], index[i], xa[cur], xa[prev], box); } /* calculate the center of mass */ if (gnx_com) { prep_data(bMol, gnx_com[0], index_com[0], xa[cur], xa[prev], box); calc_com(bMol, gnx_com[0], index_com[0], xa[cur], xa[prev], box, &top->atoms, com); } /* loop over all groups in index file */ for (i = 0; (i < curr->ngrp); i++) { /* calculate something useful, like mean square displacements */ calc_corr(curr, i, gnx[i], index[i], xa[cur], (gnx_com != NULL), com, calc1, bTen); } cur = prev; t_prev = t; curr->nframes++; } while (read_next_x(oenv, status, &t, x[cur], box)); fprintf(stderr, "\nUsed %d restart points spaced %g %s over %g %s\n\n", curr->nrestart, output_env_conv_time(oenv, dt), output_env_get_time_unit(oenv), output_env_conv_time(oenv, curr->time[curr->nframes-1]), output_env_get_time_unit(oenv) ); if (bMol) { gmx_rmpbc_done(gpbc); } close_trj(status); return natoms; }
void Molecule::print_com() { calc_com(true); }