예제 #1
0
 public static HessMatrix operator-(HessMatrix left, HessMatrix right)
 {
     HessMatrix mat = left.CloneHess(); mat.UpdateAdd(right, -1, null, 0); return(mat);
 }
예제 #2
0
 public static HessRTB GetHessRTB(HessMatrix hess, Vector[] coords, double[] masses, IList <int[]> blocks, string opt)
 {
     return(BuilderHessRTB.GetHessRTB(hess, coords, masses, blocks, opt));
 }
예제 #3
0
            public static Vector[] ToOrthonormal(Vector[] coords, double[] masses, int[] block, Vector[] PBlk)
            {
                if (HDebug.IsDebuggerAttached)
                #region check if elements in non-block are zeros.
                {
                    int leng = coords.Length;
                    foreach (int i in HEnum.HEnumCount(leng).HEnumExcept(block.HToHashSet()))
                    {
                        for (int r = 0; r < PBlk.Length; r++)
                        {
                            int c0 = i * 3;
                            HDebug.Assert(PBlk[r][c0 + 0] == 0);
                            HDebug.Assert(PBlk[r][c0 + 1] == 0);
                            HDebug.Assert(PBlk[r][c0 + 2] == 0);
                        }
                    }
                }
                #endregion

                Matrix Pmat = new double[block.Length * 3, PBlk.Length];
                for (int r = 0; r < PBlk.Length; r++)
                {
                    for (int i = 0; i < block.Length; i++)
                    {
                        int i0 = i * 3;
                        int c0 = block[i] * 3;
                        Pmat[i0 + 0, r] = PBlk[r][c0 + 0];
                        Pmat[i0 + 1, r] = PBlk[r][c0 + 1];
                        Pmat[i0 + 2, r] = PBlk[r][c0 + 2];
                    }
                }

                using (new Matlab.NamedLock(""))
                {
                    Matlab.PutValue("n", PBlk.Length);
                    Matlab.PutMatrix("P", Pmat);
                    Matlab.Execute("[U,S,V] = svd(P);");
                    Matlab.Execute("U = U(:,1:n);");
                    if (HDebug.IsDebuggerAttached)
                    {
                        Matlab.Execute("SV = S(1:n,1:n)*V';");
                        double err = Matlab.GetValue("max(max(abs(P - U*SV)))");
                        HDebug.Assert(Math.Abs(err) < 0.00000001);
                    }
                    Pmat = Matlab.GetMatrix("U");
                }

                Vector[] PBlkOrth = new Vector[PBlk.Length];
                for (int r = 0; r < PBlk.Length; r++)
                {
                    Vector PBlkOrth_r = new double[PBlk[r].Size];
                    for (int i = 0; i < block.Length; i++)
                    {
                        int i0 = i * 3;
                        int c0 = block[i] * 3;
                        PBlkOrth_r[c0 + 0] = Pmat[i0 + 0, r];
                        PBlkOrth_r[c0 + 1] = Pmat[i0 + 1, r];
                        PBlkOrth_r[c0 + 2] = Pmat[i0 + 2, r];
                    }
                    PBlkOrth[r] = PBlkOrth_r;
                }

                if (HDebug.IsDebuggerAttached)
                #region checi the orthonormal condition, and rot/trans condition (using ANM)
                {
                    {   // check if all trans/rot modes are orthonormal
                        for (int i = 0; i < PBlkOrth.Length; i++)
                        {
                            HDebug.Exception(Math.Abs(PBlkOrth[i].Dist - 1) < 0.00000001);
                            for (int j = i + 1; j < PBlkOrth.Length; j++)
                            {
                                double dot = LinAlg.VtV(PBlkOrth[i], PBlkOrth[j]);
                                HDebug.Exception(Math.Abs(dot) < 0.00000001);
                            }
                        }
                    }
                    {   // check if this is true rot/trans modes using ANM
                        Vector[] anmcoords = coords.HClone();
                        int      leng      = coords.Length;
                        foreach (int i in HEnum.HEnumCount(leng).HEnumExcept(block.HToHashSet()))
                        {
                            anmcoords[i] = null;
                        }
                        HessMatrix H = GetHessAnm(anmcoords, 100);
                        Matrix     PHP;
                        using (new Matlab.NamedLock(""))
                        {
                            Matlab.PutSparseMatrix("H", H.GetMatrixSparse(), 3, 3);
                            Matlab.PutMatrix("P", PBlkOrth.ToMatrix(true));
                            PHP = Matlab.GetMatrix("P'*H*P");
                        }
                        double maxerr = PHP.HAbsMax();
                        HDebug.Exception(Math.Abs(maxerr) < 0.00000001);
                    }
                }
                #endregion

                return(PBlkOrth);
            }
예제 #4
0
        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);
        }
예제 #5
0
            public static HessInfoCoarseResiIter GetHessCoarseResiIter
                (Hess.HessInfo hessinfo
                , Vector[] coords
                , FuncGetIdxKeepListRemv GetIdxKeepListRemv
                , ILinAlg ila
                , double thres_zeroblk = 0.001
                , IterOption iteropt   = IterOption.Matlab_experimental
                , string[] options     = null
                )
            {
                bool rediag = true;

                HessMatrix H = null;

                List <int>[] lstNewIdxRemv = null;
                int          numca         = 0;

                double[] reMass   = null;
                object[] reAtoms  = null;
                Vector[] reCoords = null;
                Tuple <int[], int[][]> idxKeepRemv = null;

                //System.Console.WriteLine("begin re-indexing hess");
                {
                    object[] atoms = hessinfo.atoms;
                    idxKeepRemv = GetIdxKeepListRemv(atoms, coords);
                    int[]   idxKeep  = idxKeepRemv.Item1;
                    int[][] idxsRemv = idxKeepRemv.Item2;
                    {
                        List <int> check = new List <int>();
                        check.AddRange(idxKeep);
                        foreach (int[] idxRemv in idxsRemv)
                        {
                            check.AddRange(idxRemv);
                        }
                        check = check.HToHashSet().ToList();
                        if (check.Count != coords.Length)
                        {
                            throw new Exception("the re-index contains the duplicated atoms or the missing atoms");
                        }
                    }
                    List <int> idxs = new List <int>();
                    idxs.AddRange(idxKeep);
                    foreach (int[] idxRemv in idxsRemv)
                    {
                        idxs.AddRange(idxRemv);
                    }
                    HDebug.Assert(idxs.Count == idxs.HToHashSet().Count);

                    H        = hessinfo.hess.ReshapeByAtom(idxs);
                    numca    = idxKeep.Length;
                    reMass   = hessinfo.mass.ToArray().HSelectByIndex(idxs);
                    reAtoms  = hessinfo.atoms.ToArray().HSelectByIndex(idxs);
                    reCoords = coords.HSelectByIndex(idxs);

                    int nidx = idxKeep.Length;
                    lstNewIdxRemv = new List <int> [idxsRemv.Length];
                    for (int i = 0; i < idxsRemv.Length; i++)
                    {
                        lstNewIdxRemv[i] = new List <int>();
                        foreach (var idx in idxsRemv[i])
                        {
                            lstNewIdxRemv[i].Add(nidx);
                            nidx++;
                        }
                    }
                    HDebug.Assert(nidx == lstNewIdxRemv.Last().Last() + 1);
                    HDebug.Assert(nidx == idxs.Count);
                }
                GC.Collect(0);
                HDebug.Assert(numca == H.ColBlockSize - lstNewIdxRemv.HListCount().Sum());

                //if(bool.Parse("false"))
                {
                    if (bool.Parse("false"))
                    #region
                    {
                        int[]      idxKeep  = idxKeepRemv.Item1;
                        int[][]    idxsRemv = idxKeepRemv.Item2;
                        Pdb.Atom[] pdbatoms = hessinfo.atomsAsUniverseAtom.ListPdbAtoms();
                        Pdb.ToFile(@"C:\temp\coarse-keeps.pdb", pdbatoms.HSelectByIndex(idxKeep), false);
                        if (HFile.Exists(@"C:\temp\coarse-graining.pdb"))
                        {
                            HFile.Delete(@"C:\temp\coarse-graining.pdb");
                        }
                        foreach (int[] idxremv in idxsRemv.Reverse())
                        {
                            List <Pdb.Element> delatoms = new List <Pdb.Element>();
                            foreach (int idx in idxremv)
                            {
                                if (pdbatoms[idx] == null)
                                {
                                    continue;
                                }
                                string   line    = pdbatoms[idx].GetUpdatedLine(coords[idx]);
                                Pdb.Atom delatom = Pdb.Atom.FromString(line);
                                delatoms.Add(delatom);
                            }
                            Pdb.ToFile(@"C:\temp\coarse-graining.pdb", delatoms.ToArray(), true);
                        }
                    }
                    #endregion

                    if (bool.Parse("false"))
                    #region
                    {
                        // export matrix to matlab, so the matrix can be checked in there.
                        int[] idxca  = HEnum.HEnumCount(numca).ToArray();
                        int[] idxoth = HEnum.HEnumFromTo(numca, coords.Length - 1).ToArray();
                        Matlab.Register(@"C:\temp\");
                        Matlab.PutSparseMatrix("H", H.GetMatrixSparse(), 3, 3);
                        Matlab.Execute("figure; spy(H)");
                        Matlab.Clear();
                    }
                    #endregion

                    if (bool.Parse("false"))
                    #region
                    {
                        HDirectory.CreateDirectory(@"K:\temp\$coarse-graining\");
                        {   // export original hessian matrix
                            List <int> cs = new List <int>();
                            List <int> rs = new List <int>();
                            foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in hessinfo.hess.EnumBlocks())
                            {
                                cs.Add(bc_br_bval.Item1);
                                rs.Add(bc_br_bval.Item2);
                            }
                            Matlab.Clear();
                            Matlab.PutVector("cs", cs.ToArray());
                            Matlab.PutVector("rs", rs.ToArray());
                            Matlab.Execute("hess = sparse(cs+1, rs+1, ones(size(cs)));");
                            Matlab.Execute("hess = float(hess);");
                            Matlab.Execute("figure; spy(hess)");
                            Matlab.Execute("cs = int32(cs+1);");
                            Matlab.Execute("rs = int32(rs+1);");
                            Matlab.Execute(@"save('K:\temp\$coarse-graining\hess-original.mat', 'cs', 'rs', '-v6');");
                            Matlab.Clear();
                        }
                        {   // export reshuffled hessian matrix
                            List <int> cs = new List <int>();
                            List <int> rs = new List <int>();
                            foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in H.EnumBlocks())
                            {
                                cs.Add(bc_br_bval.Item1);
                                rs.Add(bc_br_bval.Item2);
                            }
                            Matlab.Clear();
                            Matlab.PutVector("cs", cs.ToArray());
                            Matlab.PutVector("rs", rs.ToArray());
                            Matlab.Execute("H = sparse(cs+1, rs+1, ones(size(cs)));");
                            Matlab.Execute("H = float(H);");
                            Matlab.Execute("figure; spy(H)");
                            Matlab.Execute("cs = int32(cs+1);");
                            Matlab.Execute("rs = int32(rs+1);");
                            Matlab.Execute(@"save('K:\temp\$coarse-graining\hess-reshuffled.mat', 'cs', 'rs', '-v6');");
                            Matlab.Clear();
                        }
                    }
                    #endregion

                    if (bool.Parse("false"))
                    #region
                    {
                        int[] idxca  = HEnum.HEnumCount(numca).ToArray();
                        int[] idxoth = HEnum.HEnumFromTo(numca, coords.Length - 1).ToArray();

                        HessMatrix A = H.SubMatrixByAtoms(false, idxca, idxca);
                        HessMatrix B = H.SubMatrixByAtoms(false, idxca, idxoth);
                        HessMatrix C = H.SubMatrixByAtoms(false, idxoth, idxca);
                        HessMatrix D = H.SubMatrixByAtoms(false, idxoth, idxoth);
                        Matlab.Clear();
                        Matlab.PutSparseMatrix("A", A.GetMatrixSparse(), 3, 3);
                        Matlab.PutSparseMatrix("B", B.GetMatrixSparse(), 3, 3);
                        Matlab.PutSparseMatrix("C", C.GetMatrixSparse(), 3, 3);
                        Matlab.PutSparseMatrix("D", D.GetMatrixSparse(), 3, 3);
                        Matlab.Clear();
                    }
                    #endregion
                }

                List <HessCoarseResiIterInfo> iterinfos = null;
                {
                    object[] atoms = reAtoms; // reAtoms.HToType(null as Universe.Atom[]);
                    CGetHessCoarseResiIterImpl info = null;
                    switch (iteropt)
                    {
                    case IterOption.ILinAlg_20150329: info = GetHessCoarseResiIterImpl_ILinAlg_20150329(H, lstNewIdxRemv, thres_zeroblk, ila, false);                    break;

                    case IterOption.ILinAlg: info = GetHessCoarseResiIterImpl_ILinAlg(H, lstNewIdxRemv, thres_zeroblk, ila, false);                             break;

                    case IterOption.Matlab: info = GetHessCoarseResiIterImpl_Matlab(atoms, H, lstNewIdxRemv, thres_zeroblk, ila, false, options);              break;

                    case IterOption.Matlab_experimental: info = GetHessCoarseResiIterImpl_Matlab_experimental(atoms, H, lstNewIdxRemv, thres_zeroblk, ila, false, options); break;

                    case IterOption.Matlab_IterLowerTri: info = GetHessCoarseResiIterImpl_Matlab_IterLowerTri(atoms, H, lstNewIdxRemv, thres_zeroblk, ila, false, options); break;

                    case IterOption.LinAlg_IterLowerTri: info = GetHessCoarseResiIterImpl_LinAlg_IterLowerTri.Do(atoms, H, lstNewIdxRemv, thres_zeroblk, ila, false, options); break;
                    }
                    ;
                    H         = info.H;
                    iterinfos = info.iterinfos;
                }
                //{
                //    var info = GetHessCoarseResiIterImpl_Matlab(H, lstNewIdxRemv, thres_zeroblk);
                //    H = info.H;
                //}
                GC.Collect(0);

                if (HDebug.IsDebuggerAttached)
                {
                    int   nidx  = 0;
                    int[] ikeep = idxKeepRemv.Item1;
                    foreach (int idx in ikeep)
                    {
                        bool equal = object.ReferenceEquals(hessinfo.atoms[idx], reAtoms[nidx]);
                        if (equal == false)
                        {
                            HDebug.Assert(false);
                        }
                        HDebug.Assert(equal);
                        nidx++;
                    }
                }

                if (rediag)
                {
                    H = H.CorrectHessDiag();
                }
                //System.Console.WriteLine("finish fixing diag");

                return(new HessInfoCoarseResiIter
                {
                    hess = H,
                    mass = reMass.HSelectCount(numca),
                    atoms = reAtoms.HSelectCount(numca),
                    coords = reCoords.HSelectCount(numca),
                    numZeroEigval = 6,
                    iterinfos = iterinfos,
                });
            }
예제 #6
0
            public static HessMatrix GetHessElec(IList <Vector> coords, IEnumerable <Universe.Nonbonded14> nonbonded14s, HessMatrix hessian)
            {
                double ee = 80;

                return(GetHessElec(coords, nonbonded14s, hessian, ee));
            }
예제 #7
0
            public Mode[] GetModesMassReduced(bool delhess, int?numModeReturn, Dictionary <string, object> secs)
            {
                HessMatrix       mwhess_ = GetHessMassWeighted(delhess);
                IMatrix <double> mwhess  = mwhess_;
                bool             bsparse = (mwhess_ is HessMatrixSparse);

                Mode[] modes;
                using (new Matlab.NamedLock(""))
                {
                    string msg = "";
                    {
                        if (bsparse)
                        {
                            Matlab.PutSparseMatrix("V", mwhess_.GetMatrixSparse(), 3, 3);
                        }
                        else
                        {
                            Matlab.PutMatrix("V", ref mwhess, true, true);
                        }
                    }
                    msg += Matlab.Execute("tic;");
                    msg += Matlab.Execute("V = (V+V')/2;                   "); // make symmetric
                    {                                                          // eigen-decomposition
                        if (bsparse)
                        {
                            if (numModeReturn != null)
                            {
                                int    numeig = numModeReturn.Value;
                                string cmd    = "eigs(V," + numeig + ",'sm')";
                                msg += Matlab.Execute("[V,D] = " + cmd + ";        ");
                            }
                            else
                            {
                                msg += Matlab.Execute("[V,D] = eig(full(V));         ");
                            }
                        }
                        else
                        {
                            msg += Matlab.Execute("[V,D] = eig(V);         ");
                        }
                    }
                    msg += Matlab.Execute("tm=toc;                         ");
                    if (secs != null)
                    {
                        int    numcore = Matlab.Environment.NumCores;
                        double tm      = Matlab.GetValue("tm");
                        secs.Clear();
                        secs.Add("num cores", numcore);
                        secs.Add("secs multi-threaded", tm);
                        secs.Add("secs estimated single-threaded", tm * Math.Sqrt(numcore));
                        /// x=[]; for i=1:20; tic; H=rand(100*i); [V,D]=eig(H+H'); xx=toc; x=[x;i,xx]; fprintf('%d, %f\n',i,xx); end; x
                        ///
                        /// http://www.mathworks.com/help/matlab/ref/matlabwindows.html
                        ///     run matlab in single-thread: matlab -nodesktop -singleCompThread
                        ///                    multi-thread: matlab -nodesktop
                        ///
                        /// my computer, single thread: cst1={0.0038,0.0106,0.0277,0.0606,0.1062,0.1600,0.2448,0.3483,0.4963,0.6740,0.9399,1.1530,1.4568,1.7902,2.1794,2.6387,3.0510,3.6241,4.2203,4.8914};
                        ///                    2 cores: cst2={0.0045,0.0098,0.0252,0.0435,0.0784,0.1203,0.1734,0.2382,0.3316,0.4381,0.5544,0.6969,1.0170,1.1677,1.4386,1.7165,2.0246,2.4121,2.8124,3.2775};
                        ///                      scale: (cst1.cst2)/(cst1.cst1)              = 0.663824
                        ///                     approx: (cst1.cst2)/(cst1.cst1)*Sqrt[2.2222] = 0.989566
                        /// my computer, single thread: cst1={0.0073,0.0158,0.0287,0.0573,0.0998,0.1580,0.2377,0.3439,0.4811,0.6612,0.8738,1.0974,1.4033,1.7649,2.1764,2.6505,3.1142,3.5791,4.1910,4.8849};
                        ///                    2 cores: cst2={0.0085,0.0114,0.0250,0.0475,0.0719,0.1191,0.1702,0.2395,0.3179,0.4319,0.5638,0.7582,0.9454,1.1526,1.4428,1.7518,2.0291,2.4517,2.8200,3.3090};
                        ///                      scale: (cst1.cst2)/(cst1.cst1)              = 0.671237
                        ///                     approx: (cst1.cst2)/(cst1.cst1)*Sqrt[2.2222] = 1.00062
                        /// ts4-stat   , singhe thread: cst1={0.0048,0.0213,0.0641,0.1111,0.1560,0.2013,0.3307,0.3860,0.4213,0.8433,1.0184,1.3060,1.9358,2.2699,2.1718,3.0149,3.1081,4.3594,5.0356,5.5260};
                        ///                   12 cores: cst2={0.2368,0.0614,0.0235,0.1321,0.0574,0.0829,0.1078,0.1558,0.1949,0.3229,0.4507,0.3883,0.4685,0.6249,0.6835,0.8998,0.9674,1.1851,1.3415,1.6266};
                        ///                      scale: (cst1.cst2)/(cst1.cst1)                 = 0.286778
                        ///                             (cst1.cst2)/(cst1.cst1)*Sqrt[12*1.1111] = 1.04716
                        /// ts4-stat   , singhe thread: cst1={0.0138,0.0215,0.0522,0.0930,0.1783,0.2240,0.2583,0.4054,0.4603,0.9036,0.9239,1.5220,1.9443,2.1042,2.3583,3.0208,3.5507,3.8810,3.6943,6.2085};
                        ///                   12 cores: cst2={0.1648,0.1429,0.1647,0.0358,0.0561,0.0837,0.1101,0.1525,0.2084,0.2680,0.3359,0.4525,0.4775,0.7065,0.6691,0.9564,1.0898,1.2259,1.2926,1.5879};
                        ///                      scale: (cst1.cst2)/(cst1.cst1)          = 0.294706
                        ///                             (cst1.cst2)/(cst1.cst1)*Sqrt[12] = 1.02089
                        /// ts4-stat   , singhe thread: cst1={0.0126,0.0183,0.0476,0.0890,0.1353,0.1821,0.2265,0.3079,0.4551,0.5703,1.0009,1.2175,1.5922,1.8805,2.1991,2.3096,3.7680,3.7538,3.9216,5.2899,5.6737,7.0783,8.8045,9.0091,9.9658,11.6888,12.8311,14.4933,17.2462,17.5660};
                        ///                   12 cores: cst2={0.0690,0.0117,0.0275,0.0523,0.0819,0.1071,0.1684,0.1984,0.1974,0.2659,0.3305,0.4080,0.4951,0.7089,0.9068,0.7936,1.2632,1.0708,1.3187,1.6106,1.7216,2.1114,2.8249,2.7840,2.8259,3.3394,4.3092,4.2708,5.3358,5.7479};
                        ///                      scale: (cst1.cst2)/(cst1.cst1)          = 0.311008
                        ///                             (cst1.cst2)/(cst1.cst1)*Sqrt[12]  = 1.07736
                        /// Therefore, the speedup using multi-core could be sqrt(#core)
                    }
                    msg += Matlab.Execute("D = diag(D);                    ");

                    if (msg.Trim() != "")
                    {
                        System.Console.WriteLine();
                        bool domanual = HConsole.ReadValue <bool>("possibly failed. Will you do ((('V = (V+V')/2;[V,D] = eig(V);D = diag(D);))) manually ?", false, null, false, true);
                        if (domanual)
                        {
                            Matlab.Clear();
                            Matlab.PutMatrix("V", ref mwhess, true, true);
                            System.Console.WriteLine("cleaning working-space and copying V in matlab are done.");
                            System.Console.WriteLine("do V = (V+V')/2; [V,D]=eig(V); D=diag(D);");
                            while (HConsole.ReadValue <bool>("V and D are ready to use in matlab?", false, null, false, true) == false)
                            {
                                ;
                            }
                            //string path_V = HConsole.ReadValue<string>("path V.mat", @"C:\temp\V.mat", null, false, true);
                            //Matlab.Execute("clear;");
                            //Matlab.PutMatrix("V", ref mwhess, true, true);
                            //Matlab.Execute(string.Format("save('{0}', '-V7.3');", path_V));
                            //while(HConsole.ReadValue<bool>("ready for VD.mat containing V and D?", false, null, false, true) == false) ;
                            //string path_VD = HConsole.ReadValue<string>("path VD.mat", @"C:\temp\VD.mat", null, false, true);
                            //Matlab.Execute(string.Format("load '{0}';", path_V));
                        }
                    }

                    if (numModeReturn != null)
                    {
                        Matlab.PutValue("nmode", numModeReturn.Value);
                        Matlab.Execute("V = V(:,1:nmode);");
                        Matlab.Execute("D = D(1:nmode);");
                    }
                    MatrixByRowCol V = Matlab.GetMatrix("V", MatrixByRowCol.Zeros, true, true);
                    Vector         D = Matlab.GetVector("D");
                    HDebug.Assert(V.RowSize == D.Size);
                    modes = new Mode[D.Size];
                    for (int i = 0; i < D.Size; i++)
                    {
                        Vector eigvec = V.GetColVector(i);
                        double eigval = D[i];
                        modes[i] = new Mode
                        {
                            th     = i,
                            eigval = eigval,
                            eigvec = eigvec,
                        };
                    }
                    V = null;
                }
                System.GC.Collect();

                modes.UpdateMassReduced(mass.ToArray());

                return(modes);
            }
예제 #8
0
        public static HessMatrix GetHessByKijFij(IList <Vector> coords, double[,] K, double[,] F, HessMatrix hess = null)
        {
            int size = coords.Count;

            if (hess == null)
            {
                hess = HessMatrixDense.ZerosDense(size * 3, size * 3);
            }
            if (K == null)
            {
                K = new double[size, size];
            }
            if (F == null)
            {
                F = new double[size, size];
            }
            /// Parallel.For(0, size, delegate(int i)
            for (int i = 0; i < size; i++)
            {
                for (int j = i; j < size; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    if (K[i, j] == 0 && F[i, j] == 0)
                    {
                        continue;
                    }

                    MatrixByArr hessij = GetHessByKijFij(coords[i], coords[j], K[i, j], F[i, j]);
                    HDebug.AssertTolerance(0.00000001, K[i, j] - K[j, i]);
                    HDebug.AssertTolerance(0.00000001, F[i, j] - F[j, i]);
                    if (HDebug.IsDebuggerAttached)
                    {
                        HDebug.AssertTolerance(0.00000001, hessij - GetHessByKijFij(coords[j], coords[i], K[j, i], F[j, i]));
                    }

                    int n0 = i * 3;
                    int n1 = j * 3;
                    for (int di = 0; di < 3; di++)
                    {
                        for (int dj = 0; dj < 3; dj++)
                        {
                            hess[n0 + di, n0 + dj] -= hessij[di, dj];
                            hess[n0 + di, n1 + dj] += hessij[di, dj];
                            hess[n1 + di, n0 + dj] += hessij[di, dj];
                            hess[n1 + di, n1 + dj] -= hessij[di, dj];
                        }
                    }
                }
            }
            /// );
            return(hess);
        }
예제 #9
0
            public static HessMatrix GetHessAngle
                (IList <Vector> coords, IEnumerable <Universe.Angle> angles, bool useUreybrad, double?K_theta, double?K_ub, HessMatrix hessian
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, double, double> collector
                )
            {
                Matrix pwspr = null;

                return(GetHessAngle(coords, angles, useUreybrad, K_theta, K_ub, hessian, pwspr, collector));
            }
예제 #10
0
            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,
                });
            }
예제 #11
0
            public static HessInfo GetHessSbNMA
                (Universe univ
                , IList <Vector> coords
                , double nbondMaxDist // =12
                , double?maxAbsSpring
                , bool b_bonds
                , bool b_angles
                , bool b_impropers
                , bool b_dihedrals
                , bool b_nonbondeds
                , bool b_nonbonded14s
                , double?sca_bonds
                , double?sca_angles
                , double?sca_impropers
                , double?sca_dihedrals
                , double?sca_nonbondeds
                , double?sca_nonbonded14s
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, double> collectorBond
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, double, double> collectorAngle
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, double, double> collectorImproper
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, double, double> collectorDihedral
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, double> collectorNonbonded
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, double> collectorNonbonded14
                , Func <HessSpr.CustomKijInfo, double> GetCustomKij = null
                , params string[] options
                )
            {
                IEnumerable <Universe.Nonbonded>   nonbondeds   = null;
                IEnumerable <Universe.Nonbonded14> nonbonded14s = univ.nonbonded14s.GetEnumerable();

                if (options.Contains("TIP3P: tetrahedral hydrogen bonds"))
                {
                    nonbondeds = EnumNonbondeds(univ.atoms, coords, univ.size, nbondMaxDist, ListTip3pTetraHBond, options);
                }
                else if (options.Contains("TIP3P: near waters"))
                {
                    nonbondeds = EnumNonbondeds(univ.atoms, coords, univ.size, nbondMaxDist, ListTip3pNears, options);
                }
                else
                {
                    nonbondeds = EnumNonbondeds(univ.atoms, coords, univ.size, nbondMaxDist);
                }

                bool   vdW       = true;                    // use vdW
                bool   elec      = false;                   // ignore electrostatic
                double D         = double.PositiveInfinity; // dielectric constant for Tinker is "1"
                bool   ignNegSpr = true;                    // ignore negative spring (do not add the spring into hessian matrix)

                double?K_r     = null;                      // null for sbNMA, and 340.00  for ssNMA
                double?K_theta = null;                      // null for sbNMA, and 45.00   for ssNMA
                double?K_ub    = null;                      // null for sbNMA, and 10.00   for ssNMA
                double?K_psi   = null;                      // null for sbNMA, and 70.00   for ssNMA
                double?K_chi   = null;                      // null for sbNMA, and 1.00    for ssNMA
                double?n       = null;                      // null for sbNMA, and 1       for ssNMA
                string K_nbnd  = null;                      // null for sbNMA, and "Unif"  for ssNMA

                if (options.Contains("TIP3P: (vdW+elec) for OH,OO,HH"))
                {
                    K_nbnd = "TIP3P: (vdW+elec) for OH,OO,HH";
                }
                if (options.Contains("TIP3P: (vdW+elec) for OH"))
                {
                    K_nbnd = "TIP3P: (vdW+elec) for OH";
                }
                if (options.Contains("vdW:L79"))
                {
                    K_nbnd = "L79";
                }
                if (options.Contains("vdW:UnifSgn"))
                {
                    K_nbnd = "UnifSgn";
                }
                if (options.Contains("K_chi:1"))
                {
                    K_chi = 1;
                }

                HessMatrix hess = null;

                if (b_bonds)
                {
                    hess = STeM.GetHessBond(coords, univ.bonds, K_r: K_r, hessian: hess, collector: collectorBond);
                }
                if (b_angles)
                {
                    hess = STeM.GetHessAngle(coords, univ.angles, true, K_theta: K_theta, K_ub: K_ub, hessian: hess, collector: collectorAngle);
                }
                if (b_impropers)
                {
                    hess = STeM.GetHessImproper(coords, univ.impropers, K_psi: K_psi, hessian: hess, useArnaud96: true, collector: collectorImproper);
                }
                if (b_dihedrals)
                {
                    hess = STeM.GetHessDihedral(coords, univ.dihedrals, K_chi: K_chi, n: n, hessian: hess, useAbsSpr: true, useArnaud96: true, collector: collectorDihedral);
                }
                if (b_nonbondeds)
                {
                    hess = HessSpr.GetHessNonbond(coords, nonbondeds, D, K_nbnd: K_nbnd, hessian: hess, vdW: vdW, elec: elec, ignNegSpr: ignNegSpr, maxAbsSpring: maxAbsSpring, collector: collectorNonbonded, GetCustomKij: GetCustomKij);
                }
                if (b_nonbonded14s)
                {
                    hess = HessSpr.GetHessNonbond(coords, nonbonded14s, D, K_nbnd: K_nbnd, hessian: hess, vdW: vdW, elec: elec, ignNegSpr: ignNegSpr, maxAbsSpring: maxAbsSpring, collector: collectorNonbonded14, GetCustomKij: GetCustomKij);
                }

                if (sca_bonds != null)
                {
                    if (sca_bonds.Value != 1)
                    {
                        hess += (sca_bonds.Value - 1) * STeM.GetHessBond(coords, univ.bonds, K_r: K_r, hessian: null);
                    }
                }
                if (sca_angles != null)
                {
                    if (sca_angles.Value != 1)
                    {
                        hess += (sca_angles.Value - 1) * STeM.GetHessAngle(coords, univ.angles, true, K_theta: K_theta, K_ub: K_ub, hessian: null);
                    }
                }
                if (sca_impropers != null)
                {
                    if (sca_impropers.Value != 1)
                    {
                        hess += (sca_impropers.Value - 1) * STeM.GetHessImproper(coords, univ.impropers, K_psi: K_psi, hessian: null, useArnaud96: true);
                    }
                }
                if (sca_dihedrals != null)
                {
                    if (sca_dihedrals.Value != 1)
                    {
                        hess += (sca_dihedrals.Value - 1) * STeM.GetHessDihedral(coords, univ.dihedrals, K_chi: K_chi, n: n, hessian: null, useAbsSpr: true, useArnaud96: true);
                    }
                }
                if (sca_nonbondeds != null)
                {
                    if (sca_nonbondeds.Value != 1)
                    {
                        hess += (sca_nonbondeds.Value - 1) * HessSpr.GetHessNonbond(coords, nonbondeds, D, K_nbnd: K_nbnd, hessian: null, vdW: vdW, elec: elec, ignNegSpr: ignNegSpr, maxAbsSpring: maxAbsSpring);
                    }
                }
                if (sca_nonbonded14s != null)
                {
                    if (sca_nonbonded14s.Value != 1)
                    {
                        hess += (sca_nonbonded14s.Value - 1) * HessSpr.GetHessNonbond(coords, nonbonded14s, D, K_nbnd: K_nbnd, hessian: null, vdW: vdW, elec: elec, ignNegSpr: ignNegSpr, maxAbsSpring: maxAbsSpring);
                    }
                }

                //Hess.UpdateHessNaN(hess, coords);
                {
                    foreach (var bc_br_bval in hess.EnumBlocks())
                    {
                        int bc   = bc_br_bval.Item1;
                        int br   = bc_br_bval.Item2;
                        var bval = bc_br_bval.Item3;

                        if (coords[bc] == null)
                        {
                            throw new HException("have hess block for null-coord");
                        }
                        if (coords[br] == null)
                        {
                            throw new HException("have hess block for null-coord");
                        }
                        if (bval == null)
                        {
                            throw new HException();
                        }
                        for (int c = 0; c < bval.ColSize; c++)
                        {
                            for (int r = 0; r < bval.RowSize; r++)
                            {
                                double val = bval[c, r];
                                if (double.IsNaN(val))
                                {
                                    throw new HException("hess has nan element");
                                }
                                if (double.IsPositiveInfinity(val))
                                {
                                    throw new HException("hess has pos-inf element");
                                }
                                if (double.IsNegativeInfinity(val))
                                {
                                    throw new HException("hess has neg-inf element");
                                }
                            }
                        }
                    }
                }

                return(new HessInfo
                {
                    hess = hess,
                    mass = univ.GetMasses(),
                    atoms = univ.atoms.ToArray(),
                    coords = coords.HCloneVectors().ToArray(),
                    numZeroEigval = 6,
                });
            }
            public static HessForcInfo GetCoarseHessForcSubSimple
                (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();

                if (cloneH)
                {
                    H = H.CloneHess();
                }

                bool process_disp_console = false;
                bool parallel             = true;

                for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; 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.SubMatrixByAtoms(false, idxkeep, idxkeep);
                    HessMatrix B = H.SubMatrixByAtoms(false, idxkeep, idxremv);
                    HessMatrix C = H.SubMatrixByAtoms(false, idxremv, idxkeep);
                    HessMatrix D = H.SubMatrixByAtoms(false, idxremv, idxremv);
                    Vector     nF;
                    Vector     nG;
                    {
                        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];
                        }
                    }

                    Matlab.PutMatrix("A", A, true);
                    Matlab.PutMatrix("B", B, true);
                    Matlab.PutMatrix("C", C, true);
                    Matlab.PutMatrix("D", D, true);
                    Matlab.PutVector("F", nF);
                    Matlab.PutVector("G", nG);

                    ////////////////////////////////////////////////////////////////////////////////////////
                    // Get B.inv(D).C
                    //
                    // var BInvDC_BInvDG = Get_BInvDC_BInvDG_WithSqueeze(C, D, nG, process_disp_console
                    //     , options
                    //     , thld_BinvDC: thres_zeroblk/lstNewIdxRemv.Length
                    //     , parallel: parallel
                    //     );
                    // HessMatrix B_invD_C = BInvDC_BInvDG.Item1;
                    // Vector     B_invD_G = BInvDC_BInvDG.Item2;
                    // GC.Collect(0);
                    Matlab.Execute("BinvD = B * inv(D);");
                    Matlab.Execute("clear B, D;");
                    Matlab.Execute("BinvDC = BinvD * C;");
                    Matlab.Execute("BinvDG = BinvD * G;");

                    ////////////////////////////////////////////////////////////////////////////////////////
                    // Get A - B.inv(D).C
                    //     F - B.inv(D).G
                    Matlab.Execute("HH = A - BinvDC;");
                    Matlab.Execute("FF = F - BinvDG;");

                    ////////////////////////////////////////////////////////////////////////////////////////
                    // Replace A -> H
                    H = Matlab.GetMatrix("HH", H.Zeros, true);
                    F = Matlab.GetVector("FF");
                    Matlab.Execute("clear;");

                    {
                        ValueTuple <HessMatrix, Vector> BBInvDDCC_BBInvDDGG = Get_BInvDC_BInvDG_Simple
                                                                                  (C
                                                                                  , D
                                                                                  , nG
                                                                                  , process_disp_console: process_disp_console
                                                                                  , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length
                                                                                  , parallel: parallel
                                                                                  );
                        HessMatrix HH     = A - BBInvDDCC_BBInvDDGG.Item1;
                        Vector     FF     = nF - BBInvDDCC_BBInvDDGG.Item2;
                        double     dbg_HH = (HH - H).HAbsMax();
                        double     dbg_FF = (FF - F).ToArray().MaxAbs();
                        HDebug.Assert(Math.Abs(dbg_HH) < 0.00000001);
                        HDebug.Assert(Math.Abs(dbg_FF) < 0.00000001);
                    }
                    {
                        ValueTuple <HessMatrix, Vector> BBInvDDCC_BBInvDDGG = Get_BInvDC_BInvDG
                                                                                  (C
                                                                                  , D
                                                                                  , nG
                                                                                  , process_disp_console: process_disp_console
                                                                                  , options: new string[0]
                                                                                  , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length
                                                                                  , parallel: parallel
                                                                                  );
                        HessMatrix HH     = A - BBInvDDCC_BBInvDDGG.Item1;
                        Vector     FF     = nF - BBInvDDCC_BBInvDDGG.Item2;
                        double     dbg_HH = (HH - H).HAbsMax();
                        double     dbg_FF = (FF - F).ToArray().MaxAbs();
                        HDebug.Assert(Math.Abs(dbg_HH) < 0.00000001);
                        HDebug.Assert(Math.Abs(dbg_FF) < 0.00000001);
                    }
                    {
                        ValueTuple <HessMatrix, Vector> BBInvDDCC_BBInvDDGG = Get_BInvDC_BInvDG_WithSqueeze
                                                                                  (C
                                                                                  , D
                                                                                  , nG
                                                                                  , process_disp_console: process_disp_console
                                                                                  , options: new string[0]
                                                                                  , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length
                                                                                  , parallel: parallel
                                                                                  );
                        HessMatrix HH     = A - BBInvDDCC_BBInvDDGG.Item1;
                        Vector     FF     = nF - BBInvDDCC_BBInvDDGG.Item2;
                        double     dbg_HH = (HH - H).HAbsMax();
                        double     dbg_FF = (FF - F).ToArray().MaxAbs();
                        HDebug.Assert(Math.Abs(dbg_HH) < 0.00000001);
                        HDebug.Assert(Math.Abs(dbg_FF) < 0.00000001);
                    }

                    GC.Collect();
                }

                HDebug.Assert(H.ColSize == H.RowSize);
                HDebug.Assert(H.ColSize == F.Size);
                return(new HessForcInfo
                {
                    hess = H,
                    forc = F.ToVectors(3),
                });
            }
예제 #13
0
            public static Mode[] GetModeByTorsional(HessMatrix hessian, Vector masses, Matrix J
                                                    , HPack <Matrix> optoutJMJ = null // J' M J
                                                    , HPack <Matrix> optoutJM  = null // J' M
                                                    , Func <Matrix, Tuple <Matrix, Vector> > fnEigSymm = null
                                                    , Func <Matrix, Matrix, Matrix, Matrix> fnMul      = null
                                                    )
            {
                string opt;

                opt = "eig(JMJ^-1/2 * JHJ * JMJ^-1/2)";
                //opt = "mwhess->tor->eig(H)->cart->mrmode";
                if ((fnEigSymm != null) && (fnMul != null))
                {
                    opt = "fn-" + opt;
                }
                switch (opt)
                {
                case "mwhess->tor->eig(H)->cart->mrmode":
                    /// http://www.lct.jussieu.fr/manuels/Gaussian03/g_whitepap/vib.htm
                    /// http://www.lct.jussieu.fr/manuels/Gaussian03/g_whitepap/vib/vib.pdf
                    /// does not work properly.
                    HDebug.Assert(false);
                    using (new Matlab.NamedLock("GetModeByTor"))
                    {
                        int n = J.ColSize;
                        int m = J.RowSize;

                        //Matrix M = massmat; // univ.GetMassMatrix(3);
                        Vector[] toreigvecs = new Vector[m];
                        Vector[] tormodes   = new Vector[m];
                        double[] toreigvals = new double[m];
                        Mode[]   modes      = new Mode[m];
                        {
                            Matlab.Clear("GetModeByTor");
                            Matlab.PutMatrix("GetModeByTor.H", hessian);
                            Matlab.PutMatrix("GetModeByTor.J", J);
                            //Matlab.PutMatrix("GetModeByTor.M", M);
                            Matlab.PutVector("GetModeByTor.m", masses);                         // ex: m = [1,2,...,n]
                            Matlab.Execute("GetModeByTor.m3 = kron(GetModeByTor.m,[1;1;1]);");  // ex: m3 = [1,1,1,2,2,2,...,n,n,n]
                            Matlab.Execute("GetModeByTor.M = diag(GetModeByTor.m3);");
                            Matlab.Execute("GetModeByTor.m = diag(1 ./ sqrt(diag(GetModeByTor.M)));");
                            Matlab.Execute("GetModeByTor.mHm = GetModeByTor.m * GetModeByTor.H * GetModeByTor.m;");
                            Matlab.Execute("GetModeByTor.JmHmJ = GetModeByTor.J' * GetModeByTor.mHm * GetModeByTor.J;");
                            Matlab.Execute("[GetModeByTor.V, GetModeByTor.D] = eig(GetModeByTor.JmHmJ);");
                            Matlab.Execute("GetModeByTor.JV = GetModeByTor.m * GetModeByTor.J * GetModeByTor.V;");
                            Matrix V  = Matlab.GetMatrix("GetModeByTor.V");
                            Vector D  = Matlab.GetVector("diag(GetModeByTor.D)");
                            Matrix JV = Matlab.GetMatrix("GetModeByTor.JV");
                            Matlab.Clear("GetModeByTor");
                            for (int i = 0; i < m; i++)
                            {
                                toreigvecs[i]   = V.GetColVector(i);
                                toreigvals[i]   = D[i];
                                tormodes[i]     = JV.GetColVector(i);
                                modes[i]        = new Mode();
                                modes[i].eigval = toreigvals[i];
                                modes[i].eigvec = tormodes[i];
                                modes[i].th     = i;
                            }
                        }
                        return(modes);
                    }

                case "eig(JMJ^-1/2 * JHJ * JMJ^-1/2)":
                    /// Solve the problem of using eng(H,M).
                    ///
                    /// eig(H,M) => H.v = M.v.l
                    ///             H.(M^-1/2 . M^1/2).v = (M^1/2 . M^1/2).v.l
                    ///             M^-1/2 . H.(M^-1/2 . M^1/2).v = M^1/2 .v.l
                    ///             (M^-1/2 . H . M^-1/2) . (M^1/2.v) = (M^1/2.v).l
                    ///             (M^-1/2 . H . M^-1/2) . w = w.l
                    ///       where (M^1/2.v) = w
                    ///             v = M^-1/2 . w
                    ///       where M = V . D . V'
                    ///             M^-1/2 = V . (1/sqrt(D)) . V'
                    ///             M^-1/2 . M^-1/2 . M = (V . (1/sqrt(D)) . V') . (V . (1/sqrt(D)) . V') . (V . D . V')
                    ///                                 = V . (1/sqrt(D)) . (1/sqrt(D)) . D . V'
                    ///                                 = V . I . V'
                    ///                                 = I
                    using (new Matlab.NamedLock("GetModeByTor"))
                    {
                        int n = J.ColSize;
                        int m = J.RowSize;

                        //Matrix M = massmat; // univ.GetMassMatrix(3);
                        Vector[] toreigvecs = new Vector[m];
                        Vector[] tormodes   = new Vector[m];
                        double[] toreigvals = new double[m];
                        Mode[]   modes      = new Mode[m];
                        {
                            Matlab.Clear("GetModeByTor");
                            Matlab.PutMatrix("GetModeByTor.J", J.ToArray(), true);
                            //Matlab.PutMatrix("GetModeByTor.M", M      , true);
                            //Matlab.PutMatrix("GetModeByTor.H", hessian, true);
                            Matlab.PutSparseMatrix("GetModeByTor.H", hessian.GetMatrixSparse(), 3, 3);
                            if (HDebug.IsDebuggerAttached && hessian.ColSize < 10000)
                            {
                                Matlab.PutMatrix("GetModeByTor.Htest", hessian.ToArray(), true);
                                double dHessErr = Matlab.GetValue("max(max(abs(GetModeByTor.H - GetModeByTor.Htest)))");
                                Matlab.Execute("clear GetModeByTor.Htest");
                                HDebug.Assert(dHessErr == 0);
                            }
                            Matlab.PutVector("GetModeByTor.m", masses);                         // ex: m = [1,2,...,n]
                            Matlab.Execute("GetModeByTor.m3 = kron(GetModeByTor.m,[1;1;1]);");  // ex: m3 = [1,1,1,2,2,2,...,n,n,n]
                            Matlab.Execute("GetModeByTor.M = diag(GetModeByTor.m3);");

                            Matlab.Execute("GetModeByTor.JMJ = GetModeByTor.J' * GetModeByTor.M * GetModeByTor.J;");
                            Matlab.Execute("GetModeByTor.JHJ = GetModeByTor.J' * GetModeByTor.H * GetModeByTor.J;");
                            Matlab.Execute("[GetModeByTor.V, GetModeByTor.D] = eig(GetModeByTor.JMJ);");
                            Matlab.Execute("GetModeByTor.jmj = GetModeByTor.V * diag(1 ./ sqrt(diag(GetModeByTor.D))) * GetModeByTor.V';"); // jmj = sqrt(JMJ)
                            //Matlab.Execute("max(max(abs(JMJ*jmj*jmj - eye(size(JMJ)))));"); // for checking
                            //Matlab.Execute("max(max(abs(jmj*JMJ*jmj - eye(size(JMJ)))));"); // for checking
                            //Matlab.Execute("max(max(abs(jmj*jmj*JMJ - eye(size(JMJ)))));"); // for checking

                            Matlab.Execute("[GetModeByTor.V, GetModeByTor.D] = eig(GetModeByTor.jmj * GetModeByTor.JHJ * GetModeByTor.jmj);");
                            Matlab.Execute("GetModeByTor.D = diag(GetModeByTor.D);");
                            Matlab.Execute("GetModeByTor.V = GetModeByTor.jmj * GetModeByTor.V;");
                            Matlab.Execute("GetModeByTor.JV = GetModeByTor.J * GetModeByTor.V;");
                            Matrix V  = Matlab.GetMatrix("GetModeByTor.V", true);
                            Vector D  = Matlab.GetVector("GetModeByTor.D");
                            Matrix JV = Matlab.GetMatrix("GetModeByTor.JV", true);
                            if (optoutJMJ != null)
                            {
                                optoutJMJ.value = Matlab.GetMatrix("GetModeByTor.JMJ", true);
                            }
                            if (optoutJM != null)
                            {
                                optoutJM.value = Matlab.GetMatrix("GetModeByTor.J' * GetModeByTor.M", true);
                            }
                            Matlab.Clear("GetModeByTor");
                            for (int i = 0; i < m; i++)
                            {
                                toreigvecs[i]   = V.GetColVector(i);
                                toreigvals[i]   = D[i];
                                tormodes[i]     = JV.GetColVector(i);
                                modes[i]        = new Mode();
                                modes[i].eigval = toreigvals[i];
                                modes[i].eigvec = tormodes[i];
                                modes[i].th     = i;
                            }
                        }
                        return(modes);
                    }

                case "fn-eig(JMJ^-1/2 * JHJ * JMJ^-1/2)":
                    /// Solve the problem of using eng(H,M).
                    ///
                    /// eig(H,M) => H.v = M.v.l
                    ///             H.(M^-1/2 . M^1/2).v = (M^1/2 . M^1/2).v.l
                    ///             M^-1/2 . H.(M^-1/2 . M^1/2).v = M^1/2 .v.l
                    ///             (M^-1/2 . H . M^-1/2) . (M^1/2.v) = (M^1/2.v).l
                    ///             (M^-1/2 . H . M^-1/2) . w = w.l
                    ///       where (M^1/2.v) = w
                    ///             v = M^-1/2 . w
                    ///       where M = V . D . V'
                    ///             M^-1/2 = V . (1/sqrt(D)) . V'
                    ///             M^-1/2 . M^-1/2 . M = (V . (1/sqrt(D)) . V') . (V . (1/sqrt(D)) . V') . (V . D . V')
                    ///                                 = V . (1/sqrt(D)) . (1/sqrt(D)) . D . V'
                    ///                                 = V . I . V'
                    ///                                 = I
                {
                    int n = J.ColSize;
                    int m = J.RowSize;

                    //Matrix M = massmat; // univ.GetMassMatrix(3);
                    Vector[] toreigvecs = new Vector[m];
                    Vector[] tormodes   = new Vector[m];
                    double[] toreigvals = new double[m];
                    Mode[]   modes      = new Mode[m];
                    {
                        Matrix H = hessian; HDebug.Assert(hessian.ColSize == hessian.RowSize);
                        Matrix M = Matrix.Zeros(hessian.ColSize, hessian.RowSize); HDebug.Assert(3 * masses.Size == M.ColSize, M.ColSize == M.RowSize);
                        for (int i = 0; i < M.ColSize; i++)
                        {
                            M[i, i] = masses[i / 3];
                        }
                        Matrix Jt = J.Tr();

                        Matrix JMJ = fnMul(Jt, M, J);       // JMJ = J' * M * J
                        Matrix JHJ = fnMul(Jt, H, J);       // JHJ = J' * H * J
                        Matrix V; Vector D; {               // [V, D] = eig(JMJ)
                            var VD = fnEigSymm(JMJ);
                            V = VD.Item1;
                            D = VD.Item2;
                        }
                        Matrix jmj; {                       // jmj = sqrt(JMJ)
                            Vector isD = new double[D.Size];
                            for (int i = 0; i < isD.Size; i++)
                            {
                                isD[i] = 1 / Math.Sqrt(D[i]);
                            }
                            jmj = fnMul(V, LinAlg.Diag(isD), V.Tr());
                        }
                        {                                   // [V, D] = eig(jmj * JHJ * jmj)
                            Matrix jmj_JHJ_jmj = fnMul(jmj, JHJ, jmj);
                            var    VD          = fnEigSymm(jmj_JHJ_jmj);
                            V = VD.Item1;
                            D = VD.Item2;
                        }
                        V = fnMul(jmj, V, null);            // V = jmj * V
                        Matrix JV = fnMul(J, V, null);      // JV = J * V
                        if (optoutJMJ != null)
                        {
                            optoutJMJ.value = JMJ;
                        }
                        if (optoutJM != null)
                        {
                            optoutJM.value = fnMul(Jt, M, null);     // J' * M
                        }
                        for (int i = 0; i < m; i++)
                        {
                            toreigvecs[i]   = V.GetColVector(i);
                            toreigvals[i]   = D[i];
                            tormodes[i]     = JV.GetColVector(i);
                            modes[i]        = new Mode();
                            modes[i].eigval = toreigvals[i];
                            modes[i].eigvec = tormodes[i];
                            modes[i].th     = i;
                        }
                    }
                    //if(Debug.IsDebuggerAttached)
                    //{
                    //    Mode[] tmodes = GetModeByTorsional(hessian, masses, J);
                    //    Debug.Assert(modes.Length ==  tmodes.Length);
                    //    for(int i=0; i<modes.Length; i++)
                    //    {
                    //        Debug.AssertTolerance(0.00001, modes[i].eigval - tmodes[i].eigval);
                    //        Debug.AssertTolerance(0.00001, modes[i].eigvec - tmodes[i].eigvec);
                    //    }
                    //}
                    return(modes);
                }

                case "eig(JHJ,JMJ)":
                    /// Generalized eigendecomposition does not guarantee that the eigenvalue be normalized.
                    /// This becomes a problem when a B-factor (determined using eig(H,M)) is compared with another B-factor (determined using eig(M^-1/2 H M^-1/2)).
                    /// This problem is being solved using case "eig(JMJ^-1/2 * JHJ * JMJ^-1/2)"
                    using (new Matlab.NamedLock("GetModeByTor"))
                    {
                        int n = J.ColSize;
                        int m = J.RowSize;

                        //Matrix M = massmat; // univ.GetMassMatrix(3);
                        Matrix JMJ;
                        {
                            Matlab.PutMatrix("GetModeByTor.J", J);
                            //Matlab.PutMatrix("GetModeByTor.M", M);
                            Matlab.PutVector("GetModeByTor.m", masses);                         // ex: m = [1,2,...,n]
                            Matlab.Execute("GetModeByTor.m3 = kron(GetModeByTor.m,[1;1;1]);");  // ex: m3 = [1,1,1,2,2,2,...,n,n,n]
                            Matlab.Execute("GetModeByTor.M = diag(GetModeByTor.m3);");
                            Matlab.Execute("GetModeByTor.JMJ = GetModeByTor.J' * GetModeByTor.M * GetModeByTor.J;");
                            JMJ = Matlab.GetMatrix("GetModeByTor.JMJ");
                            Matlab.Clear("GetModeByTor");
                        }
                        Matrix JHJ;
                        {
                            Matlab.PutMatrix("GetModeByTor.J", J);
                            Matlab.PutMatrix("GetModeByTor.H", hessian);
                            Matlab.Execute("GetModeByTor.JHJ = GetModeByTor.J' * GetModeByTor.H * GetModeByTor.J;");
                            JHJ = Matlab.GetMatrix("GetModeByTor.JHJ");
                            Matlab.Clear("GetModeByTor");
                        }
                        Vector[] toreigvecs = new Vector[m];
                        Vector[] tormodes   = new Vector[m];
                        double[] toreigvals = new double[m];
                        Mode[]   modes      = new Mode[m];
                        {
                            Matlab.PutMatrix("GetModeByTor.JHJ", JHJ);
                            Matlab.PutMatrix("GetModeByTor.JMJ", JMJ);
                            Matlab.PutMatrix("GetModeByTor.J", J);
                            Matlab.Execute("[GetModeByTor.V, GetModeByTor.D] = eig(GetModeByTor.JHJ, GetModeByTor.JMJ);");
                            Matlab.Execute("GetModeByTor.D = diag(GetModeByTor.D);");
                            Matlab.Execute("GetModeByTor.JV = GetModeByTor.J * GetModeByTor.V;");
                            Matrix V  = Matlab.GetMatrix("GetModeByTor.V");
                            Vector D  = Matlab.GetVector("GetModeByTor.D");
                            Matrix JV = Matlab.GetMatrix("GetModeByTor.JV");
                            Matlab.Clear("GetModeByTor");
                            for (int i = 0; i < m; i++)
                            {
                                toreigvecs[i]   = V.GetColVector(i);
                                toreigvals[i]   = D[i];
                                tormodes[i]     = JV.GetColVector(i);
                                modes[i]        = new Mode();
                                modes[i].eigval = toreigvals[i];
                                modes[i].eigvec = tormodes[i];
                                modes[i].th     = i;
                            }
                        }
                        return(modes);
                    }
                }
                return(null);
            }
예제 #14
0
            public static TorEigen[] GetEigenTorsional(HessMatrix hessian, Vector masses, Matrix J)
            {
                int n = J.ColSize;
                int m = J.RowSize;

                //Matrix M = massmat; // univ.GetMassMatrix(3);
                Matrix JMJ;

                using (new Matlab.NamedLock("GetModeByTor"))
                {
                    Matlab.PutMatrix("GetModeByTor.J", J);
                    //Matlab.PutMatrix("GetModeByTor.M", M);
                    Matlab.PutVector("GetModeByTor.m", masses);                        // ex: m = [1,2,...,n]
                    Matlab.Execute("GetModeByTor.m3 = kron(GetModeByTor.m,[1;1;1]);"); // ex: m3 = [1,1,1,2,2,2,...,n,n,n]
                    Matlab.Execute("GetModeByTor.M = diag(GetModeByTor.m3);");
                    Matlab.Execute("GetModeByTor.JMJ = GetModeByTor.J' * GetModeByTor.M * GetModeByTor.J;");
                    JMJ = Matlab.GetMatrix("GetModeByTor.JMJ");
                    Matlab.Clear("GetModeByTor");
                }
                Matrix JHJ;

                using (new Matlab.NamedLock("GetModeByTor"))
                {
                    Matlab.PutMatrix("GetModeByTor.J", J);
                    Matlab.PutMatrix("GetModeByTor.H", hessian);
                    Matlab.Execute("GetModeByTor.JHJ = GetModeByTor.J' * GetModeByTor.H * GetModeByTor.J;");
                    JHJ = Matlab.GetMatrix("GetModeByTor.JHJ");
                    Matlab.Clear("GetModeByTor");
                }
                TorEigen[] toreigens = new TorEigen[m];
                using (new Matlab.NamedLock("GetModeByTor"))
                {
                    Matlab.PutMatrix("GetModeByTor.JHJ", JHJ);
                    Matlab.PutMatrix("GetModeByTor.JMJ", JMJ);
                    Matlab.PutMatrix("GetModeByTor.J", J);
                    Matlab.Execute("[GetModeByTor.V, GetModeByTor.D] = eig(GetModeByTor.JHJ, GetModeByTor.JMJ);");
                    Matlab.Execute("GetModeByTor.D = diag(GetModeByTor.D);");
                    Matrix V = Matlab.GetMatrix("GetModeByTor.V");
                    Vector D = Matlab.GetVector("GetModeByTor.D");
                    Matlab.Clear("GetModeByTor");
                    for (int i = 0; i < m; i++)
                    {
                        toreigens[i]        = new TorEigen();
                        toreigens[i].th     = i;
                        toreigens[i].eigval = D[i];
                        toreigens[i].eigvec = V.GetColVector(i);
                    }
                }
                if (HDebug.IsDebuggerAttached)
                {
                    Mode[] modes0 = GetModeByTorsional(hessian, masses, J);
                    Mode[] modes1 = GetModeByTorsional(toreigens, J);
                    HDebug.Assert(modes0.Length == modes1.Length);
                    for (int i = 0; i < modes1.Length; i++)
                    {
                        HDebug.Assert(modes0[i].th == modes1[i].th);
                        HDebug.AssertTolerance(0.000000001, modes0[i].eigval - modes1[i].eigval);
                        HDebug.AssertTolerance(0.000000001, modes0[i].eigvec - modes1[i].eigvec);
                    }
                }
                return(toreigens);
            }
예제 #15
0
            public static HessMatrix GetHessBond
                (IList <Vector> coords, IEnumerable <Universe.Bond> bonds, double?K_r, HessMatrix hessian, Matrix pwspr
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, double> collector
                )
            {
                int size = coords.Count;

                if (hessian == null)
                {
                    hessian = HessMatrixSparse.ZerosSparse(size * 3, size * 3);
                }

                foreach (Universe.Bond bond in bonds)
                {
                    int idx0 = bond.atoms[0].ID; if (coords[idx0] == null)
                    {
                        continue;
                    }
                    int idx1 = bond.atoms[1].ID; if (coords[idx1] == null)
                    {
                        continue;
                    }
                    double lK_r = (K_r != null)? K_r.Value : bond.Kb;
                    HDebug.Assert(lK_r >= 0);
                    FirstTerm(coords, lK_r, hessian, idx0, idx1);

                    if (pwspr != null)
                    {
                        pwspr[idx0, idx1] += lK_r;
                        pwspr[idx1, idx0] += lK_r;
                    }

                    if (collector != null)
                    {
                        collector
                            (bond.atoms[0], coords[idx0]
                            , bond.atoms[1], coords[idx1]
                            , lK_r);
                    }
                }

                return(hessian);
            }
예제 #16
0
            public static HessMatrix GetHessAngle
                (IList <Vector> coords, IEnumerable <Universe.Angle> angles, bool useUreybrad, double?K_theta, double?K_ub, HessMatrix hessian
                , Matrix pwspr
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, double, double> collector
                )
            {
                int size = coords.Count;

                if (hessian == null)
                {
                    hessian = HessMatrixSparse.ZerosSparse(size * 3, size * 3);
                }

                foreach (Universe.Angle angle in angles)
                {
                    int idx0 = angle.atoms[0].ID; if (coords[idx0] == null)
                    {
                        continue;
                    }
                    int idx1 = angle.atoms[1].ID; if (coords[idx1] == null)
                    {
                        continue;
                    }
                    int idx2 = angle.atoms[2].ID; if (coords[idx2] == null)
                    {
                        continue;
                    }
                    double lK_theta = (K_theta != null)? K_theta.Value : angle.Ktheta;
                    HDebug.Assert(lK_theta >= 0);
                    SecondTerm(coords, lK_theta, hessian, idx0, idx1, idx2);

                    double lK_ub = 0;
                    if (useUreybrad)
                    {
                        HDebug.Assert(angle.Kub >= 0);
                        lK_ub = (K_ub != null)? K_ub.Value : angle.Kub;
                        FirstTerm(coords, lK_ub, hessian, idx0, idx2);

                        if (pwspr != null)
                        {
                            pwspr[idx0, idx1] += lK_ub;
                            pwspr[idx1, idx0] += lK_ub;
                        }
                    }

                    if (collector != null)
                    {
                        collector
                            (angle.atoms[0], coords[idx0]
                            , angle.atoms[1], coords[idx1]
                            , angle.atoms[2], coords[idx2]
                            , lK_theta, lK_ub);
                    }
                }

                return(hessian);
            }
예제 #17
0
            public static HessMatrix GetHessVdw(IList <Vector> coords, IEnumerable <Universe.Nonbonded14> nonbonded14s, double?Epsilon, string opt, HessMatrix hessian)
            {
                int size = coords.Count;

                if (hessian == null)
                {
                    hessian = HessMatrixSparse.ZerosSparse(size * 3, size * 3);
                }

                foreach (Universe.Nonbonded14 nonbonded14 in nonbonded14s)
                {
                    Universe.Atom atom0 = nonbonded14.atoms[0];
                    Universe.Atom atom1 = nonbonded14.atoms[1];
                    int           idx0  = atom0.ID; if (coords[idx0] == null)
                    {
                        continue;
                    }
                    int idx1 = atom1.ID; if (coords[idx1] == null)
                    {
                        continue;
                    }
                    double lEpsilon;
                    if (Epsilon != null)
                    {
                        lEpsilon = Epsilon.Value;
                    }
                    else
                    {
                        switch (opt)
                        {
                        case "gromacs":
                        {
                            var    nbndpar0 = atom0.ConvertGromacsToCharmm;
                            var    nbndpar1 = atom1.ConvertGromacsToCharmm;
                            double eps0_14  = nbndpar0.eps_14; eps0_14 = (double.IsNaN(eps0_14) == false) ? eps0_14 : nbndpar0.eps;
                            double eps1_14  = nbndpar1.eps_14; eps1_14 = (double.IsNaN(eps1_14) == false) ? eps1_14 : nbndpar1.eps;
                            lEpsilon = Math.Sqrt(eps0_14 * eps1_14);
                        }
                        break;

                        default:
                        {
                            double eps0_14 = atom0.eps_14; eps0_14 = (double.IsNaN(eps0_14) == false) ? eps0_14 : atom0.epsilon;
                            double eps1_14 = atom1.eps_14; eps1_14 = (double.IsNaN(eps1_14) == false) ? eps1_14 : atom1.epsilon;
                            lEpsilon = Math.Sqrt(eps0_14 * eps1_14);
                        }
                        break;
                        }
                    }
                    FourthTerm(coords, lEpsilon, hessian, idx0, idx1);
                    FourthTerm(coords, lEpsilon, hessian, idx1, idx0);
                }

                return(hessian);
            }
예제 #18
0
            //public static void GetHessAngle(IList<Vector> coords, IEnumerable<Universe.Angle> angles, bool useUreybrad, double? K_theta, double? K_ub, MatrixSparse<MatrixByArr> hessian)
            //{
            //    Matrix pwspr = null;
            //    GetHessAngle(coords, angles, useUreybrad, K_theta, K_ub, hessian, pwspr);
            //}
            //public static void GetHessAngle(IList<Vector> coords, IEnumerable<Universe.Angle> angles, bool useUreybrad, double? K_theta, double? K_ub, MatrixSparse<MatrixByArr> hessian
            //                               , Matrix pwspr)
            //{
            //    int size = coords.Count;
            //    HDebug.AssertAllEquals(size, hessian.ColSize, hessian.RowSize);
            //
            //    foreach(Universe.Angle angle in angles)
            //    {
            //        int idx0 = angle.atoms[0].ID; if(coords[idx0] == null) continue;
            //        int idx1 = angle.atoms[1].ID; if(coords[idx1] == null) continue;
            //        int idx2 = angle.atoms[2].ID; if(coords[idx2] == null) continue;
            //        double lK_theta = (K_theta != null)? K_theta.Value : angle.Ktheta;
            //        HDebug.Assert(lK_theta >= 0);
            //        SecondTerm(coords, lK_theta, hessian, idx0, idx1, idx2);
            //        if(useUreybrad)
            //        {
            //            HDebug.Assert(angle.Kub >= 0);
            //            double lK_ub = (K_ub != null)? K_ub.Value : angle.Kub;
            //            FirstTerm(coords, lK_ub, hessian, idx0, idx2);
            //
            //            if(pwspr != null)
            //            {
            //                pwspr[idx0, idx1] += lK_ub;
            //                pwspr[idx1, idx0] += lK_ub;
            //            }
            //        }
            //    }
            //}

            //////////////////////////////////////////////////////////////////////////////
            /// IMPROPER : Kpsi(psi - psi0)**2
            ///            Kpsi: kcal/mole/rad**2
            ///            psi0: degrees
            ///            note that the second column of numbers (0) is ignored
            ///
            /// STeM     : V3          = ktheta1 ( 1 - cos(theta - theta0))
            ///                        = ktheta1/2 * (theta - theta0)^2 + O(theta^3)
            ///                       => ktheta1/2 * (theta - theta0)^2
            /// charmm22 : V(improper) = Kpsi        (psi   - psi0  )^2
            ///                       (= 2*Kpsi    * (psi   - psi0  )^2 - O(  psi^3)
            ///                       (= 2*Kpsi  ( 1 - cos(theta - theta0))
            /// charmm22 => STeM       : ktheta = 2*Kpsi
            ///                          n      = 1
            ///                          theta  = from coords
            ///                          theta0 = not use
            public static HessMatrix GetHessImproper(IList <Vector> coords, IEnumerable <Universe.Improper> impropers, double?K_psi, HessMatrix hessian
                                                     , bool useArnaud96 = false)
            {
                Action <Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, double, double> collector = null;

                return(GetHessImproper(coords, impropers, K_psi, hessian, collector: collector, useArnaud96: useArnaud96));
            }
예제 #19
0
            public static HessMatrix GetHessElec(IList <Vector> coords, IEnumerable <Universe.Nonbonded14> nonbonded14s, HessMatrix hessian, double ee)
            {
                int size = coords.Count;

                if (hessian == null)
                {
                    hessian = HessMatrixSparse.ZerosSparse(size * 3, size * 3);
                }

                foreach (Universe.Nonbonded14 nonbonded14 in nonbonded14s)
                {
                    Universe.Atom atom0 = nonbonded14.atoms[0];
                    Universe.Atom atom1 = nonbonded14.atoms[1];
                    int           idx0  = atom0.ID; if (coords[idx0] == null)
                    {
                        continue;
                    }
                    int idx1 = atom1.ID; if (coords[idx1] == null)
                    {
                        continue;
                    }
                    double pch0 = atom0.Charge;
                    double pch1 = atom1.Charge;
                    TermElec(coords, pch0, pch1, ee, hessian, idx0, idx1);
                    TermElec(coords, pch0, pch1, ee, hessian, idx1, idx0);
                }

                return(hessian);
            }
예제 #20
0
            public static HessMatrix GetHessImproper
                (IList <Vector> coords, IEnumerable <Universe.Improper> impropers, double?K_psi, HessMatrix hessian
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, double, double> collector
                , bool useArnaud96 = false
                )
            {
                int size = coords.Count;

                if (hessian == null)
                {
                    hessian = HessMatrixSparse.ZerosSparse(size * 3, size * 3);
                }

                double sqrt2 = Math.Sqrt(2);

                foreach (Universe.Improper improper in impropers)
                {
                    int idx0 = improper.atoms[0].ID; if (coords[idx0] == null)
                    {
                        continue;
                    }
                    int idx1 = improper.atoms[1].ID; if (coords[idx1] == null)
                    {
                        continue;
                    }
                    int idx2 = improper.atoms[2].ID; if (coords[idx2] == null)
                    {
                        continue;
                    }
                    int idx3 = improper.atoms[3].ID; if (coords[idx3] == null)
                    {
                        continue;
                    }
                    double lK_psi = (K_psi != null)? K_psi.Value : improper.Kpsi;
                    double n      = sqrt2; // make (K_chi * n^2 / 2 == K_chi) when calling ThirdTermN(IList<Vector> caArray, double K_phi, double n)

                    lK_psi = lK_psi * 2;
                    n      = 1;
                    HDebug.Assert(lK_psi >= 0);
                    ThirdTermN(coords, lK_psi, n, hessian, idx0, idx1, idx2, idx3, useArnaud96: useArnaud96);

                    if (collector != null)
                    {
                        collector
                            (improper.atoms[0], coords[idx0]
                            , improper.atoms[1], coords[idx1]
                            , improper.atoms[2], coords[idx2]
                            , improper.atoms[3], coords[idx3]
                            , lK_psi, n);
                    }
                }

                return(hessian);
            }
예제 #21
0
        public static HessMatrix GetHessAnm(IList <Vector> coords, IList <double> cutoffs, string options = "")
        {
            if (coords.Count > 10000)
            {
                HDebug.ToDo("System size is too big. Use EnumHessAnmSpr() and other GetHessAnm()");
            }

            //Debug.Assert(AnmHessianSelfTest());

            HDebug.Assert(coords.Count == cutoffs.Count);

            double[] cutoffs2 = new double[cutoffs.Count];
            for (int i = 0; i < cutoffs.Count; i++)
            {
                cutoffs2[i] = cutoffs[i] * cutoffs[i];
            }

            double Epsilon = 0;// double.Epsilon;

            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);
            }
            Action <int> comp_hess_i = delegate(int i)
            {
                if (coords[i] == null)
                {
                    return;
                }
                //continue;
                for (int j = 0; j < n; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    if (coords[j] == null)
                    {
                        continue;
                    }
                    Vector vec_ij  = coords[j] - coords[i];
                    double dist2   = vec_ij.Dist2;
                    double cutoff2 = Math.Max(cutoffs2[i], cutoffs2[j]);
                    if (dist2 > cutoff2)
                    {
                        if (Epsilon == 0)
                        {
                            continue;
                        }
                        HDebug.Assert(hess[i * 3 + 0, j * 3 + 0] == 0); hess[i * 3 + 0, j *3 + 0] = Epsilon;
                        HDebug.Assert(hess[i * 3 + 0, j * 3 + 1] == 0); hess[i * 3 + 0, j *3 + 1] = Epsilon;
                        HDebug.Assert(hess[i * 3 + 0, j * 3 + 2] == 0); hess[i * 3 + 0, j *3 + 2] = Epsilon;
                        HDebug.Assert(hess[i * 3 + 1, j * 3 + 0] == 0); hess[i * 3 + 1, j *3 + 0] = Epsilon;
                        HDebug.Assert(hess[i * 3 + 1, j * 3 + 1] == 0); hess[i * 3 + 1, j *3 + 1] = Epsilon;
                        HDebug.Assert(hess[i * 3 + 1, j * 3 + 2] == 0); hess[i * 3 + 1, j *3 + 2] = Epsilon;
                        HDebug.Assert(hess[i * 3 + 2, j * 3 + 0] == 0); hess[i * 3 + 2, j *3 + 0] = Epsilon;
                        HDebug.Assert(hess[i * 3 + 2, j * 3 + 1] == 0); hess[i * 3 + 2, j *3 + 1] = Epsilon;
                        HDebug.Assert(hess[i * 3 + 2, j * 3 + 2] == 0); hess[i * 3 + 2, j *3 + 2] = Epsilon;
                        continue;
                    }
                    Vector unit_ij = vec_ij.UnitVector();
                    double k_ij = 1; double val;
                    val = k_ij * unit_ij[0] * unit_ij[0]; hess[i * 3 + 0, j *3 + 0] = Epsilon - val; hess[i * 3 + 0, i *3 + 0] += val;  // hess[i*3+0, j*3+0] = Epsilon - k_ij * unit_ij[0]*unit_ij[0]; hess[i*3+0, i*3+0] += k_ij * unit_ij[0]*unit_ij[0];
                    val = k_ij * unit_ij[0] * unit_ij[1]; hess[i * 3 + 0, j *3 + 1] = Epsilon - val; hess[i * 3 + 0, i *3 + 1] += val;  // hess[i*3+0, j*3+1] = Epsilon - k_ij * unit_ij[0]*unit_ij[1]; hess[i*3+0, i*3+1] += k_ij * unit_ij[0]*unit_ij[1];
                    val = k_ij * unit_ij[0] * unit_ij[2]; hess[i * 3 + 0, j *3 + 2] = Epsilon - val; hess[i * 3 + 0, i *3 + 2] += val;  // hess[i*3+0, j*3+2] = Epsilon - k_ij * unit_ij[0]*unit_ij[2]; hess[i*3+0, i*3+2] += k_ij * unit_ij[0]*unit_ij[2];
                    val = k_ij * unit_ij[1] * unit_ij[0]; hess[i * 3 + 1, j *3 + 0] = Epsilon - val; hess[i * 3 + 1, i *3 + 0] += val;  // hess[i*3+1, j*3+0] = Epsilon - k_ij * unit_ij[1]*unit_ij[0]; hess[i*3+1, i*3+0] += k_ij * unit_ij[1]*unit_ij[0];
                    val = k_ij * unit_ij[1] * unit_ij[1]; hess[i * 3 + 1, j *3 + 1] = Epsilon - val; hess[i * 3 + 1, i *3 + 1] += val;  // hess[i*3+1, j*3+1] = Epsilon - k_ij * unit_ij[1]*unit_ij[1]; hess[i*3+1, i*3+1] += k_ij * unit_ij[1]*unit_ij[1];
                    val = k_ij * unit_ij[1] * unit_ij[2]; hess[i * 3 + 1, j *3 + 2] = Epsilon - val; hess[i * 3 + 1, i *3 + 2] += val;  // hess[i*3+1, j*3+2] = Epsilon - k_ij * unit_ij[1]*unit_ij[2]; hess[i*3+1, i*3+2] += k_ij * unit_ij[1]*unit_ij[2];
                    val = k_ij * unit_ij[2] * unit_ij[0]; hess[i * 3 + 2, j *3 + 0] = Epsilon - val; hess[i * 3 + 2, i *3 + 0] += val;  // hess[i*3+2, j*3+0] = Epsilon - k_ij * unit_ij[2]*unit_ij[0]; hess[i*3+2, i*3+0] += k_ij * unit_ij[2]*unit_ij[0];
                    val = k_ij * unit_ij[2] * unit_ij[1]; hess[i * 3 + 2, j *3 + 1] = Epsilon - val; hess[i * 3 + 2, i *3 + 1] += val;  // hess[i*3+2, j*3+1] = Epsilon - k_ij * unit_ij[2]*unit_ij[1]; hess[i*3+2, i*3+1] += k_ij * unit_ij[2]*unit_ij[1];
                    val = k_ij * unit_ij[2] * unit_ij[2]; hess[i * 3 + 2, j *3 + 2] = Epsilon - val; hess[i * 3 + 2, i *3 + 2] += val;  // hess[i*3+2, j*3+2] = Epsilon - k_ij * unit_ij[2]*unit_ij[2]; hess[i*3+2, i*3+2] += k_ij * unit_ij[2]*unit_ij[2];
                }
            };

            if (options.Split(';').Contains("parallel"))
            {
                System.Threading.Tasks.Parallel.For(0, n, comp_hess_i);
            }
            else
            {
                for (int i = 0; i < n; i++)
                {
                    comp_hess_i(i);
                }
            }

            return(hess);
        }
예제 #22
0
            //public static void GetHessImproper(IList<Vector> coords, IEnumerable<Universe.Improper> impropers, double? K_psi, MatrixSparse<MatrixByArr> hessian
            //                                  , bool useArnaud96=true
            //                                  )
            //{
            //    int size = coords.Count;
            //    HDebug.AssertAllEquals(size, hessian.ColSize, hessian.RowSize);
            //
            //    double sqrt2 = Math.Sqrt(2);
            //
            //    foreach(Universe.Improper improper in impropers)
            //    {
            //        int idx0 = improper.atoms[0].ID; if(coords[idx0] == null) continue;
            //        int idx1 = improper.atoms[1].ID; if(coords[idx1] == null) continue;
            //        int idx2 = improper.atoms[2].ID; if(coords[idx2] == null) continue;
            //        int idx3 = improper.atoms[3].ID; if(coords[idx3] == null) continue;
            //        double lK_psi = (K_psi != null)? K_psi.Value : improper.Kpsi;
            //        double     n = sqrt2; // make (K_chi * n^2 / 2 == K_chi) when calling ThirdTermN(IList<Vector> caArray, double K_phi, double n)
            //
            //        lK_psi = lK_psi*2;
            //        n = 1;
            //        HDebug.Assert(lK_psi >= 0);
            //        ThirdTermN(coords, lK_psi, n, hessian, idx0, idx1, idx2, idx3, useArnaud96: useArnaud96);
            //    }
            //}
            public static HessMatrix GetHessDihedral(IList <Vector> coords, IEnumerable <Universe.Dihedral> dihedrals, double?K_chi, double?n, HessMatrix hessian, bool useAbsSpr = false
                                                     , bool useArnaud96 = false)
            {
                Action <Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, double, double> collector = null;

                return(GetHessDihedral(coords, dihedrals, K_chi, n, hessian, collector, useAbsSpr: useAbsSpr, useArnaud96: useArnaud96));
            }
예제 #23
0
            public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_Matlab(HessMatrix H, List <int>[] lstNewIdxRemv, double thres_zeroblk)
            {
                HessMatrix CGH = null;
                List <HessCoarseResiIterInfo> iterinfos = new List <HessCoarseResiIterInfo>();

                using (new Matlab.NamedLock("CGHessIter"))
                {
                    Matlab.PutSparseMatrix("CG.H", H.GetMatrixSparse(), 3, 3);
                    Matlab.PutValue("CG.th", thres_zeroblk);
                    Matlab.PutValue("CG.iter", lstNewIdxRemv.Length);
                    for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--)
                    {
                        int[] iremv   = lstNewIdxRemv[iter].ToArray();
                        int[] idxkeep = HEnum.HEnumFromTo(0, iremv.Min() - 1).ToArray();
                        int[] idxremv = HEnum.HEnumFromTo(iremv.Min(), iremv.Max()).ToArray();
                        Matlab.PutVector("CG.idxkeep", idxkeep);
                        Matlab.PutVector("CG.idxremv", idxremv);
                        Matlab.Execute("CG.idxkeep = sort([CG.idxkeep*3+1; CG.idxkeep*3+2; CG.idxkeep*3+3]);");
                        Matlab.Execute("CG.idxremv = sort([CG.idxremv*3+1; CG.idxremv*3+2; CG.idxremv*3+3]);");

                        HessCoarseResiIterInfo iterinfo = new HessCoarseResiIterInfo();
                        iterinfo.sizeHessBlkMat  = idxremv.Max() + 1; // H.ColBlockSize;
                        iterinfo.numAtomsRemoved = idxremv.Length;
                        iterinfo.idxkeep         = idxkeep.HClone();
                        iterinfo.idxremv         = idxremv.HClone();
                        iterinfo.time0           = DateTime.UtcNow;

                        if (HDebug.IsDebuggerAttached)
                        {
                            int maxkeep = Matlab.GetValueInt("max(CG.idxkeep)");
                            int minremv = Matlab.GetValueInt("min(CG.idxremv)");
                            HDebug.Assert(maxkeep + 1 == minremv);
                            int maxremv = Matlab.GetValueInt("max(CG.idxremv)");
                            int Hsize   = Matlab.GetValueInt("max(size(CG.H))");
                            HDebug.Assert(Hsize == maxremv);
                            int idxsize = Matlab.GetValueInt("length(union(CG.idxkeep,CG.idxremv))");
                            HDebug.Assert(Hsize == idxsize);
                        }
                        Matlab.Execute("CG.A = CG.H(CG.idxkeep, CG.idxkeep);");
                        Matlab.Execute("CG.B = CG.H(CG.idxkeep, CG.idxremv);");
                        //Matlab.Execute("CG.C = CG.H(CG.idxremv, CG.idxkeep);");
                        Matlab.Execute("CG.D = CG.H(CG.idxremv, CG.idxremv);");
                        HDebug.Assert(false);
                        Matlab.Execute("CG.B(abs(CG.B) < CG.th) = 0;");     /// matlab cannot handle this call. Matlab try to use 20G memory.
                        Matlab.Execute("CG.BDC = CG.B * inv(full(CG.D)) * CG.B';");
                        Matlab.Execute("CG.BDC = sparse(CG.BDC);");
                        Matlab.Execute("CG.BDC(abs(CG.BDC) < (CG.th / CG.iter)) = 0;");
                        Matlab.Execute("CG.H = CG.A - sparse(CG.BDC);");

                        iterinfo.numSetZeroBlock = -1;
                        iterinfo.numNonZeroBlock = -1;
                        iterinfo.numAddIgnrBlock = -1;
                        iterinfo.usedMemoryByte  = -1;
                        iterinfo.time1           = DateTime.UtcNow;
                        iterinfos.Add(iterinfo);

                        System.Console.WriteLine(" - {0:000} : makezero {1,5}, nonzero {2,5}, numIgnMul {3,7}, numRemvAtoms {4,3}, {5,5:0.00} sec, {6} mb, {7}x{7}"
                                                 , iter
                                                 , iterinfo.numSetZeroBlock
                                                 , iterinfo.numNonZeroBlock
                                                 , iterinfo.numAddIgnrBlock
                                                 , iterinfo.numAtomsRemoved
                                                 , iterinfo.compSec
                                                 , iterinfo.usedMemoryByte / (1024 * 1024)
                                                 , (idxkeep.Length * 3)
                                                 );
                    }
                    Matrix CG_H = Matlab.GetMatrix("CG.H");
                    CGH = new HessMatrixDense {
                        hess = CG_H
                    };
                }

                return(new CGetHessCoarseResiIterImpl
                {
                    iterinfos = iterinfos,
                    H = CGH,
                });
            }
예제 #24
0
            public static HessMatrix GetHessDihedral
                (IList <Vector> coords, IEnumerable <Universe.Dihedral> dihedrals, double?K_chi, double?n, HessMatrix hessian
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, double, double> collector
                , bool useAbsSpr   = false
                , bool useArnaud96 = false
                )
            {
                int size = coords.Count;

                if (hessian == null)
                {
                    hessian = HessMatrixSparse.ZerosSparse(size * 3, size * 3);
                }

                foreach (Universe.Dihedral dihedral in dihedrals)
                {
                    int idx0 = dihedral.atoms[0].ID; if (coords[idx0] == null)
                    {
                        continue;
                    }
                    int idx1 = dihedral.atoms[1].ID; if (coords[idx1] == null)
                    {
                        continue;
                    }
                    int idx2 = dihedral.atoms[2].ID; if (coords[idx2] == null)
                    {
                        continue;
                    }
                    int idx3 = dihedral.atoms[3].ID; if (coords[idx3] == null)
                    {
                        continue;
                    }
                    double lK_chi = (K_chi != null)? K_chi.Value : dihedral.Kchi;
                    double ln     = (n != null)? n.Value     : dihedral.n;
                    if (useAbsSpr)
                    {
                        /// https://www.charmm.org/ubbthreads/ubbthreads.php?ubb=showflat&Number=24521
                        /// ==========================================================================
                        /// Dear all, Recently I found a parameter file for some carbohydrates, like
                        /// NAG and FUC, which described the dihedral angle as following:
                        ///
                        /// OC CC CTS CTS -1.2007 1 0.0
                        /// OC CC CTS CTS -0.3145 2 0.0
                        /// OC CC CTS CTS -0.0618 3 0.0
                        /// CA OSL SL O2L 0.0000 3 0.0
                        /// CA CA OSL SL 0.0000 3 0.0
                        ///
                        /// In some entries the values of the Kchi for the dihedral angle are 0 or
                        /// negatives. But this value usually is a positive. I understand that the
                        /// kchi value reflect the flexibility of the dihedral, so what do the
                        /// negatives here mean? Thanks a million.
                        /// --------------------------------------------------------------------------
                        /// May I ask where you found these parameters?
                        ///
                        /// Although the negative values violate the convention, they are not
                        /// incorrect. Switching the sign of the amplitude is mathematically
                        /// equivalent to reversing the phase. (See the class I potential energy
                        /// function, as discussed in any paper or textbook on the subject.) In other
                        /// words, -1.2 1 0 is equivalent to 1.2 1 180. CHARMM handles this correctly.
                        /// ==========================================================================
                        /// htna:
                        /// Still "taking absolute value" is not a good choice, but because there is
                        /// no option that I can taek, maybe this is OK in this situation, in order
                        /// to avoid negative springs.
                        lK_chi = Math.Abs(lK_chi);
                    }
                    HDebug.Assert(lK_chi >= 0);
                    ThirdTermN(coords, lK_chi, ln, hessian, idx0, idx1, idx2, idx3, useArnaud96: useArnaud96);

                    if (collector != null)
                    {
                        collector
                            (dihedral.atoms[0], coords[idx0]
                            , dihedral.atoms[1], coords[idx1]
                            , dihedral.atoms[2], coords[idx2]
                            , dihedral.atoms[3], coords[idx3]
                            , lK_chi, ln);
                    }
                }

                return(hessian);
            }
예제 #25
0
            private static HessMatrix Get_BInvDC
                (HessMatrix A
                , HessMatrix C
                , HessMatrix D
                , bool process_disp_console
                , string[] options
                , bool parallel = false
                )
            {
                HessMatrix            B_invD_C;
                Dictionary <int, int> Cbr_CCbr = new Dictionary <int, int>();
                List <int>            CCbr_Cbr = new List <int>();

                foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in C.EnumBlocks())
                {
                    int Cbr = bc_br_bval.Item2;
                    if (Cbr_CCbr.ContainsKey(Cbr) == false)
                    {
                        HDebug.Assert(Cbr_CCbr.Count == CCbr_Cbr.Count);
                        int CCbr = Cbr_CCbr.Count;
                        Cbr_CCbr.Add(Cbr, CCbr);
                        CCbr_Cbr.Add(Cbr);
                        HDebug.Assert(CCbr_Cbr[CCbr] == Cbr);
                    }
                }

                HessMatrix CC = HessMatrixSparse.ZerosSparse(C.ColSize, Cbr_CCbr.Count * 3);

                {
                    Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval)
                    {
                        int Cbc = bc_br_bval.Item1; int CCbc = Cbc;
                        int Cbr = bc_br_bval.Item2; int CCbr = Cbr_CCbr[Cbr];
                        var bval = bc_br_bval.Item3;
                        lock (CC)
                            CC.SetBlock(CCbc, CCbr, bval);
                    };

                    if (parallel)
                    {
                        Parallel.ForEach(C.EnumBlocks(), func);
                    }
                    else
                    {
                        foreach (var bc_br_bval in C.EnumBlocks())
                        {
                            func(bc_br_bval);
                        }
                    }
                }
                if (process_disp_console)
                {
                    System.Console.Write("squeezeC({0,6}->{1,6} blk), ", C.RowBlockSize, CC.RowBlockSize);
                }
                {
                    /// If a diagonal element of D is null, that row and column should be empty.
                    /// This assume that the atom is removed. In this case, the removed diagonal block
                    /// is replace as the 3x3 identity matrix.
                    ///
                    ///  [B1  0] [ A 0 ]^-1 [C1 C2 C3] = [B1  0] [ A^-1  0    ] [C1 C2 C3]
                    ///  [B2  0] [ 0 I ]    [ 0  0  0]   [B2  0] [ 0     I^-1 ] [ 0  0  0]
                    ///  [B3  0]                         [B3  0]
                    ///                                = [B1.invA  0] [C1 C2 C3]
                    ///                                  [B2.invA  0] [ 0  0  0]
                    ///                                  [B3.invA  0]
                    ///                                = [B1.invA.C1  B1.invA.C2  B1.invA.C3]
                    ///                                  [B2.invA.C1  B2.invA.C2  B2.invA.C3]
                    ///                                  [B3.invA.C1  B3.invA.C2  B3.invA.C3]
                    ///
                    {
                        //HDebug.Exception(D.ColBlockSize == D.RowBlockSize);
                        for (int bi = 0; bi < D.ColBlockSize; bi++)
                        {
                            if (D.HasBlock(bi, bi) == true)
                            {
                                continue;
                            }
                            //for(int bc=0; bc< D.ColBlockSize; bc++) HDebug.Exception( D.HasBlock(bc, bi) == false);
                            //for(int br=0; br< D.RowBlockSize; br++) HDebug.Exception( D.HasBlock(bi, br) == false);
                            //for(int br=0; br<CC.RowBlockSize; br++) HDebug.Exception(CC.HasBlock(bi, br) == false);
                            D.SetBlock(bi, bi, new double[3, 3] {
                                { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }
                            });
                        }
                    }

                    HessMatrixSparse BB_invDD_CC;
                    using (new Matlab.NamedLock(""))
                    {
                        Matlab.Execute("clear;");                                                               if (process_disp_console)
                        {
                            System.Console.Write("matlab(");
                        }
                        Matlab.PutMatrix("C", CC);                                                              if (process_disp_console)
                        {
                            System.Console.Write("C");                                                                                                              //Matlab.PutSparseMatrix("C", CC.GetMatrixSparse(), 3, 3);
                        }
                        Matlab.PutMatrix("D", D);                                                               if (process_disp_console)
                        {
                            System.Console.Write("D");
                        }
                        {   // Matlab.Execute("BinvDC = (C' / D) * C;");
                            if (options != null && options.Contains("pinv(D)"))
                            {
                                string msg = Matlab.Execute("BinvDC = (C' / D) * C;", true);
                                if (msg != "")
                                {
                                    Matlab.Execute("BinvDC = C' * pinv(D) * C;");
                                }
                            }
                            else
                            {
                                Matlab.Execute("BinvDC = (C' / D) * C;");
                            }
                        }                                                                                       if (process_disp_console)
                        {
                            System.Console.Write("X");
                        }
                        /// » whos
                        ///   Name         Size                 Bytes  Class     Attributes
                        ///                                                                                 //   before compressing C matrix
                        ///   C         1359x507              5512104  double                               //   C         1359x1545            16797240  double
                        ///   CC        1359x507               198464  double    sparse                     //   CC        1359x1545              206768  double    sparse
                        ///   D         1359x1359            14775048  double                               //   D         1359x1359            14775048  double
                        ///   DD        1359x1359              979280  double    sparse                     //   DD        1359x1359              979280  double    sparse
                        ///   ans          1x1                      8  double
                        ///
                        /// » tic; for i=1:30; A=(C' / D) * C; end; toc         dense  * dense  * dense  => 8.839463 seconds. (win)
                        /// Elapsed time is 8.839463 seconds.
                        /// » tic; for i=1:30; AA=(CC' / DD) * CC; end; toc     sparse * sparse * sparse => 27.945534 seconds.
                        /// Elapsed time is 27.945534 seconds.
                        /// » tic; for i=1:30; AAA=(C' / DD) * C; end; toc      sparse * dense  * sparse => 29.136144 seconds.
                        /// Elapsed time is 29.136144 seconds.
                        /// »
                        /// » tic; for i=1:30; A=(C' / D) * C; end; toc         dense  * dense  * dense  => 8.469071 seconds. (win)
                        /// Elapsed time is 8.469071 seconds.
                        /// » tic; for i=1:30; AA=(CC' / DD) * CC; end; toc     sparse * sparse * sparse => 28.309953 seconds.
                        /// Elapsed time is 28.309953 seconds.
                        /// » tic; for i=1:30; AAA=(C' / DD) * C; end; toc      sparse * dense  * sparse => 28.586375 seconds.
                        /// Elapsed time is 28.586375 seconds.
                        Matrix BBinvDDCC = Matlab.GetMatrix("BinvDC", true);                                    if (process_disp_console)
                        {
                            System.Console.Write("Y");
                        }
                        //Matlab.Execute("[i,j,s] = find(sparse(BinvDC));");
                        //int[] listi = Matlab.GetVectorInt("i");
                        //int[] listj = Matlab.GetVectorInt("j");
                        //double[] lists = Matlab.GetVector("s");
                        //int colsize = Matlab.GetValueInt("size(BinvDC,1)");
                        //int rowsize = Matlab.GetValueInt("size(BinvDC,2)");
                        //Matrix BBinvDDCC = Matrix.Zeros(colsize, rowsize);
                        //for(int i=0; i<listi.Length; i++)
                        //    BBinvDDCC[listi[i], listj[i]] = lists[i];
                        //GC.Collect(0);
                        BB_invDD_CC = HessMatrixSparse.FromMatrix(BBinvDDCC, parallel);                         if (process_disp_console)
                        {
                            System.Console.Write("Z), ");
                        }
                        Matlab.Execute("clear;");
                    }
                    //GC.Collect(0);

                    B_invD_C = HessMatrixSparse.ZerosSparse(C.RowSize, C.RowSize);
                    {
                        //  for(int bcc=0; bcc<CCbr_Cbr.Count; bcc++)
                        //  {
                        //      int bc = CCbr_Cbr[bcc];
                        //      for(int brr=0; brr<CCbr_Cbr.Count; brr++)
                        //      {
                        //          int br   = CCbr_Cbr[brr];
                        //          HDebug.Assert(B_invD_C.HasBlock(bc, br) == false);
                        //          if(BB_invDD_CC.HasBlock(bcc, brr) == false)
                        //              continue;
                        //          var bval = BB_invDD_CC.GetBlock(bcc, brr);
                        //          B_invD_C.SetBlock(bc, br, bval);
                        //          HDebug.Exception(A.HasBlock(bc, bc));
                        //          HDebug.Exception(A.HasBlock(br, br));
                        //      }
                        //  }
                        Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bcc_brr_bval)
                        {
                            int bcc  = bcc_brr_bval.Item1;
                            int brr  = bcc_brr_bval.Item2;
                            var bval = bcc_brr_bval.Item3;

                            int bc = CCbr_Cbr[bcc];
                            int br = CCbr_Cbr[brr];
                            lock (B_invD_C)
                                B_invD_C.SetBlock(bc, br, bval);
                        };

                        if (parallel)
                        {
                            Parallel.ForEach(BB_invDD_CC.EnumBlocks(), func);
                        }
                        else
                        {
                            foreach (var bcc_brr_bval in BB_invDD_CC.EnumBlocks())
                            {
                                func(bcc_brr_bval);
                            }
                        }
                    }
                }
                GC.Collect(0);
                return(B_invD_C);
            }
예제 #26
0
            public static HessMatrix GetHessBond
                (IList <Vector> coords, IEnumerable <Universe.Bond> bonds, double?K_r, HessMatrix hessian
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, double> collector
                )
            {
                Matrix pwspr = null;

                return(GetHessBond(coords, bonds, K_r, hessian, pwspr, collector));
            }
예제 #27
0
            public static HessRTB GetHessRTB(HessMatrix hess, Vector[] coords, double[] masses, IList <int[]> blocks, string opt)
            {
                #region check pre-condition
                {
                    HDebug.Assert(coords.Length == hess.ColBlockSize);                      // check hess matrix
                    HDebug.Assert(coords.Length == hess.RowBlockSize);                      // check hess matrix
                    HDebug.Assert(coords.Length == blocks.HMerge().HToHashSet().Count);     // check hess contains all blocks
                    HDebug.Assert(coords.Length == blocks.HMerge().Count);                  // no duplicated index in blocks
                }
                #endregion

                List <Vector> Ps = new List <Vector>();
                foreach (int[] block in blocks)
                {
                    List <Vector> PBlk = new List <Vector>();
                    switch (opt)
                    {
                    case "v1":
                        // GetRotate is incorrect
                        PBlk.AddRange(GetTrans(coords, masses, block));
                        PBlk.AddRange(GetRotate(coords, masses, block));
                        break;

                    case "v2":
                        PBlk.AddRange(GetRotTran(coords, masses, block));
                        break;

                    case null:
                        goto case "v2";
                    }
                    {
                        // PBlk = ToOrthonormal   (coords, masses, block, PBlk.ToArray()).ToList();
                        ///
                        ///     Effect of making orthonormal is not significant as below table, but consumes time by calling SVD
                        ///     Therefore, skip making orthonormal
                        ///     =========================================================================================================================================================
                        ///     model   | making orthonormal?|             | MSF corr   , check sparsity              , overlap weighted by eigval : overlap of mode 1-1, 2-2, 3-3, ...
                        ///     =========================================================================================================================================================
                        ///     NMA     | orthonormal by SVD | RTB         | corr 0.9234, spcty(all    NaN, ca    NaN), wovlp 0.5911 : 0.82,0.79,0.74,0.69,0.66,0.63,0.60,0.59,0.56,0.54)
                        ///             | orthogonal         | RTB         | corr 0.9230, spcty(all    NaN, ca    NaN), wovlp 0.5973 : 0.83,0.80,0.75,0.70,0.67,0.64,0.60,0.59,0.58,0.55)
                        ///     ---------------------------------------------------------------------------------------------------------------------------------------------------------
                        ///     scrnNMA | orthonormal by SVD | RTB         | corr 0.9245, spcty(all    NaN, ca    NaN), wovlp 0.5794 : 0.83,0.78,0.73,0.68,0.65,0.62,0.60,0.58,0.55,0.55)
                        ///             | orthogonal         | RTB         | corr 0.9243, spcty(all    NaN, ca    NaN), wovlp 0.5844 : 0.83,0.78,0.73,0.68,0.66,0.62,0.60,0.58,0.55,0.55)
                        ///     ---------------------------------------------------------------------------------------------------------------------------------------------------------
                        ///     sbNMA   | orthonormal by SVD | RTB         | corr 0.9777, spcty(all    NaN, ca    NaN), wovlp 0.6065 : 0.93,0.89,0.86,0.81,0.75,0.71,0.69,0.66,0.63,0.62)
                        ///             | orthogonal         | RTB         | corr 0.9776, spcty(all    NaN, ca    NaN), wovlp 0.6175 : 0.94,0.90,0.87,0.82,0.76,0.73,0.71,0.69,0.66,0.63)
                        ///     ---------------------------------------------------------------------------------------------------------------------------------------------------------
                        ///     ssNMA   | orthonormal by SVD | RTB         | corr 0.9677, spcty(all    NaN, ca    NaN), wovlp 0.5993 : 0.92,0.87,0.83,0.77,0.72,0.69,0.66,0.63,0.60,0.59)
                        ///             | orthogonal         | RTB         | corr 0.9675, spcty(all    NaN, ca    NaN), wovlp 0.6076 : 0.92,0.88,0.84,0.78,0.73,0.70,0.67,0.64,0.62,0.60)
                        ///     ---------------------------------------------------------------------------------------------------------------------------------------------------------
                        ///     eANM    | orthonormal by SVD | RTB         | corr 0.9870, spcty(all    NaN, ca    NaN), wovlp 0.5906 : 0.95,0.91,0.87,0.83,0.77,0.73,0.71,0.68,0.66,0.61)
                        ///             | orthogonal         | RTB         | corr 0.9869, spcty(all    NaN, ca    NaN), wovlp 0.6014 : 0.95,0.92,0.88,0.84,0.78,0.74,0.73,0.70,0.67,0.65)
                        ///     ---------------------------------------------------------------------------------------------------------------------------------------------------------
                        ///     AA-ANM  | orthonormal by SVD | RTB         | corr 0.9593, spcty(all    NaN, ca    NaN), wovlp 0.4140 : 0.94,0.90,0.85,0.78,0.74,0.72,0.66,0.64,0.61,0.61)
                        ///             | orthogonal         | RTB         | corr 0.9589, spcty(all    NaN, ca    NaN), wovlp 0.4204 : 0.94,0.91,0.85,0.80,0.76,0.73,0.68,0.66,0.63,0.61)
                    }
                    Ps.AddRange(PBlk);
                }

                Matrix P = Matrix.FromColVectorList(Ps);

                Matrix PHP;
                Matrix PMP;
                using (new Matlab.NamedLock(""))
                {
                    if (hess is HessMatrixSparse)
                    {
                        Matlab.PutSparseMatrix("H", hess.GetMatrixSparse(), 3, 3);
                    }
                    else if (hess is HessMatrixDense)
                    {
                        Matlab.PutMatrix("H", hess, true);
                    }
                    else
                    {
                        HDebug.Exception();
                    }
                    Matlab.PutMatrix("P", P, true);
                    Matlab.PutVector("M", masses);
                    Matlab.Execute("M=diag(reshape([M,M,M]',length(M)*3,1));");
                    Matlab.Execute("PHP = P'*H*P; PHP = (PHP + PHP')/2;");
                    Matlab.Execute("PMP = P'*M*P; PMP = (PMP + PMP')/2;");
                    PHP = Matlab.GetMatrix("PHP", true);
                    PMP = Matlab.GetMatrix("PMP", true);
                }

                return(new HessRTB
                {
                    hess = hess,
                    coords = coords,
                    masses = masses,
                    blocks = blocks,
                    P = P,
                    PHP = PHP,
                    PMP = PMP,
                });
            }
예제 #28
0
            public static HessMatrix GetHessVdw(IList <Vector> coords, IEnumerable <Universe.AtomPack> pairs, double?Epsilon, string opt, HessMatrix hessian)
            {
                int size = coords.Count;

                if (hessian == null)
                {
                    hessian = HessMatrixSparse.ZerosSparse(size * 3, size * 3);
                }

                foreach (Universe.AtomPack pair in pairs)
                {
                    Universe.Atom atom0 = pair.atoms.First();
                    Universe.Atom atom1 = pair.atoms.Last();
                    int           idx0  = atom0.ID; if (coords[idx0] == null)
                    {
                        continue;
                    }
                    int idx1 = atom1.ID; if (coords[idx1] == null)
                    {
                        continue;
                    }
                    double lEpsilon;
                    if (Epsilon != null)
                    {
                        lEpsilon = Epsilon.Value;
                    }
                    else
                    {
                        switch (opt)
                        {
                        case "gromacs":
                        {
                            double eps0 = atom0.ConvertGromacsToCharmm.eps;
                            double eps1 = atom1.ConvertGromacsToCharmm.eps;
                            lEpsilon = Math.Sqrt(eps0 * eps1);
                        }
                        break;

                        default:
                        {
                            double eps0 = atom0.epsilon;
                            double eps1 = atom1.epsilon;
                            lEpsilon = Math.Sqrt(eps0 * eps1);
                        }
                        break;
                        }
                    }
                    FourthTerm(coords, lEpsilon, hessian, idx0, idx1);
                    FourthTerm(coords, lEpsilon, hessian, idx1, idx0);
                }

                return(hessian);
            }
            public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_ILinAlg(HessMatrix H, List <int>[] lstNewIdxRemv, double thres_zeroblk, ILinAlg ila, bool cloneH)
            {
                if (cloneH)
                {
                    H = H.CloneHess();
                }

                bool process_disp_console = true;

                DateTime[] process_time = new DateTime[7];

                //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 = H.SubMatrixByAtoms(false, idxremv, idxkeep);                                      if (process_disp_console)
                        {
                            process_time[1] = DateTime.UtcNow; System.Console.Write("C({0:00.00} min), ", (process_time[1] - process_time[0]).TotalMinutes);
                        }
                        HessMatrix D = H.SubMatrixByAtoms(false, idxremv, idxremv);                                      if (process_disp_console)
                        {
                            process_time[2] = DateTime.UtcNow; System.Console.Write("D({0:00.00} min), ", (process_time[2] - process_time[1]).TotalMinutes);
                        }
                        HessMatrix invD = new HessMatrixDense {
                            hess = ila.InvSymm(D)
                        };                                      if (process_disp_console)
                        {
                            process_time[3] = DateTime.UtcNow; System.Console.Write("invD({0:00.00} min), ", (process_time[3] - process_time[2]).TotalMinutes);
                        }

                        // make B,C sparse
                        //int B_cntzero = B.MakeNearZeroBlockAsZero(thres_zeroblk);
                        C_density0 = C.RatioUsedBlocks;
                        iterinfo.numSetZeroBlock = C.MakeNearZeroBlockAsZero(thres_zeroblk);                                if (process_disp_console)
                        {
                            process_time[4] = DateTime.UtcNow; System.Console.Write("sparseC({0:00.00} min), ", (process_time[4] - process_time[3]).TotalMinutes);
                        }
                        //int B_nzeros = B.NumUsedBlocks; double B_nzeros_ = Math.Sqrt(B_nzeros);
                        iterinfo.numNonZeroBlock = C.NumUsedBlocks;
                        C_density1 = C.RatioUsedBlocks;

                        HessMatrix B        = C.Tr();
                        HessMatrix B_invD_C = HessMatrix.GetMul(ila, B, invD, C); /* B * invD * C;*/ if (process_disp_console)
                        {
                            process_time[5] = DateTime.UtcNow; System.Console.Write("B.invD.C({0:00.00} min), ", (process_time[5] - process_time[4]).TotalMinutes);
                        }
                        iterinfo.numAddIgnrBlock = A.UpdateAdd(B_invD_C, -1, null, thres_zeroblk / lstNewIdxRemv.Length);     if (process_disp_console)
                        {
                            process_time[6] = DateTime.UtcNow; System.Console.Write("A+BinvDC({0:00.00} min), ", (process_time[6] - process_time[5]).TotalMinutes);
                        }
                        //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,
                });
            }
예제 #30
0
 public static HessMatrix operator/(HessMatrix left, double right)
 {
     HessMatrix mat = left.CloneHess(); mat.UpdateMul(1 / right); return(mat);
 }