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, }); }
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); }