public static void SelectCommonAtoms <Atom>(ref List <Atom> atoms1, ref List <Atom> atoms2) where Atom : IAtom { List <Atom> _atoms1 = new List <Atom>(atoms1); List <Atom> _atoms2 = new List <Atom>(atoms2); _atoms1 = _atoms1.ListCommon(_atoms2); HPack <List <int> > idxAtom2ToAtom1 = new HPack <List <int> >(); //{ // List<Atom> cas1 = _atoms1.SelectByName("CA"); // List<Atom> cas2 = _atoms2.SelectByName("CA"); // List<int> idx1 = new List<int>(); // List<int> idx2 = new List<int>(); // LCS.LongestCommonSubsequence( cas1 , cas2 , idx1, idx2, Atom.CompareNameResName); // cas1 = cas1.SelectByIndex(idx1); // cas2 = cas2.SelectByIndex(idx2); //} _atoms2 = _atoms2.ListCommon(_atoms1, idxAtom2ToAtom1); _atoms1 = _atoms1.HSelectByIndex(idxAtom2ToAtom1.value).ToList(); if (HDebug.IsDebuggerAttached) { HDebug.AssertAllEquals(_atoms1.Count, _atoms2.Count); for (int i = 0; i < _atoms1.Count; i++) { HDebug.AssertAllEquals(_atoms1[i].name.Trim(), _atoms2[i].name.Trim()); HDebug.AssertAllEquals(_atoms1[i].resName.Trim(), _atoms1[i].resName.Trim()); HDebug.AssertAllEquals(_atoms1[i].resSeq, _atoms1[i].resSeq); } } atoms1 = _atoms1; atoms2 = _atoms2; }
public static void Align(IList <Vector> C1 , IList <Anisou> anisou1 , ref List <Vector> C2 , HPack <List <Vector> > optMoveC2 = null , HPack <Trans3> outTrans = null , HPack <double> optEnergy = null ) { Trans3 trans = GetTrans(C1, anisou1, C2, optEnergy: optEnergy); Vector[] nC2 = trans.GetTransformed(C2).ToArray(); if (optMoveC2 != null) { optMoveC2.value = new List <Vector>(nC2.Length); for (int i = 0; i < nC2.Length; i++) { optMoveC2.value.Add(nC2[i] - C2[i]); } } if (outTrans != null) { outTrans.value = trans; } C2 = new List <Vector>(nC2); }
public static void Align(IList <Vector> C1 , IList <Anisou> anisou1 , ref IList <Vector> C2 , ref IList <Anisou> anisou2 , HPack <Trans3> outTrans = null , HPack <double> optEnergy = null ) { Trans3 trans = GetTrans(C1, anisou1, C2, anisou2, optEnergy: optEnergy); C2 = new List <Vector>(C2); anisou2 = new List <Anisou>(anisou2); Vector[] nC2 = trans.GetTransformed(C2).ToArray(); for (int i = 0; i < C2.Count; i++) { Vector p2i = C2[i]; Anisou a2i = anisou2[i]; Vector np2i = trans.DoTransform(p2i); Anisou na2i = a2i.Clone(); na2i.eigvecs[0] = (trans.DoTransform(p2i + a2i.eigvecs[0]) - np2i).UnitVector(); na2i.eigvecs[1] = (trans.DoTransform(p2i + a2i.eigvecs[1]) - np2i).UnitVector(); na2i.eigvecs[2] = (trans.DoTransform(p2i + a2i.eigvecs[2]) - np2i).UnitVector(); C2[i] = np2i; anisou2[i] = na2i; } if (outTrans != null) { outTrans.value = trans; } }
public static void Align(IList <Vector> C1 , ref List <Vector> C2 , HPack <List <Vector> > optMoveC2 = null , HPack <Trans3> outTrans = null , HPack <double> optRmsd = null ) { Trans3 trans = GetTrans(C1, C2); Vector[] nC2 = trans.GetTransformed(C2).ToArray(); if (optMoveC2 != null) { optMoveC2.value = new List <Vector>(nC2.Length); for (int i = 0; i < nC2.Length; i++) { optMoveC2.value[i] = nC2[i] - C2[i]; } } if (optRmsd != null) { optRmsd.value = 0; for (int i = 0; i < nC2.Length; i++) { optRmsd.value += (nC2[i] - C1[i]).Dist2; } optRmsd.value /= nC2.Length; } C2 = new List <Vector>(nC2); if (outTrans != null) { outTrans.value = trans.Clone(); } }
public static List <Atom> ListCommon <Atom>(this IList <Atom> atoms, IList <Atom> atomsToCompare , HPack <List <int> > outAtomIdx = null // index for the returned list ) where Atom : IAtom { List <Atom> list = new List <Atom>(); if (outAtomIdx != null) { outAtomIdx.value = new List <int>(); } foreach (Atom atom in atoms) { int idx = atomsToCompare.IndexOfAtom(atom.name, atom.resSeq); if (idx == -1) { continue; } list.Add(atom); if (outAtomIdx != null) { outAtomIdx.value.Add(idx); } } return(list); }
public static void SelectCommonAtoms <Atom>(ref List <Atom> atoms1, ref List <Atom> atoms2, ref List <Atom> atoms3, ref List <Atom> atoms4, ref List <Atom> atoms5) where Atom : IAtom { List <Atom> _atoms1 = new List <Atom>(atoms1); List <Atom> _atoms2 = new List <Atom>(atoms2); List <Atom> _atoms3 = new List <Atom>(atoms3); List <Atom> _atoms4 = new List <Atom>(atoms4); List <Atom> _atoms5 = new List <Atom>(atoms5); _atoms1 = _atoms1.ListCommon(_atoms2); _atoms1 = _atoms1.ListCommon(_atoms3); _atoms1 = _atoms1.ListCommon(_atoms4); _atoms1 = _atoms1.ListCommon(_atoms5); HPack <List <int> > idxAtom2ToAtom1 = new HPack <List <int> >(); _atoms2 = _atoms2.ListCommon(_atoms1, idxAtom2ToAtom1); _atoms2 = _atoms2.HSelectByIndex(idxAtom2ToAtom1.value).ToList(); HPack <List <int> > idxAtom3ToAtom1 = new HPack <List <int> >(); _atoms3 = _atoms3.ListCommon(_atoms1, idxAtom3ToAtom1); _atoms3 = _atoms3.HSelectByIndex(idxAtom3ToAtom1.value).ToList(); HPack <List <int> > idxAtom4ToAtom1 = new HPack <List <int> >(); _atoms4 = _atoms4.ListCommon(_atoms1, idxAtom4ToAtom1); _atoms4 = _atoms4.HSelectByIndex(idxAtom4ToAtom1.value).ToList(); HPack <List <int> > idxAtom5ToAtom1 = new HPack <List <int> >(); _atoms5 = _atoms5.ListCommon(_atoms1, idxAtom5ToAtom1); _atoms5 = _atoms5.HSelectByIndex(idxAtom5ToAtom1.value).ToList(); if (HDebug.IsDebuggerAttached) { HDebug.AssertAllEquals(_atoms1.Count, _atoms2.Count, _atoms3.Count, _atoms4.Count, _atoms5.Count); for (int i = 0; i < _atoms1.Count; i++) { HDebug.AssertAllEquals(_atoms1[i].name, _atoms2[i].name, _atoms3[i].name, _atoms4[i].name, _atoms5[i].name); HDebug.AssertAllEquals(_atoms1[i].resName, _atoms1[i].resName, _atoms3[i].resName, _atoms4[i].resName, _atoms5[i].resName); HDebug.AssertAllEquals(_atoms1[i].resSeq, _atoms1[i].resSeq, _atoms3[i].resSeq, _atoms4[i].resSeq, _atoms5[i].resSeq); } } atoms1 = _atoms1; atoms2 = _atoms2; atoms3 = _atoms3; atoms4 = _atoms4; atoms5 = _atoms5; }
public static void Align(IList <Vector> C1 , ref List <Vector> C2 , IList <double> weight , HPack <Trans3> outTrans = null ) { Trans3 trans = GetTrans(C1, C2, weight); Vector[] nC2 = trans.GetTransformed(C2).ToArray(); C2 = new List <Vector>(nC2); if (outTrans != null) { outTrans.value = trans.Clone(); } }
public static void Align(ref List <Pdb.Atom>[] ensemble , int maxiteration = int.MaxValue , HPack <List <Trans3[]> > outTrajTrans = null ) { List <Vector>[] coordss = new List <Vector> [ensemble.Length]; for (int i = 0; i < ensemble.Length; i++) { coordss[i] = ensemble[i].ListCoord(); } Align(ref coordss, maxiteration: maxiteration, outTrajTrans: outTrajTrans); ensemble = ensemble.HClone <List <Pdb.Atom> >(); for (int i = 0; i < ensemble.Length; i++) { ensemble[i] = ensemble[i].CloneByUpdateCoord(coordss[i]); } }
public static Trans3 GetTrans(IList <Vector> C1, IList <Vector> C2, HPack <int> optIter = null, HPack <List <double> > optListWeightSum = null) { HDebug.Assert(C1.Count == C2.Count); int size = C1.Count; if (optIter != null) { optIter.value = 0; } Trans3 trans0 = new Trans3(new double[3], 1, Quaternion.UnitRotation); Trans3 trans1 = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1); if (optListWeightSum != null) { optListWeightSum.value = new List <double>(); } while ((trans0.TransformMatrix - trans1.TransformMatrix).ToArray().HAbs().HMax() > 0.00000001) { if (optIter != null) { optIter.value++; } Vector[] C2trans = trans1.GetTransformed(C2).ToArray(); double[] weight = new double[size]; double[] dist2s = new double[size]; for (int i = 0; i < size; i++) { double dist2 = (C1[i] - C2trans[i]).Dist2; dist2 = HMath.Between(0.001, dist2, double.PositiveInfinity); weight[i] = 1 / dist2; dist2s[i] = dist2; } if (optListWeightSum != null) { optListWeightSum.value.Add(weight.Sum()); } trans0 = trans1; trans1 = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1, weight); } return(trans1); }
public static void Align(List <Vector> coords1 , ref List <Vector> coords2 , int maxiteration = int.MaxValue , HPack <List <Trans3[]> > outTrajTrans = null ) { List <Vector>[] ensemble = new List <Vector>[] { coords1.HClone(), coords2.HClone() }; Align(ref ensemble, maxiteration: maxiteration, outTrajTrans: outTrajTrans); Trans3 trans = MinRMSD.GetTrans(coords1, ensemble[0]); Vector[] ensemble0 = trans.GetTransformed(ensemble[0]).ToArray(); Vector[] ensemble1 = trans.GetTransformed(ensemble[1]).ToArray(); coords2 = new List <Vector>(ensemble1); }
private PreparedHeader(PreparedHeaderName name, string value, byte[] valueEncoded, uint http2StaticIndex) { Value = value; _name = name; _value = valueEncoded; int http1EncodedLen = Http1Connection.GetEncodeHeaderLength(name._http1Encoded, valueEncoded); _http1Encoded = new byte[http1EncodedLen]; Http1Connection.EncodeHeader(name._http1Encoded, valueEncoded, _http1Encoded); _http2Encoded = http2StaticIndex != 0 ? HPack.EncodeIndexedHeader(http2StaticIndex) : name._http2StaticIndex != 0 ? HPack.EncodeHeaderWithoutIndexing(name._http2StaticIndex, valueEncoded) : HPack.EncodeHeaderWithoutIndexing(name._http2Encoded, valueEncoded); _http2StaticIndex = http2StaticIndex; }
public static Mode[] GetModeByTorsional(Universe univ , Matrix hessian , List <Universe.RotableInfo> univ_rotinfos = null , Matrix J = null , Vector[] coords = null , HPack <Matrix> optoutJMJ = null // J' M J , HPack <Matrix> optoutJM = null // J' M , Func <Matrix, Tuple <Matrix, Vector> > fnEigSymm = null , Func <Matrix, Matrix, Matrix, Matrix> fnMul = null ) { return(GetModeByTorsional(univ , new HessMatrixDense { hess = hessian } , univ_rotinfos, J , coords, optoutJMJ, optoutJM , fnEigSymm, fnMul )); }
private static double Align(List <Vector>[] ensemble, Vector[] meancoords, Anisou[] meananisous, Trans3[] outTranss) { double[] move2s = new double[ensemble.Length]; System.Threading.Tasks.Parallel.For(0, ensemble.Length, delegate(int i) //for(int i=0; i<ensemble.Length; i++) { HPack <List <Vector> > optMoveConf = new HPack <List <Vector> >(); HPack <Trans3> outTrans = new HPack <Trans3>(); MinAnisou.Align(meancoords, meananisous, ref ensemble[i], optMoveConf, outTrans: outTrans); if (outTranss != null) { outTranss[i] = outTrans.value; } move2s[i] = optMoveConf.value.Dist2().Average(); } ); double move2 = move2s.Average(); return(move2); }
private void GetPotentialAndTorForce(List <ForceField.IForceField> frcflds, Vector[] coords , out double energy, out Vector[] forces , Dictionary <string, object> cache) { MatrixByArr J; { Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = univ.BuildFlexibilityGraph(); List <Universe.RotableInfo> univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); J = Paper.TNM.GetJ(univ, coords, univ_rotinfos); } Vector[] forces0 = univ.GetVectorsZero(); MatrixByArr hessian = null; energy = univ.GetPotential(frcflds, coords, ref forces0, ref hessian, cache); HPack <Vector[]> lforces = new HPack <Vector[]>(); double[] dtor = Paper.TNM.GetRotAngles(univ, coords, forces0, 1, J: J, forcesProjectedByTorsional: lforces); forces = lforces.value; }
public static Top FromPdb(string pdbpath , string ff = "charmm27" , string water = "none" , HPack <Pdb> optout_confout = null ) { Top top; FileInfo pdbinfo = new FileInfo(pdbpath); string currdir = HEnvironment.CurrentDirectory; DirectoryInfo temproot = HDirectory.CreateTempDirectory(); HEnvironment.CurrentDirectory = temproot.FullName; { HFile.Copy(pdbinfo.FullName, "protein.pdb"); RunPdb2gmx(f: "protein.pdb" , o: "confout.pdb" , p: "topol.top" , q: "clean.pdb" , ff: ff , water: water , merge: "all" , lineStderr: null , lineStdout: null ); top = Top.FromFile("topol.top"); if (optout_confout != null) { optout_confout.value = Pdb.FromFile("confout.pdb"); } } HEnvironment.CurrentDirectory = currdir; Thread.Sleep(100); try{ temproot.Delete(true); } catch (Exception) {} return(top); }
public static Mode[] GetModeByTorsional(Universe univ , HessMatrix hessian , List <Universe.RotableInfo> univ_rotinfos = null , Matrix J = null , Vector[] coords = null , HPack <Matrix> optoutJMJ = null // J' M J , HPack <Matrix> optoutJM = null // J' M , Func <Matrix, Tuple <Matrix, Vector> > fnEigSymm = null , Func <Matrix, Matrix, Matrix, Matrix> fnMul = null ) { if (univ_rotinfos == null) { Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = univ.BuildFlexibilityGraph(null as IList <Bond>); if (univ_flexgraph.FindLoops().Count > 0) { // loop should not exist in the flexibility-graph; no-global loop in backbone return(null); } univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); } if (coords == null) { coords = univ.GetCoords(); } if (J == null) { J = TNM.GetJ(univ, coords, univ_rotinfos); } Vector masses = univ.GetMasses(); Mode[] modes = GetModeByTorsional(hessian, masses, J , optoutJMJ: optoutJMJ, optoutJM: optoutJM , fnEigSymm: fnEigSymm, fnMul: fnMul ); return(modes); }
//////////////////////////////////////////////////////////////////////////// // Source: Gromacs, g_nmens.c // // #define BOLTZ (RGAS/KILO) /* (kJ/(mol K)) */ // #define RGAS (BOLTZMANN*AVOGADRO) /* (J/(mol K)) */ // #define BOLTZMANN (1.380658e-23) /* (J/K) */ // #define AVOGADRO (6.0221367e23) /* () */ // #define KILO (1e3) /* Thousand */ // // for(s=0; s<nstruct; s++) { // for(i=0; i<natoms; i++) // copy_rvec(xav[i],xout1[i]); // ////////////////////////////////////////////////// // randnorms_mag = 0; // for(j=0; j<noutvec; j++) // { // randnorms[j] = RandNormal(); // randnorms_mag += randnorms[j]*randnorms[j]; // } // randnorms_mag = sqrt(randnorms_mag); // for(j=0; j<noutvec; j++) // { // randnorms[j] = randnorms[j] / randnorms_mag; // } // ////////////////////////////////////////////////// // for(j=0; j<noutvec; j++) { // v = outvec[j]; // /* (r-0.5) n times: var_n = n * var_1 = n/12 // n=4: var_n = 1/3, so multiply with 3 */ // // rfac = sqrt(3.0 * BOLTZ*temp/eigval[iout[j]]); // //rhalf = 2.0*rfac; // //rfac = rfac/(real)im; // // // //jran = (jran*ia+ic) & im; // //jr = (real)jran; // //jran = (jran*ia+ic) & im; // //jr += (real)jran; // //jran = (jran*ia+ic) & im; // //jr += (real)jran; // //jran = (jran*ia+ic) & im; // //jr += (real)jran; // //disp = rfac * jr - rhalf; // disp = rfac*randnorms[j]; // // for(i=0; i<natoms; i++) // for(d=0; d<DIM; d++) // xout1[i][d] += disp*eigvec[v][i][d]*invsqrtm[i]; // } // for(i=0; i<natoms; i++) // copy_rvec(xout1[i],xout2[index[i]]); // t = s+1; // write_trx(out,natoms,index,atoms,0,t,box,xout2,NULL,NULL); // fprintf(stderr,"\rGenerated %d structures",s+1); // } //////////////////////////////////////////////////////////////////////////// public static Vector[] GenerateEnsemble(IList <Vector> coords, Mode mode, IList <double> mass, double temperature = 300, bool normalize = true, HPack <Vector> optOutRandNorms = null) { return(GenerateEnsemble(coords, new Mode[] { mode }, mass, temperature: temperature, normalize: normalize, optOutRandNorms: optOutRandNorms)); }
public int ConjugateGradient(List <ForceField.IForceField> frcflds , double threshold , double?k = null , double max_atom_movement = 0.01 , int?max_iteration = null , IMinimizeLogger logger = null // logger = new MinimizeLogger_PrintEnergyForceMag(logpath); , HPack <double> optOutEnergy = null // optional output for final energy , List <Vector> optOutForces = null // optional output for final force vectors , HPack <double> optOutForcesNorm1 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNorm2 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNormInf = null // optional output for norm of final force vectors ) { if (k == null) { k = double.MaxValue; foreach (ForceField.IForceField frcfld in frcflds) { double?kk = frcfld.GetDefaultMinimizeStep(); if (kk.HasValue) { k = Math.Min(k.Value, kk.Value); } } } Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = univ.BuildFlexibilityGraph(); List <Universe.RotableInfo> univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); // double k = 0.0001; int iter = 0; // 0. Initial configuration of atoms Vector[] coords0 = univ.GetCoords(); Vectors coords = univ.GetCoords(); bool[] atomsMovable = null; if (atomsMovable == null) { atomsMovable = new bool[size]; for (int i = 0; i < size; i++) { atomsMovable[i] = true; } } Vectors h = univ.GetVectorsZero(); Vectors forces = univ.GetVectorsZero(); Dictionary <string, object> cache; double energy; cache = new Dictionary <string, object>(); GetPotentialAndTorForce(frcflds, coords , out energy, out forces._vecs , cache); double forces_NormInf = NormInf(forces, atomsMovable); double forces_Norm1 = Norm(1, forces, atomsMovable); double forces_Norm2 = Norm(2, forces, atomsMovable); Vectors forces0 = forces; double energy0 = energy; while (true) { if (forces.IsComputable == false) { System.Console.Error.WriteLine("non-computable components while doing steepest-descent"); HEnvironment.Exit(0); } if (logger != null) { logger.log(iter, coords, energy, forces, atomsMovable); { // logger.logTrajectory(univ, iter, coords); Vector[] coordsx = coords._vecs.HClone <Vector>(); Trans3 trans = ICP3.OptimalTransform(coordsx, coords0); trans.DoTransform(coordsx); logger.logTrajectory(univ, iter, coordsx); } } // 1. Save the position of atoms // 2. Calculate the potential energy of system and the net forces on atoms // 3. Check if every force reaches to zero, // , and END if yes bool stopIteration = false; if (forces_NormInf < threshold) { stopIteration = true; } if ((max_iteration != null) && (iter >= max_iteration.Value)) { stopIteration = true; } if (stopIteration) { // double check cache = new Dictionary <string, object>(); // reset cache GetPotentialAndTorForce(frcflds, coords , out energy, out forces._vecs , cache); forces_NormInf = NormInf(forces, atomsMovable); forces_Norm1 = Norm(1, forces, atomsMovable); forces_Norm2 = Norm(2, forces, atomsMovable); if (forces_NormInf < threshold) { if (iter != 1) { univ.SetCoords((Vector[])coords); } { if (optOutEnergy != null) { optOutEnergy.value = energy; } if (optOutForces != null) { optOutForces.Clear(); optOutForces.AddRange(forces.ToArray()); } if (optOutForcesNorm1 != null) { optOutForcesNorm1.value = forces_Norm1; } if (optOutForcesNorm2 != null) { optOutForcesNorm2.value = forces_Norm2; } if (optOutForcesNormInf != null) { optOutForcesNormInf.value = forces_NormInf; } } return(iter); } } // 4. Move atoms with conjugated gradient Vectors coords_prd; { if ((iter > 0) && (iter % 100 == 0)) { cache = new Dictionary <string, object>(); // reset cache } if (iter >= 1) { HDebug.Assert(forces0 != null); double r = Vectors.VtV(forces, forces).Sum() / Vectors.VtV(forces0, forces0).Sum(); h = forces + r * h; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } Vector dangles = Paper.TNM.GetRotAngles(univ, coords, kk * h, 1); //dangles *= -1; coords_prd = Paper.TNM.RotateTorsionals(coords, dangles, univ_rotinfos); } else { // same to the steepest descent for the first iteration h = forces; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } Vector dangles = Paper.TNM.GetRotAngles(univ, coords, kk * h, 1); //dangles *= -1; coords_prd = Paper.TNM.RotateTorsionals(coords, dangles, univ_rotinfos); } } // 5. Predict energy or forces on atoms iter++; double energy_prd; Vectors forces_prd = univ.GetVectorsZero(); GetPotentialAndTorForce(frcflds, coords_prd , out energy_prd, out forces_prd._vecs , cache); // double energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache); // Vector[] dcoord_prd = univ.GetVectorsZero(); // double[] dangles_prd = TNM.GetRotAngles(univ, coords_prd, forces_prd, 1, dcoordsRotated: dcoord_prd); // dangles_prd = TNM.GetRotAngles(univ, coords_prd, hessian_prd, forces_prd, forceProjectedByTorsional: dcoord_prd); //Vectors coords_prd2 = coords_prd.Clone(); //TNM.RotateTorsionals(coords_prd2, dangles_prd, univ_rotinfos); double forces_prd_NormInf = NormInf(forces_prd, atomsMovable); // NormInf(forces_prd, atomsMovable); double forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); // Norm(1, forces_prd, atomsMovable); double forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); // Norm(2, forces_prd, atomsMovable); // 6. Check if the predicted forces or energy will exceed over the limit // , and goto 1 if no if ((energy_prd < energy + 0.1) && (forces_prd_NormInf < forces_NormInf + 0.0001)) { energy0 = energy; forces0 = forces; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; continue; } if (logger != null) { logger.log(iter, coords_prd, energy_prd, forces_prd, atomsMovable, "will do steepest"); } // 7. Back to saved configuration // 8. Move atoms with simple gradient { // same to the steepest descent h = forces; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } Vector dangles = Paper.TNM.GetRotAngles(univ, coords, kk * h, 1); //dangles *= -1; coords_prd = Paper.TNM.RotateTorsionals(coords, dangles, univ_rotinfos); } forces_prd = univ.GetVectorsZero(); //energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache); GetPotentialAndTorForce(frcflds, coords_prd , out energy_prd, out forces_prd._vecs , cache); forces_prd_NormInf = NormInf(forces_prd, atomsMovable); forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); energy0 = energy; forces0 = forces; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; // 9. goto 1 } }
public static Trans3 GetTrans(IList <Vector> C1, IList <Anisou> anisou1, IList <Vector> C2, IList <Anisou> anisou2, HPack <double> optEnergy = null) { int size = C1.Count; HDebug.Assert(size == C1.Count, size == C2.Count); Vector[] srcs = new Vector[size * 3 * 2]; // sources Vector[] tars = new Vector[size * 3 * 2]; // targets double[] weis = new double[size * 3 * 2]; // weights double[] engs = new double[size * 3 * 2]; // energies //for(int i=0; i<size; i++) //{ // Debug.Assert(anisou1[i].eigvals[0] >= 0); W1s[i*3+0] = (anisou1[i].eigvals[0] <= 0) ? 0 : 1 / anisou1[i].eigvals[0]; // Debug.Assert(anisou1[i].eigvals[1] >= 0); W1s[i*3+1] = (anisou1[i].eigvals[1] <= 0) ? 0 : 1 / anisou1[i].eigvals[1]; // Debug.Assert(anisou1[i].eigvals[2] >= 0); W1s[i*3+2] = (anisou1[i].eigvals[2] <= 0) ? 0 : 1 / anisou1[i].eigvals[2]; // enrgs[i*3+0] = enrgs[i*3+1] = enrgs[i*3+2] = double.NaN; //} //Trans3 trans = ICP3.OptimalTransform(C2, C1); Trans3 trans = new Trans3(new double[] { 0, 0, 0 }, 1, Quaternion.UnitRotation);// = transICP3.OptimalTransformWeighted(C2, C1, W1s); int iter = 0; int iter_max = 1000; //double enrg = double.NaN; while (iter < iter_max) { iter++; //for(int i=0; i<size; i++) System.Threading.Tasks.Parallel.For(0, size, delegate(int i) { for (int j = 0; j < 3; j++) { Vector p1 = C1[i]; Vector n1 = anisou1[i].axes[j]; double w1 = anisou1[i].eigvals[j]; w1 = (w1 <= 0) ? 0 : 1 / w1; Vector p2 = trans.DoTransform(C2[i]); Vector n2 = (trans.DoTransform(C2[i] + anisou2[i].axes[j]) - p2).UnitVector(); double w2 = anisou2[i].eigvals[j]; w2 = (w2 <= 0) ? 0 : 1 / w2; Vector clo12 = p2 - LinAlg.DotProd(n1, p2 - p1) * n1; // closest point from p1 to plane2 Vector clo21 = p1 - LinAlg.DotProd(n2, p1 - p2) * n2; // closest point from p1 to plane2 HDebug.AssertTolerance(0.00001, LinAlg.DotProd(clo12 - p1, n1)); HDebug.AssertTolerance(0.00001, LinAlg.DotProd(clo21 - p2, n2)); // p2 -> (pt closest to p2 on plane1 with w1) srcs[(i * 3 + j) * 2 + 0] = p2; tars[(i * 3 + j) * 2 + 0] = clo12; weis[(i * 3 + j) * 2 + 0] = w1; engs[(i * 3 + j) * 2 + 0] = w1 * (p2 - clo12).Dist2; // inverse of {p1 -> (pt closest to p1 on plane2 with w2)} // = (pt closest to p1 on plane2 with w2) -> p1 srcs[(i * 3 + j) * 2 + 1] = clo21; tars[(i * 3 + j) * 2 + 1] = p1; weis[(i * 3 + j) * 2 + 1] = w2; engs[(i * 3 + j) * 2 + 1] = w2 * (clo21 - p1).Dist2; } }); Trans3 dtrans = ICP3.OptimalTransformWeighted(srcs, tars, weis); trans = Trans3.AppendTrans(trans, dtrans); double max_dtrans_matrix = (dtrans.TransformMatrix - LinAlg.Eye(4)).ToArray().HAbs().HMax(); if (max_dtrans_matrix < 0.0000001) { break; } } if (optEnergy != null) { optEnergy.value = engs.Sum() / size; } return(trans); }
public static double[] GetRotAngles(Universe univ , Vector[] coords , MatrixByArr hessian , Vector[] forces , MatrixByArr J = null , Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = null , List <Universe.RotableInfo> univ_rotinfos = null , Vector[] forceProjectedByTorsional = null , HPack <Vector> optEigvalOfTorHessian = null ) { Vector mass = univ.GetMasses(); //Vector[] dcoords = new Vector[univ.size]; //double t2 = t*t; //for(int i=0; i<univ.size; i++) // dcoords[i] = forces[i] * (0.5*t2/mass[i]); if (J == null) { if (univ_rotinfos == null) { if (univ_flexgraph == null) { univ_flexgraph = univ.BuildFlexibilityGraph(); } univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); } J = TNM.GetJ(univ, coords, univ_rotinfos); } double[] dangles; using (new Matlab.NamedLock("TEST")) { Matlab.Clear("TEST"); Matlab.PutVector("TEST.F", Vector.FromBlockvector(forces)); Matlab.PutMatrix("TEST.J", J); Matlab.PutMatrix("TEST.H", hessian); Matlab.PutVector("TEST.M", univ.GetMasses(3)); Matlab.Execute("TEST.M = diag(TEST.M);"); Matlab.Execute("TEST.JHJ = TEST.J' * TEST.H * TEST.J;"); Matlab.Execute("TEST.JMJ = TEST.J' * TEST.M * TEST.J;"); // (J' H J) tor = J' F // (V' D V) tor = J' F <= (V,D) are (eigvec,eigval) of generalized eigenvalue problem with (A = JHJ, B = JMJ) // tor = inv(V' D V) J' F Matlab.Execute("[TEST.V, TEST.D] = eig(TEST.JHJ, TEST.JMJ);"); if (optEigvalOfTorHessian != null) { optEigvalOfTorHessian.value = Matlab.GetVector("diag(TEST.D)"); } { Matlab.Execute("TEST.D = diag(TEST.D);"); Matlab.Execute("TEST.D(abs(TEST.D)<1) = 0;"); // remove "eigenvalue < 1" because they will increase // the magnitude of force term too big !!! Matlab.Execute("TEST.D = diag(TEST.D);"); } Matlab.Execute("TEST.invJHJ = TEST.V * pinv(TEST.D) * TEST.V';"); Matlab.Execute("TEST.dtor = TEST.invJHJ * TEST.J' * TEST.F;"); /// f = m a /// d = 1/2 a t^2 /// = 0.5 a : assuming t=1 /// = 0.5 f/m /// f = m a /// = 2 m d t^-2 /// = 2 m d : assuming t=1 /// /// coord change /// dr = 0.5 a t^2 /// = 0.5 f/m : assuming t=1 /// = 0.5 M^-1 F : M is mass matrix, F is the net force of each atom /// /// torsional angle change /// dtor = (J' M J)^-1 J' M * dr : (6) of TNM paper /// = (J' M J)^-1 J' M * 0.5 M^-1 F /// = 0.5 (J' M J)^-1 J' F /// /// force filtered by torsional ... /// F_tor = ma /// = 2 M (J dtor) /// = 2 M J 0.5 (J' M J)^-1 J' F /// = M J (J' M J)^-1 J' F /// /// H J dtor = F /// = F_tor : update force as the torsional filtered force /// = M J (J' M J)^-1 J' F /// (J' H J) dtor = (J' M J) (J' M J)^-1 J' F /// (V D V') dtor = (J' M J) (J' M J)^-1 J' F : eigen decomposition of (J' H J) using /// generalized eigenvalue problem with (J' M J) /// dtor = (V D^-1 V') (J' M J) (J' M J)^-1 J' F : (J' M J) (J' M J)^-1 = I. However, it has /// the projection effect of J'F into (J' M J) /// vector space(?). The projection will be taken /// care by (V D^-1 V') /// = (V D^-1 V') J' F /// dangles = Matlab.GetVector("TEST.dtor"); if (forceProjectedByTorsional != null) { HDebug.Assert(forceProjectedByTorsional.Length == forces.Length); Matlab.Execute("TEST.F_tor = TEST.M * TEST.J * pinv(TEST.JMJ) * TEST.J' * TEST.F;"); Vector lforceProjectedByTorsional = Matlab.GetVector("TEST.F_tor"); HDebug.Assert(lforceProjectedByTorsional.Size == forceProjectedByTorsional.Length * 3); for (int i = 0; i < forceProjectedByTorsional.Length; i++) { int i3 = i * 3; forceProjectedByTorsional[i] = new double[] { lforceProjectedByTorsional[i3 + 0], lforceProjectedByTorsional[i3 + 1], lforceProjectedByTorsional[i3 + 2], }; } } Matlab.Clear("TEST"); } return(dangles); }
public static double[] GetRotAngles(Universe univ , Vector[] coords , Vector[] forces , double t // 0.1 , MatrixByArr J = null , Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = null , List <Universe.RotableInfo> univ_rotinfos = null , HPack <Vector[]> forcesProjectedByTorsional = null , HPack <Vector[]> dcoordsProjectedByTorsional = null ) { Vector mass = univ.GetMasses(); //Vector[] dcoords = new Vector[univ.size]; double t2 = t * t; //for(int i=0; i<univ.size; i++) // dcoords[i] = forces[i] * (0.5*t2/mass[i]); if (J == null) { if (univ_rotinfos == null) { if (univ_flexgraph == null) { univ_flexgraph = univ.BuildFlexibilityGraph(); } univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); } J = TNM.GetJ(univ, coords, univ_rotinfos); } double[] dangles; using (new Matlab.NamedLock("TEST")) { Matlab.Clear("TEST"); Matlab.PutVector("TEST.F", Vector.FromBlockvector(forces)); Matlab.PutValue("TEST.t2", t2); //Matlab.PutVector("TEST.R", Vector.FromBlockvector(dcoords)); Matlab.PutMatrix("TEST.J", J); Matlab.PutVector("TEST.M", univ.GetMasses(3)); Matlab.Execute("TEST.M = diag(TEST.M);"); /// f = m a /// d = 1/2 a t^2 /// = 0.5 f/m t^2 /// f = m a /// = 2 m d t^-2 /// /// coord change /// dcoord = 0.5 a t^2 /// = (0.5 t^2) f/m /// = (0.5 t^2) M^-1 F : M is mass matrix, F is the net force of each atom /// /// torsional angle change /// dtor = (J' M J)^-1 J' M * dcoord : (6) of TNM paper /// = (J' M J)^-1 J' M * (0.5 t^2) M^-1 F /// = (0.5 t^2) (J' M J)^-1 J' F /// = (0.5 t^2) (J' M J)^-1 J' F /// = (0.5 t2) invJMJ JF /// /// force filtered by torsional ... /// F_tor = m a /// = 2 m d t^-2 /// = 2 M (J * dtor) t^-2 /// = 2 M (J * (0.5 t^2) (J' M J)^-1 J' F) t^-2 /// = M J (J' M J)^-1 J' F /// = MJ invJMJ JF /// /// coord change filtered by torsional /// R_tor = (0.5 t^2) M^-1 * F_tor /// = (0.5 t^2) J (J' M J)^-1 J' F /// = (0.5 t2) J invJMJ JF Matlab.Execute("TEST.JMJ = TEST.J' * TEST.M * TEST.J;"); Matlab.Execute("TEST.invJMJ = inv(TEST.JMJ);"); Matlab.Execute("TEST.MJ = TEST.M * TEST.J;"); Matlab.Execute("TEST.JF = TEST.J' * TEST.F;"); Matlab.Execute("TEST.dtor = (0.5 * TEST.t2) * TEST.invJMJ * TEST.JF;"); // (6) of TNM paper Matlab.Execute("TEST.F_tor = TEST.MJ * TEST.invJMJ * TEST.JF;"); Matlab.Execute("TEST.R_tor = (0.5 * TEST.t2) * TEST.J * TEST.invJMJ * TEST.JF;"); dangles = Matlab.GetVector("TEST.dtor"); if (forcesProjectedByTorsional != null) { Vector F_tor = Matlab.GetVector("TEST.F_tor"); HDebug.Assert(F_tor.Size == forces.Length * 3); forcesProjectedByTorsional.value = new Vector[forces.Length]; for (int i = 0; i < forces.Length; i++) { int i3 = i * 3; forcesProjectedByTorsional.value[i] = new double[] { F_tor[i3 + 0], F_tor[i3 + 1], F_tor[i3 + 2] }; } } if (dcoordsProjectedByTorsional != null) { Vector R_tor = Matlab.GetVector("TEST.R_tor"); HDebug.Assert(R_tor.Size == coords.Length * 3); dcoordsProjectedByTorsional.value = new Vector[coords.Length]; for (int i = 0; i < coords.Length; i++) { int i3 = i * 3; dcoordsProjectedByTorsional.value[i] = new double[] { R_tor[i3 + 0], R_tor[i3 + 1], R_tor[i3 + 2] }; } } Matlab.Clear("TEST"); } return(dangles); }
public int QuasiNewton(List <ForceField.IForceField> frcflds , double threshold , double?k = null , double max_atom_movement = 0.01 , int?max_iteration = null , IMinimizeLogger logger = null // logger = new MinimizeLogger_PrintEnergyForceMag(logpath); , HPack <double> optOutEnergy = null // optional output for final energy , List <Vector> optOutForces = null // optional output for final force vectors , HPack <double> optOutForcesNorm1 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNorm2 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNormInf = null // optional output for norm of final force vectors ) { if (k == null) { k = double.MaxValue; foreach (ForceField.IForceField frcfld in frcflds) { double?kk = frcfld.GetDefaultMinimizeStep(); if (kk.HasValue) { k = Math.Min(k.Value, kk.Value); } } } Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = univ.BuildFlexibilityGraph(); List <Universe.RotableInfo> univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); // double k = 0.0001; int iter = 0; // 0. Initial configuration of atoms Vector[] coords = univ.GetCoords(); Vector[] coords0 = univ.GetCoords(); bool[] atomsMovable = null; { atomsMovable = new bool[size]; for (int i = 0; i < size; i++) { atomsMovable[i] = true; } } Dictionary <string, object> cache = new Dictionary <string, object>(); Vector[] forces = null; MatrixByArr hessian; double energy = 0; double[] dtor; double forces_NormInf; double forces_Norm1; double forces_Norm2; do { if (logger != null) { if (forces != null) { logger.log(iter, coords, energy, forces, atomsMovable); } { Vector[] coordsx = coords.HClone <Vector>(); Trans3 trans = ICP3.OptimalTransform(coordsx, coords0); trans.DoTransform(coordsx); logger.logTrajectory(univ, iter, coordsx); } } //GetPotentialAndTorForce(frcflds, coords // , out energy, out forces, out hessian, out dtor // , cache); { MatrixByArr J = Paper.TNM.GetJ(univ, coords, univ_rotinfos); Vector[] forces0 = univ.GetVectorsZero(); hessian = new double[size * 3, size *3]; energy = univ.GetPotential(frcflds, coords, ref forces0, ref hessian, cache); forces = univ.GetVectorsZero(); dtor = Paper.TNM.GetRotAngles(univ, coords, hessian, forces0, J: J, forceProjectedByTorsional: forces); for (int i = 0; i < forces0.Length; i++) { forces0[i] = forces0[i] * 0.001; } dtor = Paper.TNM.GetRotAngles(univ, coords, hessian, forces0, J: J); } forces_NormInf = NormInf(forces, atomsMovable); // NormInf(forces_prd, atomsMovable); forces_Norm1 = Norm(1, forces, atomsMovable); // Norm(1, forces_prd, atomsMovable); forces_Norm2 = Norm(2, forces, atomsMovable); // Norm(2, forces_prd, atomsMovable); if (forces_NormInf < 0.0001) { System.Environment.Exit(0); break; } coords = Paper.TNM.RotateTorsionals(coords, dtor, univ_rotinfos); iter++; }while(true); while (true) { // if(forces.IsComputable == false) // { // System.Console.Error.WriteLine("non-computable components while doing steepest-descent"); // Environment.Exit(0); // } if (logger != null) { logger.log(iter, coords, energy, forces, atomsMovable); logger.logTrajectory(univ, iter, coords); //if(iter %10 == 0) //{ // System.IO.Directory.CreateDirectory("output"); // string pdbname = string.Format("mini.conju.{0:D5}.pdb", iter); // pdb.ToFile("output\\"+pdbname, coords.ToArray()); // System.IO.File.AppendAllLines("output\\mini.conju.[animation].pml", new string[] { "load "+pdbname+", 1A6G" }); //} } // 1. Save the position of atoms // 2. Calculate the potential energy of system and the net forces on atoms // 3. Check if every force reaches to zero, // , and END if yes bool stopIteration = false; if (forces_NormInf < threshold) { stopIteration = true; } if ((max_iteration != null) && (iter >= max_iteration.Value)) { stopIteration = true; } if (stopIteration) { // double check cache = new Dictionary <string, object>(); // reset cache //energy = GetPotential(frcflds, coords, out forces, cache); // energy = univ.GetPotential(frcflds, coords, ref forces._vecs, ref hessian, cache); forces_NormInf = NormInf(forces, atomsMovable); forces_Norm1 = Norm(1, forces, atomsMovable); forces_Norm2 = Norm(2, forces, atomsMovable); if (forces_NormInf < threshold) { if (iter != 1) { univ.SetCoords(coords); } //{ // string pdbname = string.Format("mini.conju.{0:D5}.pdb", iter); // pdb.ToFile("output\\"+pdbname, coords.ToArray()); // System.IO.File.AppendAllLines("output\\mini.conju.[animation].pml", new string[] { "load "+pdbname+", 1A6G" }); //} { if (optOutEnergy != null) { optOutEnergy.value = energy; } if (optOutForces != null) { optOutForces.Clear(); optOutForces.AddRange(forces.ToArray()); } if (optOutForcesNorm1 != null) { optOutForcesNorm1.value = forces_Norm1; } if (optOutForcesNorm2 != null) { optOutForcesNorm2.value = forces_Norm2; } if (optOutForcesNormInf != null) { optOutForcesNormInf.value = forces_NormInf; } } return(iter); } } // 4. Move atoms with conjugated gradient //Vectors coords_prd; { if ((iter > 0) && (iter % 100 == 0)) { cache = new Dictionary <string, object>(); // reset cache } if (iter > 1) { // Debug.Assert(forces0 != null); // double r = Vectors.VtV(forces, forces).Sum() / Vectors.VtV(forces0, forces0).Sum(); // h = forces + r * h; // double kk = k.Value; // double hNormInf = NormInf(h, atomsMovable); // if(kk*hNormInf > max_atom_movement) // // make the maximum movement as atomsMovable // kk = max_atom_movement/(hNormInf); // //double kk = (k*h.NormsInf().NormInf() < max_atom_movement) ? k : (max_atom_movement/h.NormsInf().NormInf()); // //double kk = (k.Value*NormInf(h,atomsMovable) < max_atom_movement)? k.Value : (max_atom_movement/NormInf(h,atomsMovable)); // double[] dangles = TNM.GetRotAngles(univ, coords._vecs, hessian, (kk * h)._vecs); // coords_prd = TNM.RotateTorsionals(coords, dangles, univ_rotinfos); } else { // // same to the steepest descent for the first iteration // h = forces; // double kk = k.Value; // double hNormInf = NormInf(h, atomsMovable); // if(kk*hNormInf > max_atom_movement) // // make the maximum movement as atomsMovable // kk = max_atom_movement/(hNormInf); // //double kk = (k*h.NormsInf().NormInf() < max_atom_movement) ? k : (max_atom_movement/h.NormsInf().NormInf()); // //double kk = (k.Value*NormInf(h,atomsMovable) < max_atom_movement)? k.Value : (max_atom_movement/NormInf(h, atomsMovable)); // // //double[] dangles = TNM.GetRotAngles(this, coords, kk * h, 1); // double[] dangles = TNM.GetRotAngles(univ, coords._vecs, hessian, (kk * h)._vecs); // coords_prd = TNM.RotateTorsionals(coords, dangles, univ_rotinfos); // // // coords_prd = AddConditional(coords, kk * h, atomsMovable); } } // 5. Predict energy or forces on atoms iter++; //double energy_prd; Vectors forces_prd = univ.GetVectorsZero(); MatrixByArr hessian_prd = new double[size * 3, size *3]; //double energy_prd = GetPotential(frcflds, coords_prd, out forces_prd, cache); iter++; // GetPotentialAndTorForce(frcflds, coords_prd // , out energy_prd, out forces_prd._vecs, out hessian_prd // , cache); // // double energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache); // // Vector[] dcoord_prd = univ.GetVectorsZero(); // // double[] dangles_prd = TNM.GetRotAngles(univ, coords_prd, forces_prd, 1, dcoordsRotated: dcoord_prd); // // dangles_prd = TNM.GetRotAngles(univ, coords_prd, hessian_prd, forces_prd, forceProjectedByTorsional: dcoord_prd); // //Vectors coords_prd2 = coords_prd.Clone(); // //TNM.RotateTorsionals(coords_prd2, dangles_prd, univ_rotinfos); // // double forces_prd_NormInf = NormInf(forces_prd, atomsMovable); // NormInf(forces_prd, atomsMovable); // double forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); // Norm(1, forces_prd, atomsMovable); // double forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); // Norm(2, forces_prd, atomsMovable); // // 6. Check if the predicted forces or energy will exceed over the limit // // , and goto 1 if no // // doSteepDeescent = true; // //if((doSteepDeescent == false) || ((energy_prd <= energy) && (forces_prd_NormInf < forces_NormInf+1.0)) // if((energy_prd < energy+0.1) && (forces_prd_NormInf < forces_NormInf+0.0001)) // { // energy0 = energy; // forces0 = forces; // coords = coords_prd; // forces = forces_prd; // hessian = hessian_prd; // energy = energy_prd; // forces_NormInf = forces_prd_NormInf; // forces_Norm1 = forces_prd_Norm1; // forces_Norm2 = forces_prd_Norm2; // continue; // } // if(logger != null) // logger.log(iter, coords_prd, energy_prd, forces_prd, atomsMovable, "will do steepest"); // // 7. Back to saved configuration // // 8. Move atoms with simple gradient // { // // same to the steepest descent // h = forces; // double kk = k.Value; // double hNormInf = NormInf(h, atomsMovable); // if(kk*hNormInf > max_atom_movement) // // make the maximum movement as atomsMovable // kk = max_atom_movement/(hNormInf); // double[] dangles = TNM.GetRotAngles(univ, coords._vecs, hessian, (kk * h)._vecs); // coords_prd = TNM.RotateTorsionals(coords, dangles, univ_rotinfos); // } // forces_prd = univ.GetVectorsZero(); // hessian_prd = new double[size*3, size*3]; // //energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache); // GetPotentialAndTorForce(frcflds, coords_prd // , out energy_prd, out forces_prd._vecs, out hessian_prd // , cache); // forces_prd_NormInf = NormInf(forces_prd, atomsMovable); // forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); // forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); // // energy0 = energy; // forces0 = forces; // coords = coords_prd; // forces = forces_prd; // energy = energy_prd; // forces_NormInf = forces_prd_NormInf; // forces_Norm1 = forces_prd_Norm1; // forces_Norm2 = forces_prd_Norm2; // // 9. goto 1 } }
public static List <double> ScaleBFactorComp(List <double> bfactorExpr, List <double> bfactorComp, HPack <double> outScale4BfactorComp) { HDebug.Assert(bfactorExpr.Count == bfactorComp.Count); int size = bfactorComp.Count; Matrix A = new double[size, 1]; //Matrix A = new double[size, 2]; Vector b = new double[size]; for (int i = 0; i < size; i++) { A[i, 0] = bfactorComp[i]; //A[i, 1] = 1; b[i] = bfactorExpr[i]; } /// A x = b /// (A' A) x = (A' b) /// x = inv(A' A) * (A' b) Matrix At = A.Tr(); Matrix AtA = At * A; Vector Atb = LinAlg.MV(At, b); // = At * b; Matrix invAtA = NumericSolver.Inv(AtA); Vector x = LinAlg.MV(invAtA, Atb); // = invAtA * Atb; double scale = x[0]; double add = 0; //= x[1]; double[] bfactorCompScaled = new double[size]; for (int i = 0; i < size; i++) { bfactorCompScaled[i] = bfactorComp[i] * scale + add; } if (outScale4BfactorComp != null) { outScale4BfactorComp.value = scale; } return(new List <double>(bfactorCompScaled)); }
public static Tinker.Prm.Atom SelectByXyzAtom(this IList <Tinker.Prm.Atom> prmatoms, Tinker.Xyz.Atom xyzatom, HPack <Dictionary <int, Tinker.Prm.Atom> > cache = null) { foreach (var prmatom in prmatoms) { if (xyzatom.AtomId == prmatom.Id) { return(prmatom); } } return(null); }
public int Minimize_ConjugateGradient_AtomwiseUpdate( List <ForceField.IForceField> frcflds , double threshold = 0.001 // * threshold for forces.NormInf , double?k = null // * step step // 0.0001 , double max_atom_movement = 0.1 // * maximum atom movement , int?max_iteration = null // null for the infinite iteration until converged , bool[] atomsMovable = null // * selection of movable atoms // move all atoms if (atomsMovable == null) or (atomsMovable[all] == true) // move only atom whose (atomsMovable[id] == true) , IMinimizeLogger logger = null // * write log // = new MinimizeLogger_PrintEnergyForceMag() , InfoPack extra = null // get extra information , bool?doSteepDeescent = null // null or true for default , HPack <double> optOutEnergy = null // optional output for final energy , List <Vector> optOutForces = null // optional output for final force vectors , HPack <double> optOutForcesNorm1 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNorm2 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNormInf = null // optional output for norm of final force vectors ) { if (doSteepDeescent == null) { doSteepDeescent = true; } if (k == null) { k = double.MaxValue; foreach (ForceField.IForceField frcfld in frcflds) { double?kk = frcfld.GetDefaultMinimizeStep(); if (kk.HasValue) { k = Math.Min(k.Value, kk.Value); } } } int iter = 0; // 0. Initial configuration of atoms Vector[] coords = GetCoords(); if (atomsMovable == null) { atomsMovable = new bool[size]; for (int i = 0; i < size; i++) { atomsMovable[i] = true; } } Vectors h = GetVectorsZero(); Vectors forces = Vector.NewVectors(size, new double[3]); Vectors moves = Vector.NewVectors(size, new double[3]); Nonbondeds_v1 nonbondeds = null; // Dictionary<string,object> cache = new Dictionary<string, object>(); double energy = GetPotentialUpdated(frcflds, null, null, null, coords, forces, ref nonbondeds); double forces_NormInf = NormInf(forces, atomsMovable); double forces_Norm1 = Norm(1, forces, atomsMovable); double forces_Norm2 = Norm(2, forces, atomsMovable); Vector[] forces0 = forces; double energy0 = energy; Vectors moves0 = moves; double leastMove = 0.000001; while (true) { if (forces.IsComputable == false) { System.Console.Error.WriteLine("non-computable components while doing steepest-descent"); HEnvironment.Exit(0); } if (logger != null) { logger.log(iter, coords, energy, forces, atomsMovable); logger.logTrajectory(this, iter, coords); } // 1. Save the position of atoms // 2. Calculate the potential energy of system and the net forces on atoms // 3. Check if every force reaches to zero, // , and END if yes bool stopIteration = false; if (forces_NormInf < threshold) { stopIteration = true; } if ((max_iteration != null) && (iter >= max_iteration.Value)) { stopIteration = true; } if (stopIteration) { // double check //cache = new Dictionary<string, object>(); // reset cache //energy = GetPotential(frcflds, coords, out forces, cache); nonbondeds = null; energy = GetPotentialUpdated(frcflds, null, null, null, coords, forces, ref nonbondeds); forces_NormInf = NormInf(forces, atomsMovable); forces_Norm1 = Norm(1, forces, atomsMovable); forces_Norm2 = Norm(2, forces, atomsMovable); if (forces_NormInf < threshold) { if (iter != 1) { SetCoords(coords); } { if (optOutEnergy != null) { optOutEnergy.value = energy; } if (optOutForces != null) { optOutForces.Clear(); optOutForces.AddRange(forces.ToArray()); } if (optOutForcesNorm1 != null) { optOutForcesNorm1.value = forces_Norm1; } if (optOutForcesNorm2 != null) { optOutForcesNorm2.value = forces_Norm2; } if (optOutForcesNormInf != null) { optOutForcesNormInf.value = forces_NormInf; } } return(iter); } } // 4. Move atoms with conjugated gradient Vectors coords_prd; double kk; { if ((iter > 0) && (iter % 100 == 0)) { //cache = new Dictionary<string, object>(); // reset cache nonbondeds = null; } if (iter > 1) { HDebug.Assert(forces0 != null); double r = Vectors.VtV(forces, forces).Sum() / Vectors.VtV(forces0, forces0).Sum(); h = forces + r * h; kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } moves = moves0.Clone(); coords_prd = AddConditional(coords, atomsMovable, moves, kk * h, leastMove); } else { // same to the steepest descent for the first iteration h = forces; kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } //double kk = (k*h.NormsInf().NormInf() < max_atom_movement) ? k : (max_atom_movement/h.NormsInf().NormInf()); //double kk = (k.Value*NormInf(h,atomsMovable) < max_atom_movement)? k.Value : (max_atom_movement/NormInf(h, atomsMovable)); moves = moves0.Clone(); coords_prd = AddConditional(coords, atomsMovable, moves, kk * h, leastMove); } } // 5. Predict energy or forces on atoms Vectors forces_prd = forces.Clone(); double energy_prd = GetPotentialUpdated(frcflds, energy, coords, forces, coords_prd, forces_prd, ref nonbondeds); iter++; //double energy_prd = GetPotential(frcflds, coords_prd, out forces_prd, cache); iter++; double forces_prd_NormInf = NormInf(forces_prd, atomsMovable); double forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); double forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); // 6. Check if the predicted forces or energy will exceed over the limit // , and goto 1 if no doSteepDeescent = true; //if((doSteepDeescent == false) || ((energy_prd <= energy) && (forces_prd_NormInf < forces_NormInf+1.0)) if ((energy_prd < energy + 0.1) && (forces_prd_NormInf < forces_NormInf + 0.0001)) { energy0 = energy; forces0 = forces; moves0 = moves; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; continue; } if (logger != null) { logger.log(iter, coords_prd, energy_prd, forces_prd, atomsMovable, "will do steepest"); } // 7. Back to saved configuration // 8. Move atoms with simple gradient { // same to the steepest descent h = forces; kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } moves = moves0.Clone(); coords_prd = AddConditional(coords, atomsMovable, moves, kk * h, leastMove); } //energy_prd = GetPotential(frcflds, coords_prd, out forces_prd, cache); energy_prd = GetPotentialUpdated(frcflds, energy, coords, forces, coords_prd, forces_prd, ref nonbondeds); forces_prd_NormInf = NormInf(forces_prd, atomsMovable); forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); energy0 = energy; forces0 = forces; moves0 = moves; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; // 9. goto 1 } }
public static Mode[] GetModeByTorsional(HessMatrix hessian, Vector masses, Matrix J , HPack <Matrix> optoutJMJ = null // J' M J , HPack <Matrix> optoutJM = null // J' M , Func <Matrix, Tuple <Matrix, Vector> > fnEigSymm = null , Func <Matrix, Matrix, Matrix, Matrix> fnMul = null ) { string opt; opt = "eig(JMJ^-1/2 * JHJ * JMJ^-1/2)"; //opt = "mwhess->tor->eig(H)->cart->mrmode"; if ((fnEigSymm != null) && (fnMul != null)) { opt = "fn-" + opt; } switch (opt) { case "mwhess->tor->eig(H)->cart->mrmode": /// http://www.lct.jussieu.fr/manuels/Gaussian03/g_whitepap/vib.htm /// http://www.lct.jussieu.fr/manuels/Gaussian03/g_whitepap/vib/vib.pdf /// does not work properly. HDebug.Assert(false); using (new Matlab.NamedLock("GetModeByTor")) { int n = J.ColSize; int m = J.RowSize; //Matrix M = massmat; // univ.GetMassMatrix(3); Vector[] toreigvecs = new Vector[m]; Vector[] tormodes = new Vector[m]; double[] toreigvals = new double[m]; Mode[] modes = new Mode[m]; { Matlab.Clear("GetModeByTor"); Matlab.PutMatrix("GetModeByTor.H", hessian); Matlab.PutMatrix("GetModeByTor.J", J); //Matlab.PutMatrix("GetModeByTor.M", M); Matlab.PutVector("GetModeByTor.m", masses); // ex: m = [1,2,...,n] Matlab.Execute("GetModeByTor.m3 = kron(GetModeByTor.m,[1;1;1]);"); // ex: m3 = [1,1,1,2,2,2,...,n,n,n] Matlab.Execute("GetModeByTor.M = diag(GetModeByTor.m3);"); Matlab.Execute("GetModeByTor.m = diag(1 ./ sqrt(diag(GetModeByTor.M)));"); Matlab.Execute("GetModeByTor.mHm = GetModeByTor.m * GetModeByTor.H * GetModeByTor.m;"); Matlab.Execute("GetModeByTor.JmHmJ = GetModeByTor.J' * GetModeByTor.mHm * GetModeByTor.J;"); Matlab.Execute("[GetModeByTor.V, GetModeByTor.D] = eig(GetModeByTor.JmHmJ);"); Matlab.Execute("GetModeByTor.JV = GetModeByTor.m * GetModeByTor.J * GetModeByTor.V;"); Matrix V = Matlab.GetMatrix("GetModeByTor.V"); Vector D = Matlab.GetVector("diag(GetModeByTor.D)"); Matrix JV = Matlab.GetMatrix("GetModeByTor.JV"); Matlab.Clear("GetModeByTor"); for (int i = 0; i < m; i++) { toreigvecs[i] = V.GetColVector(i); toreigvals[i] = D[i]; tormodes[i] = JV.GetColVector(i); modes[i] = new Mode(); modes[i].eigval = toreigvals[i]; modes[i].eigvec = tormodes[i]; modes[i].th = i; } } return(modes); } case "eig(JMJ^-1/2 * JHJ * JMJ^-1/2)": /// Solve the problem of using eng(H,M). /// /// eig(H,M) => H.v = M.v.l /// H.(M^-1/2 . M^1/2).v = (M^1/2 . M^1/2).v.l /// M^-1/2 . H.(M^-1/2 . M^1/2).v = M^1/2 .v.l /// (M^-1/2 . H . M^-1/2) . (M^1/2.v) = (M^1/2.v).l /// (M^-1/2 . H . M^-1/2) . w = w.l /// where (M^1/2.v) = w /// v = M^-1/2 . w /// where M = V . D . V' /// M^-1/2 = V . (1/sqrt(D)) . V' /// M^-1/2 . M^-1/2 . M = (V . (1/sqrt(D)) . V') . (V . (1/sqrt(D)) . V') . (V . D . V') /// = V . (1/sqrt(D)) . (1/sqrt(D)) . D . V' /// = V . I . V' /// = I using (new Matlab.NamedLock("GetModeByTor")) { int n = J.ColSize; int m = J.RowSize; //Matrix M = massmat; // univ.GetMassMatrix(3); Vector[] toreigvecs = new Vector[m]; Vector[] tormodes = new Vector[m]; double[] toreigvals = new double[m]; Mode[] modes = new Mode[m]; { Matlab.Clear("GetModeByTor"); Matlab.PutMatrix("GetModeByTor.J", J.ToArray(), true); //Matlab.PutMatrix("GetModeByTor.M", M , true); //Matlab.PutMatrix("GetModeByTor.H", hessian, true); Matlab.PutSparseMatrix("GetModeByTor.H", hessian.GetMatrixSparse(), 3, 3); if (HDebug.IsDebuggerAttached && hessian.ColSize < 10000) { Matlab.PutMatrix("GetModeByTor.Htest", hessian.ToArray(), true); double dHessErr = Matlab.GetValue("max(max(abs(GetModeByTor.H - GetModeByTor.Htest)))"); Matlab.Execute("clear GetModeByTor.Htest"); HDebug.Assert(dHessErr == 0); } Matlab.PutVector("GetModeByTor.m", masses); // ex: m = [1,2,...,n] Matlab.Execute("GetModeByTor.m3 = kron(GetModeByTor.m,[1;1;1]);"); // ex: m3 = [1,1,1,2,2,2,...,n,n,n] Matlab.Execute("GetModeByTor.M = diag(GetModeByTor.m3);"); Matlab.Execute("GetModeByTor.JMJ = GetModeByTor.J' * GetModeByTor.M * GetModeByTor.J;"); Matlab.Execute("GetModeByTor.JHJ = GetModeByTor.J' * GetModeByTor.H * GetModeByTor.J;"); Matlab.Execute("[GetModeByTor.V, GetModeByTor.D] = eig(GetModeByTor.JMJ);"); Matlab.Execute("GetModeByTor.jmj = GetModeByTor.V * diag(1 ./ sqrt(diag(GetModeByTor.D))) * GetModeByTor.V';"); // jmj = sqrt(JMJ) //Matlab.Execute("max(max(abs(JMJ*jmj*jmj - eye(size(JMJ)))));"); // for checking //Matlab.Execute("max(max(abs(jmj*JMJ*jmj - eye(size(JMJ)))));"); // for checking //Matlab.Execute("max(max(abs(jmj*jmj*JMJ - eye(size(JMJ)))));"); // for checking Matlab.Execute("[GetModeByTor.V, GetModeByTor.D] = eig(GetModeByTor.jmj * GetModeByTor.JHJ * GetModeByTor.jmj);"); Matlab.Execute("GetModeByTor.D = diag(GetModeByTor.D);"); Matlab.Execute("GetModeByTor.V = GetModeByTor.jmj * GetModeByTor.V;"); Matlab.Execute("GetModeByTor.JV = GetModeByTor.J * GetModeByTor.V;"); Matrix V = Matlab.GetMatrix("GetModeByTor.V", true); Vector D = Matlab.GetVector("GetModeByTor.D"); Matrix JV = Matlab.GetMatrix("GetModeByTor.JV", true); if (optoutJMJ != null) { optoutJMJ.value = Matlab.GetMatrix("GetModeByTor.JMJ", true); } if (optoutJM != null) { optoutJM.value = Matlab.GetMatrix("GetModeByTor.J' * GetModeByTor.M", true); } Matlab.Clear("GetModeByTor"); for (int i = 0; i < m; i++) { toreigvecs[i] = V.GetColVector(i); toreigvals[i] = D[i]; tormodes[i] = JV.GetColVector(i); modes[i] = new Mode(); modes[i].eigval = toreigvals[i]; modes[i].eigvec = tormodes[i]; modes[i].th = i; } } return(modes); } case "fn-eig(JMJ^-1/2 * JHJ * JMJ^-1/2)": /// Solve the problem of using eng(H,M). /// /// eig(H,M) => H.v = M.v.l /// H.(M^-1/2 . M^1/2).v = (M^1/2 . M^1/2).v.l /// M^-1/2 . H.(M^-1/2 . M^1/2).v = M^1/2 .v.l /// (M^-1/2 . H . M^-1/2) . (M^1/2.v) = (M^1/2.v).l /// (M^-1/2 . H . M^-1/2) . w = w.l /// where (M^1/2.v) = w /// v = M^-1/2 . w /// where M = V . D . V' /// M^-1/2 = V . (1/sqrt(D)) . V' /// M^-1/2 . M^-1/2 . M = (V . (1/sqrt(D)) . V') . (V . (1/sqrt(D)) . V') . (V . D . V') /// = V . (1/sqrt(D)) . (1/sqrt(D)) . D . V' /// = V . I . V' /// = I { int n = J.ColSize; int m = J.RowSize; //Matrix M = massmat; // univ.GetMassMatrix(3); Vector[] toreigvecs = new Vector[m]; Vector[] tormodes = new Vector[m]; double[] toreigvals = new double[m]; Mode[] modes = new Mode[m]; { Matrix H = hessian; HDebug.Assert(hessian.ColSize == hessian.RowSize); Matrix M = Matrix.Zeros(hessian.ColSize, hessian.RowSize); HDebug.Assert(3 * masses.Size == M.ColSize, M.ColSize == M.RowSize); for (int i = 0; i < M.ColSize; i++) { M[i, i] = masses[i / 3]; } Matrix Jt = J.Tr(); Matrix JMJ = fnMul(Jt, M, J); // JMJ = J' * M * J Matrix JHJ = fnMul(Jt, H, J); // JHJ = J' * H * J Matrix V; Vector D; { // [V, D] = eig(JMJ) var VD = fnEigSymm(JMJ); V = VD.Item1; D = VD.Item2; } Matrix jmj; { // jmj = sqrt(JMJ) Vector isD = new double[D.Size]; for (int i = 0; i < isD.Size; i++) { isD[i] = 1 / Math.Sqrt(D[i]); } jmj = fnMul(V, LinAlg.Diag(isD), V.Tr()); } { // [V, D] = eig(jmj * JHJ * jmj) Matrix jmj_JHJ_jmj = fnMul(jmj, JHJ, jmj); var VD = fnEigSymm(jmj_JHJ_jmj); V = VD.Item1; D = VD.Item2; } V = fnMul(jmj, V, null); // V = jmj * V Matrix JV = fnMul(J, V, null); // JV = J * V if (optoutJMJ != null) { optoutJMJ.value = JMJ; } if (optoutJM != null) { optoutJM.value = fnMul(Jt, M, null); // J' * M } for (int i = 0; i < m; i++) { toreigvecs[i] = V.GetColVector(i); toreigvals[i] = D[i]; tormodes[i] = JV.GetColVector(i); modes[i] = new Mode(); modes[i].eigval = toreigvals[i]; modes[i].eigvec = tormodes[i]; modes[i].th = i; } } //if(Debug.IsDebuggerAttached) //{ // Mode[] tmodes = GetModeByTorsional(hessian, masses, J); // Debug.Assert(modes.Length == tmodes.Length); // for(int i=0; i<modes.Length; i++) // { // Debug.AssertTolerance(0.00001, modes[i].eigval - tmodes[i].eigval); // Debug.AssertTolerance(0.00001, modes[i].eigvec - tmodes[i].eigvec); // } //} return(modes); } case "eig(JHJ,JMJ)": /// Generalized eigendecomposition does not guarantee that the eigenvalue be normalized. /// This becomes a problem when a B-factor (determined using eig(H,M)) is compared with another B-factor (determined using eig(M^-1/2 H M^-1/2)). /// This problem is being solved using case "eig(JMJ^-1/2 * JHJ * JMJ^-1/2)" using (new Matlab.NamedLock("GetModeByTor")) { int n = J.ColSize; int m = J.RowSize; //Matrix M = massmat; // univ.GetMassMatrix(3); Matrix JMJ; { Matlab.PutMatrix("GetModeByTor.J", J); //Matlab.PutMatrix("GetModeByTor.M", M); Matlab.PutVector("GetModeByTor.m", masses); // ex: m = [1,2,...,n] Matlab.Execute("GetModeByTor.m3 = kron(GetModeByTor.m,[1;1;1]);"); // ex: m3 = [1,1,1,2,2,2,...,n,n,n] Matlab.Execute("GetModeByTor.M = diag(GetModeByTor.m3);"); Matlab.Execute("GetModeByTor.JMJ = GetModeByTor.J' * GetModeByTor.M * GetModeByTor.J;"); JMJ = Matlab.GetMatrix("GetModeByTor.JMJ"); Matlab.Clear("GetModeByTor"); } Matrix JHJ; { Matlab.PutMatrix("GetModeByTor.J", J); Matlab.PutMatrix("GetModeByTor.H", hessian); Matlab.Execute("GetModeByTor.JHJ = GetModeByTor.J' * GetModeByTor.H * GetModeByTor.J;"); JHJ = Matlab.GetMatrix("GetModeByTor.JHJ"); Matlab.Clear("GetModeByTor"); } Vector[] toreigvecs = new Vector[m]; Vector[] tormodes = new Vector[m]; double[] toreigvals = new double[m]; Mode[] modes = new Mode[m]; { Matlab.PutMatrix("GetModeByTor.JHJ", JHJ); Matlab.PutMatrix("GetModeByTor.JMJ", JMJ); Matlab.PutMatrix("GetModeByTor.J", J); Matlab.Execute("[GetModeByTor.V, GetModeByTor.D] = eig(GetModeByTor.JHJ, GetModeByTor.JMJ);"); Matlab.Execute("GetModeByTor.D = diag(GetModeByTor.D);"); Matlab.Execute("GetModeByTor.JV = GetModeByTor.J * GetModeByTor.V;"); Matrix V = Matlab.GetMatrix("GetModeByTor.V"); Vector D = Matlab.GetVector("GetModeByTor.D"); Matrix JV = Matlab.GetMatrix("GetModeByTor.JV"); Matlab.Clear("GetModeByTor"); for (int i = 0; i < m; i++) { toreigvecs[i] = V.GetColVector(i); toreigvals[i] = D[i]; tormodes[i] = JV.GetColVector(i); modes[i] = new Mode(); modes[i].eigval = toreigvals[i]; modes[i].eigvec = tormodes[i]; modes[i].th = i; } } return(modes); } } return(null); }
public static Trans3 GetTrans(IList <Vector> C1, IList <Anisou> anisou1, IList <Vector> C2, HPack <double> optEnergy = null) { int size = C1.Count; HDebug.Assert(size == C1.Count, size == C2.Count); Vector[] C1s = C1.ToArray().Clone(3); Vector[] C2s = C2.ToArray().Clone(3); double[] W1s = new double[size * 3]; double[] enrgs = new double[size * 3]; for (int i = 0; i < size; i++) { HDebug.Assert(anisou1[i].eigvals[0] >= 0); W1s[i * 3 + 0] = (anisou1[i].eigvals[0] <= 0) ? 0 : 1 / anisou1[i].eigvals[0]; HDebug.Assert(anisou1[i].eigvals[1] >= 0); W1s[i * 3 + 1] = (anisou1[i].eigvals[1] <= 0) ? 0 : 1 / anisou1[i].eigvals[1]; HDebug.Assert(anisou1[i].eigvals[2] >= 0); W1s[i * 3 + 2] = (anisou1[i].eigvals[2] <= 0) ? 0 : 1 / anisou1[i].eigvals[2]; enrgs[i * 3 + 0] = enrgs[i * 3 + 1] = enrgs[i * 3 + 2] = double.NaN; } //Trans3 trans = ICP3.OptimalTransform(C2, C1); Trans3 trans = new Trans3(new double[] { 0, 0, 0 }, 1, Quaternion.UnitRotation);// = transICP3.OptimalTransformWeighted(C2, C1, W1s); int iter = 0; int iter_max = 1000; //double enrg = double.NaN; while (iter < iter_max) { iter++; Vector[] C2sUpdated = trans.GetTransformed(C2s); //for(int i=0; i<size; i++) System.Threading.Tasks.Parallel.For(0, size, delegate(int i) { for (int j = 0; j < 3; j++) { Vector planeNormal = anisou1[i].axes[j]; Vector planeBase = C1[i]; Vector query = C2sUpdated[i * 3 + j]; Vector closest = query - LinAlg.DotProd(planeNormal, query - planeBase) * planeNormal; HDebug.AssertTolerance(0.00001, LinAlg.DotProd(closest - planeBase, planeNormal)); C1s[i * 3 + j] = closest; enrgs[i * 3 + j] = W1s[i * 3 + j] * (query - closest).Dist2; } }); Trans3 dtrans = ICP3.OptimalTransformWeighted(C2sUpdated, C1s, W1s); trans = Trans3.AppendTrans(trans, dtrans); double max_dtrans_matrix = (dtrans.TransformMatrix - LinAlg.Eye(4)).ToArray().HAbs().HMax(); if (max_dtrans_matrix < 0.0000001) { break; } } if (optEnergy != null) { optEnergy.value = enrgs.Sum() / size; } return(trans); }
public static void Align(ref List <Vector>[] ensemble , int maxiteration = int.MaxValue , HPack <List <Trans3[]> > outTrajTrans = null ) { List <Vector>[] lensemble = ensemble.HClone <List <Vector> >(); int size = lensemble[0].Count; for (int i = 1; i < lensemble.Length; i++) { HDebug.Assert(size == lensemble[i].Count); } // initial alignment using RMSD Trans3[] transs = new Trans3[lensemble.Length]; transs[0] = Trans3.UnitTrans; Vector[] coords = new Vector[size]; Anisou[] anisous = new Anisou[size]; double anisou_eigvalthres = 0.00001 * 0.00001; double[] bfactors = new double[size]; { // set ensemble[0] as the initial mean structure for (int i = 0; i < size; i++) { coords[i] = lensemble[0][0].Clone(); } // set anisou as sphere (with radii as one) Anisou U0 = Anisou.FromMatrix(new double[3, 3] { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }); for (int i = 0; i < anisous.Length; i++) { anisous[i] = U0; } // set bfactor as one for (int i = 0; i < bfactors.Length; i++) { bfactors[i] = 1; } } //List<double>[] bfactorss = new List<double>[ensemble.Length]; //for(int i=0; i<bfactorss.Length; i++) // bfactorss[i] = new List<double>(bfactors); //Pdb.ToFile("ensemble.000.pdb", null, lensemble, bfactorss); System.Console.WriteLine("begin iterative alignment"); double move2 = double.PositiveInfinity; //double thres = 0.00001;// *size * lensemble.Length; double thres = 0.00001;// *size * lensemble.Length; //List<Pdb.Atom> atoms = null; //while(thres < move2) for (int iter = 0; iter < maxiteration; iter++) { transs = new Trans3[ensemble.Length]; move2 = Align(lensemble, coords, anisous, transs); if (outTrajTrans != null) { outTrajTrans.value.Add(transs); } System.Console.WriteLine(iter + "th alignment done: (move " + move2 + " Å)"); if (move2 < thres) { break; } DetermineMeanConf(lensemble, coords); DetermineThrmlFluc(lensemble, coords, anisous, null, anisou_eigvalthres); } ensemble = lensemble; }
public static Vector[] GenerateEnsemble(IList <Vector> coords, Mode[] modes, IList <double> mass, double temperature = 300, bool normalize = true, HPack <Vector> optOutRandNorms = null) { double[] invsqrtm = new double[mass.Count]; { for (int i = 0; i < mass.Count; i++) { invsqrtm[i] = 1.0 / Math.Sqrt(mass[i]); } } modes = modes.HRemoveAllNull().ToArray(); Vector randnorms; { Random rand = new Random(); randnorms = rand.NextNormalVector(modes.Length, 1); if (normalize) { randnorms = randnorms.UnitVector(); } } if (optOutRandNorms != null) { optOutRandNorms.value = randnorms; } int size = mass.Count; Vector[] ensemble = new Vector[size]; for (int i = 0; i < size; i++) { ensemble[i] = coords[i].Clone(); } for (int m = 0; m < modes.Length; m++) { double eigval = modes[m].eigval; Vector[] eigvec = modes[m].GetEigvecsOfAtoms(); HDebug.Assert(eigvec.Length == size); double rfac = Math.Sqrt(3.0 * BOLTZ * temperature / eigval); double disp = rfac * randnorms[m]; //for(int i=0; i<size; i++) System.Threading.Tasks.Parallel.For(0, size, delegate(int i) { ensemble[i] += disp * eigvec[i] * invsqrtm[i]; }); } return(ensemble); }
public static Trans3 GetTrans(IList <Vector> C1, IList <Vector> C2, HPack <int> optIter = null, HPack <List <double> > optListWeightSum = null) { HDebug.Assert(false); HDebug.Assert(C1.Count == C2.Count); int size = C1.Count; if (optIter != null) { optIter.value = 0; } int iter = 0; Trans3 trans0 = new Trans3(new double[3], 1, Quaternion.UnitRotation); Trans3 trans1 = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1); if (optListWeightSum != null) { optListWeightSum.value = new List <double>(); } double maxdist = 0; for (int i = 0; i < size; i++) { Vector diff = C1[i] - trans1.DoTransform(C2[i]); maxdist = Math.Max(maxdist, diff.Dist); } while ((trans0.TransformMatrix - trans1.TransformMatrix).ToArray().HAbs().HMax() > 0.00000001) { iter++; if (optIter != null) { optIter.value++; } Vector[] C2trans = trans1.GetTransformed(C2).ToArray(); Vector dist2s = new double[size]; Vector dists = new double[size]; for (int i = 0; i < size; i++) { double dist2 = (C1[i] - C2trans[i]).Dist2; dist2 = HMath.Between(0.00001, dist2, double.PositiveInfinity); dist2s[i] = dist2; dists[i] = Math.Sqrt(dist2); } //int[] idxsort = dist2s.ToArray().IdxSorted().Reverse(); Vector weight = dists.Clone() / dists.ToArray().Max(); for (int i = 0; i < size; i++) { double w = weight[i]; //w = (w*2-1)*4; w = (w - 1) * 4; w = 1 / (1 + Math.Exp(-1 * w)); weight[i] = w; } //weight[idxsort[i]] = (i <= 6) ? 1 : 0; if (optListWeightSum != null) { optListWeightSum.value.Add(weight.Sum()); } trans0 = trans1; trans1 = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1, weight.ToArray()); maxdist = 0; for (int i = 0; i < size; i++) { Vector diff = C1[i] - trans1.DoTransform(C2[i]); maxdist = Math.Max(maxdist, diff.Dist); } } return(trans1); }