Esempio n. 1
0
            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);
                }
            }
Esempio n. 3
0
            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);
            }
Esempio n. 4
0
            public static double[] GetBFactor(Mode[] modes, double[] mass = null)
            {
                if (HDebug.Selftest())
                #region selftest
                {
                    using (new Matlab.NamedLock("SELFTEST"))
                    {
                        Matlab.Clear("SELFTEST");
                        Matlab.Execute("SELFTEST.hess = rand(30);");
                        Matlab.Execute("SELFTEST.hess = SELFTEST.hess + SELFTEST.hess';");
                        Matlab.Execute("SELFTEST.invhess = inv(SELFTEST.hess);");
                        Matlab.Execute("SELFTEST.bfactor3 = diag(SELFTEST.invhess);");
                        Matlab.Execute("SELFTEST.bfactor = SELFTEST.bfactor3(1:3:end) + SELFTEST.bfactor3(2:3:end) + SELFTEST.bfactor3(3:3:end);");
                        MatrixByArr selftest_hess    = Matlab.GetMatrix("SELFTEST.hess");
                        Mode[]      selftest_mode    = Hess.GetModesFromHess(selftest_hess);
                        Vector      selftest_bfactor = BFactor.GetBFactor(selftest_mode);
                        Vector      selftest_check   = Matlab.GetVector("SELFTEST.bfactor");
                        Vector      selftest_diff    = selftest_bfactor - selftest_check;
                        HDebug.AssertTolerance(0.00000001, selftest_diff);
                        Matlab.Clear("SELFTEST");
                    }
                }
                #endregion

                int size = modes[0].size;
                if (mass != null)
                {
                    HDebug.Assert(size == mass.Length);
                }
                double[] bfactor = new double[size];
                for (int i = 0; i < size; i++)
                {
                    foreach (Mode mode in modes)
                    {
                        bfactor[i] += mode.eigvec[i * 3 + 0] * mode.eigvec[i * 3 + 0] / mode.eigval;
                        bfactor[i] += mode.eigvec[i * 3 + 1] * mode.eigvec[i * 3 + 1] / mode.eigval;
                        bfactor[i] += mode.eigvec[i * 3 + 2] * mode.eigvec[i * 3 + 2] / mode.eigval;
                    }
                    if (mass != null)
                    {
                        bfactor[i] /= mass[i];
                    }
                }
                return(bfactor);
            }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
            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);
            }
Esempio n. 7
0
            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);
            }
Esempio n. 8
0
        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);
            }
        }
Esempio n. 9
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,
                });
            }
Esempio n. 10
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);
            }
Esempio n. 11
0
        public static Matrix[] GetAnisou(Matrix hessMassWeighted, double[] mass, double scale = 10000 *1000)
        {
            /// Estimation of "anisotropic temperature factors" (ANISOU)
            ///
            /// delta = hess^-1 * force
            ///       = (0 + V7*V7'/L7 + V8*V8'/L8 + V9*V9'/L9 + ...) * force    (* assume that 1-6 eigvecs/eigvals are ignored, because rot,trans *)
            ///
            /// Assume that force[i] follows gaussian distributions N(0,1). Here, if there are 1000 samples, let denote i-th force as fi, and its j-th element as fi[j]
            /// Then, $V7' * fi = si7, V8' * fi = si8, ...$ follows gaussian distribution N(0,1), too.
            /// Its moved position by k-th eigen component is determined then, as
            ///     dik = (Vk * Vk' / Lk) * Fi
            ///         = Vk / Lk * (Vk' * Fi)
            ///         = Vk / Lk * Sik.
            /// Additionally, the moved position j-th atom is:
            ///     dik[j] = Vk[j] / Lk[j] * Sik.
            /// and its correlation matrix is written as (because its mean position is 0 !!!):
            ///     Cik[j] = dik[j] * dik[j]'
            ///            = [dik[j]_x * dik[j]_x    dik[j]_x * dik[j]_y    dik[j]_x * dik[j]_z]
            ///              [dik[j]_y * dik[j]_x    dik[j]_y * dik[j]_y    dik[j]_y * dik[j]_z]
            ///              [dik[j]_z * dik[j]_x    dik[j]_z * dik[j]_y    dik[j]_z * dik[j]_z]
            ///            = (Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) * (Sik*Sik).
            ///
            /// Note that Sik*Sik follows the chi-square distribution, because Sik follows the gaussian distribution N(0,1).
            /// Additionally, note that the thermal fluctuation is (not one projection toward k-th eigen component with only i-th force, but) the results of 1..i.. forced movements and 1..k.. eigen components.
            /// Therefore, for j-th atom, the accumulation of the correlation over all forces (1..i..) with all eigen components (1..k..) is:
            ///     C[j] = sum_{i,k} {(Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) * (Sik*Sik)}.
            ///
            /// Here, Sik is normal distribution independent to i and k. Therefore, the mean of C[j] is
            ///     E(C[j]) = E( sum_{i,k} {(Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) * (Sik*Sik)} )
            ///             = sum_{i,k} E( (Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) * (Sik*Sik) )
            ///             = sum_{i,k} { (Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) * E(Sik*Sik) }
            ///             = sum_{i,k} { (Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) * 1          }          (* because mean of E(x*x)=1 where x~N(0,1) *)
            ///             = sum_{k} { (Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) }
            ///
            /// Note that E(C[j]) is same to the j-th diagonal component of inverse hessian matrix (except, the eigenvalues are squared).
            ///
            /// Fixation: Gromacx generate the ensemble X by
            ///               X[j] = sum_{k} {Vk / sqrt(Lk[j]) / sqrt(mass[j]) * x_k},
            ///           where x~N(0,1). However, the above is assumed as
            ///               X[j] = sum_{k} {Vk / Lk[j] * x_k}.
            ///           In order to apply the assumption by the Gromacs ensemble, The equation should be fixed as
            ///               E(C[j]) = sum_{k} { (Vk[j] * Vk[j]') / (sqrt(Lk[j])*sqrt(Lk[j])) }
            ///                       = sum_{k} { (Vk[j] * Vk[j]') / Lk[j] / mass[j] }
            ///



            // anisotropic temperature factors
            int size = mass.Length;

            HDebug.Assert(hessMassWeighted.RowSize == size * 3, hessMassWeighted.ColSize == size * 3);
            Matrix[] anisous = new Matrix[size];
            using (new Matlab.NamedLock("ANISOU"))
            {
                Matlab.Clear("ANISOU");
                Matlab.PutMatrix("ANISOU.H", hessMassWeighted);
                Matlab.Execute("[ANISOU.V,ANISOU.D] = eig(ANISOU.H);");
                Matlab.Execute("ANISOU.D = diag(ANISOU.D);");
                Matlab.Execute("ANISOU.D = ANISOU.D(7:end);");
                //Matlab.Execute("ANISOU.D = ANISOU.D .^ 2;"); // assume the gromacs ensemble condition
                Matlab.Execute("ANISOU.V = ANISOU.V(:,7:end);");
                Matlab.Execute("ANISOU.invH = ANISOU.V * pinv(diag(ANISOU.D)) * ANISOU.V';");
                for (int i = 0; i < size; i++)
                {
                    string idx = string.Format("{0}:{1}", i * 3 + 1, i * 3 + 3);
                    anisous[i] = Matlab.GetMatrix("ANISOU.invH(" + idx + "," + idx + ")");
                }
                for (int i = 0; i < size; i++)
                {
                    anisous[i] *= (scale / mass[i]);
                }
                Matlab.Clear("ANISOU");
            }
            return(anisous);
        }
Esempio n. 12
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);
            }
Esempio n. 13
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);
            }
Esempio n. 14
0
        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
            });
        }
Esempio n. 15
0
        public static Dictionary <double, double> GetDegeneracyOverlap(IList <Mode> modes1, IList <Mode> modes2, IList <double> masses, double domega)
        {
            List <double> invmasses = new List <double>();

            foreach (var mass in masses)
            {
                invmasses.Add(1 / mass);
            }

            List <Vector> modes1_massweighted = new List <Vector>();

            foreach (var mode in modes1)
            {
                modes1_massweighted.Add(mode.GetMassReduced(invmasses).eigvec);
            }
            List <Vector> modes2_massweighted = new List <Vector>();

            foreach (var mode in modes2)
            {
                modes2_massweighted.Add(mode.GetMassReduced(invmasses).eigvec);
            }

            Matrix modemat1_massweighted = Matrix.FromColVectorList(modes1_massweighted);
            Matrix modemat2_massweighted = Matrix.FromColVectorList(modes2_massweighted);

            Matlab.Clear();
            Matlab.PutMatrix("m1", modemat1_massweighted, true);
            Matlab.PutMatrix("m2", modemat2_massweighted, true);
            Matlab.Execute("dot12 = m1' * m2;");
            Matrix dot12 = Matlab.GetMatrix("dot12", Matrix.Zeros, true);

            Matlab.Clear();

            List <double> freqs2 = modes2.ListFreq().ToList();

            Dictionary <double, double> freq1_dovlp = new Dictionary <double, double>();

            for (int i1 = 0; i1 < modes1.Count; i1++)
            {
                double freq1 = modes1[i1].freq;

                int idx0 = freqs2.BinarySearch(freq1 - domega);
                int idx1 = freqs2.BinarySearch(freq1 + domega);
                //     The zero-based index of item in the sorted System.Collections.Generic.List`1,
                //     if item is found; otherwise, a negative number that is the bitwise complement
                //     of the index of the next element that is larger than item or, if there is no
                //     larger element, the bitwise complement of System.Collections.Generic.List`1.Count.
                if (idx0 < 0)
                {
                    idx0 = Math.Abs(idx0);
                }
                if (idx1 < 0)
                {
                    idx1 = Math.Min(Math.Abs(idx1) - 1, freqs2.Count - 1);
                }

                double dovlp = 0;
                for (int i2 = idx0; i2 <= idx1; i2++)
                {
                    double dot12_i1_i2 = dot12[i1, i2];
                    dovlp += dot12_i1_i2 * dot12_i1_i2;
                }
                dovlp = Math.Sqrt(dovlp);
                freq1_dovlp.Add(freq1, dovlp);
            }

            //modes1.GetMassReduced
            return(freq1_dovlp);
        }
Esempio n. 16
0
        public static Anisou[] FromHessian(MatrixByArr hessMassWeighted, double[] mass, double scale = 10000 *1000
                                           , string cachepath = null
                                           )
        {
            /// Estimation of "anisotropic temperature factors" (ANISOU)
            ///
            /// delta = hess^-1 * force
            ///       = (0 + V7*V7'/L7 + V8*V8'/L8 + V9*V9'/L9 + ...) * force    (* assume that 1-6 eigvecs/eigvals are ignored, because rot,trans *)
            ///
            /// Assume that force[i] follows gaussian distributions N(0,1). Here, if there are 1000 samples, let denote i-th force as fi, and its j-th element as fi[j]
            /// Then, $V7' * fi = si7, V8' * fi = si8, ...$ follows gaussian distribution N(0,1), too.
            /// Its moved position by k-th eigen component is determined then, as
            ///     dik = (Vk * Vk' / Lk) * Fi
            ///         = Vk / Lk * (Vk' * Fi)
            ///         = Vk / Lk * Sik.
            /// Additionally, the moved position j-th atom is:
            ///     dik[j] = Vk[j] / Lk[j] * Sik.
            /// and its correlation matrix is written as (because its mean position is 0 !!!):
            ///     Cik[j] = dik[j] * dik[j]'
            ///            = [dik[j]_x * dik[j]_x    dik[j]_x * dik[j]_y    dik[j]_x * dik[j]_z]
            ///              [dik[j]_y * dik[j]_x    dik[j]_y * dik[j]_y    dik[j]_y * dik[j]_z]
            ///              [dik[j]_z * dik[j]_x    dik[j]_z * dik[j]_y    dik[j]_z * dik[j]_z]
            ///            = (Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) * (Sik*Sik).
            ///
            /// Note that Sik*Sik follows the chi-square distribution, because Sik follows the gaussian distribution N(0,1).
            /// Additionally, note that the thermal fluctuation is (not one projection toward k-th eigen component with only i-th force, but) the results of 1..i.. forced movements and 1..k.. eigen components.
            /// Therefore, for j-th atom, the accumulation of the correlation over all forces (1..i..) with all eigen components (1..k..) is:
            ///     C[j] = sum_{i,k} {(Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) * (Sik*Sik)}.
            ///
            /// Here, Sik is normal distribution independent to i and k. Therefore, the mean of C[j] is
            ///     E(C[j]) = E( sum_{i,k} {(Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) * (Sik*Sik)} )
            ///             = sum_{i,k} E( (Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) * (Sik*Sik) )
            ///             = sum_{i,k} { (Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) * E(Sik*Sik) }
            ///             = sum_{i,k} { (Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) * 1          }          (* because mean of E(x*x)=1 where x~N(0,1) *)
            ///             = sum_{k} { (Vk[j] * Vk[j]') / (Lk[j]*Lk[j]) }
            ///
            /// Note that E(C[j]) is same to the j-th diagonal component of inverse hessian matrix (except, the eigenvalues are squared).
            ///
            /// Fixation: Gromacx generate the ensemble X by
            ///               X[j] = sum_{k} {Vk / sqrt(Lk[j]) / sqrt(mass[j]) * x_k},
            ///           where x~N(0,1). However, the above is assumed as
            ///               X[j] = sum_{k} {Vk / Lk[j] * x_k}.
            ///           In order to apply the assumption by the Gromacs ensemble, The equation should be fixed as
            ///               E(C[j]) = sum_{k} { (Vk[j] * Vk[j]') / (sqrt(Lk[j])*sqrt(Lk[j])) }
            ///                       = sum_{k} { (Vk[j] * Vk[j]') / Lk[j] / mass[j] }
            ///

            int size = mass.Length;

            HDebug.Assert(hessMassWeighted.RowSize == size * 3, hessMassWeighted.ColSize == size * 3);
            Anisou[] anisous = new Anisou[size];

            if (cachepath != null && HFile.Exists(cachepath))
            {
                List <Anisou> lstanisou;
                HDebug.Verify(HSerialize.Deserialize <List <Anisou> >(cachepath, null, out lstanisou));
                anisous = lstanisou.ToArray();
                return(anisous);
            }

            // anisotropic temperature factors
            using (new Matlab.NamedLock("ANISOU"))
            {
                Matlab.Clear("ANISOU");
                Matlab.PutMatrix("ANISOU.H", hessMassWeighted);
                Matlab.Execute("[ANISOU.V,ANISOU.D] = eig(ANISOU.H);");
                Matlab.Execute("ANISOU.D = diag(ANISOU.D);");                                 // get diagonal
                {
                    Matlab.Execute("[ANISOU.sortD, ANISOU.sortIdxD] = sort(abs(ANISOU.D));"); // sorted index of abs(D)
                    Matlab.Execute("ANISOU.D(ANISOU.sortIdxD(1:6)) = 0;");                    // set the 6 smallest eigenvalues as zero
                    //Matlab.Execute("ANISOU.D(ANISOU.D < 0) = 0;");                              // set negative eigenvalues as zero
                }
                //{
                //    Matlab.Execute("ANISOU.D(1:6) = 0;");
                //}
                Matlab.Execute("ANISOU.invD = 1 ./ ANISOU.D;");                             // set invD
                Matlab.Execute("ANISOU.invD(ANISOU.D == 0) = 0;");                          // set Inf (by divided by zero) as zero
                //Matlab.Execute("ANISOU.D = ANISOU.D .^ 2;"); // assume the gromacs ensemble condition
                Matlab.Execute("ANISOU.invH = ANISOU.V * diag(ANISOU.invD) * ANISOU.V';");
                for (int i = 0; i < size; i++)
                {
                    string      idx = string.Format("{0}:{1}", i * 3 + 1, i * 3 + 3);
                    MatrixByArr U   = Matlab.GetMatrix("ANISOU.invH(" + idx + "," + idx + ")");
                    U *= (scale / mass[i]);

                    anisous[i] = Anisou.FromMatrix(U);
                }
                Matlab.Clear("ANISOU");
            }

            if (cachepath != null)
            {
                HSerialize.Serialize(cachepath, null, new List <Anisou>(anisous));
            }

            return(anisous);
        }
Esempio n. 17
0
        public static Mode[] PCA(Matrix cov, int numconfs, Func <Matrix, Tuple <Matrix, Vector> > fnEig = null)
        {
            HDebug.Assert(cov.RowSize == cov.ColSize);
            int size3 = cov.ColSize;

            if (fnEig == null)
            {
                fnEig = delegate(Matrix A)
                {
                    using (new Matlab.NamedLock("TEST"))
                    {
                        Matlab.Clear("TEST");
                        Matlab.PutMatrix("TEST.H", A);
                        Matlab.Execute("TEST.H = (TEST.H + TEST.H')/2;");
                        Matlab.Execute("[TEST.V, TEST.D] = eig(TEST.H);");
                        Matlab.Execute("TEST.D = diag(TEST.D);");
                        //Matlab.Execute("TEST.idx = find(TEST.D>0.00000001);");
                        //Matrix leigvecs = Matlab.GetMatrix("TEST.V(:,TEST.idx)");
                        //Vector leigvals = Matlab.GetVector("TEST.D(TEST.idx)");
                        Matrix leigvecs = Matlab.GetMatrix("TEST.V");
                        Vector leigvals = Matlab.GetVector("TEST.D");
                        Matlab.Clear("TEST");
                        return(new Tuple <Matrix, Vector>(leigvecs, leigvals));
                    }
                }
            }
            ;

            Tuple <Matrix, Vector> eigs = fnEig(cov);
            Matrix eigvecs = eigs.Item1;
            Vector eigvals = eigs.Item2;

            HDebug.Assert(eigvecs.ColSize == size3, eigvals.Size == eigvecs.RowSize);

            Mode[] modes = new Mode[eigvals.Size];
            for (int im = 0; im < modes.Length; im++)
            {
                modes[im] = new Mode
                {
                    eigvec = eigvecs.GetColVector(im),
                    eigval = 1.0 / eigvals[im],
                    th     = im
                }
            }
            ;

            int maxNumEigval = Math.Min(numconfs - 1, size3);

            HDebug.Assert(maxNumEigval >= 0);
            HDebug.Assert(eigvals.Size == size3);
            if (maxNumEigval < size3)
            {
                modes = modes.SortByEigvalAbs().ToArray();
                modes = modes.Take(maxNumEigval).ToArray();
                foreach (var mode in modes)
                {
                    HDebug.Assert(mode.eigval >= 0);
                }
                //Tuple<Mode[], Mode[]> nzmodes_zeromodes = modes.SeparateTolerants();
                //Mode[] modesNonzero = nzmodes_zeromodes.Item1;
                //Mode[] modesZero    = nzmodes_zeromodes.Item2;
                //modes = modesZero;
            }
            HDebug.Assert(modes.Length == maxNumEigval);

            return(modes);
        }