static HessMatrix GetMulImpl(HessMatrix left, HessMatrix right, ILinAlg ila, bool warning) { if (HDebug.Selftest()) { Matrix h1 = new double[, ] { { 0, 1, 2, 3, 4, 5 } , { 1, 2, 3, 4, 5, 6 } , { 2, 3, 4, 5, 6, 7 } , { 3, 4, 5, 6, 7, 8 } , { 4, 5, 6, 7, 8, 9 } , { 5, 6, 7, 8, 9, 0 } }; HessMatrix h2 = HessMatrixSparse.FromMatrix(h1); Matrix h11 = Matrix.GetMul(h1, h1); HessMatrix h22 = HessMatrix.GetMulImpl(h2, h2, null, false); Matrix hdiff = h11 - h22; HDebug.AssertToleranceMatrix(0, hdiff); } if ((left is HessMatrixDense) && (right is HessMatrixDense)) { if (ila != null) { return(new HessMatrixDense { hess = ila.Mul(left, right) }); } if (warning) { HDebug.ToDo("Check (HessMatrixDense * HessMatrixDense) !!!"); } } Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > > left_ic_rows = new Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > >(); foreach (var ic_row in left.EnumRowBlocksAll()) { left_ic_rows.Add(ic_row.Item1, ic_row.Item2.HToDictionaryWithKeyItem2()); } Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > > right_ir_cols = new Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > >(); foreach (var ir_col in right.EnumColBlocksAll()) { right_ir_cols.Add(ir_col.Item1, ir_col.Item2.HToDictionaryWithKeyItem1()); } HessMatrix mul = null; if ((left is HessMatrixDense) && (right is HessMatrixDense)) { mul = HessMatrixDense.ZerosDense(left.ColSize, right.RowSize); } else { mul = HessMatrixSparse.ZerosSparse(left.ColSize, right.RowSize); } for (int ic = 0; ic < left.ColBlockSize; ic++) { var left_row = left_ic_rows[ic]; if (left_row.Count == 0) { continue; } for (int ir = 0; ir < right.RowBlockSize; ir++) { var right_col = right_ir_cols[ir]; if (right_col.Count == 0) { continue; } foreach (var left_ck in left_row) { int ik = left_ck.Key; HDebug.Assert(ic == left_ck.Value.Item1); HDebug.Assert(ik == left_ck.Value.Item2); if (right_col.ContainsKey(ik)) { var right_kr = right_col[ik]; HDebug.Assert(ik == right_kr.Item1); HDebug.Assert(ir == right_kr.Item2); MatrixByArr mul_ckr = mul.GetBlock(ic, ir) + left_ck.Value.Item3 * right_kr.Item3; mul.SetBlock(ic, ir, mul_ckr); } } } } return(mul); }
public int UpdateAdd(HessMatrix other, double mul_other, IList <int> idxOther, double thres_NearZeroBlock, bool parallel = false) { Matrix debug_updateadd = null; if (UpdateAdd_SelfTest && idxOther == null && thres_NearZeroBlock == 0) { if ((100 < ColBlockSize) && (ColBlockSize < 1000) && (100 < RowBlockSize) && (RowBlockSize < 1000) && (other.NumUsedBlocks > 20)) { UpdateAdd_SelfTest = false; debug_updateadd = this.ToArray(); debug_updateadd.UpdateAdd(other, mul_other); } } int[] idx_other; if (idxOther == null) { //HDebug.Exception(ColSize == other.ColSize); //HDebug.Exception(RowSize == other.RowSize); idx_other = HEnum.HEnumCount(other.ColSize).ToArray(); } else { idx_other = idxOther.ToArray(); } int count = 0; int count_ignored = 0; object _lock = new object(); object _lock_ignored = new object(); Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval) { count++; int other_bc = bc_br_bval.Item1; int other_br = bc_br_bval.Item2; MatrixByArr other_bmat = bc_br_bval.Item3; if (other_bmat.HAbsMax() <= thres_NearZeroBlock) { lock (_lock_ignored) count_ignored++; //continue; return; } int bc = idx_other[other_bc]; int br = idx_other[other_br]; lock (_lock) { MatrixByArr this_bmat = GetBlock(bc, br); MatrixByArr new_bmat; if (this_bmat == null) { if (other_bmat == null) { new_bmat = null; } else { new_bmat = mul_other * other_bmat; } } else { if (other_bmat == null) { new_bmat = this_bmat.CloneT(); } else { new_bmat = this_bmat + mul_other * other_bmat; } } SetBlock(bc, br, new_bmat); } }; if (parallel) { Parallel.ForEach(other.EnumBlocks(), func); } else { foreach (var bc_br_bval in other.EnumBlocks()) { func(bc_br_bval); } } if (debug_updateadd != null) { Matrix debug_diff = debug_updateadd - this; double debug_absmax = debug_diff.HAbsMax(); HDebug.AssertToleranceMatrix(0, debug_diff); } return(count_ignored); }
public int SteepestDescent(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); MatrixByArr hessian = null; energy = univ.GetPotential(frcflds, coords, ref forces._vecs, ref hessian, 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 } { // 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 { 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; } } }
private void GetPotentialAndTorForce(List <ForceField.IForceField> frcflds, Vector[] coords , out double energy, out Vector[] forces, out MatrixByArr hessian , Dictionary <string, object> cache) { double[] dtor; GetPotentialAndTorForce(frcflds, coords, out energy, out forces, out hessian, out dtor, cache); }
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 void __MinimizeTNM(List <ForceField.IForceField> frcflds) { HDebug.Assert(false); // do not use this, because not finished yet Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = this.BuildFlexibilityGraph(); List <Universe.RotableInfo> univ_rotinfos = this.GetRotableInfo(univ_flexgraph); Vector[] coords = this.GetCoords(); double tor_normInf = double.PositiveInfinity; //double maxRotAngle = 0.1; Vector[] forces = null; MatrixByArr hessian = null; double forces_normsInf = 1; int iter = 0; double scale = 1; this._SaveCoordsToPdb(iter.ToString("0000") + ".pdb", coords); while (true) { iter++; forces = this.GetVectorsZero(); hessian = new double[size * 3, size *3]; Dictionary <string, object> cache = new Dictionary <string, object>(); double energy = this.GetPotential(frcflds, coords, ref forces, ref hessian, cache); forces_normsInf = (new Vectors(forces)).NormsInf().ToArray().Max(); //System.Console.WriteLine("iter {0:###}: frcnrminf {1}, energy {2}, scale {3}", iter, forces_normsInf, energy, scale); //if(forces_normsInf < 0.001) //{ // break; //} Vector torz = null; double maxcarz = 1; Vector car = null; //double using (new Matlab.NamedLock("TEST")) { MatrixByArr H = hessian; MatrixByArr J = Paper.TNM.GetJ(this, this.GetCoords(), univ_rotinfos); Vector m = this.GetMasses(3); Matlab.PutVector("TEST.F", Vector.FromBlockvector(forces)); Matlab.PutMatrix("TEST.J", J); Matlab.PutMatrix("TEST.H", H); Matlab.PutVector("TEST.M", m); Matlab.Execute("TEST.M = diag(TEST.M);"); Matlab.Execute("TEST.JMJ = TEST.J' * TEST.M * TEST.J;"); Matlab.Execute("TEST.JHJ = TEST.J' * TEST.H * 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);"); //Matlab.Execute("TEST.zidx = 3:end;"); Matlab.Execute("TEST.invJHJ = TEST.V * pinv(TEST.D ) * TEST.V';"); Matlab.Execute("TEST.tor = TEST.invJHJ * TEST.J' * TEST.F;"); Matlab.Execute("TEST.car = TEST.J * TEST.tor;"); car = Matlab.GetVector("TEST.car"); Matlab.Execute("[TEST.DS, TEST.DSI] = sort(abs(diag(TEST.D)));"); Matlab.Execute("TEST.zidx = TEST.DSI(6:end);"); Matlab.Execute("TEST.Dz = TEST.D;"); //Matlab.Execute("TEST.Dz(TEST.zidx,TEST.zidx) = 0;"); Matlab.Execute("TEST.invJHJz = TEST.V * pinv(TEST.Dz) * TEST.V';"); Matlab.Execute("TEST.torz = TEST.invJHJz * TEST.J' * TEST.F;"); Matlab.Execute("TEST.carz = TEST.J * TEST.torz;"); torz = Matlab.GetVector("TEST.torz"); maxcarz = Matlab.GetValue("max(max(abs(TEST.carz)))"); scale = 1; if (maxcarz > 0.01) { scale = scale * 0.01 / maxcarz; } Matlab.Clear("TEST"); }; tor_normInf = torz.NormInf(); double frcnrinf = car.ToArray().HAbs().Max(); if (maxcarz < 0.001) { break; } System.Console.WriteLine("iter {0:###}: frcnrminf {1}, tor(frcnrinf) {2}, energy {3}, scale {4}", iter, forces_normsInf, frcnrinf, energy, scale); HDebug.Assert(univ_rotinfos.Count == torz.Size); for (int i = 0; i < univ_rotinfos.Count; i++) { Universe.RotableInfo rotinfo = univ_rotinfos[i]; Vector rotOrigin = coords[rotinfo.bondedAtom.ID]; double rotAngle = torz[i] * scale; // (maxRotAngle / tor_normInf); if (rotAngle == 0) { continue; } Vector rotAxis = coords[rotinfo.bond.atoms[1].ID] - coords[rotinfo.bond.atoms[0].ID]; Quaternion rot = new Quaternion(rotAxis, rotAngle); MatrixByArr rotMat = rot.RotationMatrix; foreach (Atom atom in rotinfo.rotAtoms) { int id = atom.ID; Vector coord = rotMat * (coords[id] - rotOrigin) + rotOrigin; coords[id] = coord; } } this._SaveCoordsToPdb(iter.ToString("0000") + ".pdb", coords); } }
public static Vector GetAa(Vector ea, Vector R, Vector Ra, Vector sa, double Ma, MatrixByArr invI, MatrixByArr Ia) { Vector ea_Rasa = LinAlg.CrossProd3(ea, Ra - sa); Vector IAa = -LinAlg.MV(Ia, ea) + Ma * LinAlg.CrossProd3(R - Ra, ea_Rasa); Vector Aa = LinAlg.MV(invI, IAa); return(Aa); }
public static void ToFile(string filepath , IList <Atom> atoms , IList <Vector> coords = null , IList <MatrixByArr> anisous = null , double?anisouScale = null , IList <double> bfactors = null , bool append = false , IList <string> headers = null , int?modelidx = null ) { List <string> lines = new List <string>(); int size = atoms.Count; if (coords != null) { HDebug.Assert(size == coords.Count); } if (anisous != null) { HDebug.Assert(size == anisous.Count); } //if(anisouScale != null) Debug.Assert(size == anisouScale.Count); if (headers != null) { lines.AddRange(headers); } { // 1 2 3 4 5 6 7 8 // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 // "MODEL 1 " string line = "MODEL 1 "; if (modelidx != null) { line.Replace("1", modelidx.Value.ToString()); } line = line.Substring(0, 80); lines.Add(line); } for (int i = 0; i < size; i++) { Atom atom = atoms[i]; if (atom == null) { continue; } { if (coords != null) { double x = coords[i][0]; double y = coords[i][1]; double z = coords[i][2]; atom = Atom.FromString(atom.GetUpdatedLine(x, y, z)); } if (bfactors != null) { atom = Atom.FromString(atom.GetUpdatedLineTempFactor(bfactors[i])); } lines.Add(atom.line); } { if (anisous != null) { MatrixByArr U = anisous[i]; if (anisouScale != null) { U = U * anisouScale.Value; } Anisou anisou = Anisou.FromAtom(atom, U.ToArray().HToInt()); string line = anisou.line; //anisou.GetUpdatedU(anisous[i]) lines.Add(line); } } } lines.Add("ENDMDL "); //int idx = 0; //foreach(Element element in elements) //{ // string line = element.line; // if(typeof(Atom).IsInstanceOfType(element)) // { // double x = coords[idx][0]; // double y = coords[idx][1]; // double z = coords[idx][2]; // Atom atom = (Atom)element; // line = atom.GetUpdatedLine(x, y, z); // idx++; // } // lines.Add(line); //} if (append == false) { HFile.WriteAllLines(filepath, lines); } else { StringBuilder text = new StringBuilder(); foreach (string line in lines) { text.AppendLine(line); } HFile.AppendAllText(filepath, text.ToString()); } }
public static void GetMaRaMaraITa(IList <Atom> atoms, Vector[] coords, ref double Ma, ref Vector Ra, ref Vector MaRa, ref MatrixByArr ITa) { //////////////////////////////////////////////////////////////////////// // http://en.wikipedia.org/wiki/Moment_of_inertia_tensor#Definition // // // // I = [Ixx Ixy Ixz] // // [Iyx Iyy Iyz] // // [Izx Izy Izz] // // Ixx = sum(i=1..n}{ mi (yi^2 + zi^2) } // // Iyy = sum{i=1..n}{ mi (xi^2 + zi^2) } // // Izz = sum{i=1..n}{ mi (xi^2 + yi^2) } // // Ixy = Iyx = sum{i=1..n}{ - mi xi yi } // // Ixz = Izx = sum{i=1..n}{ - mi xi zi } // // Iyz = Izy = sum{i=1..n}{ - mi yi zi } // //////////////////////////////////////////////////////////////////////// Ma = 0; HDebug.Assert(ITa.ColSize == 3, ITa.RowSize == 3); ITa[0, 0] = ITa[0, 1] = ITa[0, 2] = ITa[1, 0] = ITa[1, 1] = ITa[1, 2] = ITa[2, 0] = ITa[2, 1] = ITa[2, 2] = 0; HDebug.Assert(Ra.Size == 3); Ra[0] = Ra[1] = Ra[2] = 0; HDebug.Assert(MaRa.Size == 3); MaRa[0] = MaRa[1] = MaRa[2] = 0; foreach (Atom atom in atoms) { double m = atom.Mass; double x = coords[atom.ID][0]; double y = coords[atom.ID][1]; double z = coords[atom.ID][2]; double xx = m * (y * y + z * z); double yy = m * (x * x + z * z); double zz = m * (x * x + y * y); double xy = -m * x * y; double xz = -m * x * z; double yz = -m * y * z; Ma += m; Ra[0] += x; Ra[1] += y; Ra[2] += z; MaRa[0] += m * x; MaRa[1] += m * y; MaRa[2] += m * z; ITa[0, 0] += xx; ITa[0, 1] += xy; ITa[0, 2] += xz; ITa[1, 0] += xy; ITa[1, 1] += yy; ITa[1, 2] += yz; ITa[2, 0] += xz; ITa[2, 1] += yz; ITa[2, 2] += zz; } }
public unsafe static MatrixByArr GetJ(Universe univ, Vector[] coords, List <RotableInfo> rotInfos) { HDebug.Assert(rotInfos.ListMolecule().HUnion().Length == 1); Dictionary <Universe.Molecule, Dictionary <string, object> > moleMRI = new Dictionary <Universe.Molecule, Dictionary <string, object> >(); int n = univ.atoms.Count; int m = rotInfos.Count; MatrixByArr J = new double[3 * n, m]; double[] _Ja = new double[3 * n]; for (int a = 0; a < m; a++) { var mole = rotInfos[a].mole; if (moleMRI.ContainsKey(rotInfos[a].mole) == false) { double _M = 0; Vector _R = new double[3]; Vector _MR = new double[3]; MatrixByArr _I = new double[3, 3]; GetMaRaMaraITa(mole.atoms.ToArray(), coords, ref _M, ref _R, ref _MR, ref _I); MatrixByArr _invI = LinAlg.Inv3x3(_I); MatrixByArr _MRx = GetSSMatrix(_MR); MatrixByArr _MRxt = _MRx.Tr(); MatrixByArr _III = _I - (1.0 / _M) * _MRx * _MRxt; // { MI - 1/M * [MR]x * [MR]x^t } MatrixByArr _invIII = LinAlg.Inv3x3(_III); moleMRI.Add(mole, new Dictionary <string, object>()); moleMRI[mole].Add("invI", _invI); moleMRI[mole].Add("invIII", _invIII); moleMRI[mole].Add("MR", _MR); moleMRI[mole].Add("R", _R); moleMRI[mole].Add("M", _M); } MatrixByArr invI = moleMRI[mole]["invI"] as MatrixByArr; MatrixByArr invIII = moleMRI[mole]["invIII"] as MatrixByArr; Vector MR = moleMRI[mole]["MR"] as Vector; Vector R = moleMRI[mole]["R"] as Vector; double M = (double)(moleMRI[mole]["M"]); RotableInfo rotInfo = rotInfos[a]; double Ma = 0; Vector Ra = new double[3]; Vector MaRa = new double[3]; MatrixByArr Ia = new double[3, 3]; GetMaRaMaraITa(rotInfo.rotAtoms, coords, ref Ma, ref Ra, ref MaRa, ref Ia); HDebug.Assert(rotInfo.rotAtoms.Contains(rotInfo.bondedAtom)); Vector sa = coords[rotInfo.bondedAtom.ID]; Vector ea; { Atom bondatom = null; HDebug.Assert(rotInfo.bond.atoms.Length == 2); if (rotInfo.bond.atoms[0] == rotInfo.bondedAtom) { bondatom = rotInfo.bond.atoms[1]; } else { bondatom = rotInfo.bond.atoms[0]; } HDebug.Assert(rotInfo.rotAtoms.Contains(bondatom) == false); ea = (sa - coords[bondatom.ID]).UnitVector(); } Vector Aa; { Vector ea_Rasa = LinAlg.CrossProd3(ea, Ra - sa); Vector IAa = -LinAlg.MV(Ia, ea) + LinAlg.CrossProd3(Ma * R - MaRa, ea_Rasa); Aa = LinAlg.MV(invI, IAa); } { //Vector ea_MaRa_Masa = Vector.CrossProd3(ea, MaRa-Ma*sa); //Vector ea_sa = Vector.CrossProd3(ea, sa); Vector IAa = new double[3]; IAa += -LinAlg.MV(Ia, ea); IAa += LinAlg.CrossProd3(MaRa, LinAlg.CrossProd3(ea, sa)); IAa += LinAlg.CrossProd3(MR, LinAlg.CrossProd3(ea, MaRa - Ma * sa)) / M; Aa = LinAlg.MV(invIII, IAa); } Vector ta = new double[3]; { //Aa = new double[3]; // check "translational Eckart condition" only //ta += (-1/M) * Vector.CrossProd3(Aa, MMR); ta += (-1 / M) * LinAlg.CrossProd3(Aa, MR); ta += (-1 / M) * LinAlg.CrossProd3(ea, MaRa - Ma * sa); } fixed(double *Ja = _Ja) { //for(int i=0; i<n; i++) foreach (Atom iaa in mole.atoms) { int i = iaa.ID; double mi = univ.atoms[i].Mass; Vector ri = coords[univ.atoms[i].ID]; Vector Jia = new double[3]; //Jia += Vector.CrossProd3(Aa, ri*mi); Jia += LinAlg.CrossProd3(Aa, ri); Jia += ta; //J[i, a] = Jia.ToColMatrix(); Ja[i * 3 + 0] = Jia[0]; Ja[i * 3 + 2] = Jia[2]; Ja[i * 3 + 1] = Jia[1]; } foreach (Atom ira in rotInfo.rotAtoms) { int i = ira.ID; Vector ri = coords[univ.atoms[i].ID]; Vector Jia = LinAlg.CrossProd3(ea, ri - sa); //J[i, a] += Jia.ToColMatrix(); Ja[i * 3 + 0] += Jia[0]; Ja[i * 3 + 1] += Jia[1]; Ja[i * 3 + 2] += Jia[2]; } //for(int i=0; i<n; i++) foreach (Atom iaa in mole.atoms) { int i = iaa.ID; J[i * 3 + 0, a] = Ja[i * 3 + 0]; J[i * 3 + 1, a] = Ja[i * 3 + 1]; J[i * 3 + 2, a] = Ja[i * 3 + 2]; } } if (HDebug.IsDebuggerAttached) { // check Eckart condition // http://en.wikipedia.org/wiki/Eckart_conditions ////////////////////////////////////////////////////////////////////// // 1. translational Eckart condition // sum{i=1..n}{mi * Jia} = 0 Vector mJ = new double[3]; //for(int i=0; i<n; i++) foreach (Atom iaa in mole.atoms) { int i = iaa.ID; double mi = univ.atoms[i].Mass; //Vector Jia = J[i, a].ToVector(); Vector Jia = new double[3] { J[i * 3 + 0, a], J[i * 3 + 1, a], J[i * 3 + 2, a] }; mJ += mi * Jia; } HDebug.AssertTolerance(0.00000001, mJ); ////////////////////////////////////////////////////////////////////// // 1. rotational Eckart condition // sum{i=1..n}{mi * r0i x Jia} = 0, // where 'x' is the cross product Vector mrJ = new double[3]; //for(int i=0; i<n; i++) foreach (Atom iaa in mole.atoms) { int i = iaa.ID; double mi = univ.atoms[i].Mass; Vector ri = coords[univ.atoms[i].ID]; //Vector Jia = J[i, a].ToVector(); Vector Jia = new double[3] { J[i * 3 + 0, a], J[i * 3 + 1, a], J[i * 3 + 2, a] }; mrJ += mi * LinAlg.CrossProd3(ri, Jia); } HDebug.AssertTolerance(0.0000001, mrJ); } } return(J); }
public static void Validate(Vibrate vibrate, MatrixByArr hess, Vector mass, ILinAlg la) { /// tested with "1I2T" int size = mass.Size; Vector mass05 = new double[size]; { for (int i = 0; i < size; i++) { mass05[i] = Math.Sqrt(mass[i]); } } /// mass05 = {Vector [968] {3.74259, 3.46569, 3.46569, 3.99987, 1.00399, 1.00399, 1.00399, 1.00399, 3.46569, 3.46569, 3.74259, 3.46569, 3.46569, 3.74259, 1.00399, 1.00399, 1.00399, 1.00399, 1.00399, 1.00399, 3.74259, 3.46569, 3.46569, 3.99987, 1.00399, 1.00399, 3.46569,... Vector vibrateEigval; Vector vibrateFreq; Vector[] vibrateEigvec; Vector vibrateEigvecDist; MatrixByArr vibrateEigvecDot; { int[] idxs = vibrate.idx2eigval.Keys.ToArray().HSort().ToArray(); HDebug.Assert(vibrate.idx2eigval.Count == size * 3); HDebug.Assert(vibrate.idx2freq.Count == size * 3); HDebug.Assert(vibrate.idx2freq_mode.Count == size * 3); vibrateEigval = new double[size * 3]; vibrateFreq = new double[size * 3]; vibrateEigvec = new Vector[size * 3]; for (int i = 0; i < size * 3; i++) { int idx = idxs[i]; vibrateEigval[i] = vibrate.idx2eigval[idx]; vibrateFreq[i] = vibrate.idx2freq[idx]; Vector[] eigvec = new Vector[size]; foreach (var ia_vec in vibrate.idx2freq_mode[idx].Item2) { eigvec[ia_vec.Item1 - 1] = ia_vec.Item2; } vibrateEigvec[i] = eigvec.ToVector(); HDebug.Assert(vibrateEigvec[i].Size == size * 3); } var _V = la.ToILMat(vibrateEigvec.ToMatrix()); var _VtV = _V.Tr * _V; vibrateEigvecDot = _VtV.ToArray(); for (int i = 0; i < size * 3; i++) { vibrateEigvecDot[i, i] = 0; } _V.Dispose(); _VtV.Dispose(); vibrateEigvecDist = new double[size * 3]; for (int i = 0; i < size * 3; i++) { vibrateEigvecDist[i] = vibrateEigvec[i].Dist; } } /// vibrateEigval = Vector [2904] { 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.01900, 0.02600, 0.03200, 0.04200, 0.05800, 0.06800, 0.07700, 0.08200, 0.08800, 0.08900, 0.10400, 0.12100, 0.12500, 0.13100, 0.15000, 0.16100, 0.16600, 0.18000, ... /// vibrateFreq = Vector [2904] {-0.01900, -0.01400, -0.00800, 0.00000, 0.00000, 0.00100, 5.97000, 6.71700, 7.78700, 9.02500, 10.48100, 11.23200, 11.86700, 12.47600, 12.78600, 14.07900, 15.24600, 15.46200, 15.73700, 16.34300, 16.82800, 17.57300, 18.04300, 18.67400, ... /// vibrateEigvec[ 0] = Vector [2904] {-0.00394, -0.06017, -0.00576, -0.00632, -0.05673, -0.00295, -0.00450, -0.05276, -0.00406, -0.00552, -0.05206, -0.00297, -0.00530, -0.06312, -0.00493, -0.00239, -0.05843, -0.00695, -0.00233, -0.06123, -0.00745, -0.00733, -0.05510, -0.00174, ... /// vibrateEigvec[ 1] = Vector [2904] { 0.00730, -0.01099, 0.00744, 0.00414, -0.00792, 0.00451, 0.00615, -0.00426, 0.00541, 0.00562, 0.00042, 0.00420, 0.00594, -0.01300, 0.00675, 0.00824, -0.01384, 0.00864, 0.00999, -0.00856, 0.00907, 0.00196, -0.01082, 0.00335, ... /// vibrateEigvec[ 2] = Vector [2904] { 0.04084, -0.01332, 0.04505, 0.03959, -0.01264, 0.04154, 0.03911, -0.01186, 0.03638, 0.04150, -0.01180, 0.03316, 0.04167, -0.01391, 0.04842, 0.03775, -0.01289, 0.04551, 0.04367, -0.01360, 0.04376, 0.03608, -0.01223, 0.04266, ... /// vibrateEigvec[ 3] = Vector [2904] { 0.00893, -0.03084, -0.00143, 0.00893, -0.03084, -0.00143, 0.00893, -0.03084, -0.00143, 0.00893, -0.03084, -0.00143, 0.00893, -0.03084, -0.00143, 0.00893, -0.03084, -0.00143, 0.00893, -0.03084, -0.00143, 0.00893, -0.03084, -0.00143, ... /// vibrateEigvec[ 4] = Vector [2904] { 0.01849, 0.00415, 0.02596, 0.01849, 0.00415, 0.02596, 0.01849, 0.00415, 0.02596, 0.01849, 0.00415, 0.02596, 0.01849, 0.00415, 0.02596, 0.01849, 0.00415, 0.02596, 0.01849, 0.00415, 0.02596, 0.01849, 0.00415, 0.02596, ... /// vibrateEigvec[ 5] = Vector [2904] {-0.02473, -0.00803, 0.01890, -0.02473, -0.00803, 0.01890, -0.02473, -0.00803, 0.01890, -0.02473, -0.00803, 0.01890, -0.02473, -0.00803, 0.01890, -0.02473, -0.00803, 0.01890, -0.02473, -0.00803, 0.01890, -0.02473, -0.00803, 0.01890, ... /// vibrateEigvec[ 6] = Vector [2904] {-0.06781, -0.03888, -0.07685, -0.06685, -0.03630, -0.06009, -0.06096, -0.03343, -0.03323, -0.07658, -0.03381, -0.01218, -0.07491, -0.04028, -0.09513, -0.04916, -0.04365, -0.07857, -0.07827, -0.03504, -0.06911, -0.05202, -0.04051, -0.06630, ... /// vibrateEigvec[ 7] = Vector [2904] { 0.03161, 0.02115, 0.03936, 0.03104, 0.02005, 0.03134, 0.02924, 0.01891, 0.02376, 0.03471, 0.02148, 0.01541, 0.03384, 0.02216, 0.04418, 0.02552, 0.02031, 0.04109, 0.03526, 0.02170, 0.03866, 0.02581, 0.01924, 0.03217, ... /// vibrateEigvec[ 8] = Vector [2904] { 0.03021, 0.00406, 0.03089, 0.03006, 0.00293, 0.02496, 0.02767, 0.00156, 0.01482, 0.03339, 0.00061, 0.00757, 0.03282, 0.00471, 0.03739, 0.02347, 0.00580, 0.03149, 0.03379, 0.00262, 0.02810, 0.02467, 0.00479, 0.02741, ... /// vibrateEigvec[ 9] = Vector [2904] {-0.06629, 0.00026, -0.05240, -0.06201, -0.00132, -0.03691, -0.06003, -0.00365, -0.01796, -0.07120, -0.01011, -0.00037, -0.06995, 0.00149, -0.06501, -0.05369, -0.00009, -0.05497, -0.07695, 0.00040, -0.04852, -0.04857, -0.00130, -0.04028, ... /// vibrateEigvec[10] = Vector [2904] { 0.00818, 0.03787, 0.01628, 0.00657, 0.03785, 0.00764, 0.00619, 0.03720, 0.00652, 0.00847, 0.04099, 0.00194, 0.00861, 0.03853, 0.01640, 0.00574, 0.03272, 0.01931, 0.01109, 0.04177, 0.01940, 0.00305, 0.03318, 0.00576, ... /// ... /// vibrateEigvecDist = Vector [2904] { 1.00000, 1.00000, 1.00000, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, ... /// vibrateEigvecDot = Matrix [2904,2904] {{ 0.00000, -0.01485, 0.00001, 0.01752, -0.00421, 0.00847, -0.00656, -0.00295, 0.00356, -0.00522, 0.01579, -0.01792, -0.00070, -0.00707, 0.02013, 0.00371, 0.00914, 0.03035, -0.02114, -0.00362, -0.00913, -0.00568, 0.00833, -0.00252, -0.00904, 0.00400, -0.00919, ... /// ,{-0.01485, 0.00000, 0.01000, -0.01121, 0.00223, -0.00495, 0.01197, 0.01521, -0.01948, -0.01693, -0.00648, -0.02468, 0.00928, -0.01702, 0.00342, 0.02020, 0.00512, -0.01993, -0.02434, -0.00910, -0.00043, -0.01359, 0.00281, 0.01066, -0.00091, -0.00113, -0.01498, ... /// ,{ 0.00001, 0.01000, 0.00000, 0.01739, 0.01857, 0.03472, 0.00842, -0.01255, -0.01425, -0.01602, 0.02960, 0.01683, -0.01402, 0.00583, 0.00893, -0.05121, 0.02122, 0.02011, 0.03181, 0.01768, 0.01980, 0.01491, -0.01098, -0.00655, 0.02637, 0.02226, 0.01920, ... /// ,{ 0.01752, -0.01121, 0.01739, 0.00000, 0.00001, 0.00001, -0.00032, -0.02216, 0.02828, 0.00288, 0.02392, 0.01872, -0.01179, -0.00516, -0.00306, -0.01100, 0.00863, 0.02967, -0.00337, 0.00510, 0.01070, -0.00051, -0.01931, -0.00691, -0.00043, -0.00015, -0.00532, ... /// ,{-0.00421, 0.00223, 0.01857, 0.00001, 0.00000, 0.00001, 0.01531, 0.01124, -0.00910, 0.01547, 0.00651, 0.00388, 0.02127, 0.01495, 0.01143, -0.01195, -0.00747, -0.00166, -0.03168, 0.00453, 0.01475, -0.02963, 0.00326, -0.02032, 0.00063, 0.00535, 0.00091, ... /// ,{ 0.00847, -0.00495, 0.03472, 0.00001, 0.00001, 0.00000, -0.00846, 0.00057, -0.01390, -0.01859, 0.00969, 0.01731, 0.00026, -0.00321, 0.00537, 0.01203, 0.00221, 0.00119, 0.01690, 0.00005, -0.00702, -0.00638, 0.01118, 0.00489, 0.00875, -0.00975, -0.01986, ... /// ,{-0.00656, 0.01197, 0.00842, -0.00032, 0.01531, -0.00846, 0.00000, -0.03024, -0.04005, 0.02021, 0.00542, 0.03616, 0.02653, 0.02007, 0.00238, -0.01524, 0.01094, -0.02750, 0.01223, -0.04935, 0.00435, 0.00496, -0.00377, 0.02044, -0.00450, -0.02870, 0.01467, ... /// ,{-0.00295, 0.01521, -0.01255, -0.02216, 0.01124, 0.00057, -0.03024, 0.00000, -0.00478, 0.01508, -0.00418, -0.00935, -0.00450, -0.03316, -0.01132, 0.03958, -0.05918, 0.01136, 0.00087, -0.02228, -0.00603, 0.00367, 0.01700, 0.01592, -0.02086, -0.01957, 0.00634, ... /// ,{ 0.00356, -0.01948, -0.01425, 0.02828, -0.00910, -0.01390, -0.04005, -0.00478, 0.00000, 0.04574, 0.01629, -0.00962, 0.02596, -0.01312, -0.02689, 0.02066, 0.00827, -0.01266, 0.01362, 0.00747, 0.00746, -0.01274, -0.00248, 0.01370, 0.00041, 0.00077, 0.03418, ... /// ,{-0.00522, -0.01693, -0.01602, 0.00288, 0.01547, -0.01859, 0.02021, 0.01508, 0.04574, 0.00000, 0.03420, -0.01509, 0.00495, -0.03103, -0.01061, -0.00449, 0.00189, 0.01069, -0.00097, -0.04002, 0.06662, -0.02209, -0.02746, -0.00327, -0.00542, 0.01026, 0.03653, ... /// ,{ 0.01579, -0.00648, 0.02960, 0.02392, 0.00651, 0.00969, 0.00542, -0.00418, 0.01629, 0.03420, 0.00000, -0.00570, 0.01489, -0.00290, 0.03163, -0.04236, 0.02447, 0.02609, -0.02314, 0.00057, 0.01577, -0.00808, 0.00852, 0.01132, 0.02774, 0.05619, 0.05177, ... /// ... } Vector[] mwvibrateEigvec; Vector mwvibrateEigvecDist; MatrixByArr mwvibrateEigvecDot; { mwvibrateEigvec = new Vector[size * 3]; for (int im = 0; im < size * 3; im++) { mwvibrateEigvec[im] = new double[size * 3]; for (int i = 0; i < size * 3; i++) { mwvibrateEigvec[im][i] = vibrateEigvec[im][i] * mass05[i / 3]; } } var _V = la.ToILMat(mwvibrateEigvec.ToMatrix()); var _VtV = _V.Tr * _V; mwvibrateEigvecDot = _VtV.ToArray(); for (int i = 0; i < size * 3; i++) { mwvibrateEigvecDot[i, i] = 0; } _V.Dispose(); _VtV.Dispose(); mwvibrateEigvecDist = new double[size * 3]; for (int i = 0; i < size * 3; i++) { mwvibrateEigvecDist[i] = mwvibrateEigvec[i].Dist; } } /// mwvibrateEigvec[ 0] = Vector [2904] {-0.01473, -0.22519, -0.02156, -0.02190, -0.19660, -0.01023, -0.01558, -0.18284, -0.01407, -0.02209, -0.20822, -0.01189, -0.00532, -0.06337, -0.00495, -0.00240, -0.05867, -0.00698, -0.00234, -0.06148, -0.00748, -0.00736, -0.05532, -0.00174, -0.03280, -0.20514, -0.00122, ... /// mwvibrateEigvec[ 1] = Vector [2904] { 0.02732, -0.04112, 0.02784, 0.01435, -0.02746, 0.01563, 0.02131, -0.01478, 0.01875, 0.02248, 0.00168, 0.01681, 0.00596, -0.01305, 0.00677, 0.00827, -0.01390, 0.00868, 0.01003, -0.00860, 0.00911, 0.00196, -0.01087, 0.00336, 0.00510, -0.01633, 0.00669, ... /// mwvibrateEigvec[ 2] = Vector [2904] { 0.15284, -0.04984, 0.16861, 0.13720, -0.04380, 0.14395, 0.13553, -0.04110, 0.12608, 0.16598, -0.04720, 0.13263, 0.04184, -0.01397, 0.04862, 0.03790, -0.01294, 0.04569, 0.04384, -0.01365, 0.04394, 0.03622, -0.01228, 0.04283, 0.14978, -0.04586, 0.14431, ... /// mwvibrateEigvec[ 3] = Vector [2904] { 0.03341, -0.11543, -0.00535, 0.03094, -0.10689, -0.00495, 0.03094, -0.10689, -0.00495, 0.03571, -0.12337, -0.00572, 0.00896, -0.03097, -0.00143, 0.00896, -0.03097, -0.00143, 0.00896, -0.03097, -0.00143, 0.00896, -0.03097, -0.00143, 0.03094, -0.10689, -0.00495, ... /// mwvibrateEigvec[ 4] = Vector [2904] { 0.06919, 0.01553, 0.09717, 0.06407, 0.01438, 0.08998, 0.06407, 0.01438, 0.08998, 0.07395, 0.01660, 0.10384, 0.01856, 0.00417, 0.02607, 0.01856, 0.00417, 0.02607, 0.01856, 0.00417, 0.02607, 0.01856, 0.00417, 0.02607, 0.06407, 0.01438, 0.08998, ... /// mwvibrateEigvec[ 5] = Vector [2904] {-0.09254, -0.03007, 0.07072, -0.08570, -0.02784, 0.06549, -0.08570, -0.02784, 0.06549, -0.09890, -0.03213, 0.07558, -0.02483, -0.00807, 0.01897, -0.02483, -0.00807, 0.01897, -0.02483, -0.00807, 0.01897, -0.02483, -0.00807, 0.01897, -0.08570, -0.02784, 0.06549, ... /// mwvibrateEigvec[ 6] = Vector [2904] {-0.25378, -0.14551, -0.28761, -0.23168, -0.12582, -0.20824, -0.21127, -0.11587, -0.11515, -0.30630, -0.13523, -0.04871, -0.07521, -0.04044, -0.09551, -0.04935, -0.04383, -0.07889, -0.07858, -0.03518, -0.06938, -0.05223, -0.04067, -0.06656, -0.31267, -0.10855, -0.21408, ... /// mwvibrateEigvec[ 7] = Vector [2904] { 0.11831, 0.07917, 0.14730, 0.10757, 0.06950, 0.10860, 0.10135, 0.06555, 0.08236, 0.13883, 0.08592, 0.06162, 0.03397, 0.02225, 0.04436, 0.02562, 0.02039, 0.04126, 0.03540, 0.02179, 0.03882, 0.02592, 0.01931, 0.03230, 0.13407, 0.07328, 0.10201, ... /// mwvibrateEigvec[ 8] = Vector [2904] { 0.11305, 0.01520, 0.11560, 0.10416, 0.01015, 0.08649, 0.09590, 0.00539, 0.05138, 0.13354, 0.00244, 0.03027, 0.03295, 0.00473, 0.03754, 0.02356, 0.00582, 0.03162, 0.03392, 0.00263, 0.02821, 0.02476, 0.00481, 0.02752, 0.13548, 0.00227, 0.08985, ... /// mwvibrateEigvec[ 9] = Vector [2904] {-0.24809, 0.00098, -0.19612, -0.21492, -0.00459, -0.12793, -0.20803, -0.01266, -0.06223, -0.28479, -0.04045, -0.00147, -0.07023, 0.00150, -0.06527, -0.05390, -0.00009, -0.05519, -0.07725, 0.00040, -0.04871, -0.04876, -0.00131, -0.04044, -0.26445, -0.00370, -0.12262, ... /// mwvibrateEigvec[10] = Vector [2904] { 0.03062, 0.14174, 0.06091, 0.02278, 0.13118, 0.02647, 0.02145, 0.12891, 0.02259, 0.03387, 0.16394, 0.00776, 0.00864, 0.03868, 0.01647, 0.00577, 0.03285, 0.01938, 0.01114, 0.04194, 0.01948, 0.00306, 0.03332, 0.00578, 0.03239, 0.15042, 0.00838, ... /// ... /// mwvibrateEigvecDist = Vector [2904] { 2.63914, 2.64117, 2.60684, 2.63907, 2.63908, 2.63909, 2.54591, 2.61693, 2.50533, 2.46113, 2.51293, 2.54366, 2.57329, 2.51375, 2.53133, 2.31010, 2.40230, 2.47630, 2.49624, 2.33080, 2.48450, 2.49505, 2.41665, 2.54134, 2.55567, 2.45052, 2.41150, ... /// mwvibrateEigvecDot = Matrix [2904,2904] {{ 0.00000, 0.00020, -0.00082, 0.00002, 0.00000, 0.00003, 0.00000, 0.00000, 0.00000, 0.00000, 0.00001, 0.00000, 0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00001, -0.00001, 0.00001, 0.00000, -0.00001, 0.00000, 0.00000, 0.00000, -0.00001, ... /// { 0.00020, 0.00000, 0.12062, 0.00002, 0.00002, -0.00007, 0.00000, 0.00000, -0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00001, 0.00000, 0.00000, 0.00000, 0.00000, -0.00001, 0.00000, 0.00000, 0.00000, ... /// {-0.00082, 0.12062, 0.00000, 0.04691, 0.01196, 0.34243, 0.00000, 0.00000, -0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, -0.00001, 0.00000, -0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, -0.00001, -0.00001, 0.00000, ... /// { 0.00002, 0.00002, 0.04691, 0.00000, 0.00004, 0.00004, 0.00001, 0.00000, 0.00001, -0.00001, 0.00001, -0.00002, 0.00001, 0.00000, 0.00003, 0.00000, 0.00001, 0.00000, 0.00000, 0.00001, 0.00000, 0.00000, -0.00001, 0.00000, 0.00000, 0.00001, 0.00000, 0.00000, 0.00002, ... /// { 0.00000, 0.00002, 0.01196, 0.00004, 0.00000, 0.00004, -0.00002, 0.00001, 0.00000, 0.00000, 0.00001, 0.00003, 0.00001, 0.00001, 0.00000, -0.00001, 0.00001, 0.00000, 0.00000, 0.00000, -0.00001, 0.00000, 0.00000, -0.00001, 0.00000, 0.00000, -0.00001, 0.00000, 0.00000, ... /// { 0.00003, -0.00007, 0.34243, 0.00004, 0.00004, 0.00000, -0.00001, -0.00001, 0.00000, -0.00001, 0.00000, 0.00000, 0.00000, -0.00001, 0.00001, 0.00000, 0.00000, 0.00001, 0.00000, 0.00000, 0.00001, 0.00000, 0.00000, 0.00000, 0.00000, -0.00001, 0.00000, 0.00000, -0.00001, ... /// (7th eigenvector) { 0.00000, 0.00000, 0.00000, 0.00001, -0.00002, -0.00001, 0.00000, -0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00001, 0.00001, 0.00000, ... /// { 0.00000, 0.00000, 0.00000, 0.00000, 0.00001, -0.00001, -0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, -0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, -0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// { 0.00000, -0.00001, -0.00001, 0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00001, -0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// { 0.00000, 0.00000, 0.00000, -0.00001, 0.00000, -0.00001, 0.00000, 0.00000, 0.00001, 0.00000, 0.00000, -0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, -0.00001, 0.00000, -0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// { 0.00001, 0.00000, 0.00000, 0.00001, 0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00001, 0.00000, 0.00000, 0.00000, -0.00001, 0.00000, 0.00001, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, -0.00001, 0.00000, 0.00000, 0.00000, ... /// ... } Tuple <Vector, double>[] hessEig; MatrixByArr hessEigvecDot; double hessEigvecDotMaxAbs; { hessEig = new Tuple <Vector, double> [size * 3]; var _hess = la.ToILMat(hess); var _VD = la.EigSymm(_hess); MatrixByArr V = _VD.Item1.ToArray(); Vector D = _VD.Item2; for (int i = 0; i < size * 3; i++) { double eigval = D[i]; Vector eigvec = V.GetColVector(i); hessEig[i] = new Tuple <Vector, double>(eigvec, eigval); } var _V = _VD.Item1; var _VtV = _V.Tr * _V; hessEigvecDot = _VtV.ToArray(); for (int i = 0; i < size * 3; i++) { hessEigvecDot[i, i] = 0; } hessEigvecDotMaxAbs = hessEigvecDot.ToArray().HAbs().HMax(); _hess.Dispose(); _VD.Item1.Dispose(); _V.Dispose(); _VtV.Dispose(); } Vector[] hessEigVec = hessEig.HListItem1().ToArray(); Vector hessEigVal = hessEig.HListItem2().ToArray(); /// hessEigVal = Vector [2904] {-0.00010, -0.00006, -0.00005, -0.00001, 0.00005, 0.00010, 0.01944, 0.02618, 0.03199, 0.04183, 0.05824, 0.06837, 0.07660, 0.08224, 0.08755, 0.08917, 0.10386, 0.12144, 0.12444, 0.13126, 0.15030, 0.16139, 0.16551, 0.17947, 0.19501, 0.20400, 0.21379, 0.22191, 0.22934, 0.24248, 0.24686, ... /// hessEigvecDot = Matrix [2904,2904] {{0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// ...} /// hessEigvecDotMaxAbs = 0.0000000000010620164686905853 Matrix mwHess; Tuple <Vector, double>[] mwHessEig; Matrix mwhessEigvecDot; double mwhessEigvecDotMaxAbs; Mode[] mwMode; { mwHess = Hess.GetMassWeightedHess(hess, mass); mwHessEig = new Tuple <Vector, double> [size * 3]; mwMode = new Mode[size * 3]; var _mwhess = la.ToILMat(mwHess); var _VD = la.EigSymm(_mwhess); MatrixByArr V = _VD.Item1.ToArray(); Vector D = _VD.Item2; for (int i = 0; i < size * 3; i++) { double eigval = D[i]; Vector eigvec = V.GetColVector(i); mwHessEig[i] = new Tuple <Vector, double>(eigvec, eigval); mwMode[i] = new Mode(); mwMode[i].eigval = eigval; mwMode[i].eigvec = eigvec; } var _V = _VD.Item1; var _VtV = _V.Tr * _V; mwhessEigvecDot = _VtV.ToArray(); for (int i = 0; i < size * 3; i++) { mwhessEigvecDot[i, i] = 0; } mwhessEigvecDotMaxAbs = mwhessEigvecDot.ToArray().HAbs().HMax(); _mwhess.Dispose(); _VD.Item1.Dispose(); //Vector[] xxx = mwhessEigvecDot.GetRowVectorList(); } Vector[] mwHessEigVec = mwHessEig.HListItem1().ToArray(); Vector mwHessEigVal = mwHessEig.HListItem2().ToArray(); /// mwHessEigVal = Vector [2904] {-0.00001, -0.00001, -0.00001, 0.00000, 0.00001, 0.00001, 0.00302, 0.00382, 0.00515, 0.00690, 0.00933, 0.01070, 0.01194, 0.01320, 0.01386, 0.01682, 0.01970, 0.02027, 0.02101, 0.02264, 0.02401, 0.02619, 0.02760, 0.02957, 0.03047, 0.03368, 0.03644, 0.03660, 0.03897, 0.04051, 0.04351, ... /// mwhessEigvecDot = Matrix [2904,2904] {{0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ... /// ...} /// mwhessEigvecDotMaxAbs = 0.0000000000026275308697473049 Mode[] mrMode = mwMode.GetMassReduced(mass.ToArray()).ToArray(); Mode[] mrModeNorm = mrMode.GetNormalized(); Vector ratFreqMode1; Vector ratFreqMode2; Vector ratFreqMode3; Vector ratFreqMode4; Vector ratFreqMode5; Vector ratFreqMode6; { /// reference /// * eq. (14) in http://www3.nd.edu/~csweet1/NormalMode7.pdf /// * http://en.wikipedia.org/wiki/Boltzmann_constant /// * http://www.charmm.org/documentation/c34b1/subst.html ratFreqMode1 = new double[size * 3]; ratFreqMode2 = new double[size * 3]; ratFreqMode3 = new double[size * 3]; ratFreqMode4 = new double[size * 3]; ratFreqMode5 = new double[size * 3]; ratFreqMode6 = new double[size * 3]; double kB = 0.0019872041; /// kcal/mol/K, http://en.wikipedia.org/wiki/Boltzmann_constant, http://www.charmm.org/documentation/c34b1/subst.html double T3 = 310.0; /// temperature in kelvin. 14 is the adjustment to make the ratio close to 1 double T4 = 310.0; /// temperature in kelvin. 14 is the adjustment to make the ratio close to 1 double T5 = 310.0 - 13.0; /// temperature in kelvin. 14 is the adjustment to make the ratio close to 1 double scale1 = 10000; /// manually searched double scale2 = 10000; /// manually searched double scale3 = 10000; /// manually searched double scale4 = 10000; /// manually searched double scale5 = 10000; /// manually searched double scale6 = 100000; /// manually searched for (int im = 0; im < size * 3; im++) { ratFreqMode1[im] = (vibrateFreq[im] * vibrateFreq[im]) / (scale1 * vibrateEigval[im]); ratFreqMode2[im] = (vibrateFreq[im] * vibrateFreq[im]) / (scale2 * hessEigVal[im]); ratFreqMode3[im] = (vibrateFreq[im] * vibrateFreq[im]) / (scale3 * mwvibrateEigvecDist[im] * (2 * mwMode[im].eigval * kB * T3)); ratFreqMode4[im] = (vibrateFreq[im] * vibrateFreq[im]) / (scale4 * (2 * mwMode[im].eigval * kB * T4)); ratFreqMode5[im] = (vibrateFreq[im] * vibrateFreq[im]) / (scale5 * (2 * mwMode[im].eigval * kB * T5)); ratFreqMode6[im] = (vibrateFreq[im] * vibrateFreq[im]) / (scale6 * mrModeNorm[im].eigval); } StringBuilder outs = new StringBuilder(); { var vals = ratFreqMode1.ToArray().HSelectFromCount(6, size * 3 - 6).ToArray(); outs.Append(string.Format("{0,9:0.000000} {0,9:0.000000} {0,9:0.000000} {0,9:0.000000}\n", vals.Min(), vals.Average(), vals.Max(), vals.Variance())); } { var vals = ratFreqMode2.ToArray().HSelectFromCount(6, size * 3 - 6).ToArray(); outs.Append(string.Format("{0,9:0.000000} {0,9:0.000000} {0,9:0.000000} {0,9:0.000000}\n", vals.Min(), vals.Average(), vals.Max(), vals.Variance())); } { var vals = ratFreqMode3.ToArray().HSelectFromCount(6, size * 3 - 6).ToArray(); outs.Append(string.Format("{0,9:0.000000} {0,9:0.000000} {0,9:0.000000} {0,9:0.000000}\n", vals.Min(), vals.Average(), vals.Max(), vals.Variance())); } { var vals = ratFreqMode4.ToArray().HSelectFromCount(6, size * 3 - 6).ToArray(); outs.Append(string.Format("{0,9:0.000000} {0,9:0.000000} {0,9:0.000000} {0,9:0.000000}\n", vals.Min(), vals.Average(), vals.Max(), vals.Variance())); } { var vals = ratFreqMode5.ToArray().HSelectFromCount(6, size * 3 - 6).ToArray(); outs.Append(string.Format("{0,9:0.000000} {0,9:0.000000} {0,9:0.000000} {0,9:0.000000}\n", vals.Min(), vals.Average(), vals.Max(), vals.Variance())); } { var vals = ratFreqMode6.ToArray().HSelectFromCount(6, size * 3 - 6).ToArray(); outs.Append(string.Format("{0,9:0.000000} {0,9:0.000000} {0,9:0.000000} {0,9:0.000000}\n", vals.Min(), vals.Average(), vals.Max(), vals.Variance())); } } /// ratFreqMode1 = tinkFreq^2 / ( 10000 * tinkEigval ) Vector [2904] {Infinity, Infinity, Infinity, NaN, NaN, Infinity, 0.18758, 0.17353, 0.18949, 0.19393, 0.18940, 0.18553, 0.18289, 0.18982, 0.18577, 0.22272, 0.22350, 0.19758, 0.19812, 0.20389, 0.18879, 0.19181, 0.19611, 0.19373, 0.18427, 0.19463, 0.20089, 0.19443, 0.20073, 0.19660, 0.20774, 0.19878, 0.19981, 0.20473, 0.20848, 0.20524, 0.20610, 0.20544, ... /// ratFreqMode2 = tinkFreq^2 / ( 10000 * hessEigval ) Vector [2904] {-0.00035, -0.00032, -0.00013, 0.00000, 0.00000, 0.00000, 0.18333, 0.17235, 0.18953, 0.19470, 0.18861, 0.18452, 0.18384, 0.18927, 0.18672, 0.22229, 0.22381, 0.19687, 0.19901, 0.20349, 0.18841, 0.19135, 0.19669, 0.19431, 0.18426, 0.19463, 0.20108, 0.19451, 0.20044, 0.19702, 0.20785, 0.19852, 0.20019, 0.20506, 0.20835, 0.20506, 0.20621, 0.20561, ... /// ratFreqMode3 = tinkFreq^2 / ( 10000 * Vector [2904] {-0.00076, -0.00068, -0.00028, 0.00000, 0.00000, 0.00000, 0.37598, 0.36591, 0.38171, 0.38948, 0.38030, 0.37608, 0.37197, 0.38080, 0.37831, 0.41414, 0.39858, 0.38660, 0.38329, 0.41078, 0.38533, 0.38361, 0.39613, 0.37669, 0.37453, 0.39045, 0.39708, 0.39297, 0.40276, 0.39117, 0.37568, 0.38563, 0.38705, 0.40232, 0.41826, 0.39828, 0.39591, 0.39734, ... /// ratFreqMode4 = tinkFreq^2 / ( 10000 * Vector [2904] {-0.00202, -0.00180, -0.00074, 0.00000, 0.00000, 0.00001, 0.95720, 0.95757, 0.95632, 0.95855, 0.95567, 0.95663, 0.95718, 0.95725, 0.95763, 0.95670, 0.95750, 0.95734, 0.95679, 0.95746, 0.95735, 0.95712, 0.95732, 0.95731, 0.95718, 0.95681, 0.95757, 0.95709, 0.95731, 0.95720, 0.95712, 0.95731, 0.95703, 0.95721, 0.95715, 0.95709, 0.95727, 0.95707, ... /// ratFreqMode5 = tinkFreq^2 / ( 10000 * Vector [2904] {-0.00210, -0.00188, -0.00077, 0.00000, 0.00000, 0.00001, 0.99910, 0.99948, 0.99818, 1.00051, 0.99750, 0.99850, 0.99908, 0.99915, 0.99954, 0.99857, 0.99941, 0.99925, 0.99867, 0.99937, 0.99925, 0.99902, 0.99922, 0.99921, 0.99907, 0.99869, 0.99948, 0.99899, 0.99921, 0.99910, 0.99901, 0.99921, 0.99892, 0.99911, 0.99905, 0.99898, 0.99917, 0.99896, ... /// ratFreqMode6 = tinkFreq^2 / (100000 * Vector [2904] {-0.00174, -0.00156, -0.00064, 0.00000, 0.00000, 0.00000, 0.76481, 0.80792, 0.73961, 0.71527, 0.74349, 0.76241, 0.78110, 0.74524, 0.75597, 0.62897, 0.68103, 0.72307, 0.73431, 0.64111, 0.72797, 0.73423, 0.68870, 0.76232, 0.76976, 0.70769, 0.68559, 0.70019, 0.66656, 0.70610, 0.76526, 0.72679, 0.72086, 0.66728, 0.61773, 0.68114, 0.68943, 0.68425, ... /// min average max variance /// ratFreqMode1 0.157480 0.157480 0.157480 0.157480 /// ratFreqMode2 0.157480 0.157480 0.157480 0.157480 /// ratFreqMode3 0.296715 0.296715 0.296715 0.296715 /// ratFreqMode4 0.955668 0.955668 0.955668 0.955668 /// ratFreqMode5 0.997499 0.997499 0.997499 0.997499 /// ratFreqMode6 0.122140 0.122140 0.122140 0.122140 /// Tinker Eigenvalue: determined using the original hessian matrix /// [V, D] = eig(H) /// eig := diag(D) /// Tinker Frequency : determined using the mass-weighted hessian matrix /// [V, D] = eig(M^-0.5 H M^-0.5) /// freq := sqrt(scale * 2 * diag(D) * kB * T) /// where scale = 10000 /// kB = 0.0019872041 [kcal/mol/K] /// T = approx. 310 /// Tinker Mode : determined using the normalized mass-reduced eigenvalue of mass-weighted hessian matrix, /// [V0, D] = eig(M^-0.5 H M^-0.5) /// V1 = M^-0.5 * V0 /// V2i = V1i / sqrt(V1i' * V1i) /// mode: = V2i Vector dot_vibrateEigvec_hessEig; Vector dot_vibrateEigvec_mrModeNorm; { dot_vibrateEigvec_hessEig = new double[size * 3]; dot_vibrateEigvec_mrModeNorm = new double[size * 3]; for (int i = 0; i < size * 3; i++) { Vector v0 = vibrateEigvec[i].UnitVector(); Vector v1 = hessEig[i].Item1.UnitVector(); Vector v2 = mrModeNorm[i].eigvec; dot_vibrateEigvec_hessEig [i] = Math.Abs(LinAlg.VtV(v0, v1)); dot_vibrateEigvec_mrModeNorm[i] = Math.Abs(LinAlg.VtV(v0, v2)); } } /// dot_vibrateEigvec_hessEig = Vector [2904] {0.48985, 0.13230, 0.44747, 0.04888, 0.07929, 0.52681, 0.99419, 0.99184, 0.97989, 0.97002, 0.98092, 0.98450, 0.84740, 0.80494, 0.03774, 0.08663, 0.75053, 0.88493, 0.11468, 0.12843, 0.83637, 0.73307, 0.69806, 0.39251, 0.52766, 0.47411, 0.84648, 0.32370, 0.60035, 0.37242, 0.08106, 0.34824, 0.31312, 0.00374, 0.10264, 0.53659, 0.52061, 0.00238, 0.01090, 0.42059, 0.18661, 0.57478, 0.11763, 0.16953, 0.01308, 0.15673, 0.29348, ... /// dot_vibrateEigvec_mrModeNorm = Vector [2904] {0.48193, 0.12355, 0.45875, 0.04765, 0.08948, 0.52432, 0.99998, 0.99998, 0.99999, 0.99999, 0.99999, 0.99999, 0.99998, 0.99999, 0.99998, 0.99999, 0.99999, 0.99998, 0.99993, 0.99996, 0.99997, 0.99999, 0.99999, 0.99994, 0.99994, 1.00000, 0.99993, 0.99993, 0.99999, 1.00000, 1.00000, 1.00000, 0.99999, 0.99998, 0.99999, 0.99999, 1.00000, 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 0.99999, 0.99999, ... }
public double GetPotential(List <ForceField.IForceField> frcflds, Vector[] coords, ref Vector[] forces, ref MatrixByArr hessian, Dictionary <string, object> cache, Vector[,] forceij = null, double[,] pwfrc = null, double[,] pwspr = null) { //forceij = new Vector[size, size]; MatrixByArr[,] hess = null; if (hessian != null) { int size = coords.GetLength(0); hess = LinAlg.CreateMatrixArray(size, size, new double[3, 3]); } double energy = 0; double energy_bonds = GetPotentialBonds(frcflds, coords, ref forces, ref hess, cache, forceij, pwfrc, pwspr); energy += energy_bonds; double energy_angles = GetPotentialAngles(frcflds, coords, ref forces, ref hess, cache, forceij, pwfrc, pwspr); energy += energy_angles; double energy_dihedrals = GetPotentialDihedrals(frcflds, coords, ref forces, ref hess, cache, forceij, pwfrc, pwspr); energy += energy_dihedrals; double energy_impropers = GetPotentialImpropers(frcflds, coords, ref forces, ref hess, cache, forceij, pwfrc, pwspr); energy += energy_impropers; double energy_nonbondeds = GetPotentialNonbondeds(frcflds, coords, ref forces, ref hess, cache, forceij, pwfrc, pwspr); energy += energy_nonbondeds; double energy_customs = GetPotentialCustoms(frcflds, coords, ref forces, ref hess, cache, forceij, pwfrc, pwspr); energy += energy_customs; if (hess != null) { GetPotentialBuildHessian(coords, hess, ref hessian); } if (cache != null) { if (cache.ContainsKey("energy_bonds ") == false) { cache.Add("energy_bonds ", 0); } cache["energy_bonds "] = energy_bonds; if (cache.ContainsKey("energy_angles ") == false) { cache.Add("energy_angles ", 0); } cache["energy_angles "] = energy_angles; if (cache.ContainsKey("energy_dihedrals ") == false) { cache.Add("energy_dihedrals ", 0); } cache["energy_dihedrals "] = energy_dihedrals; if (cache.ContainsKey("energy_impropers ") == false) { cache.Add("energy_impropers ", 0); } cache["energy_impropers "] = energy_impropers; if (cache.ContainsKey("energy_nonbondeds") == false) { cache.Add("energy_nonbondeds", 0); } cache["energy_nonbondeds"] = energy_nonbondeds; if (cache.ContainsKey("energy_customs ") == false) { cache.Add("energy_customs ", 0); } cache["energy_customs "] = energy_customs; } return(energy); }
public double GetPotential(List <ForceField.IForceField> frcflds, ref Vector[] forces, ref MatrixByArr hessian, Dictionary <string, object> cache, Vector[,] forceij = null, double[,] pwfrc = null, double[,] pwspr = null) { Vector[] coords = new Vector[size]; foreach (Atom atom in atoms) { HDebug.Assert(coords[atom.ID] == null); coords[atom.ID] = atom.Coord; } return(GetPotential(frcflds, coords, ref forces, ref hessian, cache, forceij, pwfrc, pwspr)); }
public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_Matlab_experimental (object[] atoms , HessMatrix H , List <int>[] lstNewIdxRemv , double thres_zeroblk , ILinAlg ila , bool cloneH , string[] options ) { ila = null; if (cloneH) { H = H.CloneHess(); } bool process_disp_console = true; if (options != null && options.Contains("print process")) { process_disp_console = true; } bool parallel = true; GC.Collect(0); DateTime[] process_time = new DateTime[6]; //System.Console.WriteLine("begin coarse-graining"); List <HessCoarseResiIterInfo> iterinfos = new List <HessCoarseResiIterInfo>(); for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--) { if (process_disp_console) { process_time[0] = DateTime.UtcNow; System.Console.Write(" - {0:000} : ", iter); } //int[] ikeep = lstNewIdxRemv[iter].Item1; int[] iremv = lstNewIdxRemv[iter].ToArray(); HDebug.Assert(H.ColBlockSize == H.RowBlockSize); int blksize = H.ColBlockSize; //HDebug.Assert(ikeep.Max() < blksize); //HDebug.Assert(iremv.Max() < blksize); //HDebug.Assert(iremv.Max()+1 == blksize); //HDebug.Assert(iremv.Max() - iremv.Min() + 1 == iremv.Length); int[] idxkeep = HEnum.HEnumFromTo(0, iremv.Min() - 1).ToArray(); int[] idxremv = HEnum.HEnumFromTo(iremv.Min(), iremv.Max()).ToArray(); //HDebug.Assert(idxkeep.HUnionWith(idxremv).Length == blksize); HessCoarseResiIterInfo iterinfo = new HessCoarseResiIterInfo(); iterinfo.sizeHessBlkMat = idxremv.Max() + 1; // H.ColBlockSize; iterinfo.numAtomsRemoved = idxremv.Length; iterinfo.time0 = DateTime.UtcNow; double C_density0 = double.NaN; double C_density1 = double.NaN; { //HessMatrix A = H.SubMatrixByAtoms(false, idxkeep, idxkeep); HessMatrix A = H; //HessMatrix B = H.SubMatrixByAtoms(false, idxkeep, idxremv); HessMatrix C, D; /// HessMatrix C = H.SubMatrixByAtoms(false, idxremv, idxkeep, parallel:parallel); /// HessMatrix D = H.SubMatrixByAtoms(false, idxremv, idxremv, parallel:parallel); { C = H.Zeros(idxremv.Length * 3, idxkeep.Length * 3); D = H.Zeros(idxremv.Length * 3, idxremv.Length * 3); int iremv_min = iremv.Min(); int iremv_max = iremv.Max(); foreach (var bc_br_bval in H.EnumBlocksInCols(idxremv)) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; if (bc > iremv_max) { continue; } if (br > iremv_max) { continue; } if (br < iremv_min) { int nc = bc - iremv_min; int nr = br; C.SetBlock(nc, nr, bval.CloneT()); } else { int nc = bc - iremv_min; int nr = br - iremv_min; D.SetBlock(nc, nr, bval.CloneT()); } } } if (process_disp_console) { process_time[1] = process_time[2] = DateTime.UtcNow; System.Console.Write("CD({0:00.00} min), ", (process_time[2] - process_time[0]).TotalMinutes); } // make B,C sparse //int B_cntzero = B.MakeNearZeroBlockAsZero(thres_zeroblk); C_density0 = C.RatioUsedBlocks; /// iterinfo.numSetZeroBlock = C.MakeNearZeroBlockAsZero(thres_zeroblk); { double thres_absmax = thres_zeroblk; List <Tuple <int, int> > lstIdxToMakeZero = new List <Tuple <int, int> >(); foreach (var bc_br_bval in C.EnumBlocks()) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; double absmax_bval = bval.HAbsMax(); if (absmax_bval < thres_absmax) { lstIdxToMakeZero.Add(new Tuple <int, int>(bc, br)); } } foreach (var bc_br in lstIdxToMakeZero) { int cc = bc_br.Item1; int cr = bc_br.Item2; var Cval = C.GetBlock(cc, cr); C.SetBlock(cc, cr, null); var Dval = D.GetBlock(cc, cc); // nCval = Cval -Cval D.SetBlock(cc, cc, Dval + Cval); // nDval = Dval - (-Cval) = Dval + Cval int bc = cr; int br = cc; var Bval = Cval.Tr(); var Aval = A.GetBlock(bc, bc); // nBval = Bval -Bval A.SetBlock(bc, bc, Aval + Bval); // nAval = Aval - (-Bval) = Aval + Bval } iterinfo.numSetZeroBlock = lstIdxToMakeZero.Count; } //int B_nzeros = B.NumUsedBlocks; double B_nzeros_ = Math.Sqrt(B_nzeros); iterinfo.numNonZeroBlock = C.NumUsedBlocks; C_density1 = C.RatioUsedBlocks; HessMatrix B_invD_C = Get_BInvDC(A, C, D, process_disp_console , options , parallel: parallel ); if (process_disp_console) { process_time[4] = DateTime.UtcNow; System.Console.Write("B.invD.C({0:00.00} min), ", (process_time[4] - process_time[3]).TotalMinutes); } /// iterinfo.numAddIgnrBlock = A.UpdateAdd(B_invD_C, -1, null, thres_zeroblk/lstNewIdxRemv.Length, parallel:parallel); { HessMatrix _this = A; HessMatrix other = B_invD_C; double thres_NearZeroBlock = thres_zeroblk / lstNewIdxRemv.Length; int count = 0; int count_ignored = 0; foreach (var bc_br_bval in other.EnumBlocks()) { count++; int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; MatrixByArr other_bmat = bc_br_bval.Item3; if (other_bmat.HAbsMax() <= thres_NearZeroBlock) { // other_bmat = other_bmat -other_bmat; // other_diag = other_diag - (-other_bmat) = other_diag + other_bmat; // this_diag = this_diat - B_invD_C // = this_diat - other_diag // = this_diat - (other_diag + other_bmat) // = this_diat - other_diag - other_bmat // = (this_diat - other_bmat) - other_diag // = (this_diat - other_bmat) - (processed later) // = (this_diat - other_bmat) MatrixByArr this_diag = _this.GetBlock(bc, bc); MatrixByArr new_diag = this_diag - other_bmat; _this.SetBlock(bc, bc, new_diag); other_bmat = null; count_ignored++; } if (other_bmat != null) { MatrixByArr this_bmat = _this.GetBlock(bc, br); MatrixByArr new_bmat = this_bmat - other_bmat; _this.SetBlock(bc, br, new_bmat); } } iterinfo.numAddIgnrBlock = count_ignored; } //HessMatrix nH = A - B_invD_C; //nH = ((nH + nH.Tr())/2).ToHessMatrix(); H = A; } iterinfo.usedMemoryByte = GC.GetTotalMemory(false); iterinfo.time1 = DateTime.UtcNow; iterinfos.Add(iterinfo); if (process_disp_console) { System.Console.WriteLine("summary(makezero {0,5}, nonzero {1,5}, numIgnMul {2,7}, numRemvAtoms {3,3}, {4,5:0.00} sec, {5} mb, {6}x{6}, nzeroBlk/Atom {7:0.00})" , iterinfo.numSetZeroBlock , iterinfo.numNonZeroBlock , iterinfo.numAddIgnrBlock , iterinfo.numAtomsRemoved , iterinfo.compSec , iterinfo.usedMemoryByte / (1024 * 1024) , (idxkeep.Length * 3) , ((double)iterinfo.numNonZeroBlock / idxremv.Length) ); } GC.Collect(0); } int numca = H.ColBlockSize - lstNewIdxRemv.HListCount().Sum(); //System.Console.WriteLine("finish coarse-graining"); { int[] idxkeep = HEnum.HEnumCount(numca).ToArray(); H = H.SubMatrixByAtoms(false, idxkeep, idxkeep, false); } { H.MakeNearZeroBlockAsZero(thres_zeroblk); } GC.Collect(0); //System.Console.WriteLine("finish resizing"); return(new CGetHessCoarseResiIterImpl { iterinfos = iterinfos, H = H, }); }
public static MatrixByArr[,] GetJ(Universe univ, Vector[] coords, List <RotableInfo> rotInfos, Func <MatrixByArr, MatrixByArr> fnInv3x3 = null) { if (fnInv3x3 == null) { fnInv3x3 = delegate(MatrixByArr A) { using (new Matlab.NamedLock("GetJ")) { return(LinAlg.Inv3x3(A)); } } } ; MatrixByArr I = GetITa(univ.atoms.ToArray(), coords); MatrixByArr invI = fnInv3x3(I); Vector R = GetRa(univ.atoms.ToArray(), coords); double M = GetMa(univ.atoms.ToArray()); Vector MR = GetMaRa(univ.atoms.ToArray(), coords); MatrixByArr MRx = GetSSMatrix(MR); MatrixByArr MRxt = MRx.Tr(); MatrixByArr III = I - (1.0 / M) * MRx * MRxt; // { MI - 1/M * [MR]x * [MR]x^t } MatrixByArr invIII = fnInv3x3(III); //Vector MMR = GetMaMaRa(univ.atoms.ToArray()); int n = univ.atoms.Count; int m = rotInfos.Count; MatrixByArr[,] J = new MatrixByArr[n, m]; for (int a = 0; a < m; a++) { RotableInfo rotInfo = rotInfos[a]; Vector Ra = GetRa(rotInfo.rotAtoms, coords); double Ma = GetMa(rotInfo.rotAtoms); Vector MaRa = GetMaRa(rotInfo.rotAtoms, coords); MatrixByArr Ia = GetITa(rotInfo.rotAtoms, coords); HDebug.Assert(rotInfo.rotAtoms.Contains(rotInfo.bondedAtom)); Vector sa = coords[rotInfo.bondedAtom.ID]; //Vector Sa = sa * rotInfos[a].rotAtoms.Length; Vector ea; { HashSet <Atom> bondatoms = new HashSet <Atom>(rotInfo.bond.atoms); bondatoms.Remove(rotInfo.bondedAtom); HDebug.Assert(bondatoms.Count == 1); HDebug.Assert(rotInfo.rotAtoms.Contains(bondatoms.First()) == false); ea = (sa - coords[bondatoms.First().ID]).UnitVector(); } Vector Aa; { Vector ea_Rasa = LinAlg.CrossProd3(ea, Ra - sa); Vector IAa = -LinAlg.MV(Ia, ea) + LinAlg.CrossProd3(Ma * R - MaRa, ea_Rasa); Aa = LinAlg.MV(invI, IAa); } { //Vector ea_MaRa_Masa = Vector.CrossProd3(ea, MaRa-Ma*sa); //Vector ea_sa = Vector.CrossProd3(ea, sa); Vector IAa = new double[3]; IAa += -LinAlg.MV(Ia, ea); IAa += LinAlg.CrossProd3(MaRa, LinAlg.CrossProd3(ea, sa)); IAa += LinAlg.CrossProd3(MR, LinAlg.CrossProd3(ea, MaRa - Ma * sa)) / M; Aa = LinAlg.MV(invIII, IAa); } Vector ta = new double[3]; { //Aa = new double[3]; // check "translational Eckart condition" only //ta += (-1/M) * Vector.CrossProd3(Aa, MMR); ta += (-1 / M) * LinAlg.CrossProd3(Aa, MR); ta += (-1 / M) * LinAlg.CrossProd3(ea, MaRa - Ma * sa); } for (int i = 0; i < n; i++) { double mi = univ.atoms[i].Mass; Vector ri = coords[univ.atoms[i].ID]; Vector Jia = new double[3]; //Jia += Vector.CrossProd3(Aa, ri*mi); Jia += LinAlg.CrossProd3(Aa, ri); Jia += ta; J[i, a] = Jia.ToColMatrix(); } foreach (Atom ira in rotInfo.rotAtoms) { int i = ira.ID; Vector ri = coords[univ.atoms[i].ID]; Vector Jia = LinAlg.CrossProd3(ea, ri - sa); J[i, a] += Jia.ToColMatrix(); } //if(Debug.IsDebuggerAttached) //{ // // check Eckart condition // // http://en.wikipedia.org/wiki/Eckart_conditions // ////////////////////////////////////////////////////////////////////// // // 1. translational Eckart condition // // sum{i=1..n}{mi * Jia} = 0 // Vector mJ = EckartConditionTrans(univ, J, a); // Debug.AssertTolerance(0.00000001, mJ); // // 2. rotational Eckart condition // // sum{i=1..n}{mi * r0i x Jia} = 0, // // where 'x' is the cross product // Vector mrJ = EckartConditionRotat(univ, coords, J, a); // Debug.AssertTolerance(0.00000001, mrJ); //} } return(J); }
public void ToFile(string filepath, IList <Vector> coords = null, IList <double> bfactors = null, IList <MatrixByArr> anisous = null, double anisous_scale = 1, bool append = false) { List <string> lines = new List <string>(); if (coords == null) { coords = this.atoms.ListCoord(); } //Debug.Assert(atoms.Length == coords.Count); int idx = 0; foreach (Element element in elements) { //string line = element.line; if (typeof(Atom).IsInstanceOfType(element)) { double x = coords[idx][0]; double y = coords[idx][1]; double z = coords[idx][2]; Atom atom = (Atom)element; atom = Atom.FromString(atom.GetUpdatedLine(x, y, z)); if (bfactors != null) { atom = Atom.FromString(atom.GetUpdatedLineTempFactor(bfactors[idx])); } lines.Add(atom.line); if (anisous != null) { MatrixByArr anisoui = anisous[idx] * anisous_scale; int[,] U = new int[3, 3] { { (int)anisoui[0, 0], (int)anisoui[0, 1], (int)anisoui[0, 2], }, { (int)anisoui[1, 0], (int)anisoui[1, 1], (int)anisoui[1, 2], }, { (int)anisoui[2, 0], (int)anisoui[2, 1], (int)anisoui[2, 2], }, }; Anisou anisou = Anisou.FromAtom(atom, U); lines.Add(anisou.line); } idx++; } else if (typeof(Anisou).IsInstanceOfType(element) && anisous != null) { // skip because it is handled in the "Atom" part } else { lines.Add(element.line); } } if (append == false) { HFile.WriteAllLines(filepath, lines); } else { StringBuilder text = new StringBuilder(); foreach (string line in lines) { text.AppendLine(line); } HFile.AppendAllText(filepath, text.ToString()); } }
//public class CGetHessCoarseResiIterImpl //{ // public List<IterInfo> iterinfos = null; // public HessMatrix H = null; // public Vector F = null; //}; public static HessForcInfo GetCoarseHessForcSubIter (object[] atoms , HessMatrix hess , Vector[] forc , List <int>[] lstNewIdxRemv , double thres_zeroblk , ILinAlg ila , bool cloneH , string[] options // { "pinv(D)" } ) { HessMatrix H = hess; Vector F = forc.ToVector(); ila = null; if (cloneH) { H = H.CloneHess(); } bool process_disp_console = true; if (options != null && options.Contains("print process")) { process_disp_console = true; } bool parallel = true; /// keep only lower triangle of H (lower block triangles) { HashSet <Tuple <int, int, MatrixByArr> > lstUppTrig = new HashSet <Tuple <int, int, MatrixByArr> >(); foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in H.EnumBlocks()) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; if (bc < br) { lstUppTrig.Add(bc_br_bval.ToTuple()); } } foreach (Tuple <int, int, MatrixByArr> bc_br_bval in lstUppTrig) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; HDebug.Assert(bc < br); H.SetBlock(bc, br, null); } } GC.Collect(); List <DateTime> process_time = new List <DateTime>(); //System.Console.WriteLine("begin coarse-graining"); List <IterInfo> iterinfos = new List <IterInfo>(); for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--) { process_time.Clear(); if (process_disp_console) { process_time.Add(DateTime.UtcNow); System.Console.Write(" - {0:000} : ", iter); } //int[] ikeep = lstNewIdxRemv[iter].Item1; int[] iremv = lstNewIdxRemv[iter].ToArray(); int iremv_min = iremv.Min(); int iremv_max = iremv.Max(); HDebug.Assert(H.ColBlockSize == H.RowBlockSize); int blksize = H.ColBlockSize; //HDebug.Assert(ikeep.Max() < blksize); //HDebug.Assert(iremv.Max() < blksize); //HDebug.Assert(iremv.Max()+1 == blksize); //HDebug.Assert(iremv.Max() - iremv.Min() + 1 == iremv.Length); int[] idxkeep = HEnum.HEnumFromTo(0, iremv_min - 1).ToArray(); int[] idxremv = HEnum.HEnumFromTo(iremv_min, iremv_max).ToArray(); //HDebug.Assert(idxkeep.HUnionWith(idxremv).Length == blksize); IterInfo iterinfo = new IterInfo(); iterinfo.sizeHessBlkMat = idxremv.Max() + 1; // H.ColBlockSize; iterinfo.numAtomsRemoved = idxremv.Length; iterinfo.time0 = DateTime.UtcNow; //////////////////////////////////////////////////////////////////////////////////////// // make C sparse double C_density0; double C_density1; { double thres_absmax = thres_zeroblk; C_density0 = 0; List <Tuple <int, int> > lstIdxToMakeZero = new List <Tuple <int, int> >(); foreach (var bc_br_bval in H.EnumBlocksInCols(idxremv)) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; if (br >= iremv_min) { // bc_br is in D, not in C continue; } C_density0++; double absmax_bval = bval.HAbsMax(); if (absmax_bval < thres_absmax) { lstIdxToMakeZero.Add(new Tuple <int, int>(bc, br)); } } C_density1 = C_density0 - lstIdxToMakeZero.Count; foreach (var bc_br in lstIdxToMakeZero) { int bc = bc_br.Item1; int br = bc_br.Item2; HDebug.Assert(bc > br); var Cval = H.GetBlock(bc, br); var Dval = H.GetBlock(bc, bc); var Aval = H.GetBlock(br, br); var Bval = Cval.Tr(); H.SetBlock(bc, br, null); // nCval = Cval -Cval H.SetBlock(bc, bc, Dval + Cval); // nDval = Dval - (-Cval) = Dval + Cval // nBval = Bval -Bval H.SetBlock(br, br, Aval + Bval); // nAval = Aval - (-Bval) = Aval + Bval } iterinfo.numSetZeroBlock = lstIdxToMakeZero.Count; iterinfo.numNonZeroBlock = (int)C_density1; C_density0 /= (idxkeep.Length * idxremv.Length); C_density1 /= (idxkeep.Length * idxremv.Length); } //////////////////////////////////////////////////////////////////////////////////////// // get A, B, C, D HessMatrix A = H; // HessMatrix A = H.SubMatrixByAtoms(false, idxkeep, idxkeep); // HessMatrix B = H.SubMatrixByAtoms(false, idxkeep, idxremv); HessMatrix C; // HessMatrix C = H.SubMatrixByAtoms(false, idxremv, idxkeep, parallel:parallel); HessMatrix D; // HessMatrix D = H.SubMatrixByAtoms(false, idxremv, idxremv, parallel:parallel); Vector nF; Vector nG; { C = H.Zeros(idxremv.Length * 3, idxkeep.Length * 3); D = H.Zeros(idxremv.Length * 3, idxremv.Length * 3); //List<Tuple<int, int, MatrixByArr>> lst_bc_br_bval = H.EnumBlocksInCols(idxremv).ToList(); //foreach(var bc_br_bval in lst_bc_br_bval) foreach (var bc_br_bval in H.EnumBlocksInCols(idxremv)) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; if (bc < br) { HDebug.Assert(false); continue; } H.SetBlock(bc, br, null); if (bc > iremv_max) { HDebug.Assert(false); continue; } if (br > iremv_max) { HDebug.Assert(false); continue; } if (br < iremv_min) { int nc = bc - iremv_min; int nr = br; HDebug.Assert(C.HasBlock(nc, nr) == false); C.SetBlock(nc, nr, bval.CloneT()); } else { int nc = bc - iremv_min; int nr = br - iremv_min; HDebug.Assert(D.HasBlock(nc, nr) == false); D.SetBlock(nc, nr, bval); if (nc != nr) { HDebug.Assert(D.HasBlock(nr, nc) == false); D.SetBlock(nr, nc, bval.Tr()); } } } HDebug.Assert(H.EnumBlocksInCols(idxremv).Count() == 0); nF = new double[idxkeep.Length * 3]; nG = new double[idxremv.Length * 3]; for (int i = 0; i < idxkeep.Length * 3; i++) { nF[i] = F[i]; } for (int i = 0; i < idxremv.Length * 3; i++) { nG[i] = F[i + nF.Size]; } } if (process_disp_console) { process_time.Add(DateTime.UtcNow); int ptc = process_time.Count; System.Console.Write("CD({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes); } //////////////////////////////////////////////////////////////////////////////////////// // Get B.inv(D).C HessMatrix B_invD_C; Vector B_invD_G; { { var BInvDC_BInvDG = Get_BInvDC_BInvDG_WithSqueeze(C, D, nG, process_disp_console , options , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length , parallel: parallel ); B_invD_C = BInvDC_BInvDG.Item1; B_invD_G = BInvDC_BInvDG.Item2; } if (process_disp_console) { process_time.Add(DateTime.UtcNow); int ptc = process_time.Count; System.Console.Write("B.invD.C({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes); } GC.Collect(0); } //////////////////////////////////////////////////////////////////////////////////////// // Get A - B.inv(D).C /// iterinfo.numAddIgnrBlock = A.UpdateAdd(B_invD_C, -1, null, thres_zeroblk/lstNewIdxRemv.Length, parallel:parallel); { HessMatrix __this = A; HessMatrix other = B_invD_C; double _thres_NearZeroBlock = thres_zeroblk / lstNewIdxRemv.Length; int[] _count = new int[1]; int[] _count_ignored = new int[1]; //foreach(var bc_br_bval in other.EnumBlocks()) Action <ValueTuple <int, int, MatrixByArr>, object> func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval, object func_param) { _count[0]++; int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; MatrixByArr other_bmat = bc_br_bval.Item3; if (bc < br) { return; // continue; } if (other_bmat.HAbsMax() <= _thres_NearZeroBlock) { /// other_bmat = other_bmat -other_bmat; /// other_diag = other_diag - (-other_bmat) = other_diag + other_bmat; /// this_diag = this_diat - B_invD_C /// = this_diat - other_diag /// = this_diat - (other_diag + other_bmat) /// = this_diat - other_diag - other_bmat /// = (this_diat - other_bmat) - other_diag /// = (this_diat - other_bmat) - (processed later) /// = (this_diat - other_bmat) MatrixByArr this_diag = __this.GetBlock(bc, bc); MatrixByArr new_diag = this_diag - other_bmat; __this.SetBlockLock(bc, bc, new_diag); other_bmat = null; lock (_count_ignored) _count_ignored[0]++; } if (other_bmat != null) { //if(HDebug.IsDebuggerAttached) //{ // double trace = other_bmat.Trace(); // if(bc != br && bc<2059 && br<2059 && Math.Abs(trace) > 100) // HDebug.Assert(); //} MatrixByArr this_bmat = __this.GetBlock(bc, br); if (this_bmat == null) { this_bmat = new double[3, 3]; } MatrixByArr new_bmat = this_bmat - other_bmat; __this.SetBlockLock(bc, br, new_bmat); } }; if (parallel) { HParallel.ForEach(other.EnumBlocks(), func, null); } else { foreach (var bc_br_bval in other.EnumBlocks()) { func(bc_br_bval, null); } } iterinfo.numAddIgnrBlock = _count_ignored[0]; } if (process_disp_console) { process_time.Add(DateTime.UtcNow); int ptc = process_time.Count; System.Console.Write("A-BinvDC({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes); } //HessMatrix nH = A - B_invD_C; //nH = ((nH + nH.Tr())/2).ToHessMatrix(); //////////////////////////////////////////////////////////////////////////////////////// // Replace A -> H H = A; F = nF - B_invD_G; //////////////////////////////////////////////////////////////////////////////////////// // print iteration log iterinfo.usedMemoryByte = GC.GetTotalMemory(false); iterinfo.time1 = DateTime.UtcNow; iterinfos.Add(iterinfo); if (process_disp_console) { System.Console.Write("summary(makezero {0,5}, nonzero {1,5}, numIgnMul {2,7}, numRemvAtoms {3,3}, {4,5:0.00} min, {5} mb, {6}x{6}, nzeroBlk/Atom {7:0.00}), GC(" , iterinfo.numSetZeroBlock , iterinfo.numNonZeroBlock , iterinfo.numAddIgnrBlock , iterinfo.numAtomsRemoved , iterinfo.compTime.TotalMinutes , iterinfo.usedMemoryByte / (1024 * 1024) , (idxkeep.Length * 3) , ((double)iterinfo.numNonZeroBlock / idxremv.Length) ); } GC.Collect(); if (process_disp_console) { System.Console.WriteLine(")"); } } int numca = H.ColBlockSize - lstNewIdxRemv.HListCount().Sum(); //System.Console.WriteLine("finish coarse-graining"); { int[] idxkeep = HEnum.HEnumCount(numca).ToArray(); H = H.SubMatrixByAtoms(false, idxkeep, idxkeep, false); } { H.MakeNearZeroBlockAsZero(thres_zeroblk); } { var list_bc_br_bval = H.EnumBlocks().ToArray(); Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; HDebug.Assert(bc >= br); if (bc == br) { return; } MatrixByArr bval_tr = bval.Tr(); H.SetBlockLock(br, bc, bval_tr); HDebug.Assert(H.GetBlockLock(bc, br) == bval); }; if (parallel) { HParallel.ForEach(list_bc_br_bval, func); } else { foreach (var bc_br_bval in list_bc_br_bval) { func(bc_br_bval); } } } GC.Collect(); //System.Console.WriteLine("finish resizing"); HDebug.Assert(H.ColSize == H.RowSize); HDebug.Assert(H.ColSize == F.Size); return(new HessForcInfoIter { iterinfos = iterinfos, hess = H, forc = F.ToVectors(3), }); }
public static HessMatrix GetHessAnm(IList <Vector> coords, IEnumerable <Tuple <int, int, double> > enumKij) { if (GetHessAnm_selftest) { GetHessAnm_selftest = false; Vector[] tcoords = new Vector[] { new Vector(0, 0, 0), new Vector(1, 0, 0), new Vector(0, 2, 0), new Vector(0, 0, 3), new Vector(4, 5, 0), new Vector(0, 6, 7), new Vector(8, 0, 9), new Vector(-1, -1, -1), }; Matrix tKij = Matrix.Ones(8, 8); for (int i = 0; i < 8; i++) { tKij[i, i] = 0; } HessMatrix hess0 = GetHessAnm_debug(tcoords, tKij); HessMatrix hess1 = GetHessAnm(tcoords, tKij.HEnumNonZeros()); HDebug.Assert((hess0 - hess1).HAbsMax() == 0); } //Debug.Assert(AnmHessianSelfTest()); int n = coords.Count; HessMatrix hess = null; if (n < 100) { hess = HessMatrixDense.ZerosDense(n * 3, n * 3); } else { hess = HessMatrixSparse.ZerosSparse(n * 3, n * 3); } int numset = 0; foreach (var kij in enumKij) { int i = kij.Item1; int j = kij.Item2; double k_ij = kij.Item3; { if (i == j) { HDebug.Assert(k_ij == 0); continue; } if (coords[j] == null) { continue; } Vector vec_ij = coords[j] - coords[i]; Vector unit_ij = vec_ij.UnitVector(); HDebug.Assert(double.IsNaN(k_ij) == false); if (k_ij == 0) { continue; } MatrixByArr hessij = new double[3, 3]; hessij[0, 0] = -k_ij * unit_ij[0] * unit_ij[0]; hessij[0, 1] = -k_ij * unit_ij[0] * unit_ij[1]; hessij[0, 2] = -k_ij * unit_ij[0] * unit_ij[2]; hessij[1, 0] = -k_ij * unit_ij[1] * unit_ij[0]; hessij[1, 1] = -k_ij * unit_ij[1] * unit_ij[1]; hessij[1, 2] = -k_ij * unit_ij[1] * unit_ij[2]; hessij[2, 0] = -k_ij * unit_ij[2] * unit_ij[0]; hessij[2, 1] = -k_ij * unit_ij[2] * unit_ij[1]; hessij[2, 2] = -k_ij * unit_ij[2] * unit_ij[2]; hess.SetBlock(i, j, hessij); MatrixByArr hessii = hess.GetBlock(i, i) - hessij; hess.SetBlock(i, i, hessii); numset++; } } return(hess); }
public abstract void SetBlockLock(int bc, int br, MatrixByArr bval);
public static CGetHessCoarseResiIterImpl Do (object[] atoms , HessMatrix H , List <int>[] lstNewIdxRemv , double thres_zeroblk , ILinAlg ila , bool cloneH , string[] options ) { //HDebug.ToDo(); ila = null; cloneH = true; if (cloneH) { H = H.CloneHess(); } bool process_disp_console = true; if (options != null && options.Contains("print process")) { process_disp_console = true; } bool parallel = false; /// keep only lower triangle of H (lower block triangles) { HashSet <Tuple <int, int, MatrixByArr> > lstUppTrig = new HashSet <Tuple <int, int, MatrixByArr> >(); foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in H.EnumBlocks()) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; if (bc < br) { lstUppTrig.Add(bc_br_bval.ToTuple()); } } foreach (Tuple <int, int, MatrixByArr> bc_br_bval in lstUppTrig) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; HDebug.Assert(bc < br); H.SetBlock(bc, br, null); } } GC.Collect(); DateTime[] process_time = new DateTime[6]; //System.Console.WriteLine("begin coarse-graining"); List <HessCoarseResiIterInfo> iterinfos = new List <HessCoarseResiIterInfo>(); for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--) { bool lprocess_disp_console = (process_disp_console && iter % 5 == 0); lprocess_disp_console = true; if (lprocess_disp_console) { process_time[0] = DateTime.UtcNow; System.Console.Write(" - {0:000} : ", iter); } //int[] ikeep = lstNewIdxRemv[iter].Item1; HessCoarseResiIterInfo iterinfo = new HessCoarseResiIterInfo(); iterinfo.sizeHessBlkMat = 1; iterinfo.numAtomsRemoved = 1; iterinfo.time0 = DateTime.UtcNow; int _count_update = 0; { HDebug.Assert(lstNewIdxRemv[iter].Count == 1); int iremv = lstNewIdxRemv[iter][0]; HessMatrix A = H; MatrixByArr D = null; double D_absmin = 0; List <int> C_lstbr = new List <int>(); List <MatrixByArr> C_lstbval = new List <MatrixByArr>(); { // get C and D foreach (var(bc, br, bval) in H.EnumBlocksInCols(new int[] { iremv })) { HDebug.Assert(iremv == bc); if (bc == br) { HDebug.Assert(D == null); D = bval; D_absmin = D.HAbsMin(); } else { if (bval.HAbsMin() >= thres_zeroblk) { C_lstbr.Add(br); C_lstbval.Add(bval); } } } // remove C and D { int bc = iremv; H.SetBlock(bc, bc, null); foreach (int br in C_lstbr) { H.SetBlock(bc, br, null); } } } if (lprocess_disp_console) { process_time[1] = process_time[2] = DateTime.UtcNow; System.Console.Write("CD({0:00.00} min), ", (process_time[2] - process_time[0]).TotalMinutes); } double threshold = thres_zeroblk / lstNewIdxRemv.Length; // DD ={ { d00,d01,d02},{ d10,d11,d12},{ d20,d21,d22} }; MatrixForm[DD] // BB ={ { b00,b01,b02},{ b10,b11,b12},{ b20,b21,b22} }; MatrixForm[BB] // CC ={ { c00,c01,c02},{ c10,c11,c12},{ c20,c21,c22} }; MatrixForm[CC] // object[] dbginfo = null; // new object[] { iremv, atoms, H, D, C_lstbr, C_lstbval }; Action <ValueTuple <int, int, MatrixByArr, MatrixByArr> > Update_A_B_invD_C = delegate(ValueTuple <int, int, MatrixByArr, MatrixByArr> info) { int bc = info.Item1; // bc int br = info.Item2; // br MatrixByArr DC = info.Item3; // invDD_CC // XX ={ { x00,x01,x02},{ x10,x11,x12},{ x20,x21,x22} }; MatrixForm[CC] MatrixByArr B = info.Item4; // BB // BB ={ { b00,b01,b02},{ b10,b11,b12},{ b20,b21,b22} }; MatrixForm[BB] //var _iremv = (int)dbginfo[0]; //var _atoms = dbginfo[1] as Universe.Atom[] ; //var _H = dbginfo[2] as HessMatrix ; //var _D = dbginfo[3] as MatrixByArr ; //var _C_lstbr = dbginfo[4] as List<int> ; //var _C_lstbval = dbginfo[5] as List<MatrixByArr>; //MatrixByArr BB_invDD_CC = BB * invDD_CC; double _BDC00 = 0 - B[0, 0] * DC[0, 0] - B[0, 1] * DC[1, 0] - B[0, 2] * DC[2, 0]; // { { b00 x00 +b01 x10 + b02 x20 double _BDC01 = 0 - B[0, 0] * DC[0, 1] - B[0, 1] * DC[1, 1] - B[0, 2] * DC[2, 1]; // , b00 x01 +b01 x11 + b02 x21 double _BDC02 = 0 - B[0, 0] * DC[0, 2] - B[0, 1] * DC[1, 2] - B[0, 2] * DC[2, 2]; // , b00 x02 +b01 x12 + b02 x22 double _BDC10 = 0 - B[1, 0] * DC[0, 0] - B[1, 1] * DC[1, 0] - B[1, 2] * DC[2, 0]; // },{ b10 x00 +b11 x10 + b12 x20 double _BDC11 = 0 - B[1, 0] * DC[0, 1] - B[1, 1] * DC[1, 1] - B[1, 2] * DC[2, 1]; // , b10 x01 +b11 x11 + b12 x21 double _BDC12 = 0 - B[1, 0] * DC[0, 2] - B[1, 1] * DC[1, 2] - B[1, 2] * DC[2, 2]; // , b10 x02 +b11 x12 + b12 x22 double _BDC20 = 0 - B[2, 0] * DC[0, 0] - B[2, 1] * DC[1, 0] - B[2, 2] * DC[2, 0]; // },{ b20 x00 +b21 x10 + b22 x20 double _BDC21 = 0 - B[2, 0] * DC[0, 1] - B[2, 1] * DC[1, 1] - B[2, 2] * DC[2, 1]; // , b20 x01 +b21 x11 + b22 x21 double _BDC22 = 0 - B[2, 0] * DC[0, 2] - B[2, 1] * DC[1, 2] - B[2, 2] * DC[2, 2]; // , b20 x02 +b21 x12 + b22 x22 }} if (A.HasBlockLock(bc, br)) { MatrixByArr A_bc_br = A.GetBlockLock(bc, br); A_bc_br[0, 0] += _BDC00; // A = A + (-B.invD.C) A_bc_br[0, 1] += _BDC01; // A = A + (-B.invD.C) A_bc_br[0, 2] += _BDC02; // A = A + (-B.invD.C) A_bc_br[1, 0] += _BDC10; // A = A + (-B.invD.C) A_bc_br[1, 1] += _BDC11; // A = A + (-B.invD.C) A_bc_br[1, 2] += _BDC12; // A = A + (-B.invD.C) A_bc_br[2, 0] += _BDC20; // A = A + (-B.invD.C) A_bc_br[2, 1] += _BDC21; // A = A + (-B.invD.C) A_bc_br[2, 2] += _BDC22; // A = A + (-B.invD.C) // (small && small && small) == !(large || large || large) bool toosmall = !(Math.Abs(A_bc_br[0, 0]) > threshold || Math.Abs(A_bc_br[0, 1]) > threshold || Math.Abs(A_bc_br[0, 2]) > threshold || Math.Abs(A_bc_br[1, 0]) > threshold || Math.Abs(A_bc_br[1, 1]) > threshold || Math.Abs(A_bc_br[1, 2]) > threshold || Math.Abs(A_bc_br[2, 0]) > threshold || Math.Abs(A_bc_br[2, 1]) > threshold || Math.Abs(A_bc_br[2, 2]) > threshold); if (toosmall) { HDebug.Assert(bc != br); A.SetBlockLock(bc, br, null); } } else { // (small && small && small) == !(large || large || large) bool toosmall = !(Math.Abs(_BDC00) > threshold || Math.Abs(_BDC01) > threshold || Math.Abs(_BDC02) > threshold || Math.Abs(_BDC10) > threshold || Math.Abs(_BDC11) > threshold || Math.Abs(_BDC12) > threshold || Math.Abs(_BDC20) > threshold || Math.Abs(_BDC21) > threshold || Math.Abs(_BDC22) > threshold); if (!toosmall) { MatrixByArr A_bc_br = new double[3, 3] { { _BDC00, _BDC01, _BDC02 } // A = 0 + (-B.invD.C) , { _BDC10, _BDC11, _BDC12 } // A = 0 + (-B.invD.C) , { _BDC20, _BDC21, _BDC22 } // A = 0 + (-B.invD.C) }; A.SetBlockLock(bc, br, A_bc_br); } } System.Threading.Interlocked.Increment(ref _count_update); }; var lstCompInfo = EnumComput(D, C_lstbr, C_lstbval, threshold); if (parallel) { Parallel.ForEach(lstCompInfo, Update_A_B_invD_C); } else { foreach (var info in lstCompInfo) { Update_A_B_invD_C(info); } } //GC.Collect(0); if (lprocess_disp_console) { process_time[4] = DateTime.UtcNow; System.Console.Write("B.invD.C({0:00.00} min), ", (process_time[4] - process_time[3]).TotalMinutes); } H = A; } iterinfo.usedMemoryByte = GC.GetTotalMemory(false); iterinfo.time1 = DateTime.UtcNow; iterinfos.Add(iterinfo); if (lprocess_disp_console) { System.Console.WriteLine("summary(makezero {0,5}, nonzero {1,5}, numIgnMul {2,7}, numRemvAtoms {3,3}, {4,5:0.00} sec, {5} mb, {6}x{6}, nzeroBlk/Atom {7:0.00}, cntUpdateBlk({8}))" , iterinfo.numSetZeroBlock , iterinfo.numNonZeroBlock , iterinfo.numAddIgnrBlock , iterinfo.numAtomsRemoved , iterinfo.compSec , iterinfo.usedMemoryByte / (1024 * 1024) , (0 * 3) , 0//((double)iterinfo.numNonZeroBlock / idxremv.Length) , _count_update ); } } int numca = H.ColBlockSize - lstNewIdxRemv.HListCount().Sum(); //System.Console.WriteLine("finish coarse-graining"); { int[] idxkeep = HEnum.HEnumCount(numca).ToArray(); H = H.SubMatrixByAtoms(false, idxkeep, idxkeep, false); } { H.MakeNearZeroBlockAsZero(thres_zeroblk); } GC.Collect(0); //System.Console.WriteLine("finish resizing"); return(new CGetHessCoarseResiIterImpl { iterinfos = iterinfos, H = H, }); }
private void GetPotentialAndTorForce(List <ForceField.IForceField> frcflds, Vector[] coords , out double energy, out Vector[] forces, out MatrixByArr hessian, out double[] dtor , 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(); 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); }
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 static bool GetHessGnmSelfTest() { if (HDebug.Selftest() == false) { return(true); } Pdb pdb = Pdb.FromPdbid("1MJC"); for (int i = 0; i < pdb.atoms.Length; i++) { HDebug.Assert(pdb.atoms[0].altLoc == pdb.atoms[i].altLoc); HDebug.Assert(pdb.atoms[0].chainID == pdb.atoms[i].chainID); } List <Vector> coords = pdb.atoms.ListCoord(); double cutoff = 13; Matlab.Execute("clear"); Matlab.PutMatrix("x", MatrixByArr.FromRowVectorList(coords).ToArray()); Matlab.PutValue("cutoffR", cutoff); Matlab.Execute(@"% function cx = contactsNew(x, cutoffR) % Contact matrix within cutoff distance. % Author: Guang Song % New: 10/25/2006 % %n = size(x,1); % Method 1: slow %for i=1:n % center = x(i,:); % distSqr(:,i) = sum((x-center(ones(n,1),:)).^2,2); %end %cx = sparse(distSqr<=cutoffR^2); % Method 2: fast! about 28 times faster when array size is 659x3 %tot = zeros(n,n); %for i=1:3 % xi = x(:,ones(n,1)*i); % %tmp = (xi - xi.').^2; % %tot = tot + tmp; % tot = tot + (xi - xi.').^2; %end %cx = sparse(tot<=cutoffR^2); % Method 3: this implementation is the shortest! but sligtly slower than % method 2 %xn = x(:,:,ones(n,1)); % create n copy x %xnp = permute(xn,[3,2,1]); %tot = sum((xn-xnp).^2,2); % sum along x, y, z %cx = sparse(permute(tot,[1,3,2])<=cutoffR^2); % put it into one line like below actually slows it down. Don't do that. %cx = sparse(permute(sum((xn-permute(xn,[3,2,1])).^2,2),[1,3,2])<=cutoffR^2); %Method 4: using function pdist, which I just know % this one line implementation is even faster. 2 times than method 2. cx = sparse(squareform(pdist(x)<=cutoffR)); "); Matlab.Execute(@"% function gnm = kirchhoff(cx) % the returned gnm provide the kirchhoff matrix % cx is the contact map. % Guang Song % 11/09/06 gnm = diag(sum(cx)) - cx; "); Matlab.Execute("gnm = full(gnm);"); Matrix gnm_gsong = Matlab.GetMatrix("gnm"); Matlab.Execute("clear;"); Matrix gnm = GetHessGnm(coords.ToArray(), cutoff); if (gnm_gsong.RowSize != gnm.RowSize) { HDebug.Assert(false); return(false); } if (gnm_gsong.ColSize != gnm.ColSize) { HDebug.Assert(false); return(false); } for (int c = 0; c < gnm.ColSize; c++) { for (int r = 0; r < gnm.RowSize; r++) { if (Math.Abs(gnm_gsong[c, r] - gnm[c, r]) >= 0.00000001) { HDebug.Assert(false); return(false); } } } return(true); }