public static double Corr(Vector bfactor1, Vector bfactor2, bool ignore_nan = false) { double hcorr = HMath.HCorr(bfactor1, bfactor2, ignore_nan); if (HDebug.IsDebuggerAttached) { double corr = double.NaN; using (new Matlab.NamedLock("CORR")) { Matlab.Clear("CORR"); Matlab.PutVector("CORR.bfactor1", bfactor1); Matlab.PutVector("CORR.bfactor2", bfactor2); if (ignore_nan) { Matlab.Execute("CORR.idxnan = isnan(CORR.bfactor1) | isnan(CORR.bfactor2);"); Matlab.Execute("CORR.bfactor1 = CORR.bfactor1(~CORR.idxnan);"); Matlab.Execute("CORR.bfactor2 = CORR.bfactor2(~CORR.idxnan);"); } if (Matlab.GetValueInt("min(size(CORR.bfactor1))") != 0) { corr = Matlab.GetValue("corr(CORR.bfactor1, CORR.bfactor2)"); } Matlab.Clear("CORR"); } if ((double.IsNaN(hcorr) && double.IsNaN(corr)) == false) { HDebug.AssertTolerance(0.00000001, hcorr - corr); } //HDebug.ToDo("use HMath.HCorr(...) instead"); } return(hcorr); }
static public void MV(HessMatrixSparse M, Vector V, Vector mv, Vector bvec, Vector bmv) { HDebug.Exception(V.Size == M.RowSize); HDebug.Exception(mv.Size == M.ColSize); //Vector mv = new double[M.ColSize]; HDebug.Exception(bvec.Size == 3); //Vector bvec = new double[3]; HDebug.Exception(bmv.Size == 3); //Vector bmv = new double[3]; foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in M.EnumBlocks()) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bmat = bc_br_bval.Item3; bvec[0] = V[br * 3 + 0]; bvec[1] = V[br * 3 + 1]; bvec[2] = V[br * 3 + 2]; HTLib2.LinAlg.MV(bmat, bvec, bmv); mv[bc * 3 + 0] += bmv[0]; mv[bc * 3 + 1] += bmv[1]; mv[bc * 3 + 2] += bmv[2]; } if (HDebug.Selftest()) { Matlab.Clear(); Matlab.PutSparseMatrix("M", M.GetMatrixSparse(), 3, 3); Matlab.PutVector("V", V); Matlab.Execute("MV = M*V;"); Matlab.PutVector("MV1", mv); Vector err = Matlab.GetVector("MV-MV1"); double err_max = err.ToArray().HAbs().Max(); HDebug.Assert(err_max < 0.00000001); } }
public static double[] GetRotAngles(Universe univ , Vector[] coords , Vector[] dcoords , MatrixByArr J = null , Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = null , List <Universe.RotableInfo> univ_rotinfos = null , Vector[] dcoordsRotated = null ) { if (J == null) { if (univ_rotinfos == null) { if (univ_flexgraph == null) { univ_flexgraph = univ.BuildFlexibilityGraph(); } univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); } J = TNM.GetJ(univ, coords, univ_rotinfos); } double[] dangles; using (new Matlab.NamedLock("TEST")) { Matlab.Clear("TEST"); Matlab.PutVector("TEST.R", Vector.FromBlockvector(dcoords)); Matlab.PutMatrix("TEST.J", J.ToArray(), true); Matlab.PutVector("TEST.M", univ.GetMasses(3)); Matlab.Execute("TEST.M = diag(TEST.M);"); Matlab.Execute("TEST.invJMJ = inv(TEST.J' * TEST.M * TEST.J);"); Matlab.Execute("TEST.A = TEST.invJMJ * TEST.J' * TEST.M * TEST.R;"); // (6) of TNM paper dangles = Matlab.GetVector("TEST.A"); if (dcoordsRotated != null) { HDebug.Assert(dcoordsRotated.Length == dcoords.Length); Matlab.Execute("TEST.dR = TEST.J * TEST.A;"); Vector ldcoordsRotated = Matlab.GetVector("TEST.dR"); HDebug.Assert(ldcoordsRotated.Size == dcoordsRotated.Length * 3); for (int i = 0; i < dcoordsRotated.Length; i++) { int i3 = i * 3; dcoordsRotated[i] = new double[] { ldcoordsRotated[i3 + 0], ldcoordsRotated[i3 + 1], ldcoordsRotated[i3 + 2] }; } } Matlab.Clear("TEST"); } return(dangles); }
public static Matrix GetCorrMatrixMatlab(this IList <Mode> modes) { if (HDebug.Selftest()) { HDebug.Assert(GetCorrMatrix_SelfTest(modes, GetCorrMatrixMatlab)); } // Dii = zeros(n, 1); // For[i=1, i<=nmodes, i++, // Dii = Dii + Table[Dot[vec,vec],{vec,modei}]/eigvi; // ]; // Dij = zeros(n, n); // For[i=1, i<=nmodes, i++, // Dijx = Dijx + modei_x.Transpose[modei_x] / eigvi; // Dijy = Dijy + modei_y.Transpose[modei_y] / eigvi; // Dijz = Dijz + modei_z.Transpose[modei_z] / eigvi; // Dii = Dii + Table[Dot[vec,vec],{vec,modei}]/eigvi; // ]; // Dij = Dij / nmodes; // Dii = Dii / nmodes; // Cij = Dij / Sqrt[Transpose[{Dii}].{Dii}]; // corr = Cij; Matrix MD = modes.ListEigvec().ToMatrix(); Vector EV = modes.ListEigval().ToArray(); Matrix corrmat; using (new Matlab.NamedLock("")) { Matlab.Clear(); Matlab.PutMatrix("MD", MD, true); Matlab.PutVector("EV", EV); Matlab.Execute("nmodes = length(EV);"); Matlab.Execute("iEV = diag(1 ./ EV);"); Matlab.Execute("Dijx = MD(1:3:end,:); Dijx = Dijx*iEV*Dijx'; Dij= Dijx; clear Dijx;"); Matlab.Execute("Dijy = MD(2:3:end,:); Dijy = Dijy*iEV*Dijy'; Dij=Dij+Dijy; clear Dijy;"); Matlab.Execute("Dijz = MD(3:3:end,:); Dijz = Dijz*iEV*Dijz'; Dij=Dij+Dijz; clear Dijz;"); Matlab.Execute("clear MD; clear EV; clear iEV;"); Matlab.Execute("Dij = Dij / nmodes;"); Matlab.Execute("Dii = diag(Dij);"); Matlab.Execute("Dij = Dij ./ sqrt(Dii*Dii');"); corrmat = Matlab.GetMatrix("Dij", true); } return(corrmat); }
public static double SimFluc(IList <Mode> modes1, IList <Mode> modes2) { /// need to confirm again... /// Matrix M1 = modes1.ToModeMatrix(); Vector V1 = modes1.ToArray().ListEigval(); Matrix M2 = modes2.ToModeMatrix(); Vector V2 = modes2.ToArray().ListEigval(); using (new Matlab.NamedLock("SimFluc")) { Matlab.Execute(""); Matlab.Execute("clear"); Matlab.PutMatrix("MM1", M1); Matlab.PutVector("VV1", V1); Matlab.PutMatrix("MM2", M2); Matlab.PutVector("VV2", V2); Matlab.Execute("[U2,S2,V2] = svd(MM2);"); Matlab.Execute("U2 = U2(:, 1:length(VV2));"); Matlab.Execute("S2 = S2(1:length(VV2), :);"); Matlab.Execute("invSV2 = diag(1./diag(S2))*V2';"); // covariance of mode2 Matlab.Execute("C2 = invSV2*diag(1./VV2)*invSV2';"); Matlab.Execute("C2 = (C2 + C2')/2;"); // covariance of mode 1 projected onto U2 Matlab.Execute("C1 = U2'*(MM1*diag(VV1)*MM1')*U2;"); Matlab.Execute("C1 = pinv((C1 + C1')/2);"); Matlab.Execute("C1 = (C1 + C1')/2;"); // compute the fluctuation similarity Matlab.Execute("detInvC1 = det(inv(C1));"); Matlab.Execute("detInvC2 = det(inv(C2));"); Matlab.Execute("detInvC1InvC2 = det((inv(C1)+inv(C2))/2);"); Matlab.Execute("simfluc0 = ((detInvC1*detInvC2)^0.25);"); Matlab.Execute("simfluc1 = (detInvC1InvC2)^0.5;"); Matlab.Execute("simfluc = simfluc0 / simfluc1;"); double simfluc = Matlab.GetValue("simfluc"); Matlab.Execute("clear"); return(simfluc); } }
public static double[] GetRotAngles(Universe univ , Vector[] coords , MatrixByArr hessian , Vector[] forces , MatrixByArr J = null , Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = null , List <Universe.RotableInfo> univ_rotinfos = null , Vector[] forceProjectedByTorsional = null , HPack <Vector> optEigvalOfTorHessian = null ) { Vector mass = univ.GetMasses(); //Vector[] dcoords = new Vector[univ.size]; //double t2 = t*t; //for(int i=0; i<univ.size; i++) // dcoords[i] = forces[i] * (0.5*t2/mass[i]); if (J == null) { if (univ_rotinfos == null) { if (univ_flexgraph == null) { univ_flexgraph = univ.BuildFlexibilityGraph(); } univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); } J = TNM.GetJ(univ, coords, univ_rotinfos); } double[] dangles; using (new Matlab.NamedLock("TEST")) { Matlab.Clear("TEST"); Matlab.PutVector("TEST.F", Vector.FromBlockvector(forces)); Matlab.PutMatrix("TEST.J", J); Matlab.PutMatrix("TEST.H", hessian); Matlab.PutVector("TEST.M", univ.GetMasses(3)); Matlab.Execute("TEST.M = diag(TEST.M);"); Matlab.Execute("TEST.JHJ = TEST.J' * TEST.H * TEST.J;"); Matlab.Execute("TEST.JMJ = TEST.J' * TEST.M * TEST.J;"); // (J' H J) tor = J' F // (V' D V) tor = J' F <= (V,D) are (eigvec,eigval) of generalized eigenvalue problem with (A = JHJ, B = JMJ) // tor = inv(V' D V) J' F Matlab.Execute("[TEST.V, TEST.D] = eig(TEST.JHJ, TEST.JMJ);"); if (optEigvalOfTorHessian != null) { optEigvalOfTorHessian.value = Matlab.GetVector("diag(TEST.D)"); } { Matlab.Execute("TEST.D = diag(TEST.D);"); Matlab.Execute("TEST.D(abs(TEST.D)<1) = 0;"); // remove "eigenvalue < 1" because they will increase // the magnitude of force term too big !!! Matlab.Execute("TEST.D = diag(TEST.D);"); } Matlab.Execute("TEST.invJHJ = TEST.V * pinv(TEST.D) * TEST.V';"); Matlab.Execute("TEST.dtor = TEST.invJHJ * TEST.J' * TEST.F;"); /// f = m a /// d = 1/2 a t^2 /// = 0.5 a : assuming t=1 /// = 0.5 f/m /// f = m a /// = 2 m d t^-2 /// = 2 m d : assuming t=1 /// /// coord change /// dr = 0.5 a t^2 /// = 0.5 f/m : assuming t=1 /// = 0.5 M^-1 F : M is mass matrix, F is the net force of each atom /// /// torsional angle change /// dtor = (J' M J)^-1 J' M * dr : (6) of TNM paper /// = (J' M J)^-1 J' M * 0.5 M^-1 F /// = 0.5 (J' M J)^-1 J' F /// /// force filtered by torsional ... /// F_tor = ma /// = 2 M (J dtor) /// = 2 M J 0.5 (J' M J)^-1 J' F /// = M J (J' M J)^-1 J' F /// /// H J dtor = F /// = F_tor : update force as the torsional filtered force /// = M J (J' M J)^-1 J' F /// (J' H J) dtor = (J' M J) (J' M J)^-1 J' F /// (V D V') dtor = (J' M J) (J' M J)^-1 J' F : eigen decomposition of (J' H J) using /// generalized eigenvalue problem with (J' M J) /// dtor = (V D^-1 V') (J' M J) (J' M J)^-1 J' F : (J' M J) (J' M J)^-1 = I. However, it has /// the projection effect of J'F into (J' M J) /// vector space(?). The projection will be taken /// care by (V D^-1 V') /// = (V D^-1 V') J' F /// dangles = Matlab.GetVector("TEST.dtor"); if (forceProjectedByTorsional != null) { HDebug.Assert(forceProjectedByTorsional.Length == forces.Length); Matlab.Execute("TEST.F_tor = TEST.M * TEST.J * pinv(TEST.JMJ) * TEST.J' * TEST.F;"); Vector lforceProjectedByTorsional = Matlab.GetVector("TEST.F_tor"); HDebug.Assert(lforceProjectedByTorsional.Size == forceProjectedByTorsional.Length * 3); for (int i = 0; i < forceProjectedByTorsional.Length; i++) { int i3 = i * 3; forceProjectedByTorsional[i] = new double[] { lforceProjectedByTorsional[i3 + 0], lforceProjectedByTorsional[i3 + 1], lforceProjectedByTorsional[i3 + 2], }; } } Matlab.Clear("TEST"); } return(dangles); }
public static double[] GetRotAngles(Universe univ , Vector[] coords , Vector[] forces , double t // 0.1 , MatrixByArr J = null , Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = null , List <Universe.RotableInfo> univ_rotinfos = null , HPack <Vector[]> forcesProjectedByTorsional = null , HPack <Vector[]> dcoordsProjectedByTorsional = null ) { Vector mass = univ.GetMasses(); //Vector[] dcoords = new Vector[univ.size]; double t2 = t * t; //for(int i=0; i<univ.size; i++) // dcoords[i] = forces[i] * (0.5*t2/mass[i]); if (J == null) { if (univ_rotinfos == null) { if (univ_flexgraph == null) { univ_flexgraph = univ.BuildFlexibilityGraph(); } univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); } J = TNM.GetJ(univ, coords, univ_rotinfos); } double[] dangles; using (new Matlab.NamedLock("TEST")) { Matlab.Clear("TEST"); Matlab.PutVector("TEST.F", Vector.FromBlockvector(forces)); Matlab.PutValue("TEST.t2", t2); //Matlab.PutVector("TEST.R", Vector.FromBlockvector(dcoords)); Matlab.PutMatrix("TEST.J", J); Matlab.PutVector("TEST.M", univ.GetMasses(3)); Matlab.Execute("TEST.M = diag(TEST.M);"); /// f = m a /// d = 1/2 a t^2 /// = 0.5 f/m t^2 /// f = m a /// = 2 m d t^-2 /// /// coord change /// dcoord = 0.5 a t^2 /// = (0.5 t^2) f/m /// = (0.5 t^2) M^-1 F : M is mass matrix, F is the net force of each atom /// /// torsional angle change /// dtor = (J' M J)^-1 J' M * dcoord : (6) of TNM paper /// = (J' M J)^-1 J' M * (0.5 t^2) M^-1 F /// = (0.5 t^2) (J' M J)^-1 J' F /// = (0.5 t^2) (J' M J)^-1 J' F /// = (0.5 t2) invJMJ JF /// /// force filtered by torsional ... /// F_tor = m a /// = 2 m d t^-2 /// = 2 M (J * dtor) t^-2 /// = 2 M (J * (0.5 t^2) (J' M J)^-1 J' F) t^-2 /// = M J (J' M J)^-1 J' F /// = MJ invJMJ JF /// /// coord change filtered by torsional /// R_tor = (0.5 t^2) M^-1 * F_tor /// = (0.5 t^2) J (J' M J)^-1 J' F /// = (0.5 t2) J invJMJ JF Matlab.Execute("TEST.JMJ = TEST.J' * TEST.M * TEST.J;"); Matlab.Execute("TEST.invJMJ = inv(TEST.JMJ);"); Matlab.Execute("TEST.MJ = TEST.M * TEST.J;"); Matlab.Execute("TEST.JF = TEST.J' * TEST.F;"); Matlab.Execute("TEST.dtor = (0.5 * TEST.t2) * TEST.invJMJ * TEST.JF;"); // (6) of TNM paper Matlab.Execute("TEST.F_tor = TEST.MJ * TEST.invJMJ * TEST.JF;"); Matlab.Execute("TEST.R_tor = (0.5 * TEST.t2) * TEST.J * TEST.invJMJ * TEST.JF;"); dangles = Matlab.GetVector("TEST.dtor"); if (forcesProjectedByTorsional != null) { Vector F_tor = Matlab.GetVector("TEST.F_tor"); HDebug.Assert(F_tor.Size == forces.Length * 3); forcesProjectedByTorsional.value = new Vector[forces.Length]; for (int i = 0; i < forces.Length; i++) { int i3 = i * 3; forcesProjectedByTorsional.value[i] = new double[] { F_tor[i3 + 0], F_tor[i3 + 1], F_tor[i3 + 2] }; } } if (dcoordsProjectedByTorsional != null) { Vector R_tor = Matlab.GetVector("TEST.R_tor"); HDebug.Assert(R_tor.Size == coords.Length * 3); dcoordsProjectedByTorsional.value = new Vector[coords.Length]; for (int i = 0; i < coords.Length; i++) { int i3 = i * 3; dcoordsProjectedByTorsional.value[i] = new double[] { R_tor[i3 + 0], R_tor[i3 + 1], R_tor[i3 + 2] }; } } Matlab.Clear("TEST"); } return(dangles); }
public void __MinimizeTNM(List <ForceField.IForceField> frcflds) { HDebug.Assert(false); // do not use this, because not finished yet Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = this.BuildFlexibilityGraph(); List <Universe.RotableInfo> univ_rotinfos = this.GetRotableInfo(univ_flexgraph); Vector[] coords = this.GetCoords(); double tor_normInf = double.PositiveInfinity; //double maxRotAngle = 0.1; Vector[] forces = null; MatrixByArr hessian = null; double forces_normsInf = 1; int iter = 0; double scale = 1; this._SaveCoordsToPdb(iter.ToString("0000") + ".pdb", coords); while (true) { iter++; forces = this.GetVectorsZero(); hessian = new double[size * 3, size *3]; Dictionary <string, object> cache = new Dictionary <string, object>(); double energy = this.GetPotential(frcflds, coords, ref forces, ref hessian, cache); forces_normsInf = (new Vectors(forces)).NormsInf().ToArray().Max(); //System.Console.WriteLine("iter {0:###}: frcnrminf {1}, energy {2}, scale {3}", iter, forces_normsInf, energy, scale); //if(forces_normsInf < 0.001) //{ // break; //} Vector torz = null; double maxcarz = 1; Vector car = null; //double using (new Matlab.NamedLock("TEST")) { MatrixByArr H = hessian; MatrixByArr J = Paper.TNM.GetJ(this, this.GetCoords(), univ_rotinfos); Vector m = this.GetMasses(3); Matlab.PutVector("TEST.F", Vector.FromBlockvector(forces)); Matlab.PutMatrix("TEST.J", J); Matlab.PutMatrix("TEST.H", H); Matlab.PutVector("TEST.M", m); Matlab.Execute("TEST.M = diag(TEST.M);"); Matlab.Execute("TEST.JMJ = TEST.J' * TEST.M * TEST.J;"); Matlab.Execute("TEST.JHJ = TEST.J' * TEST.H * TEST.J;"); // (J' H J) tor = J' F // (V' D V) tor = J' F <= (V,D) are (eigvec,eigval) of generalized eigenvalue problem with (A = JHJ, B = JMJ) // tor = inv(V' D V) J' F Matlab.Execute("[TEST.V, TEST.D] = eig(TEST.JHJ, TEST.JMJ);"); //Matlab.Execute("TEST.zidx = 3:end;"); Matlab.Execute("TEST.invJHJ = TEST.V * pinv(TEST.D ) * TEST.V';"); Matlab.Execute("TEST.tor = TEST.invJHJ * TEST.J' * TEST.F;"); Matlab.Execute("TEST.car = TEST.J * TEST.tor;"); car = Matlab.GetVector("TEST.car"); Matlab.Execute("[TEST.DS, TEST.DSI] = sort(abs(diag(TEST.D)));"); Matlab.Execute("TEST.zidx = TEST.DSI(6:end);"); Matlab.Execute("TEST.Dz = TEST.D;"); //Matlab.Execute("TEST.Dz(TEST.zidx,TEST.zidx) = 0;"); Matlab.Execute("TEST.invJHJz = TEST.V * pinv(TEST.Dz) * TEST.V';"); Matlab.Execute("TEST.torz = TEST.invJHJz * TEST.J' * TEST.F;"); Matlab.Execute("TEST.carz = TEST.J * TEST.torz;"); torz = Matlab.GetVector("TEST.torz"); maxcarz = Matlab.GetValue("max(max(abs(TEST.carz)))"); scale = 1; if (maxcarz > 0.01) { scale = scale * 0.01 / maxcarz; } Matlab.Clear("TEST"); }; tor_normInf = torz.NormInf(); double frcnrinf = car.ToArray().HAbs().Max(); if (maxcarz < 0.001) { break; } System.Console.WriteLine("iter {0:###}: frcnrminf {1}, tor(frcnrinf) {2}, energy {3}, scale {4}", iter, forces_normsInf, frcnrinf, energy, scale); HDebug.Assert(univ_rotinfos.Count == torz.Size); for (int i = 0; i < univ_rotinfos.Count; i++) { Universe.RotableInfo rotinfo = univ_rotinfos[i]; Vector rotOrigin = coords[rotinfo.bondedAtom.ID]; double rotAngle = torz[i] * scale; // (maxRotAngle / tor_normInf); if (rotAngle == 0) { continue; } Vector rotAxis = coords[rotinfo.bond.atoms[1].ID] - coords[rotinfo.bond.atoms[0].ID]; Quaternion rot = new Quaternion(rotAxis, rotAngle); MatrixByArr rotMat = rot.RotationMatrix; foreach (Atom atom in rotinfo.rotAtoms) { int id = atom.ID; Vector coord = rotMat * (coords[id] - rotOrigin) + rotOrigin; coords[id] = coord; } } this._SaveCoordsToPdb(iter.ToString("0000") + ".pdb", coords); } }
public static Vector[] GetRotate(Vector[] coords, Vector cent, int[] block) { throw new Exception("this implementation is wrong. Use the following algorithm to get rotation modes for RTB."); double[] io_mass = null; if (HDebug.IsDebuggerAttached) { using (var temp = new HTempDirectory(@"K:\temp\", null)) { temp.EnterTemp(); HFile.WriteAllText("rtbProjection.m", @" function [P, xyz] = rtbProjection(xyz, mass) % the approach is to find the inertia. compute the principal axes. and then use them to determine directly translation or rotation. n = size(xyz, 1); % n: the number of atoms if nargin == 1 mass = ones(n,1); end M = sum(mass); % find the mass center. m3 = repmat(mass, 1, 3); center = sum (xyz.*m3)/M; xyz = xyz - center(ones(n, 1), :); mwX = sqrt (m3).*xyz; inertia = sum(sum(mwX.^2))*eye(3) - mwX'*mwX; [V,D] = eig(inertia); tV = V'; % tV: transpose of V. Columns of V are principal axes. for i=1:3 trans{i} = tV(ones(n,1)*i, :); % the 3 translations are along principal axes end P = zeros(n*3, 6); for i=1:3 rotate{i} = cross(trans{i}, xyz); temp = mat2vec(trans{i}); P(:,i) = temp/norm(temp); temp = mat2vec(rotate{i}); P(:,i+3) = temp/norm(temp); end m3 = mat2vec(sqrt(m3)); P = repmat (m3(:),1,size(P,2)).*P; % now normalize columns of P P = P*diag(1./normMat(P,1)); function vec = mat2vec(mat) % convert a matrix to a vector, extracting data *row-wise*. vec = reshape(mat',1,prod(size(mat))); "); Matlab.Execute("cd \'" + temp.dirinfo.FullName + "\'"); Matlab.PutMatrix("xyz", coords.ToMatrix(false)); Matlab.PutVector("mass", io_mass); temp.QuitTemp(); } } HDebug.Assert(coords.Length == io_mass.Length); Vector mwcenter = new double[3]; for (int i = 0; i < coords.Length; i++) { mwcenter += (coords[i] * io_mass[i]); } mwcenter /= io_mass.Sum(); Vector[] mwcoords = new Vector[coords.Length]; for (int i = 0; i < coords.Length; i++) { mwcoords[i] = (coords[i] - mwcenter) * io_mass[i]; } Matrix mwPCA = new double[3, 3]; for (int i = 0; i < coords.Length; i++) { mwPCA += LinAlg.VVt(mwcoords[i], mwcoords[i]); } var V_D = LinAlg.Eig(mwPCA.ToArray()); var V = V_D.Item1; Vector[] rotvecs = new Vector[3]; for (int i = 0; i < 3; i++) { Vector rotaxis = new double[] { V[0, i], V[1, i], V[2, i] }; Vector[] rotveci = new Vector[coords.Length]; for (int j = 0; j < coords.Length; j++) { rotveci[j] = LinAlg.CrossProd(rotaxis, mwcoords[i]); } rotvecs[i] = rotveci.ToVector().UnitVector(); } if (HDebug.IsDebuggerAttached) { double dot01 = LinAlg.VtV(rotvecs[0], rotvecs[1]); double dot02 = LinAlg.VtV(rotvecs[0], rotvecs[2]); double dot12 = LinAlg.VtV(rotvecs[1], rotvecs[2]); HDebug.Assert(Math.Abs(dot01) < 0.0000001); HDebug.Assert(Math.Abs(dot02) < 0.0000001); HDebug.Assert(Math.Abs(dot12) < 0.0000001); } return(rotvecs); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// from song: rtbProjection.m //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// function [P, xyz] = rtbProjection(xyz, mass) /// % the approach is to find the inertia. compute the principal axes. and then use them to determine directly translation or rotation. /// /// n = size(xyz, 1); % n: the number of atoms /// if nargin == 1 /// mass = ones(n,1); /// end /// /// M = sum(mass); /// % find the mass center. /// m3 = repmat(mass, 1, 3); /// center = sum (xyz.*m3)/M; /// xyz = xyz - center(ones(n, 1), :); /// /// mwX = sqrt (m3).*xyz; /// inertia = sum(sum(mwX.^2))*eye(3) - mwX'*mwX; /// [V,D] = eig(inertia); /// tV = V'; % tV: transpose of V. Columns of V are principal axes. /// for i=1:3 /// trans{i} = tV(ones(n,1)*i, :); % the 3 translations are along principal axes /// end /// P = zeros(n*3, 6); /// for i=1:3 /// rotate{i} = cross(trans{i}, xyz); /// temp = mat2vec(trans{i}); /// P(:,i) = temp/norm(temp); /// temp = mat2vec(rotate{i}); /// P(:,i+3) = temp/norm(temp); /// end /// m3 = mat2vec(sqrt(m3)); /// P = repmat (m3(:),1,size(P,2)).*P; /// % now normalize columns of P /// P = P*diag(1./normMat(P,1)); /// /// function vec = mat2vec(mat) /// % convert a matrix to a vector, extracting data *row-wise*. /// vec = reshape(mat',1,prod(size(mat))); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// rotx[t_ ] := { { 1,0,0,0},{ 0,Cos[t],-Sin[t],0},{ 0,Sin[t],Cos[t],0},{ 0,0,0,1} }; /// roty[t_ ] := { { Cos[t],0,Sin[t],0},{ 0,1,0,0},{ -Sin[t],0,Cos[t],0},{ 0,0,0,1} }; /// rotz[t_ ] := { { Cos[t],-Sin[t],0,0},{ Sin[t],Cos[t],0,0},{ 0,0,1,0},{ 0,0,0,1} }; /// tran[tx_, ty_, tz_] := { { 1,0,0,tx},{ 0,1,0,ty},{ 0,0,1,tz},{ 0,0,0,1} }; /// pt = Transpose[{{px,py,pz,1}}]; /// /// point : (px,py,pz) /// center : (cx,cy,cz) /// angle : t /// /// tran[cx, cy, cz].rotx[t].tran[-cx, -cy, -cz].pt = {{px}, {cy - cy Cos[t] + py Cos[t] + cz Sin[t] - pz Sin[t]}, {cz - cz Cos[t] + pz Cos[t] - cy Sin[t] + py Sin[t]}, {1}} /// tran[cx, cy, cz].roty[t].tran[-cx, -cy, -cz].pt = {{cx - cx Cos[t] + px Cos[t] - cz Sin[t] + pz Sin[t]}, {py}, {cz - cz Cos[t] + pz Cos[t] + cx Sin[t] - px Sin[t]}, {1}} /// tran[cx, cy, cz].rotz[t].tran[-cx, -cy, -cz].pt = {{cx - cx Cos[t] + px Cos[t] + cy Sin[t] - py Sin[t]}, {cy - cy Cos[t] + py Cos[t] - cx Sin[t] + px Sin[t]}, {pz}, {1}} /// /// D[tran[cx, cy, cz].rotx[t].tran[-cx, -cy, -cz].pt, t] = {{0}, {cz Cos[t] - pz Cos[t] + cy Sin[t] - py Sin[t]}, {-cy Cos[t] + py Cos[t] + cz Sin[t] - pz Sin[t]}, {0}} /// D[tran[cx, cy, cz].roty[t].tran[-cx, -cy, -cz].pt, t] = {{-cz Cos[t] + pz Cos[t] + cx Sin[t] - px Sin[t]}, {0}, {cx Cos[t] - px Cos[t] + cz Sin[t] - pz Sin[t]}, {0}} /// D[tran[cx, cy, cz].rotz[t].tran[-cx, -cy, -cz].pt, t] = {{cy Cos[t] - py Cos[t] + cx Sin[t] - px Sin[t]}, {-cx Cos[t] + px Cos[t] + cy Sin[t] - py Sin[t]}, {0}, {0}} /// /// D[tran[cx,cy,cz].rotx[a].tran[-cx,-cy,-cz].pt,a]/.a->0 = {{0}, {cz - pz}, {-cy + py}, {0}} /// D[tran[cx,cy,cz].roty[a].tran[-cx,-cy,-cz].pt,a]/.a->0 = {{-cz + pz}, {0}, {cx - px}, {0}} /// D[tran[cx,cy,cz].rotz[a].tran[-cx,-cy,-cz].pt,a]/.a->0 = {{cy - py}, {-cx + px}, {0}, {0}} /// rotx of atom (px,py,pz) with center (cx,cy,cz): {{0}, {cz - pz}, {-cy + py}, {0}} = { 0, cz - pz, -cy + py, 0 } => { 0, cz - pz, -cy + py } /// rotx of atom (px,py,pz) with center (cx,cy,cz): {{-cz + pz}, {0}, {cx - px}, {0}} = { -cz + pz, 0, cx - px, 0 } => { -cz + pz, 0, cx - px } /// rotx of atom (px,py,pz) with center (cx,cy,cz): {{cy - py}, {-cx + px}, {0}, {0}} = { cy - py, -cx + px, 0, 0 } => { cy - py, -cx + px, 0 } /// int leng = coords.Length; Vector[] rots; { Vector[] rotbyx = new Vector[leng]; Vector[] rotbyy = new Vector[leng]; Vector[] rotbyz = new Vector[leng]; double cx = cent[0]; double cy = cent[1]; double cz = cent[2]; for (int i = 0; i < leng; i++) { double px = coords[i][0]; double py = coords[i][1]; double pz = coords[i][2]; rotbyx[i] = new double[] { 0, cz - pz, -cy + py }; rotbyy[i] = new double[] { -cz + pz, 0, cx - px }; rotbyz[i] = new double[] { cy - py, -cx + px, 0 }; } rots = new Vector[] { rotbyx.ToVector().UnitVector(), rotbyy.ToVector().UnitVector(), rotbyz.ToVector().UnitVector(), }; } if (HDebug.IsDebuggerAttached) { Vector[] rotbyx = new Vector[leng]; Vector[] rotbyy = new Vector[leng]; Vector[] rotbyz = new Vector[leng]; Vector zeros = new double[3]; for (int i = 0; i < leng; i++) { rotbyx[i] = rotbyy[i] = rotbyz[i] = zeros; } Vector rx = new double[3] { 1, 0, 0 }; Vector ry = new double[3] { 0, 1, 0 }; Vector rz = new double[3] { 0, 0, 1 }; Func <Vector, Vector, Vector> GetTangent = delegate(Vector pt, Vector axisdirect) { /// Magnitude of rotation tangent is proportional to the distance from the point to the axis. /// Ex) when a point is in x-axis (r,0), rotating along z-axis by θ is: (r*sin(θ), 0) /// /// | /// | ^ sin(θ) /// | | /// -+-----------------r---------- /// Vector rot1 = cent; Vector rot2 = cent + axisdirect; double dist = Geometry.DistancePointLine(pt, rot1, rot2); Vector tan = Geometry.RotateTangentUnit(pt, rot1, rot2) * dist; return(tan); }; IEnumerable <int> enumblock = block; if (block != null) { enumblock = block; } else { enumblock = HEnum.HEnumCount(leng); } foreach (int i in enumblock) { Vector pt = coords[i]; rotbyx[i] = GetTangent(pt, rx); rotbyy[i] = GetTangent(pt, ry); rotbyz[i] = GetTangent(pt, rz); } Vector[] trots = new Vector[3] { rotbyx.ToVector().UnitVector(), rotbyy.ToVector().UnitVector(), rotbyz.ToVector().UnitVector(), }; double test0 = LinAlg.VtV(rots[0], trots[0]); double test1 = LinAlg.VtV(rots[1], trots[1]); double test2 = LinAlg.VtV(rots[2], trots[2]); HDebug.Assert(Math.Abs(test0 - 1) < 0.00000001); HDebug.Assert(Math.Abs(test1 - 1) < 0.00000001); HDebug.Assert(Math.Abs(test2 - 1) < 0.00000001); } return(rots); }
public static Vector[] GetRotTran(Vector[] coords, double[] masses) { #region source rtbProjection.m /// rtbProjection.m ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// function [P, xyz] = rtbProjection(xyz, mass) /// % the approach is to find the inertia. compute the principal axes. and then use them to determine directly translation or rotation. /// /// n = size(xyz, 1); % n: the number of atoms /// if nargin == 1 /// mass = ones(n,1); /// end /// /// M = sum(mass); /// % find the mass center. /// m3 = repmat(mass, 1, 3); /// center = sum (xyz.*m3)/M; /// xyz = xyz - center(ones(n, 1), :); /// /// mwX = sqrt (m3).*xyz; /// inertia = sum(sum(mwX.^2))*eye(3) - mwX'*mwX; /// [V,D] = eig(inertia); /// tV = V'; % tV: transpose of V. Columns of V are principal axes. /// for i=1:3 /// trans{i} = tV(ones(n,1)*i, :); % the 3 translations are along principal axes /// end /// P = zeros(n*3, 6); /// for i=1:3 /// rotate{i} = cross(trans{i}, xyz); /// temp = mat2vec(trans{i}); /// P(:,i) = temp/norm(temp); /// temp = mat2vec(rotate{i}); /// P(:,i+3) = temp/norm(temp); /// end /// m3 = mat2vec(sqrt(m3)); /// P = repmat (m3(:),1,size(P,2)).*P; /// % now normalize columns of P /// P = P*diag(1./normMat(P,1)); /// /// function vec = mat2vec(mat) /// % convert a matrix to a vector, extracting data *row-wise*. /// vec = reshape(mat',1,prod(size(mat))); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #endregion if (HDebug.Selftest()) #region selftest { // get test coords and masses Vector[] tcoords = Pdb.FromLines(SelftestData.lines_1EVC_pdb).atoms.ListCoord().ToArray(); double[] tmasses = new double[tcoords.Length]; for (int i = 0; i < tmasses.Length; i++) { tmasses[i] = 1; } // get test rot/trans RTB vectors Vector[] trottra = GetRotTran(tcoords, tmasses); HDebug.Assert(trottra.Length == 6); // get test ANM var tanm = Hess.GetHessAnm(tcoords); // size of vec_i == 1 for (int i = 0; i < trottra.Length; i++) { double dist = trottra[i].Dist; HDebug.Assert(Math.Abs(dist - 1) < 0.00000001); } // vec_i and vec_j must be orthogonal for (int i = 0; i < trottra.Length; i++) { for (int j = i + 1; j < trottra.Length; j++) { double dot = LinAlg.VtV(trottra[i], trottra[j]); HDebug.Assert(Math.Abs(dot) < 0.00000001); } } // vec_i' * ANM * vec_i == 0 for (int i = 0; i < trottra.Length; i++) { double eigi = LinAlg.VtMV(trottra[i], tanm, trottra[i]); HDebug.Assert(Math.Abs(eigi) < 0.00000001); Vector tvecx = trottra[i].Clone(); tvecx[1] += (1.0 / tvecx.Size) * Math.Sign(tvecx[1]); tvecx = tvecx.UnitVector(); double eigix = LinAlg.VtMV(tvecx, tanm, tvecx); HDebug.Assert(Math.Abs(eigix) > 0.00000001); } } #endregion Vector[] rottran; using (new Matlab.NamedLock("")) { Matlab.PutMatrix("xyz", coords.ToMatrix(), true); Matlab.Execute("xyz = xyz';"); Matlab.PutVector("mass", masses); //Matlab.Execute("function [P, xyz] = rtbProjection(xyz, mass) "); //Matlab.Execute("% the approach is to find the inertia. compute the principal axes. and then use them to determine directly translation or rotation. "); Matlab.Execute(" "); Matlab.Execute("n = size(xyz, 1); % n: the number of atoms "); //Matlab.Execute("if nargin == 1; "); //Matlab.Execute(" mass = ones(n,1); "); //Matlab.Execute("end "); Matlab.Execute(" "); Matlab.Execute("M = sum(mass); "); Matlab.Execute("% find the mass center. "); Matlab.Execute("m3 = repmat(mass, 1, 3); "); Matlab.Execute("center = sum (xyz.*m3)/M; "); Matlab.Execute("xyz = xyz - center(ones(n, 1), :); "); Matlab.Execute(" "); Matlab.Execute("mwX = sqrt (m3).*xyz; "); Matlab.Execute("inertia = sum(sum(mwX.^2))*eye(3) - mwX'*mwX; "); Matlab.Execute("[V,D] = eig(inertia); "); Matlab.Execute("tV = V'; % tV: transpose of V. Columns of V are principal axes. "); Matlab.Execute("for i=1:3 \n" + " trans{i} = tV(ones(n,1)*i, :); % the 3 translations are along principal axes \n" + "end \n"); Matlab.Execute("P = zeros(n*3, 6); "); Matlab.Execute("mat2vec = @(mat) reshape(mat',1,prod(size(mat))); "); Matlab.Execute("for i=1:3 \n" + " rotate{i} = cross(trans{i}, xyz); \n" + " temp = mat2vec(trans{i}); \n" + " P(:,i) = temp/norm(temp); \n" + " temp = mat2vec(rotate{i}); \n" + " P(:,i+3) = temp/norm(temp); \n" + "end "); Matlab.Execute("m3 = mat2vec(sqrt(m3)); "); Matlab.Execute("P = repmat (m3(:),1,size(P,2)).*P; "); //Matlab.Execute("% now normalize columns of P "); // already normalized //Matlab.Execute("normMat = @(x) sqrt(sum(x.^2,2)); "); // already normalized //Matlab.Execute("P = P*diag(1./normMat(P,1)); "); // already normalized //Matlab.Execute(" "); // already normalized ////////////////////////////////////////////////////////////////////////////////////////////////////// //Matlab.Execute("function vec = mat2vec(mat) "); //Matlab.Execute("% convert a matrix to a vector, extracting data *row-wise*. "); //Matlab.Execute("vec = reshape(mat',1,prod(size(mat))); "); ////////////////////////////////////////////////////////////////////////////////////////////////////// //Matlab.Execute("function amp = normMat(x) "); //Matlab.Execute("amp = sqrt(sum(x.^2,2)); "); Matrix xyz = Matlab.GetMatrix("xyz", true); Matrix P = Matlab.GetMatrix("P", true); rottran = P.GetColVectorList(); } return(rottran); }
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, }); }
public static HessMatrixDense GetHessCoarseBlkmat(HessMatrix hess, IList <int> idx_heavy, string invopt = "inv") { /// Hess = [ HH HL ] = [ A B ] /// [ LH LL ] [ C D ] /// /// Hess_HH = HH - HL * LL^-1 * LH /// = A - B * D^-1 * C Matrix hess_HH; using (new Matlab.NamedLock("")) { Matlab.Clear(); if (hess is HessMatrixSparse) { Matlab.PutSparseMatrix("H", hess.GetMatrixSparse(), 3, 3); } else { Matlab.PutMatrix("H", hess, true); } Matlab.Execute("H = (H + H')/2;"); int[] idx0 = new int[idx_heavy.Count * 3]; for (int i = 0; i < idx_heavy.Count; i++) { idx0[i * 3 + 0] = idx_heavy[i] * 3 + 0; idx0[i * 3 + 1] = idx_heavy[i] * 3 + 1; idx0[i * 3 + 2] = idx_heavy[i] * 3 + 2; } Matlab.PutVector("idx0", idx0); Matlab.Execute("idx0 = idx0+1;"); Matlab.PutValue("idx1", hess.ColSize); Matlab.Execute("idx1 = setdiff(1:idx1, idx0)';"); HDebug.Assert(Matlab.GetValueInt("length(union(idx0,idx1))") == hess.ColSize); Matlab.Execute("A = full(H(idx0,idx0));"); Matlab.Execute("B = H(idx0,idx1) ;"); Matlab.Execute("C = H(idx1,idx0) ;"); Matlab.Execute("D = full(H(idx1,idx1));"); Matlab.Execute("clear H;"); object linvopt = null; switch (invopt) { case "B/D": Matlab.Execute("bhess = A -(B / D)* C;"); break; case "inv": Matlab.Execute("D = inv(D);"); Matlab.Execute("bhess = A - B * D * C;"); break; case "pinv": Matlab.Execute("D = pinv(D);"); Matlab.Execute("bhess = A - B * D * C;"); break; case "_eig": bool bCheckInv = false; if (bCheckInv) { Matlab.Execute("Dbak = D;"); } Matlab.Execute("[D,DD] = eig(D);"); if (HDebug.False) { Matlab.Execute("DD(abs(DD)<" + linvopt + ") = 0;"); Matlab.Execute("DD = pinv(DD);"); } else { Matlab.Execute("DD = diag(DD);"); Matlab.Execute("DDidx = abs(DD)<" + linvopt + ";"); Matlab.Execute("DD = 1./DD;"); Matlab.Execute("DD(DDidx) = 0;"); Matlab.Execute("DD = diag(DD);"); Matlab.Execute("clear DDidx;"); } Matlab.Execute("D = D * DD * D';"); if (bCheckInv) { double err0 = Matlab.GetValue("max(max(abs(eye(size(D)) - Dbak * D)))"); } if (bCheckInv) { double err1 = Matlab.GetValue("max(max(abs(eye(size(D)) - D * Dbak)))"); } if (bCheckInv) { Matlab.Execute("clear Dbak;"); } Matlab.Execute("clear DD;"); Matlab.Execute("bhess = A - B * D * C;"); break; default: { if (invopt.StartsWith("eig(threshold:") && invopt.EndsWith(")")) { // ex: "eig(threshold:0.000000001)" linvopt = invopt.Replace("eig(threshold:", "").Replace(")", ""); linvopt = double.Parse(linvopt as string); goto case "_eig"; } } throw new HException(); } Matlab.Execute("clear A; clear B; clear C; clear D;"); Matlab.Execute("bhess = (bhess + bhess')/2;"); hess_HH = Matlab.GetMatrix("bhess", Matrix.Zeros, true); Matlab.Clear(); } return(new HessMatrixDense { hess = hess_HH }); }
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, }); }
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), }); }
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); }
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); }
public static ValueTuple <HessMatrix, Vector> Get_BInvDC_BInvDG_Simple (HessMatrix CC , HessMatrix DD , Vector GG , bool process_disp_console , double?thld_BinvDC = null , bool parallel = false ) { HessMatrix BB_invDD_CC; Vector BB_invDD_GG; 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", C.GetMatrixSparse(), 3, 3); } Matlab.PutMatrix("D", DD); if (process_disp_console) { System.Console.Write("D"); } Matlab.PutVector("G", GG); if (process_disp_console) { System.Console.Write("G"); } // Matlab.Execute("BinvDC = C' * inv(D) * C;"); { Matlab.Execute("BinvDC = C' * inv(D);"); Matlab.Execute("BinvD_G = BinvDC * G;"); Matlab.Execute("BinvDC = BinvDC * C;"); } BB_invDD_GG = Matlab.GetVector("BinvD_G"); //Matrix BBinvDDCC = Matlab.GetMatrix("BinvDC", true); if (thld_BinvDC != null) { Matlab.Execute("BinvDC(find(abs(BinvDC) < " + thld_BinvDC.ToString() + ")) = 0;"); } Func <int, int, HessMatrix> Zeros = delegate(int colsize, int rowsize) { return(HessMatrixDense.ZerosDense(colsize, rowsize)); }; BB_invDD_CC = Matlab.GetMatrix("BinvDC", Zeros, true); if (process_disp_console) { System.Console.Write("Y), "); } Matlab.Execute("clear;"); } //GC.Collect(0); return(new ValueTuple <HessMatrix, Vector> (BB_invDD_CC , BB_invDD_GG )); }
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, }); }