public Mode[] GetModesMassReduced(bool delhess, ILinAlg la) { Mode[] modes; modes = GetModesMassWeighted(delhess, la); // mass-weighted modes modes.UpdateMassReduced(mass.ToArray()); // mass-reduced modes return(modes); }
public static Mode[] GetModeCoarseBlkmat(Matrix hess, IList <int> idx_heavy, ILinAlg ila) { HDebug.Depreciated("use GetHessCoarseBlkmat() and GetModesFromHess() separately"); Matrix hess_HH = GetHessCoarseBlkmat(hess, idx_heavy, ila); //{ // Matlab.PutMatrix("H", hess); // Matlab.Execute("H = (H + H')/2;"); // // Matlab.PutVector("idx0", idx_heavy.ToArray()); // Matlab.Execute("idx0 = sort([idx0*3+1; idx0*3+2; idx0*3+3]);"); // Matlab.PutValue("idx1", hess.ColSize); // Matlab.Execute("idx1 = setdiff(1:idx1, idx0)';"); // HDebug.Assert(Matlab.GetValueInt("length(union(idx0,idx1))") == hess.ColSize*3); // // Matlab.Execute("A = full(H(idx0,idx0));"); // Matlab.Execute("B = H(idx0,idx1) ;"); // Matlab.Execute("C = H(idx1,idx0) ;"); // Matlab.Execute("D = full(H(idx1,idx1));"); // Matlab.Execute("clear H;"); // // Matlab.Execute("bhess = A - B * inv(D) * C;"); // Matlab.Execute("bhess = (bhess + bhess')/2;"); //} Mode[] modes = GetModesFromHess(hess_HH, ila); return(modes); }
public static HessCoarseResiIter.HessInfoCoarseResiIter GetHessCoarseResiIter_BlockWise (Hess.HessInfo hessinfo , Vector[] coords , ILinAlg ila , int clus_width ///= 18 | (18,500) is good for large sparse proteins , int num_atom_merge ///= 500 | (14,400) is good for small densely packed globular proteins , double thres_zeroblk ///= 0.001 | 0.001 could be fairly good for ssNMA (possibly for sbNMA and NMA, too) , IList <Universe.Atom> keeps , HessCoarseResiIter.IterOption iteropt , params string[] options ) { if (clus_width <= 0) { throw new Exception("clus_width should be > 0"); } HessCoarseResiIter.FuncGetIdxKeepListRemv GetIdxKeepListRemv = delegate(object[] latoms, Vector[] lcoords) { Universe.Atom[] lunivatoms = latoms.HToType(null as Universe.Atom[]); return(HessCoarseResiIter.GetIdxKeepListRemv_ResiCluster2(lunivatoms, lcoords, clus_width, num_atom_merge, keeps)); }; return(HessCoarseResiIter.GetHessCoarseResiIter (hessinfo, coords, GetIdxKeepListRemv, ila, thres_zeroblk , iteropt , options: options )); }
public HessInfo GetSubHessInfoByBlockHess(IList <int> idxs, ILinAlg ila) { // GetSubHessInfoByBlockHess(idxSele, ila, "pinv") Vector idxmass = mass.ToArray().HSelectByIndex(idxs); object[] idxatoms = atoms.HSelectByIndex(idxs); Vector[] idxcoords = coords.HSelectByIndex(idxs); HessMatrix idxhess = null; if (ila != null) { idxhess = Hess.GetHessCoarseBlkmat(hess, idxs, ila); } else { idxhess = Hess.GetHessCoarseBlkmat(hess, idxs); } return(new HessInfo { mass = idxmass, atoms = idxatoms, coords = idxcoords, hess = idxhess, numZeroEigval = numZeroEigval, }); }
public static double[] GetRotAngles(Universe univ , Vector[] coords , Vector[] dcoords , MatrixByArr J , ILinAlg ila ) { Vector dangles; using (ila.NewDisposables()) { Vector R = Vector.FromBlockvector(dcoords); Vector M = univ.GetMasses(3); var RR = ila.ToILMat(R).AddDisposable(); var MM = ila.ToILMat(M).Diag().AddDisposable(); var JJ = ila.ToILMat(J).AddDisposable(); var invJMJ = ila.Inv(JJ.Tr * MM * JJ).AddDisposable(); var AA = invJMJ * JJ.Tr * MM * RR; dangles = AA.ToArray().HToArray1D(); } if (HDebug.False && HDebug.IsDebuggerAttached) { Vector tdangles = GetRotAngles(univ, coords, dcoords, J); HDebug.Assert(0.9999 < (tdangles.Dist / dangles.Dist), (tdangles.Dist / dangles.Dist) < 1.0001); HDebug.Assert(LinAlg.DotProd(tdangles, dangles) / (tdangles.Dist * dangles.Dist) > 0.9999); HDebug.Assert((tdangles - dangles).Dist / tdangles.Dist < 0.0001); } return(dangles); }
public Mode[] GetModesMassWeighted(bool delhess, ILinAlg la) { Matrix mwhess = GetHessMassWeighted(delhess); Mode[] mwmodes = Hess.GetModesFromHess(mwhess, la); return(mwmodes); }
public static HessCoarseResiIter.HessInfoCoarseResiIter GetHessCoarseResiIter_SymrcmBlockWise (Hess.HessInfo hessinfo , Vector[] coords , double?symrcm_filter_blckwise_interact // null (use 1 as default) , ILinAlg ila , int clus_width ///= 18 | (18,500) is good for large sparse proteins , int num_atom_merge ///= 500 | (14,400) is good for small densely packed globular proteins , double thres_zeroblk ///= 0.001 | 0.001 could be fairly good for ssNMA (possibly for sbNMA and NMA, too) , string[] nameToKeep ) { if (clus_width <= 0) { throw new Exception("clus_width should be > 0"); } HessCoarseResiIter.FuncGetIdxKeepListRemv GetIdxKeepListRemv = delegate(object[] latoms, Vector[] lcoords) { Universe.Atom[] lunivatoms = latoms.HToType(null as Universe.Atom[]); return(HessCoarseResiIter.GetIdxKeepListRemv_ResiCluster_SymrcmBlockWise(lunivatoms, lcoords, hessinfo.hess, clus_width, num_atom_merge, symrcm_filter_blckwise_interact, nameToKeep)); }; return(HessCoarseResiIter.GetHessCoarseResiIter (hessinfo, coords, GetIdxKeepListRemv, ila, thres_zeroblk , HessCoarseResiIter.IterOption.Matlab_experimental )); }
public Mode[] GetModes(ILinAlg la) { if (_modes == null) { _modes = Hess.GetModesFromHess(hess, la); } return(_modes); }
public static void Main(string[] args, ILinAlg la) { SelfTest_Program20150111_SparsityVsAccuracy.la = la; string[] hesstypes = new string[] { "NMA", "scrnNMA", "sbNMA", "ssNMA", "eANM", "AA-ANM" }; double[] threszeroblks = new double[] { 0.0001, 0.001, 0.01, 0.1 }; Main(args, hesstypes, threszeroblks); }
public bool CheckModeWithHess(MatrixByArr hess, double[] masses, ILinAlg la, Mode[] modes = null, double tolerance = 0.00001) { if (modes == null) { modes = ToModes(masses); } HessMatrix ohess = new HessMatrixDense { hess = modes.GetHessian(masses, la), }; double corr = HMath.HCorr(hess.ToArray().HToArray1D(), ohess.ToArray().HToArray1D()); System.Console.Write("corr(TestHess,HessVibr:{0} ", corr); { HDebug.Assert(hess.ColSize == ohess.ColSize); HDebug.Assert(hess.RowSize == ohess.RowSize); double ltolerance = hess.ToArray().HAbs().HMax() * tolerance; ltolerance = tolerance; for (int c = 0; c < ohess.ColSize; c++) { for (int r = 0; r < ohess.RowSize; r++) { double v = hess[c, r]; double mwv = ohess[c, r]; double diff = Math.Abs(v - mwv); if (diff >= ltolerance) { return(false); } } } } //{ // Matrix vhess = hess / hess.ToArray().HToArray1D().HVar(); // Matrix vohess = ohess / ohess.ToArray().HToArray1D().HVar(); // // HDebug.Assert(hess.ColSize == ohess.ColSize); // HDebug.Assert(hess.RowSize == ohess.RowSize); // HDebug.Assert(vhess.Size == vohess.Size); // for(int c=0; c<vhess.ColSize; c++) // for(int r=0; r<vhess.RowSize; r++) // { // double v = vhess[c,r]; // double vo = vohess[c,r]; // double diff = Math.Abs(v - vo); // if(diff >= tolerance) // { // HDebug.Assert(false); // return false; // } // } //} return(true); }
public static Mode[] PCA(IList <Vector[]> confs, ref Vector[] meanconf, ILinAlg ila) { if (meanconf == null) { meanconf = new Vector[confs[0].Length]; for (int i = 0; i < meanconf.Length; i++) { Vector meancoord = new double[3]; foreach (Vector[] conf in confs) { meancoord += conf[i]; } meancoord /= confs.Count; meanconf[i] = meancoord; } } int size = meanconf.Length; int size3 = size * 3; int num = confs.Count; Matrix mconfs = Matrix.Zeros(size3, num); Vector vmeanconf = Vector.FromBlockvector(meanconf); for (int r = 0; r < num; r++) { Vector vconf = Vector.FromBlockvector(confs[r]); Vector dvconf = vconf - vmeanconf; for (int c = 0; c < size3; c++) { mconfs[c, r] = dvconf[c]; } } Matrix cov = null; { var CONFS = ila.ToILMat(mconfs); var COV = CONFS * CONFS.Tr; cov = COV.ToArray(); CONFS.Dispose(); COV.Dispose(); } Func <Matrix, Tuple <Matrix, Vector> > fnEig = delegate(Matrix A) { var AA = ila.ToILMat(A); var VVDD = ila.EigSymm(AA); var VV = VVDD.Item1; Vector D = VVDD.Item2; Matrix V = VV.ToArray(); AA.Dispose(); VV.Dispose(); return(new Tuple <Matrix, Vector>(V, D)); }; return(PCA(cov, confs.Count, fnEig)); }
public static HessMatrix GetMulImpl(ILinAlg ila, bool warning, params HessMatrix[] mats) { if (ila != null) { if (HDebug.Selftest()) { Matrix h0 = 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 h1 = HessMatrixDense.FromMatrix(h0); HessMatrix h2 = HessMatrixSparse.FromMatrix(h0); Matrix t0 = Matrix.GetMul(Matrix.GetMul(h1, h1), h1); { Matrix t1 = GetMulImpl(ila, false, h1, h1, h1); double d1 = (t0 - t1).HAbsMax(); HDebug.Assert(0 == d1); Matrix t2 = GetMulImpl(ila, false, h1, h1, h2); double d2 = (t0 - t2).HAbsMax(); HDebug.Assert(0 == d2); Matrix t3 = GetMulImpl(ila, false, h1, h2, h1); double d3 = (t0 - t3).HAbsMax(); HDebug.Assert(0 == d3); Matrix t4 = GetMulImpl(ila, false, h1, h2, h2); double d4 = (t0 - t4).HAbsMax(); HDebug.Assert(0 == d4); Matrix t5 = GetMulImpl(ila, false, h2, h1, h1); double d5 = (t0 - t5).HAbsMax(); HDebug.Assert(0 == d5); Matrix t6 = GetMulImpl(ila, false, h2, h1, h2); double d6 = (t0 - t6).HAbsMax(); HDebug.Assert(0 == d6); Matrix t7 = GetMulImpl(ila, false, h2, h2, h1); double d7 = (t0 - t7).HAbsMax(); HDebug.Assert(0 == d7); Matrix t8 = GetMulImpl(ila, false, h2, h2, h2); double d8 = (t0 - t8).HAbsMax(); HDebug.Assert(0 == d8); } { Matrix t1 = GetMulImpl(null, false, h1, h1, h1); double d1 = (t0 - t1).HAbsMax(); HDebug.Assert(0 == d1); Matrix t2 = GetMulImpl(null, false, h1, h1, h2); double d2 = (t0 - t2).HAbsMax(); HDebug.Assert(0 == d2); Matrix t3 = GetMulImpl(null, false, h1, h2, h1); double d3 = (t0 - t3).HAbsMax(); HDebug.Assert(0 == d3); Matrix t4 = GetMulImpl(null, false, h1, h2, h2); double d4 = (t0 - t4).HAbsMax(); HDebug.Assert(0 == d4); Matrix t5 = GetMulImpl(null, false, h2, h1, h1); double d5 = (t0 - t5).HAbsMax(); HDebug.Assert(0 == d5); Matrix t6 = GetMulImpl(null, false, h2, h1, h2); double d6 = (t0 - t6).HAbsMax(); HDebug.Assert(0 == d6); Matrix t7 = GetMulImpl(null, false, h2, h2, h1); double d7 = (t0 - t7).HAbsMax(); HDebug.Assert(0 == d7); Matrix t8 = GetMulImpl(null, false, h2, h2, h2); double d8 = (t0 - t8).HAbsMax(); HDebug.Assert(0 == d8); } } } HessMatrix mul = null; foreach (HessMatrix mat in mats) { if (mul == null) { mul = mat; } else { mul = GetMulImpl(mul, mat, ila, warning); } } return(mul); }
public static Mode[] GetModesFromHess(Matrix hess, ILinAlg la) { List <Mode> modes; { Matrix V; Vector D; switch (la) { case null: using (new Matlab.NamedLock("")) { Matlab.PutMatrix("H", hess, true); Matlab.Execute("H = (H + H')/2;"); Matlab.Execute("[V,D] = eig(H);"); Matlab.Execute("D = diag(D);"); V = Matlab.GetMatrix("V", true); D = Matlab.GetVector("D", true); } break; default: { var H = la.ToILMat(hess); H = (H + H.Tr) / 2; var VD = la.EigSymm(H); V = VD.Item1.ToMatrix(); D = VD.Item2; H.Dispose(); VD.Item1.Dispose(); } break; } int[] idxs = D.ToArray().HAbs().HIdxSorted(); modes = new List <Mode>(idxs.Length); //foreach(int idx in idxs) for (int th = 0; th < idxs.Length; th++) { int idx = idxs[th]; Mode mode = new Mode { th = (th + 1), eigval = D[idx], eigvec = V.GetColVector(idx) }; modes.Add(mode); } } System.GC.Collect(); return(modes.ToArray()); }
public static Mode[] GetModeMixAnm(IList <Vector> coords , IList <int> lstIdxCa , IList <int> lstIdxAll , ILinAlg la ) { double AaCutoff = 6.0; double AaSprcst = 0.64; double CaCutoff = 13.0; double CaSprcst = 3.10; return(GetModeMixAnm(coords, lstIdxCa, lstIdxAll , CaCutoff, CaSprcst , AaCutoff, AaSprcst , la )); }
public static MatrixByArr GetHessian(this IList <Mode> modes, ILinAlg la) { Vector[] eigvecs = modes.ListEigvec().ToArray(); Vector eigvals = modes.ListEigval().ToArray(); MatrixByArr hess; { var V = la.ToILMat(eigvecs.ToMatrix()); var D = la.ToILMat(eigvals).Diag(); var H = la.Mul(V, D, V.Tr); hess = H.ToArray(); V.Dispose(); D.Dispose(); H.Dispose(); } return(hess); }
public static HessCoarseResiIter.HessInfoCoarseResiIter GetHessCoarseResiIter_SymrcmAtomWise (Hess.HessInfo hessinfo , Vector[] coords , ILinAlg ila , int num_atom_merge ///= 500 | (14,400) is good for small densely packed globular proteins , double thres_zeroblk ///= 0.001 | 0.001 could be fairly good for ssNMA (possibly for sbNMA and NMA, too) , string[] nameToKeep ) { HessCoarseResiIter.FuncGetIdxKeepListRemv GetIdxKeepListRemv = delegate(object[] latoms, Vector[] lcoords) { Universe.Atom[] lunivatoms = latoms.HToType(null as Universe.Atom[]); return(HessCoarseResiIter.GetIdxKeepListRemv_ResiCluster_SymrcmAtomWise(lunivatoms, lcoords, hessinfo.hess, num_atom_merge, thres_zeroblk, nameToKeep)); }; return(HessCoarseResiIter.GetHessCoarseResiIter (hessinfo, coords, GetIdxKeepListRemv, ila, thres_zeroblk , HessCoarseResiIter.IterOption.Matlab_experimental )); }
public static Matrix GetInvSprTensorSymm(Matrix H, Matrix S, ILinAlg ila) { // check H be symmetric HDebug.AssertToleranceMatrix(0.00000001, H - H.Tr()); Matrix invK = GetInvSprTensor(H, S, ila); if (HDebug.IsDebuggerAttached && ila != null) { HDebug.AssertToleranceMatrix(0.00000001, invK - invK.Tr()); // check symmetric var invKK = ila.ToILMat(invK); var VVDD = ila.EigSymm(invKK); foreach (double d in VVDD.Item2) { HDebug.Assert(d > -0.00000001); } } return(invK); }
public static HessCoarseResiIter.HessInfoCoarseResiIter GetHessCoarseResiIter_BlockWise (Hess.HessInfo hessinfo , Vector[] coords , ILinAlg ila , int clus_width ///= 18 | (18,500) is good for large sparse proteins , int num_atom_merge ///= 500 | (14,400) is good for small densely packed globular proteins , double thres_zeroblk ///= 0.001 | 0.001 could be fairly good for ssNMA (possibly for sbNMA and NMA, too) ) { string[] nameToKeep = new string[] { "CA" }; return(GetHessCoarseResiIter_BlockWise (hessinfo , coords , ila , clus_width , num_atom_merge , thres_zeroblk , nameToKeep )); }
public static HessCoarseResiIter.HessInfoCoarseResiIter GetHessCoarseResiIter (Hess.HessInfo hessinfo , Vector[] coords , HessCoarseResiIter.FuncGetIdxKeepListRemv GetIdxKeepListRemv , ILinAlg ila , double thres_zeroblk = 0.001 , HessCoarseResiIter.IterOption iteropt = HessCoarseResiIter.IterOption.Matlab_experimental , string[] options = null ) { return(HessCoarseResiIter.GetHessCoarseResiIter (hessinfo: hessinfo , coords: coords , GetIdxKeepListRemv: GetIdxKeepListRemv , ila: ila , thres_zeroblk: thres_zeroblk , iteropt: iteropt , options: options )); }
public static Mode[] GetModeMixAnm(IList <Vector> coords , IList <int> lstIdxCa , IList <int> lstIdxAll , double CaCutoff, double CaSprcst , double AaCutoff, double AaSprcst , ILinAlg la ) { HessInfo hessinfo = GetHessMixAnm(coords, lstIdxCa, lstIdxAll , CaCutoff, CaSprcst , AaCutoff, AaSprcst ); int[] idxMixed = lstIdxCa.HUnionWith(lstIdxAll); var hessinfoMixed = hessinfo.GetSubHessInfo(idxMixed); Mode[] modesMixed = hessinfoMixed.GetModesMassReduced(true, la); Mode[] modes = modesMixed.ToModeEigvecResized(coords.Count, idxMixed); return(modes); }
//public static OOverlapWeighted OverlapWeightedByFreq(IList<Mode> modes1, IList<Mode> modes2, ILinAlg ila, bool bResetUnitVector, string optSelectOverlap) //{ // Vector weights = new double[modes1.Count]; // for(int i=0; i<weights.Size; i++) // weights[i] = 1/Math.Sqrt(Math.Abs(modes1[i].eigval)); // weights /= weights.Sum(); // // return OverlapWeighted(modes1, modes2, weights.ToArray(), ila, bResetUnitVector, optSelectOverlap); //} public static OOverlapWeighted OverlapWeighted(IList <Mode> modes1, double[] mass1, double[] mass2, IList <Mode> modes2, IList <double> weights, ILinAlg ila, bool bResetUnitVector, string optSelectOverlap) { Matrix soverlap = OverlapSigned(modes1, mass1, mass2, modes2, ila, bResetUnitVector); HDebug.Exception(modes1.Count == weights.Count); int[] idxOverlap1to2; switch (optSelectOverlap) { case "corresponding index": if (modes1.Count != modes2.Count) { throw new HException(); } idxOverlap1to2 = HEnum.HEnumCount(modes1.Count).ToArray(); break; case "best matching overlap": idxOverlap1to2 = new int[modes1.Count]; for (int im = 0; im < modes1.Count; im++) { idxOverlap1to2[im] = 0; for (int k = 0; k < modes2.Count; k++) { if (Math.Abs(soverlap[im, idxOverlap1to2[im]]) < Math.Abs(soverlap[im, k])) { idxOverlap1to2[im] = k; } } } break; default: throw new HException(); } Vector overlap1to2 = new double[modes1.Count]; Vector overlap1to2signed = new double[modes1.Count]; double woverlap = 0; for (int i = 0; i < modes1.Count; i++) { overlap1to2 [i] = Math.Abs(soverlap[i, idxOverlap1to2[i]]); overlap1to2signed[i] = soverlap[i, idxOverlap1to2[i]]; woverlap += weights[i] * overlap1to2[i]; } return(new OOverlapWeighted { soverlap1to2 = soverlap, woverlap = woverlap, weights = weights.ToArray(), overlaps = overlap1to2.ToArray(), sgnoverlaps = overlap1to2signed.ToArray(), idxOverlap1to2 = idxOverlap1to2, modes1 = modes1.ToArray(), modes2 = modes2.ToArray(), }); }
public static OOverlapWeighted OverlapWeightedByEigval(IList <Mode> modes1, double[] mass1, double[] mass2, IList <Mode> modes2, ILinAlg ila, bool bResetUnitVector, string optSelectOverlap) { Vector weights = new double[modes1.Count]; for (int i = 0; i < weights.Size; i++) { weights[i] = 1 / Math.Abs(modes1[i].eigval); } weights /= weights.Sum(); return(OverlapWeighted(modes1, mass1, mass2, modes2, weights.ToArray(), ila, bResetUnitVector, optSelectOverlap)); }
public static OOverlapWeighted OverlapWeightedByEigval(IList <Mode> modes1, IList <Mode> modes2, ILinAlg ila, bool bResetUnitVector, string optSelectOverlap) { return(OverlapWeightedByEigval(modes1, null, null, modes2, ila, bResetUnitVector, optSelectOverlap)); }
public static Matrix OverlapSigned(IList <Mode> modes1, double[] mass1, double[] mass2, IList <Mode> modes2, ILinAlg ila, bool bResetUnitVector) { Matrix mat1; Matrix mat2; string mat12opt = "memory-save"; switch (mat12opt) { case "initial": { Vector[] eigvecs1 = new Vector[modes1.Count]; for (int i = 0; i < modes1.Count; i++) { eigvecs1[i] = modes1[i].eigvec.Clone(); } Vector[] eigvecs2 = new Vector[modes2.Count]; for (int i = 0; i < modes2.Count; i++) { eigvecs2[i] = modes2[i].eigvec.Clone(); } { // 1. Hess // 2. mwHess <- M^-0.5 * H * M^-0.5 // 3. [V,D] <- eig(mwHess) // 4. mrMode <- M^-0.5 * V // // overlap: vi . vj // 1. vi <- M^0.5 * mrMode_i // 2. vj <- M^0.5 * mrMode_j // 3. vi.vj <- dot(vi,vj) // // [ 2 ] [4] [2*4] [ 8] // [ 2 ] [5] [2*5] [10] // M * v = [ 2 ] * [6] = [2*6] = [12] // [ 3 ] [7] [3*7] [21] // [ 3 ] [8] [3*8] [24] // [ 3 ] [9] [3*9] [27] // // V1 <- sqrt(M1) * V1 // V2 <- sqrt(M2) * V2 // 1. get sqrt(mass) 2. for each eigenvector 3 eigveci[j] = eigvec[j] * sqrt_mass[j/3] if (mass1 != null) { double[] mass1sqrt = mass1.HSqrt(); for (int i = 0; i < eigvecs1.Length; i++) { for (int j = 0; j < eigvecs1[i].Size; j++) { eigvecs1[i][j] *= mass1sqrt[j / 3]; } } } if (mass2 != null) { double[] mass2sqrt = mass2.HSqrt(); for (int i = 0; i < eigvecs2.Length; i++) { for (int j = 0; j < eigvecs2[i].Size; j++) { eigvecs2[i][j] *= mass2sqrt[j / 3]; } } } } if (bResetUnitVector) { for (int i = 0; i < modes1.Count; i++) { eigvecs1[i] = eigvecs1[i].UnitVector(); } for (int i = 0; i < modes2.Count; i++) { eigvecs2[i] = eigvecs2[i].UnitVector(); } } mat1 = eigvecs1.ToMatrix(false); HDebug.Assert(mat1.ColSize == eigvecs1.Length); eigvecs1 = null; GC.Collect(0); mat2 = eigvecs2.ToMatrix(true); HDebug.Assert(mat2.RowSize == eigvecs2.Length); eigvecs2 = null; GC.Collect(0); } break; case "memory-save": { int vecsize = modes1[0].eigvec.Size; HDebug.Exception(vecsize == modes1[0].eigvec.Size); HDebug.Exception(vecsize == modes2[0].eigvec.Size); //Vector[] eigvecs1 = new Vector[modes1.Count]; for(int i=0; i<modes1.Count; i++) eigvecs1[i] = modes1[i].eigvec.Clone(); //if(mass1 != null) { double[] mass1sqrt = mass1.HSqrt(); for(int i=0; i<modes1.Count; i++) for(int j=0; j<eigvecs1[i].Size; j++) eigvecs1[i][j] *= mass1sqrt[j/3]; } //if(bResetUnitVector) for(int i=0; i<modes1.Count; i++) eigvecs1[i] = eigvecs1[i].UnitVector(); //mat1 = eigvecs1.ToMatrix(false); HDebug.Assert(mat1.ColSize == modes1.Count); eigvecs1 = null; GC.Collect(0); mat1 = Matrix.Zeros(modes1.Count, vecsize); double[] mass1sqrt = null; if (mass1 != null) { mass1sqrt = mass1.HSqrt(); } for (int i = 0; i < modes1.Count; i++) { Vector eigvecs1i = modes1[i].eigvec.Clone(); if (mass1 != null) { for (int j = 0; j < eigvecs1i.Size; j++) { eigvecs1i[j] *= mass1sqrt[j / 3]; } } if (bResetUnitVector) { eigvecs1i = eigvecs1i.UnitVector(); } for (int j = 0; j < eigvecs1i.Size; j++) { mat1[i, j] = eigvecs1i[j]; } } HDebug.Assert(mat1.ColSize == modes1.Count); GC.Collect(0); //Vector[] eigvecs2 = new Vector[modes2.Count]; for(int i=0; i<modes2.Count; i++) eigvecs2[i] = modes2[i].eigvec.Clone(); //if(mass2 != null) { double[] mass2sqrt = mass2.HSqrt(); for(int i=0; i<modes2.Count; i++) for(int j=0; j<eigvecs2[i].Size; j++) eigvecs2[i][j] *= mass2sqrt[j/3]; } //if(bResetUnitVector) for(int i=0; i<modes2.Count; i++) eigvecs2[i] = eigvecs2[i].UnitVector(); //mat2 = eigvecs2.ToMatrix(true ); HDebug.Assert(mat2.RowSize == modes2.Count); eigvecs2 = null; GC.Collect(0); mat2 = Matrix.Zeros(vecsize, modes2.Count); double[] mass2sqrt = null; if (mass2 != null) { mass2sqrt = mass2.HSqrt(); } for (int i = 0; i < modes2.Count; i++) { Vector eigvecs2i = modes2[i].eigvec.Clone(); if (mass2 != null) { for (int j = 0; j < eigvecs2i.Size; j++) { eigvecs2i[j] *= mass2sqrt[j / 3]; } } if (bResetUnitVector) { eigvecs2i = eigvecs2i.UnitVector(); } for (int j = 0; j < eigvecs2i.Size; j++) { mat2[j, i] = eigvecs2i[j]; } } HDebug.Assert(mat2.RowSize == modes2.Count); GC.Collect(0); } break; default: throw new NotImplementedException(); } HDebug.Assert(mat1.RowSize == mat2.ColSize); Matrix overlap = null; if (ila != null) { overlap = ila.Mul(mat1, mat2); } else { overlap = Matlab.ila.Mul(mat1, mat2); } mat1 = mat2 = null; GC.Collect(0); //overlap.UpdateAbs(); if (HDebug.IsDebuggerAttached) { double[] sum_c2 = new double[overlap.ColSize]; double[] sum_r2 = new double[overlap.RowSize]; for (int c = 0; c < overlap.ColSize; c++) { for (int r = 0; r < overlap.RowSize; r++) { double v = overlap[c, r]; double v2 = v * v; HDebug.Assert(v2 <= 1.00000000001); sum_c2[c] += v2; sum_r2[r] += v2; } } for (int c = 0; c < overlap.ColSize; c++) { HDebug.AssertTolerance(0.00001, sum_c2[c] - 1.0); } for (int r = 0; r < overlap.RowSize; r++) { HDebug.AssertTolerance(0.00001, sum_r2[r] - 1.0); } } return(overlap); }
public static Matrix OverlapSigned(IList <Mode> modes1, IList <Mode> modes2, ILinAlg ila, bool bResetUnitVector) { return(OverlapSigned(modes1, null, null, modes2, ila, bResetUnitVector)); }
public static (List <(double freq, double dovlp)> freq1_dovlp, List <(double freq, double dovlp)> freq2_dovlp) DegeneratcyOverlap (IList <Mode> modes1, double[] mass1, double[] mass2, IList <Mode> modes2 , ILinAlg ila, bool bResetUnitVector , double degeneracy_tolerance // 3.0 , Matrix overlapsigned = null ) { if (overlapsigned == null) { overlapsigned = HBioinfo.OverlapSigned(modes1, mass1, mass2, modes2, ila, bResetUnitVector); } double[] freqs1 = modes1.ListFreq(); double[] freqs2 = modes2.ListFreq(); bool isfreqssorted = true; { for (int i = 1; i < freqs1.Length; i++) { isfreqssorted = isfreqssorted && (freqs1[i - 1] <= freqs1[i]); // ( sorted ) or ( freqs1[i-1] is close to zero ) } for (int i = 1; i < freqs2.Length; i++) { isfreqssorted = isfreqssorted && (freqs2[i - 1] <= freqs2[i]); // ( sorted ) or ( freqs2[i-1] is close to zero ) } } int[] idx1sorted = null; int[] idx2sorted = null; if (isfreqssorted == false) { idx1sorted = freqs1.HIdxSorted(); idx2sorted = freqs2.HIdxSorted(); modes1 = modes1.HSelectByIndex(idx1sorted); modes2 = modes2.HSelectByIndex(idx2sorted); if (mass1 != null) { HDebug.Assert(mass1.Length == idx1sorted.Length); mass1 = mass1.HSelectByIndex(idx1sorted); } if (mass2 != null) { HDebug.Assert(mass2.Length == idx2sorted.Length); mass2 = mass2.HSelectByIndex(idx2sorted); } freqs1 = modes1.ListFreq(); freqs2 = modes2.ListFreq(); overlapsigned = HBioinfo.OverlapSigned(modes1, mass1, mass2, modes2, ila, bResetUnitVector); } if (HDebug.IsDebuggerAttached) { for (int i = 1; i < freqs1.Length; i++) { HDebug.Assert(freqs1[i - 1] <= freqs1[i]); } for (int i = 1; i < freqs2.Length; i++) { HDebug.Assert(freqs2[i - 1] <= freqs2[i]); } } List <(double freq, double dovlp)> freq1_dovlp = new List <(double, double)>(); for (int i1 = 0; i1 < freqs1.Length; i1++) { double freq = freqs1[i1]; int i2a = Array.BinarySearch(freqs2, freq - degeneracy_tolerance); int i2b = Array.BinarySearch(freqs2, freq + degeneracy_tolerance); if (i2a == i2b) { freq1_dovlp.Add((freqs1[i1], 0)); continue; } if (i2a < 0) { i2a = ~i2a; } if (i2b < 0) { i2b = ~i2b; } HDebug.Assert(i2a < i2b); double dovlp = 0; for (int i2 = i2a; i2 < i2b; i2++) { dovlp += overlapsigned[i1, i2] * overlapsigned[i1, i2]; } freq1_dovlp.Add((freqs1[i1], dovlp)); } List <(double freq, double dovlp)> freq2_dovlp = new List <(double, double)>(); for (int i2 = 0; i2 < freqs2.Length; i2++) { double freq = freqs2[i2]; int i1a = Array.BinarySearch(freqs1, freq - degeneracy_tolerance); int i1b = Array.BinarySearch(freqs1, freq + degeneracy_tolerance); if (i1a == i1b) { freq2_dovlp.Add((freqs2[i2], 0)); continue; } if (i1a < 0) { i1a = ~i1a; } if (i1b < 0) { i1b = ~i1b; } HDebug.Assert(i1a < i1b); double dovlp = 0; for (int i1 = i1a; i1 < i1b; i1++) { dovlp += overlapsigned[i1, i2] * overlapsigned[i1, i2]; } freq2_dovlp.Add((freqs2[i2], dovlp)); } if (HDebug.IsDebuggerAttached) { HDebug.Assert(freqs1.Length == freq1_dovlp.Count); HDebug.Assert(freqs2.Length == freq2_dovlp.Count); for (int i = 0; i < freqs1.Length; i++) { HDebug.Assert(freqs1[i] == freq1_dovlp[i].freq); } for (int i = 0; i < freqs2.Length; i++) { HDebug.Assert(freqs2[i] == freq2_dovlp[i].freq); } } return(freq1_dovlp, freq2_dovlp); }
public static MatrixByArr GetHessian(this IList <Mode> modes, IList <double> masses, ILinAlg la) { /// mode.eigval = mweigval /// mode.eigvec = mass^-0.5 * mweigvec /// /// W = [mode(1).eigvec, mode(2).eigvec, ... ] /// M = masses /// D = diag([mode(1).eigval, mode(2).eigval, ...]) /// /// mwH = M^-0.5 H M^-0.5 /// [V,D] = eig(mwH) /// mode.eigval == D /// mode.eigvec == M^-0.5 V = W /// /// W D W' = M^-0.5 V D V M^-0.5 /// = M^-0.5 mwH M^-0.5 /// = M^-0.5 (M^-0.5 H M^-0.5) M^-0.5 /// = M^-1 H M^-1 /// H = M (M^-1 H M^-1) M /// = M (W D W') M /// = (M W) D (M W)' HDebug.Assert(modes.CheckModeMassReduced(masses.ToArray(), la, 0.000001)); Vector[] mws = modes.ListEigvec().ToArray(); for (int iv = 0; iv < mws.Length; iv++) { for (int i = 0; i < mws[iv].Size; i++) { mws[iv][i] = mws[iv][i] * masses[i / 3]; } } Vector ds = modes.ListEigval().ToArray(); MatrixByArr hess; { var MW = la.ToILMat(mws.ToMatrix()); var D = la.ToILMat(ds).Diag(); var H = la.Mul(MW, D, MW.Tr); hess = H.ToArray(); MW.Dispose(); D.Dispose(); H.Dispose(); } return(hess); }
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, }); }
public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_Matlab_IterLowerTri (object[] atoms , HessMatrix H , List <int>[] lstNewIdxRemv , double thres_zeroblk , ILinAlg ila , bool cloneH , string[] options // { "pinv(D)" } ) { 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 <HessCoarseResiIterInfo> iterinfos = new List <HessCoarseResiIterInfo>(); 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); HessCoarseResiIterInfo iterinfo = new HessCoarseResiIterInfo(); 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); { 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; 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); } 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; { { B_invD_C = GetHessCoarseResiIterImpl_Matlab_IterLowerTri_Get_BInvDC(A, C, D, process_disp_console , options , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length , parallel: parallel ); } 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> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval) { _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) { 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); } else { foreach (var bc_br_bval in other.EnumBlocks()) { func(bc_br_bval); } } 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; //////////////////////////////////////////////////////////////////////////////////////// // 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); } GC.Collect(); //System.Console.WriteLine("finish resizing"); return(new CGetHessCoarseResiIterImpl { iterinfos = iterinfos, H = H, }); }
public static bool CheckModeMassReduced(this IList <Mode> modes, double[] masses, ILinAlg la, double tolerance = 0.000000001) { Vector[] mweigvecs = modes.GetMassReduced(masses.HInv()).ListEigvec().ToArray(); MatrixByArr chkmat; { var V = la.ToILMat(mweigvecs.ToMatrix()); var VV = V.Tr * V; chkmat = VV.ToArray(); V.Dispose(); VV.Dispose(); } HDebug.Assert(chkmat.ColSize == chkmat.RowSize); for (int i = 0; i < chkmat.ColSize; i++) { if (Math.Abs(chkmat[i, i] - 1) >= tolerance) { /// not normal return(false); } chkmat[i, i] = 0; } for (int c = 0; c < chkmat.ColSize; c++) { if (modes[c].eigval == 0) { continue; } for (int r = 0; r < chkmat.RowSize; r++) { if (modes[r].eigval == 0) { continue; } double v = chkmat[c, r]; if (Math.Abs(v) >= tolerance) { /// not orthogonal return(false); } } } return(true); }