예제 #1
0
        public static PFSM GetHessFSM(IList <Vector> coords, Matrix pwspring, Matrix pwforce, ILinAlg la)
        {
            HDebug.ToDo("check!!");
            int size = coords.Count;

            Matrix khess = Hess.GetHessAnm(coords, pwspring.ToArray());
            Matrix invkhess;
            {
                var HH = la.ToILMat(khess);
                HDebug.Assert(false); // try to use eig, instead of pinv
                var invHH = la.PInv(HH);
                HH.Dispose();
                //var VVDD = la.EigSymm(HH);
                invkhess = invHH.ToArray();
                invHH.Dispose();
            }

            Matrix npwforce = Hess.GetHessFSM_GetEqlibForc(coords, khess, invkhess, pwforce);
            Matrix pwdist   = coords.Pwdist();

            Matrix anm = Hess.GetHessAnm(coords, double.PositiveInfinity);

            MatrixBySparseMatrix fhess = MatrixBySparseMatrix.Zeros(size * 3, size * 3, 3);

            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    int[] idxi = new int[] { i *3 + 0, i *3 + 1, i *3 + 2 };
                    int[] idxj = new int[] { j *3 + 0, j *3 + 1, j *3 + 2 };

                    // ANM_ij
                    MatrixByArr fhess_ij = anm.SubMatrix(idxi, idxj).ToArray();
                    // ANM_ij - GNM_ij = ANM_ij - I_33
                    fhess_ij[0, 0] += 1;
                    fhess_ij[1, 1] += 1;
                    fhess_ij[2, 2] += 1;
                    // fij/rij * (ANM_ij - GNM_ij)
                    fhess_ij *= (npwforce[i, j] / pwdist[i, j]);

                    fhess.SetBlock(i, j, fhess_ij);
                    fhess.SetBlock(i, i, fhess.GetBlock(i, i) - fhess_ij);
                }
            }

            return(new PFSM
            {
                KHess = khess,
                FHess = fhess,
            });
        }
예제 #2
0
        public static Matrix GetInvSprTensor(Matrix H, Matrix S, ILinAlg ila)
        {
            Matrix invH;
            string optInvH = "EigSymmTol";

            optInvH += ((ila == null) ? "-matlab" : "-ilnum");
            switch (optInvH)
            {
            case "InvSymm-ilnum":
                HDebug.Assert(false);
                invH = ila.InvSymm(H);
                break;

            case "PInv-ilnum":
                invH = ila.PInv(H);
                break;

            case "EigSymm-ilnum":
            {
                var HH   = ila.ToILMat(H);
                var VVDD = ila.EigSymm(HH);
                var VV   = VVDD.Item1;
                for (int i = 0; i < VVDD.Item2.Length; i++)
                {
                    VVDD.Item2[i] = 1 / VVDD.Item2[i];
                }
                for (int i = 0; i < 6; i++)
                {
                    VVDD.Item2[i] = 0;
                }
                var DD    = ila.ToILMat(VVDD.Item2).Diag();
                var invHH = ila.Mul(VV, DD, VV.Tr);
                invH = invHH.ToArray();
                //var check = (H * invH).ToArray();
                GC.Collect();
            }
            break;

            case "EigSymmTol-matlab":
            {
                using (new Matlab.NamedLock(""))
                {
                    Matlab.PutMatrix("invHH.HH", H);
                    Matlab.Execute("invHH.HH = (invHH.HH + invHH.HH')/2;");
                    Matlab.Execute("[invHH.VV, invHH.DD] = eig(invHH.HH);");
                    Matlab.Execute("invHH.DD = diag(invHH.DD);");
                    Matlab.Execute("invHH.DD(abs(invHH.DD)<0.00001) = 0;");
                    Matlab.Execute("invHH.DD = pinv(diag(invHH.DD));");
                    Matlab.Execute("invHH = invHH.VV * invHH.DD * invHH.VV';");
                    invH = Matlab.GetMatrix("invHH");
                    Matlab.Execute("clear invHH;");
                }
                GC.Collect();
            }
            break;

            case "EigSymmTol-ilnum":
            {
                var HH   = ila.ToILMat(H);
                var VVDD = ila.EigSymm(HH);
                var VV   = VVDD.Item1;
                for (int i = 0; i < VVDD.Item2.Length; i++)
                {
                    if (Math.Abs(VVDD.Item2[i]) < 0.00001)
                    {
                        VVDD.Item2[i] = 0;
                    }
                    else
                    {
                        VVDD.Item2[i] = 1 / VVDD.Item2[i];
                    }
                }
                var DD    = ila.ToILMat(VVDD.Item2).Diag();
                var invHH = ila.Mul(VV, DD, VV.Tr);
                invH = invHH.ToArray();
                //var check = (H * invH).ToArray();
                GC.Collect();
            }
            break;

            default:
                throw new NotImplementedException();
            }

            Matrix invkij = 0.5 * (S.Tr() * invH * S);

            //HDebug.Assert(invkij >= 0);

            return(invkij);
        }