public static void SelectCommonAtoms <Atom>(ref List <Atom> atoms1, ref List <Atom> atoms2)
            where Atom : IAtom
        {
            List <Atom> _atoms1 = new List <Atom>(atoms1);
            List <Atom> _atoms2 = new List <Atom>(atoms2);

            _atoms1 = _atoms1.ListCommon(_atoms2);
            HPack <List <int> > idxAtom2ToAtom1 = new HPack <List <int> >();

            //{
            //    List<Atom> cas1 = _atoms1.SelectByName("CA");
            //    List<Atom> cas2 = _atoms2.SelectByName("CA");
            //    List<int> idx1 = new List<int>();
            //    List<int> idx2 = new List<int>();
            //    LCS.LongestCommonSubsequence( cas1 , cas2 , idx1, idx2, Atom.CompareNameResName);
            //    cas1 = cas1.SelectByIndex(idx1);
            //    cas2 = cas2.SelectByIndex(idx2);
            //}
            _atoms2 = _atoms2.ListCommon(_atoms1, idxAtom2ToAtom1);
            _atoms1 = _atoms1.HSelectByIndex(idxAtom2ToAtom1.value).ToList();

            if (HDebug.IsDebuggerAttached)
            {
                HDebug.AssertAllEquals(_atoms1.Count, _atoms2.Count);
                for (int i = 0; i < _atoms1.Count; i++)
                {
                    HDebug.AssertAllEquals(_atoms1[i].name.Trim(), _atoms2[i].name.Trim());
                    HDebug.AssertAllEquals(_atoms1[i].resName.Trim(), _atoms1[i].resName.Trim());
                    HDebug.AssertAllEquals(_atoms1[i].resSeq, _atoms1[i].resSeq);
                }
            }

            atoms1 = _atoms1;
            atoms2 = _atoms2;
        }
Beispiel #2
0
            public static void Align(IList <Vector> C1
                                     , IList <Anisou> anisou1
                                     , ref List <Vector> C2
                                     , HPack <List <Vector> > optMoveC2 = null
                                     , HPack <Trans3> outTrans          = null
                                     , HPack <double> optEnergy         = null
                                     )
            {
                Trans3 trans = GetTrans(C1, anisou1, C2, optEnergy: optEnergy);

                Vector[] nC2 = trans.GetTransformed(C2).ToArray();
                if (optMoveC2 != null)
                {
                    optMoveC2.value = new List <Vector>(nC2.Length);
                    for (int i = 0; i < nC2.Length; i++)
                    {
                        optMoveC2.value.Add(nC2[i] - C2[i]);
                    }
                }
                if (outTrans != null)
                {
                    outTrans.value = trans;
                }
                C2 = new List <Vector>(nC2);
            }
Beispiel #3
0
            public static void Align(IList <Vector> C1
                                     , IList <Anisou> anisou1
                                     , ref IList <Vector> C2
                                     , ref IList <Anisou> anisou2
                                     , HPack <Trans3> outTrans  = null
                                     , HPack <double> optEnergy = null
                                     )
            {
                Trans3 trans = GetTrans(C1, anisou1, C2, anisou2, optEnergy: optEnergy);

                C2      = new List <Vector>(C2);
                anisou2 = new List <Anisou>(anisou2);

                Vector[] nC2 = trans.GetTransformed(C2).ToArray();
                for (int i = 0; i < C2.Count; i++)
                {
                    Vector p2i  = C2[i];
                    Anisou a2i  = anisou2[i];
                    Vector np2i = trans.DoTransform(p2i);
                    Anisou na2i = a2i.Clone();
                    na2i.eigvecs[0] = (trans.DoTransform(p2i + a2i.eigvecs[0]) - np2i).UnitVector();
                    na2i.eigvecs[1] = (trans.DoTransform(p2i + a2i.eigvecs[1]) - np2i).UnitVector();
                    na2i.eigvecs[2] = (trans.DoTransform(p2i + a2i.eigvecs[2]) - np2i).UnitVector();
                    C2[i]           = np2i;
                    anisou2[i]      = na2i;
                }
                if (outTrans != null)
                {
                    outTrans.value = trans;
                }
            }
Beispiel #4
0
            public static void Align(IList <Vector> C1
                                     , ref List <Vector> C2
                                     , HPack <List <Vector> > optMoveC2 = null
                                     , HPack <Trans3> outTrans          = null
                                     , HPack <double> optRmsd           = null
                                     )
            {
                Trans3 trans = GetTrans(C1, C2);

                Vector[] nC2 = trans.GetTransformed(C2).ToArray();
                if (optMoveC2 != null)
                {
                    optMoveC2.value = new List <Vector>(nC2.Length);
                    for (int i = 0; i < nC2.Length; i++)
                    {
                        optMoveC2.value[i] = nC2[i] - C2[i];
                    }
                }
                if (optRmsd != null)
                {
                    optRmsd.value = 0;
                    for (int i = 0; i < nC2.Length; i++)
                    {
                        optRmsd.value += (nC2[i] - C1[i]).Dist2;
                    }
                    optRmsd.value /= nC2.Length;
                }
                C2 = new List <Vector>(nC2);
                if (outTrans != null)
                {
                    outTrans.value = trans.Clone();
                }
            }
        public static List <Atom> ListCommon <Atom>(this IList <Atom> atoms, IList <Atom> atomsToCompare
                                                    , HPack <List <int> > outAtomIdx = null // index for the returned list
                                                    )
            where Atom : IAtom
        {
            List <Atom> list = new List <Atom>();

            if (outAtomIdx != null)
            {
                outAtomIdx.value = new List <int>();
            }
            foreach (Atom atom in atoms)
            {
                int idx = atomsToCompare.IndexOfAtom(atom.name, atom.resSeq);
                if (idx == -1)
                {
                    continue;
                }
                list.Add(atom);
                if (outAtomIdx != null)
                {
                    outAtomIdx.value.Add(idx);
                }
            }
            return(list);
        }
        public static void SelectCommonAtoms <Atom>(ref List <Atom> atoms1, ref List <Atom> atoms2, ref List <Atom> atoms3, ref List <Atom> atoms4, ref List <Atom> atoms5)
            where Atom : IAtom
        {
            List <Atom> _atoms1 = new List <Atom>(atoms1);
            List <Atom> _atoms2 = new List <Atom>(atoms2);
            List <Atom> _atoms3 = new List <Atom>(atoms3);
            List <Atom> _atoms4 = new List <Atom>(atoms4);
            List <Atom> _atoms5 = new List <Atom>(atoms5);

            _atoms1 = _atoms1.ListCommon(_atoms2);
            _atoms1 = _atoms1.ListCommon(_atoms3);
            _atoms1 = _atoms1.ListCommon(_atoms4);
            _atoms1 = _atoms1.ListCommon(_atoms5);

            HPack <List <int> > idxAtom2ToAtom1 = new HPack <List <int> >();

            _atoms2 = _atoms2.ListCommon(_atoms1, idxAtom2ToAtom1);
            _atoms2 = _atoms2.HSelectByIndex(idxAtom2ToAtom1.value).ToList();

            HPack <List <int> > idxAtom3ToAtom1 = new HPack <List <int> >();

            _atoms3 = _atoms3.ListCommon(_atoms1, idxAtom3ToAtom1);
            _atoms3 = _atoms3.HSelectByIndex(idxAtom3ToAtom1.value).ToList();

            HPack <List <int> > idxAtom4ToAtom1 = new HPack <List <int> >();

            _atoms4 = _atoms4.ListCommon(_atoms1, idxAtom4ToAtom1);
            _atoms4 = _atoms4.HSelectByIndex(idxAtom4ToAtom1.value).ToList();

            HPack <List <int> > idxAtom5ToAtom1 = new HPack <List <int> >();

            _atoms5 = _atoms5.ListCommon(_atoms1, idxAtom5ToAtom1);
            _atoms5 = _atoms5.HSelectByIndex(idxAtom5ToAtom1.value).ToList();

            if (HDebug.IsDebuggerAttached)
            {
                HDebug.AssertAllEquals(_atoms1.Count, _atoms2.Count, _atoms3.Count, _atoms4.Count, _atoms5.Count);
                for (int i = 0; i < _atoms1.Count; i++)
                {
                    HDebug.AssertAllEquals(_atoms1[i].name, _atoms2[i].name, _atoms3[i].name, _atoms4[i].name, _atoms5[i].name);
                    HDebug.AssertAllEquals(_atoms1[i].resName, _atoms1[i].resName, _atoms3[i].resName, _atoms4[i].resName, _atoms5[i].resName);
                    HDebug.AssertAllEquals(_atoms1[i].resSeq, _atoms1[i].resSeq, _atoms3[i].resSeq, _atoms4[i].resSeq, _atoms5[i].resSeq);
                }
            }

            atoms1 = _atoms1;
            atoms2 = _atoms2;
            atoms3 = _atoms3;
            atoms4 = _atoms4;
            atoms5 = _atoms5;
        }
Beispiel #7
0
            public static void Align(IList <Vector> C1
                                     , ref List <Vector> C2
                                     , IList <double> weight
                                     , HPack <Trans3> outTrans = null
                                     )
            {
                Trans3 trans = GetTrans(C1, C2, weight);

                Vector[] nC2 = trans.GetTransformed(C2).ToArray();
                C2 = new List <Vector>(nC2);
                if (outTrans != null)
                {
                    outTrans.value = trans.Clone();
                }
            }
Beispiel #8
0
 public static void Align(ref List <Pdb.Atom>[] ensemble
                          , int maxiteration = int.MaxValue
                          , HPack <List <Trans3[]> > outTrajTrans = null
                          )
 {
     List <Vector>[] coordss = new List <Vector> [ensemble.Length];
     for (int i = 0; i < ensemble.Length; i++)
     {
         coordss[i] = ensemble[i].ListCoord();
     }
     Align(ref coordss, maxiteration: maxiteration, outTrajTrans: outTrajTrans);
     ensemble = ensemble.HClone <List <Pdb.Atom> >();
     for (int i = 0; i < ensemble.Length; i++)
     {
         ensemble[i] = ensemble[i].CloneByUpdateCoord(coordss[i]);
     }
 }
Beispiel #9
0
            public static Trans3 GetTrans(IList <Vector> C1, IList <Vector> C2, HPack <int> optIter = null, HPack <List <double> > optListWeightSum = null)
            {
                HDebug.Assert(C1.Count == C2.Count);
                int size = C1.Count;

                if (optIter != null)
                {
                    optIter.value = 0;
                }

                Trans3 trans0 = new Trans3(new double[3], 1, Quaternion.UnitRotation);
                Trans3 trans1 = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1);

                if (optListWeightSum != null)
                {
                    optListWeightSum.value = new List <double>();
                }
                while ((trans0.TransformMatrix - trans1.TransformMatrix).ToArray().HAbs().HMax() > 0.00000001)
                {
                    if (optIter != null)
                    {
                        optIter.value++;
                    }
                    Vector[] C2trans = trans1.GetTransformed(C2).ToArray();

                    double[] weight = new double[size];
                    double[] dist2s = new double[size];
                    for (int i = 0; i < size; i++)
                    {
                        double dist2 = (C1[i] - C2trans[i]).Dist2;
                        dist2     = HMath.Between(0.001, dist2, double.PositiveInfinity);
                        weight[i] = 1 / dist2;
                        dist2s[i] = dist2;
                    }
                    if (optListWeightSum != null)
                    {
                        optListWeightSum.value.Add(weight.Sum());
                    }

                    trans0 = trans1;
                    trans1 = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1, weight);
                }

                return(trans1);
            }
Beispiel #10
0
            public static void Align(List <Vector> coords1
                                     , ref List <Vector> coords2
                                     , int maxiteration = int.MaxValue
                                     , HPack <List <Trans3[]> > outTrajTrans = null
                                     )
            {
                List <Vector>[] ensemble = new List <Vector>[]
                {
                    coords1.HClone(),
           coords2.HClone()
                };
                Align(ref ensemble, maxiteration: maxiteration, outTrajTrans: outTrajTrans);
                Trans3 trans = MinRMSD.GetTrans(coords1, ensemble[0]);

                Vector[] ensemble0 = trans.GetTransformed(ensemble[0]).ToArray();
                Vector[] ensemble1 = trans.GetTransformed(ensemble[1]).ToArray();
                coords2 = new List <Vector>(ensemble1);
            }
        private PreparedHeader(PreparedHeaderName name, string value, byte[] valueEncoded, uint http2StaticIndex)
        {
            Value  = value;
            _name  = name;
            _value = valueEncoded;

            int http1EncodedLen = Http1Connection.GetEncodeHeaderLength(name._http1Encoded, valueEncoded);

            _http1Encoded = new byte[http1EncodedLen];
            Http1Connection.EncodeHeader(name._http1Encoded, valueEncoded, _http1Encoded);

            _http2Encoded =
                http2StaticIndex != 0 ? HPack.EncodeIndexedHeader(http2StaticIndex) :
                name._http2StaticIndex != 0 ? HPack.EncodeHeaderWithoutIndexing(name._http2StaticIndex, valueEncoded) :
                HPack.EncodeHeaderWithoutIndexing(name._http2Encoded, valueEncoded);

            _http2StaticIndex = http2StaticIndex;
        }
Beispiel #12
0
 public static Mode[] GetModeByTorsional(Universe univ
                                         , Matrix hessian
                                         , List <Universe.RotableInfo> univ_rotinfos = null
                                         , Matrix J                 = null
                                         , Vector[] coords          = null
                                         , 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
                                         )
 {
     return(GetModeByTorsional(univ
                               , new HessMatrixDense {
         hess = hessian
     }
                               , univ_rotinfos, J
                               , coords, optoutJMJ, optoutJM
                               , fnEigSymm, fnMul
                               ));
 }
Beispiel #13
0
            private static double Align(List <Vector>[] ensemble, Vector[] meancoords, Anisou[] meananisous, Trans3[] outTranss)
            {
                double[] move2s = new double[ensemble.Length];
                System.Threading.Tasks.Parallel.For(0, ensemble.Length, delegate(int i)
                                                    //for(int i=0; i<ensemble.Length; i++)
                {
                    HPack <List <Vector> > optMoveConf = new HPack <List <Vector> >();
                    HPack <Trans3> outTrans            = new HPack <Trans3>();
                    MinAnisou.Align(meancoords, meananisous, ref ensemble[i], optMoveConf, outTrans: outTrans);
                    if (outTranss != null)
                    {
                        outTranss[i] = outTrans.value;
                    }
                    move2s[i] = optMoveConf.value.Dist2().Average();
                }
                                                    );
                double move2 = move2s.Average();

                return(move2);
            }
Beispiel #14
0
            private void GetPotentialAndTorForce(List <ForceField.IForceField> frcflds, Vector[] coords
                                                 , out double energy, out Vector[] forces
                                                 , Dictionary <string, object> cache)
            {
                MatrixByArr J;

                {
                    Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = univ.BuildFlexibilityGraph();
                    List <Universe.RotableInfo>            univ_rotinfos  = univ.GetRotableInfo(univ_flexgraph);
                    J = Paper.TNM.GetJ(univ, coords, univ_rotinfos);
                }

                Vector[]    forces0 = univ.GetVectorsZero();
                MatrixByArr hessian = null;

                energy = univ.GetPotential(frcflds, coords, ref forces0, ref hessian, cache);
                HPack <Vector[]> lforces = new HPack <Vector[]>();

                double[] dtor = Paper.TNM.GetRotAngles(univ, coords, forces0, 1, J: J, forcesProjectedByTorsional: lforces);
                forces = lforces.value;
            }
Beispiel #15
0
            public static Top FromPdb(string pdbpath
                                      , string ff    = "charmm27"
                                      , string water = "none"
                                      , HPack <Pdb> optout_confout = null
                                      )
            {
                Top top;

                FileInfo      pdbinfo  = new FileInfo(pdbpath);
                string        currdir  = HEnvironment.CurrentDirectory;
                DirectoryInfo temproot = HDirectory.CreateTempDirectory();

                HEnvironment.CurrentDirectory = temproot.FullName;
                {
                    HFile.Copy(pdbinfo.FullName, "protein.pdb");

                    RunPdb2gmx(f: "protein.pdb"
                               , o: "confout.pdb"
                               , p: "topol.top"
                               , q: "clean.pdb"
                               , ff: ff
                               , water: water
                               , merge: "all"
                               , lineStderr: null
                               , lineStdout: null
                               );

                    top = Top.FromFile("topol.top");
                    if (optout_confout != null)
                    {
                        optout_confout.value = Pdb.FromFile("confout.pdb");
                    }
                }
                HEnvironment.CurrentDirectory = currdir;
                Thread.Sleep(100);
                try{ temproot.Delete(true); } catch (Exception) {}

                return(top);
            }
Beispiel #16
0
            public static Mode[] GetModeByTorsional(Universe univ
                                                    , HessMatrix hessian
                                                    , List <Universe.RotableInfo> univ_rotinfos = null
                                                    , Matrix J                 = null
                                                    , Vector[] coords          = null
                                                    , 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
                                                    )
            {
                if (univ_rotinfos == null)
                {
                    Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = univ.BuildFlexibilityGraph(null as IList <Bond>);
                    if (univ_flexgraph.FindLoops().Count > 0)
                    {
                        // loop should not exist in the flexibility-graph; no-global loop in backbone
                        return(null);
                    }
                    univ_rotinfos = univ.GetRotableInfo(univ_flexgraph);
                }
                if (coords == null)
                {
                    coords = univ.GetCoords();
                }
                if (J == null)
                {
                    J = TNM.GetJ(univ, coords, univ_rotinfos);
                }
                Vector masses = univ.GetMasses();

                Mode[] modes = GetModeByTorsional(hessian, masses, J
                                                  , optoutJMJ: optoutJMJ, optoutJM: optoutJM
                                                  , fnEigSymm: fnEigSymm, fnMul: fnMul
                                                  );
                return(modes);
            }
        ////////////////////////////////////////////////////////////////////////////
        // Source: Gromacs, g_nmens.c
        //
        // #define BOLTZ            (RGAS/KILO)            /* (kJ/(mol K)) */
        // #define RGAS             (BOLTZMANN*AVOGADRO)   /* (J/(mol K))  */
        // #define BOLTZMANN	 (1.380658e-23)		/* (J/K)	*/
        // #define AVOGADRO	 (6.0221367e23)		/* ()		*/
        // #define KILO          (1e3)			/* Thousand	*/
        //
        //  for(s=0; s<nstruct; s++) {
        //    for(i=0; i<natoms; i++)
        //      copy_rvec(xav[i],xout1[i]);
        //	//////////////////////////////////////////////////
        //	randnorms_mag = 0;
        //	for(j=0; j<noutvec; j++)
        //	{
        //		randnorms[j] = RandNormal();
        //		randnorms_mag += randnorms[j]*randnorms[j];
        //	}
        //	randnorms_mag = sqrt(randnorms_mag);
        //	for(j=0; j<noutvec; j++)
        //	{
        //		randnorms[j] = randnorms[j] / randnorms_mag;
        //	}
        //	//////////////////////////////////////////////////
        //    for(j=0; j<noutvec; j++) {
        //      v = outvec[j];
        //      /* (r-0.5) n times:  var_n = n * var_1 = n/12
        //	 n=4:  var_n = 1/3, so multiply with 3 */
        //
        //      rfac  = sqrt(3.0 * BOLTZ*temp/eigval[iout[j]]);
        //      //rhalf = 2.0*rfac;
        //      //rfac  = rfac/(real)im;
        //	  //
        //      //jran = (jran*ia+ic) & im;
        //      //jr = (real)jran;
        //      //jran = (jran*ia+ic) & im;
        //      //jr += (real)jran;
        //      //jran = (jran*ia+ic) & im;
        //      //jr += (real)jran;
        //      //jran = (jran*ia+ic) & im;
        //      //jr += (real)jran;
        //      //disp = rfac * jr - rhalf;
        //	  disp = rfac*randnorms[j];
        //
        //      for(i=0; i<natoms; i++)
        //          for(d=0; d<DIM; d++)
        //              xout1[i][d] += disp*eigvec[v][i][d]*invsqrtm[i];
        //    }
        //    for(i=0; i<natoms; i++)
        //        copy_rvec(xout1[i],xout2[index[i]]);
        //    t = s+1;
        //    write_trx(out,natoms,index,atoms,0,t,box,xout2,NULL,NULL);
        //    fprintf(stderr,"\rGenerated %d structures",s+1);
        //  }
        ////////////////////////////////////////////////////////////////////////////

        public static Vector[] GenerateEnsemble(IList <Vector> coords, Mode mode, IList <double> mass, double temperature = 300, bool normalize = true, HPack <Vector> optOutRandNorms = null)
        {
            return(GenerateEnsemble(coords, new Mode[] { mode }, mass, temperature: temperature, normalize: normalize, optOutRandNorms: optOutRandNorms));
        }
            public int ConjugateGradient(List <ForceField.IForceField> frcflds
                                         , double threshold
                                         , double?k = null
                                         , double max_atom_movement = 0.01
                                         , int?max_iteration        = null
                                         , IMinimizeLogger logger   = null            // logger = new MinimizeLogger_PrintEnergyForceMag(logpath);

                                         , HPack <double> optOutEnergy        = null  // optional output for final energy
                                         , List <Vector> optOutForces         = null  // optional output for final force vectors
                                         , HPack <double> optOutForcesNorm1   = null  // optional output for norm of final force vectors
                                         , HPack <double> optOutForcesNorm2   = null  // optional output for norm of final force vectors
                                         , HPack <double> optOutForcesNormInf = null  // optional output for norm of final force vectors
                                         )
            {
                if (k == null)
                {
                    k = double.MaxValue;
                    foreach (ForceField.IForceField frcfld in frcflds)
                    {
                        double?kk = frcfld.GetDefaultMinimizeStep();
                        if (kk.HasValue)
                        {
                            k = Math.Min(k.Value, kk.Value);
                        }
                    }
                }

                Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = univ.BuildFlexibilityGraph();
                List <Universe.RotableInfo>            univ_rotinfos  = univ.GetRotableInfo(univ_flexgraph);
                // double k = 0.0001;
                int iter = 0;

                // 0. Initial configuration of atoms
                Vector[] coords0 = univ.GetCoords();
                Vectors  coords  = univ.GetCoords();

                bool[] atomsMovable = null;
                if (atomsMovable == null)
                {
                    atomsMovable = new bool[size];
                    for (int i = 0; i < size; i++)
                    {
                        atomsMovable[i] = true;
                    }
                }

                Vectors h      = univ.GetVectorsZero();
                Vectors forces = univ.GetVectorsZero();
                Dictionary <string, object> cache;
                double energy;

                cache = new Dictionary <string, object>();
                GetPotentialAndTorForce(frcflds, coords
                                        , out energy, out forces._vecs
                                        , cache);

                double  forces_NormInf = NormInf(forces, atomsMovable);
                double  forces_Norm1   = Norm(1, forces, atomsMovable);
                double  forces_Norm2   = Norm(2, forces, atomsMovable);
                Vectors forces0        = forces;
                double  energy0        = energy;

                while (true)
                {
                    if (forces.IsComputable == false)
                    {
                        System.Console.Error.WriteLine("non-computable components while doing steepest-descent");
                        HEnvironment.Exit(0);
                    }
                    if (logger != null)
                    {
                        logger.log(iter, coords, energy, forces, atomsMovable);
                        {   // logger.logTrajectory(univ, iter, coords);
                            Vector[] coordsx = coords._vecs.HClone <Vector>();
                            Trans3   trans   = ICP3.OptimalTransform(coordsx, coords0);
                            trans.DoTransform(coordsx);
                            logger.logTrajectory(univ, iter, coordsx);
                        }
                    }
                    // 1. Save the position of atoms
                    // 2. Calculate the potential energy of system and the net forces on atoms
                    // 3. Check if every force reaches to zero,
                    //    , and END if yes
                    bool stopIteration = false;
                    if (forces_NormInf < threshold)
                    {
                        stopIteration = true;
                    }
                    if ((max_iteration != null) && (iter >= max_iteration.Value))
                    {
                        stopIteration = true;
                    }
                    if (stopIteration)
                    {
                        // double check
                        cache = new Dictionary <string, object>(); // reset cache
                        GetPotentialAndTorForce(frcflds, coords
                                                , out energy, out forces._vecs
                                                , cache);
                        forces_NormInf = NormInf(forces, atomsMovable);
                        forces_Norm1   = Norm(1, forces, atomsMovable);
                        forces_Norm2   = Norm(2, forces, atomsMovable);

                        if (forces_NormInf < threshold)
                        {
                            if (iter != 1)
                            {
                                univ.SetCoords((Vector[])coords);
                            }
                            {
                                if (optOutEnergy != null)
                                {
                                    optOutEnergy.value = energy;
                                }
                                if (optOutForces != null)
                                {
                                    optOutForces.Clear(); optOutForces.AddRange(forces.ToArray());
                                }
                                if (optOutForcesNorm1 != null)
                                {
                                    optOutForcesNorm1.value = forces_Norm1;
                                }
                                if (optOutForcesNorm2 != null)
                                {
                                    optOutForcesNorm2.value = forces_Norm2;
                                }
                                if (optOutForcesNormInf != null)
                                {
                                    optOutForcesNormInf.value = forces_NormInf;
                                }
                            }
                            return(iter);
                        }
                    }
                    // 4. Move atoms with conjugated gradient
                    Vectors coords_prd;
                    {
                        if ((iter > 0) && (iter % 100 == 0))
                        {
                            cache = new Dictionary <string, object>(); // reset cache
                        }
                        if (iter >= 1)
                        {
                            HDebug.Assert(forces0 != null);
                            double r = Vectors.VtV(forces, forces).Sum() / Vectors.VtV(forces0, forces0).Sum();
                            h = forces + r * h;
                            double kk       = k.Value;
                            double hNormInf = NormInf(h, atomsMovable);
                            if (kk * hNormInf > max_atom_movement)
                            {
                                // make the maximum movement as atomsMovable
                                kk = max_atom_movement / (hNormInf);
                            }

                            Vector dangles = Paper.TNM.GetRotAngles(univ, coords, kk * h, 1);
                            //dangles *= -1;
                            coords_prd = Paper.TNM.RotateTorsionals(coords, dangles, univ_rotinfos);
                        }
                        else
                        {
                            // same to the steepest descent for the first iteration
                            h = forces;
                            double kk       = k.Value;
                            double hNormInf = NormInf(h, atomsMovable);
                            if (kk * hNormInf > max_atom_movement)
                            {
                                // make the maximum movement as atomsMovable
                                kk = max_atom_movement / (hNormInf);
                            }

                            Vector dangles = Paper.TNM.GetRotAngles(univ, coords, kk * h, 1);
                            //dangles *= -1;
                            coords_prd = Paper.TNM.RotateTorsionals(coords, dangles, univ_rotinfos);
                        }
                    }
                    // 5. Predict energy or forces on atoms
                    iter++;
                    double  energy_prd;
                    Vectors forces_prd = univ.GetVectorsZero();
                    GetPotentialAndTorForce(frcflds, coords_prd
                                            , out energy_prd, out forces_prd._vecs
                                            , cache);

                    //                double energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache);
                    //                Vector[] dcoord_prd = univ.GetVectorsZero();
                    //                double[] dangles_prd = TNM.GetRotAngles(univ, coords_prd, forces_prd, 1, dcoordsRotated: dcoord_prd);
                    //                         dangles_prd = TNM.GetRotAngles(univ, coords_prd, hessian_prd, forces_prd, forceProjectedByTorsional: dcoord_prd);
                    //Vectors coords_prd2 = coords_prd.Clone();
                    //TNM.RotateTorsionals(coords_prd2, dangles_prd, univ_rotinfos);

                    double forces_prd_NormInf = NormInf(forces_prd, atomsMovable); // NormInf(forces_prd, atomsMovable);
                    double forces_prd_Norm1   = Norm(1, forces_prd, atomsMovable); // Norm(1, forces_prd, atomsMovable);
                    double forces_prd_Norm2   = Norm(2, forces_prd, atomsMovable); // Norm(2, forces_prd, atomsMovable);
                    // 6. Check if the predicted forces or energy will exceed over the limit
                    //    , and goto 1 if no
                    if ((energy_prd < energy + 0.1) && (forces_prd_NormInf < forces_NormInf + 0.0001))
                    {
                        energy0        = energy;
                        forces0        = forces;
                        coords         = coords_prd;
                        forces         = forces_prd;
                        energy         = energy_prd;
                        forces_NormInf = forces_prd_NormInf;
                        forces_Norm1   = forces_prd_Norm1;
                        forces_Norm2   = forces_prd_Norm2;
                        continue;
                    }
                    if (logger != null)
                    {
                        logger.log(iter, coords_prd, energy_prd, forces_prd, atomsMovable, "will do steepest");
                    }
                    // 7. Back to saved configuration
                    // 8. Move atoms with simple gradient
                    {
                        // same to the steepest descent
                        h = forces;
                        double kk       = k.Value;
                        double hNormInf = NormInf(h, atomsMovable);
                        if (kk * hNormInf > max_atom_movement)
                        {
                            // make the maximum movement as atomsMovable
                            kk = max_atom_movement / (hNormInf);
                        }
                        Vector dangles = Paper.TNM.GetRotAngles(univ, coords, kk * h, 1);
                        //dangles *= -1;
                        coords_prd = Paper.TNM.RotateTorsionals(coords, dangles, univ_rotinfos);
                    }
                    forces_prd = univ.GetVectorsZero();
                    //energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache);
                    GetPotentialAndTorForce(frcflds, coords_prd
                                            , out energy_prd, out forces_prd._vecs
                                            , cache);
                    forces_prd_NormInf = NormInf(forces_prd, atomsMovable);
                    forces_prd_Norm1   = Norm(1, forces_prd, atomsMovable);
                    forces_prd_Norm2   = Norm(2, forces_prd, atomsMovable);

                    energy0        = energy;
                    forces0        = forces;
                    coords         = coords_prd;
                    forces         = forces_prd;
                    energy         = energy_prd;
                    forces_NormInf = forces_prd_NormInf;
                    forces_Norm1   = forces_prd_Norm1;
                    forces_Norm2   = forces_prd_Norm2;
                    // 9. goto 1
                }
            }
Beispiel #19
0
            public static Trans3 GetTrans(IList <Vector> C1, IList <Anisou> anisou1, IList <Vector> C2, IList <Anisou> anisou2, HPack <double> optEnergy = null)
            {
                int size = C1.Count;

                HDebug.Assert(size == C1.Count, size == C2.Count);

                Vector[] srcs = new Vector[size * 3 * 2]; // sources
                Vector[] tars = new Vector[size * 3 * 2]; // targets
                double[] weis = new double[size * 3 * 2]; // weights
                double[] engs = new double[size * 3 * 2]; // energies

                //for(int i=0; i<size; i++)
                //{
                //    Debug.Assert(anisou1[i].eigvals[0] >= 0); W1s[i*3+0] = (anisou1[i].eigvals[0] <= 0) ? 0 : 1 / anisou1[i].eigvals[0];
                //    Debug.Assert(anisou1[i].eigvals[1] >= 0); W1s[i*3+1] = (anisou1[i].eigvals[1] <= 0) ? 0 : 1 / anisou1[i].eigvals[1];
                //    Debug.Assert(anisou1[i].eigvals[2] >= 0); W1s[i*3+2] = (anisou1[i].eigvals[2] <= 0) ? 0 : 1 / anisou1[i].eigvals[2];
                //    enrgs[i*3+0] = enrgs[i*3+1] = enrgs[i*3+2] = double.NaN;
                //}

                //Trans3 trans = ICP3.OptimalTransform(C2, C1);
                Trans3 trans    = new Trans3(new double[] { 0, 0, 0 }, 1, Quaternion.UnitRotation);// = transICP3.OptimalTransformWeighted(C2, C1, W1s);
                int    iter     = 0;
                int    iter_max = 1000;

                //double enrg = double.NaN;
                while (iter < iter_max)
                {
                    iter++;

                    //for(int i=0; i<size; i++)
                    System.Threading.Tasks.Parallel.For(0, size, delegate(int i)
                    {
                        for (int j = 0; j < 3; j++)
                        {
                            Vector p1 = C1[i];
                            Vector n1 = anisou1[i].axes[j];
                            double w1 = anisou1[i].eigvals[j]; w1 = (w1 <= 0) ? 0 : 1 / w1;

                            Vector p2 = trans.DoTransform(C2[i]);
                            Vector n2 = (trans.DoTransform(C2[i] + anisou2[i].axes[j]) - p2).UnitVector();
                            double w2 = anisou2[i].eigvals[j]; w2 = (w2 <= 0) ? 0 : 1 / w2;

                            Vector clo12 = p2 - LinAlg.DotProd(n1, p2 - p1) * n1; // closest point from p1 to plane2
                            Vector clo21 = p1 - LinAlg.DotProd(n2, p1 - p2) * n2; // closest point from p1 to plane2
                            HDebug.AssertTolerance(0.00001, LinAlg.DotProd(clo12 - p1, n1));
                            HDebug.AssertTolerance(0.00001, LinAlg.DotProd(clo21 - p2, n2));

                            // p2 -> (pt closest to p2 on plane1 with w1)
                            srcs[(i * 3 + j) * 2 + 0] = p2;
                            tars[(i * 3 + j) * 2 + 0] = clo12;
                            weis[(i * 3 + j) * 2 + 0] = w1;
                            engs[(i * 3 + j) * 2 + 0] = w1 * (p2 - clo12).Dist2;
                            // inverse of {p1 -> (pt closest to p1 on plane2 with w2)}
                            // = (pt closest to p1 on plane2 with w2) -> p1
                            srcs[(i * 3 + j) * 2 + 1] = clo21;
                            tars[(i * 3 + j) * 2 + 1] = p1;
                            weis[(i * 3 + j) * 2 + 1] = w2;
                            engs[(i * 3 + j) * 2 + 1] = w2 * (clo21 - p1).Dist2;
                        }
                    });
                    Trans3 dtrans = ICP3.OptimalTransformWeighted(srcs, tars, weis);
                    trans = Trans3.AppendTrans(trans, dtrans);
                    double max_dtrans_matrix = (dtrans.TransformMatrix - LinAlg.Eye(4)).ToArray().HAbs().HMax();
                    if (max_dtrans_matrix < 0.0000001)
                    {
                        break;
                    }
                }

                if (optEnergy != null)
                {
                    optEnergy.value = engs.Sum() / size;
                }

                return(trans);
            }
Beispiel #20
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);
            }
Beispiel #21
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);
            }
Beispiel #22
0
            public int QuasiNewton(List <ForceField.IForceField> frcflds
                                   , double threshold
                                   , double?k = null
                                   , double max_atom_movement = 0.01
                                   , int?max_iteration        = null
                                   , IMinimizeLogger logger   = null                  // logger = new MinimizeLogger_PrintEnergyForceMag(logpath);

                                   , HPack <double> optOutEnergy        = null        // optional output for final energy
                                   , List <Vector> optOutForces         = null        // optional output for final force vectors
                                   , HPack <double> optOutForcesNorm1   = null        // optional output for norm of final force vectors
                                   , HPack <double> optOutForcesNorm2   = null        // optional output for norm of final force vectors
                                   , HPack <double> optOutForcesNormInf = null        // optional output for norm of final force vectors
                                   )
            {
                if (k == null)
                {
                    k = double.MaxValue;
                    foreach (ForceField.IForceField frcfld in frcflds)
                    {
                        double?kk = frcfld.GetDefaultMinimizeStep();
                        if (kk.HasValue)
                        {
                            k = Math.Min(k.Value, kk.Value);
                        }
                    }
                }

                Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = univ.BuildFlexibilityGraph();
                List <Universe.RotableInfo>            univ_rotinfos  = univ.GetRotableInfo(univ_flexgraph);
                // double k = 0.0001;
                int iter = 0;

                // 0. Initial configuration of atoms
                Vector[] coords       = univ.GetCoords();
                Vector[] coords0      = univ.GetCoords();
                bool[]   atomsMovable = null;
                {
                    atomsMovable = new bool[size];
                    for (int i = 0; i < size; i++)
                    {
                        atomsMovable[i] = true;
                    }
                }

                Dictionary <string, object> cache = new Dictionary <string, object>();

                Vector[]    forces = null;
                MatrixByArr hessian;
                double      energy = 0;

                double[] dtor;
                double   forces_NormInf;
                double   forces_Norm1;
                double   forces_Norm2;

                do
                {
                    if (logger != null)
                    {
                        if (forces != null)
                        {
                            logger.log(iter, coords, energy, forces, atomsMovable);
                        }
                        {
                            Vector[] coordsx = coords.HClone <Vector>();
                            Trans3   trans   = ICP3.OptimalTransform(coordsx, coords0);
                            trans.DoTransform(coordsx);
                            logger.logTrajectory(univ, iter, coordsx);
                        }
                    }

                    //GetPotentialAndTorForce(frcflds, coords
                    //                       , out energy, out forces, out hessian, out dtor
                    //                       , cache);
                    {
                        MatrixByArr J = Paper.TNM.GetJ(univ, coords, univ_rotinfos);

                        Vector[] forces0 = univ.GetVectorsZero();
                        hessian = new double[size * 3, size *3];
                        energy  = univ.GetPotential(frcflds, coords, ref forces0, ref hessian, cache);
                        forces  = univ.GetVectorsZero();
                        dtor    = Paper.TNM.GetRotAngles(univ, coords, hessian, forces0, J: J, forceProjectedByTorsional: forces);

                        for (int i = 0; i < forces0.Length; i++)
                        {
                            forces0[i] = forces0[i] * 0.001;
                        }
                        dtor = Paper.TNM.GetRotAngles(univ, coords, hessian, forces0, J: J);
                    }

                    forces_NormInf = NormInf(forces, atomsMovable); // NormInf(forces_prd, atomsMovable);
                    forces_Norm1   = Norm(1, forces, atomsMovable); // Norm(1, forces_prd, atomsMovable);
                    forces_Norm2   = Norm(2, forces, atomsMovable); // Norm(2, forces_prd, atomsMovable);

                    if (forces_NormInf < 0.0001)
                    {
                        System.Environment.Exit(0);
                        break;
                    }

                    coords = Paper.TNM.RotateTorsionals(coords, dtor, univ_rotinfos);
                    iter++;
                }while(true);

                while (true)
                {
//                    if(forces.IsComputable == false)
//                    {
//                        System.Console.Error.WriteLine("non-computable components while doing steepest-descent");
//                        Environment.Exit(0);
//                    }
                    if (logger != null)
                    {
                        logger.log(iter, coords, energy, forces, atomsMovable);
                        logger.logTrajectory(univ, iter, coords);
                        //if(iter %10 == 0)
                        //{
                        //    System.IO.Directory.CreateDirectory("output");
                        //    string pdbname = string.Format("mini.conju.{0:D5}.pdb", iter);
                        //    pdb.ToFile("output\\"+pdbname, coords.ToArray());
                        //    System.IO.File.AppendAllLines("output\\mini.conju.[animation].pml", new string[] { "load "+pdbname+", 1A6G" });
                        //}
                    }
                    // 1. Save the position of atoms
                    // 2. Calculate the potential energy of system and the net forces on atoms
                    // 3. Check if every force reaches to zero,
                    //    , and END if yes
                    bool stopIteration = false;
                    if (forces_NormInf < threshold)
                    {
                        stopIteration = true;
                    }
                    if ((max_iteration != null) && (iter >= max_iteration.Value))
                    {
                        stopIteration = true;
                    }
                    if (stopIteration)
                    {
                        // double check
                        cache = new Dictionary <string, object>(); // reset cache
                        //energy = GetPotential(frcflds, coords, out forces, cache);
//                        energy = univ.GetPotential(frcflds, coords, ref forces._vecs, ref hessian, cache);
                        forces_NormInf = NormInf(forces, atomsMovable);
                        forces_Norm1   = Norm(1, forces, atomsMovable);
                        forces_Norm2   = Norm(2, forces, atomsMovable);

                        if (forces_NormInf < threshold)
                        {
                            if (iter != 1)
                            {
                                univ.SetCoords(coords);
                            }
                            //{
                            //    string pdbname = string.Format("mini.conju.{0:D5}.pdb", iter);
                            //    pdb.ToFile("output\\"+pdbname, coords.ToArray());
                            //    System.IO.File.AppendAllLines("output\\mini.conju.[animation].pml", new string[] { "load "+pdbname+", 1A6G" });
                            //}
                            {
                                if (optOutEnergy != null)
                                {
                                    optOutEnergy.value = energy;
                                }
                                if (optOutForces != null)
                                {
                                    optOutForces.Clear(); optOutForces.AddRange(forces.ToArray());
                                }
                                if (optOutForcesNorm1 != null)
                                {
                                    optOutForcesNorm1.value = forces_Norm1;
                                }
                                if (optOutForcesNorm2 != null)
                                {
                                    optOutForcesNorm2.value = forces_Norm2;
                                }
                                if (optOutForcesNormInf != null)
                                {
                                    optOutForcesNormInf.value = forces_NormInf;
                                }
                            }
                            return(iter);
                        }
                    }
                    // 4. Move atoms with conjugated gradient
                    //Vectors coords_prd;
                    {
                        if ((iter > 0) && (iter % 100 == 0))
                        {
                            cache = new Dictionary <string, object>(); // reset cache
                        }
                        if (iter > 1)
                        {
//                            Debug.Assert(forces0 != null);
//                            double r = Vectors.VtV(forces, forces).Sum() / Vectors.VtV(forces0, forces0).Sum();
//                            h          = forces + r * h;
//                            double kk      = k.Value;
//                            double hNormInf = NormInf(h, atomsMovable);
//                            if(kk*hNormInf > max_atom_movement)
//                                // make the maximum movement as atomsMovable
//                                kk = max_atom_movement/(hNormInf);
//                            //double kk = (k*h.NormsInf().NormInf() < max_atom_movement) ? k : (max_atom_movement/h.NormsInf().NormInf());
//                            //double   kk = (k.Value*NormInf(h,atomsMovable) < max_atom_movement)? k.Value : (max_atom_movement/NormInf(h,atomsMovable));
//                            double[] dangles = TNM.GetRotAngles(univ, coords._vecs, hessian, (kk * h)._vecs);
//                            coords_prd = TNM.RotateTorsionals(coords, dangles, univ_rotinfos);
                        }
                        else
                        {
//                            // same to the steepest descent for the first iteration
//                            h          = forces;
//                            double kk      = k.Value;
//                            double hNormInf = NormInf(h, atomsMovable);
//                            if(kk*hNormInf > max_atom_movement)
//                                // make the maximum movement as atomsMovable
//                                kk = max_atom_movement/(hNormInf);
//                            //double kk = (k*h.NormsInf().NormInf() < max_atom_movement) ? k : (max_atom_movement/h.NormsInf().NormInf());
//                            //double   kk = (k.Value*NormInf(h,atomsMovable) < max_atom_movement)? k.Value : (max_atom_movement/NormInf(h, atomsMovable));
//
//                            //double[] dangles = TNM.GetRotAngles(this, coords, kk * h, 1);
//                            double[] dangles = TNM.GetRotAngles(univ, coords._vecs, hessian, (kk * h)._vecs);
//                            coords_prd = TNM.RotateTorsionals(coords, dangles, univ_rotinfos);
//
//    //                        coords_prd = AddConditional(coords, kk * h, atomsMovable);
                        }
                    }
                    // 5. Predict energy or forces on atoms
                    iter++;
                    //double energy_prd;
                    Vectors     forces_prd  = univ.GetVectorsZero();
                    MatrixByArr hessian_prd = new double[size * 3, size *3];
                    //double energy_prd = GetPotential(frcflds, coords_prd, out forces_prd, cache); iter++;

//                    GetPotentialAndTorForce(frcflds, coords_prd
//                           , out energy_prd, out forces_prd._vecs, out hessian_prd
//                           , cache);
//    //                double energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache);
//    //                Vector[] dcoord_prd = univ.GetVectorsZero();
//    //                double[] dangles_prd = TNM.GetRotAngles(univ, coords_prd, forces_prd, 1, dcoordsRotated: dcoord_prd);
//    //                         dangles_prd = TNM.GetRotAngles(univ, coords_prd, hessian_prd, forces_prd, forceProjectedByTorsional: dcoord_prd);
//                    //Vectors coords_prd2 = coords_prd.Clone();
//                    //TNM.RotateTorsionals(coords_prd2, dangles_prd, univ_rotinfos);
//
//                    double forces_prd_NormInf = NormInf(forces_prd, atomsMovable); // NormInf(forces_prd, atomsMovable);
//                    double forces_prd_Norm1   = Norm(1, forces_prd, atomsMovable); // Norm(1, forces_prd, atomsMovable);
//                    double forces_prd_Norm2   = Norm(2, forces_prd, atomsMovable); // Norm(2, forces_prd, atomsMovable);
//                    // 6. Check if the predicted forces or energy will exceed over the limit
//                    //    , and goto 1 if no
//    //                doSteepDeescent = true;
//                    //if((doSteepDeescent == false) || ((energy_prd <= energy) && (forces_prd_NormInf < forces_NormInf+1.0))
//                    if((energy_prd < energy+0.1) && (forces_prd_NormInf < forces_NormInf+0.0001))
//                    {
//                        energy0 = energy;
//                        forces0 = forces;
//                        coords = coords_prd;
//                        forces = forces_prd;
//                        hessian = hessian_prd;
//                        energy = energy_prd;
//                        forces_NormInf = forces_prd_NormInf;
//                        forces_Norm1   = forces_prd_Norm1;
//                        forces_Norm2   = forces_prd_Norm2;
//                        continue;
//                    }
//                    if(logger != null)
//                        logger.log(iter, coords_prd, energy_prd, forces_prd, atomsMovable, "will do steepest");
//                    // 7. Back to saved configuration
//                    // 8. Move atoms with simple gradient
//                    {
//                        // same to the steepest descent
//                        h          = forces;
//                        double kk      = k.Value;
//                        double hNormInf = NormInf(h, atomsMovable);
//                        if(kk*hNormInf > max_atom_movement)
//                            // make the maximum movement as atomsMovable
//                            kk = max_atom_movement/(hNormInf);
//                        double[] dangles = TNM.GetRotAngles(univ, coords._vecs, hessian, (kk * h)._vecs);
//                        coords_prd = TNM.RotateTorsionals(coords, dangles, univ_rotinfos);
//                    }
//                    forces_prd = univ.GetVectorsZero();
//                    hessian_prd = new double[size*3, size*3];
//                    //energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache);
//                    GetPotentialAndTorForce(frcflds, coords_prd
//                           , out energy_prd, out forces_prd._vecs, out hessian_prd
//                           , cache);
//                    forces_prd_NormInf = NormInf(forces_prd, atomsMovable);
//                    forces_prd_Norm1   = Norm(1, forces_prd, atomsMovable);
//                    forces_prd_Norm2   = Norm(2, forces_prd, atomsMovable);
//
//                    energy0 = energy;
//                    forces0 = forces;
//                    coords = coords_prd;
//                    forces = forces_prd;
//                    energy = energy_prd;
//                    forces_NormInf = forces_prd_NormInf;
//                    forces_Norm1   = forces_prd_Norm1;
//                    forces_Norm2   = forces_prd_Norm2;
//                    // 9. goto 1
                }
            }
Beispiel #23
0
            public static List <double> ScaleBFactorComp(List <double> bfactorExpr, List <double> bfactorComp, HPack <double> outScale4BfactorComp)
            {
                HDebug.Assert(bfactorExpr.Count == bfactorComp.Count);
                int    size = bfactorComp.Count;
                Matrix A    = new double[size, 1];
                //Matrix A = new double[size, 2];
                Vector b = new double[size];

                for (int i = 0; i < size; i++)
                {
                    A[i, 0] = bfactorComp[i];
                    //A[i, 1] = 1;
                    b[i] = bfactorExpr[i];
                }
                /// A x = b
                /// (A' A) x = (A' b)
                /// x = inv(A' A) * (A' b)
                Matrix At     = A.Tr();
                Matrix AtA    = At * A;
                Vector Atb    = LinAlg.MV(At, b);       // = At * b;
                Matrix invAtA = NumericSolver.Inv(AtA);
                Vector x      = LinAlg.MV(invAtA, Atb); // = invAtA * Atb;
                double scale  = x[0];
                double add    = 0;                      //= x[1];

                double[] bfactorCompScaled = new double[size];
                for (int i = 0; i < size; i++)
                {
                    bfactorCompScaled[i] = bfactorComp[i] * scale + add;
                }
                if (outScale4BfactorComp != null)
                {
                    outScale4BfactorComp.value = scale;
                }
                return(new List <double>(bfactorCompScaled));
            }
Beispiel #24
0
 public static Tinker.Prm.Atom SelectByXyzAtom(this IList <Tinker.Prm.Atom> prmatoms, Tinker.Xyz.Atom xyzatom, HPack <Dictionary <int, Tinker.Prm.Atom> > cache = null)
 {
     foreach (var prmatom in prmatoms)
     {
         if (xyzatom.AtomId == prmatom.Id)
         {
             return(prmatom);
         }
     }
     return(null);
 }
        public int Minimize_ConjugateGradient_AtomwiseUpdate(
            List <ForceField.IForceField> frcflds
            , double threshold = 0.001                          // * threshold for forces.NormInf
            , double?k         = null                           // * step step
                                                                // 0.0001
            , double max_atom_movement = 0.1                    // * maximum atom movement
            , int?max_iteration        = null                   // null for the infinite iteration until converged
            , bool[]  atomsMovable     = null                   // * selection of movable atoms
                                                                //   move all atoms if (atomsMovable == null) or (atomsMovable[all] == true)
                                                                //   move only atom whose (atomsMovable[id] == true)
            , IMinimizeLogger logger = null                     // * write log
                                                                // = new MinimizeLogger_PrintEnergyForceMag()
            , InfoPack extra       = null                       // get extra information
            , bool?doSteepDeescent = null                       // null or true for default

            , HPack <double> optOutEnergy        = null         // optional output for final energy
            , List <Vector> optOutForces         = null         // optional output for final force vectors
            , HPack <double> optOutForcesNorm1   = null         // optional output for norm of final force vectors
            , HPack <double> optOutForcesNorm2   = null         // optional output for norm of final force vectors
            , HPack <double> optOutForcesNormInf = null         // optional output for norm of final force vectors
            )
        {
            if (doSteepDeescent == null)
            {
                doSteepDeescent = true;
            }
            if (k == null)
            {
                k = double.MaxValue;
                foreach (ForceField.IForceField frcfld in frcflds)
                {
                    double?kk = frcfld.GetDefaultMinimizeStep();
                    if (kk.HasValue)
                    {
                        k = Math.Min(k.Value, kk.Value);
                    }
                }
            }
            int iter = 0;

            // 0. Initial configuration of atoms
            Vector[] coords = GetCoords();
            if (atomsMovable == null)
            {
                atomsMovable = new bool[size];
                for (int i = 0; i < size; i++)
                {
                    atomsMovable[i] = true;
                }
            }

            Vectors       h          = GetVectorsZero();
            Vectors       forces     = Vector.NewVectors(size, new double[3]);
            Vectors       moves      = Vector.NewVectors(size, new double[3]);
            Nonbondeds_v1 nonbondeds = null;
//            Dictionary<string,object> cache = new Dictionary<string, object>();
            double energy         = GetPotentialUpdated(frcflds, null, null, null, coords, forces, ref nonbondeds);
            double forces_NormInf = NormInf(forces, atomsMovable);
            double forces_Norm1   = Norm(1, forces, atomsMovable);
            double forces_Norm2   = Norm(2, forces, atomsMovable);

            Vector[] forces0   = forces;
            double   energy0   = energy;
            Vectors  moves0    = moves;
            double   leastMove = 0.000001;

            while (true)
            {
                if (forces.IsComputable == false)
                {
                    System.Console.Error.WriteLine("non-computable components while doing steepest-descent");
                    HEnvironment.Exit(0);
                }
                if (logger != null)
                {
                    logger.log(iter, coords, energy, forces, atomsMovable);
                    logger.logTrajectory(this, iter, coords);
                }
                // 1. Save the position of atoms
                // 2. Calculate the potential energy of system and the net forces on atoms
                // 3. Check if every force reaches to zero,
                //    , and END if yes
                bool stopIteration = false;
                if (forces_NormInf < threshold)
                {
                    stopIteration = true;
                }
                if ((max_iteration != null) && (iter >= max_iteration.Value))
                {
                    stopIteration = true;
                }
                if (stopIteration)
                {
                    // double check
                    //cache = new Dictionary<string, object>(); // reset cache
                    //energy = GetPotential(frcflds, coords, out forces, cache);
                    nonbondeds     = null;
                    energy         = GetPotentialUpdated(frcflds, null, null, null, coords, forces, ref nonbondeds);
                    forces_NormInf = NormInf(forces, atomsMovable);
                    forces_Norm1   = Norm(1, forces, atomsMovable);
                    forces_Norm2   = Norm(2, forces, atomsMovable);

                    if (forces_NormInf < threshold)
                    {
                        if (iter != 1)
                        {
                            SetCoords(coords);
                        }

                        {
                            if (optOutEnergy != null)
                            {
                                optOutEnergy.value = energy;
                            }
                            if (optOutForces != null)
                            {
                                optOutForces.Clear(); optOutForces.AddRange(forces.ToArray());
                            }
                            if (optOutForcesNorm1 != null)
                            {
                                optOutForcesNorm1.value = forces_Norm1;
                            }
                            if (optOutForcesNorm2 != null)
                            {
                                optOutForcesNorm2.value = forces_Norm2;
                            }
                            if (optOutForcesNormInf != null)
                            {
                                optOutForcesNormInf.value = forces_NormInf;
                            }
                        }
                        return(iter);
                    }
                }
                // 4. Move atoms with conjugated gradient
                Vectors coords_prd;
                double  kk;
                {
                    if ((iter > 0) && (iter % 100 == 0))
                    {
                        //cache = new Dictionary<string, object>(); // reset cache
                        nonbondeds = null;
                    }
                    if (iter > 1)
                    {
                        HDebug.Assert(forces0 != null);
                        double r = Vectors.VtV(forces, forces).Sum() / Vectors.VtV(forces0, forces0).Sum();
                        h  = forces + r * h;
                        kk = k.Value;
                        double hNormInf = NormInf(h, atomsMovable);
                        if (kk * hNormInf > max_atom_movement)
                        {
                            // make the maximum movement as atomsMovable
                            kk = max_atom_movement / (hNormInf);
                        }
                        moves      = moves0.Clone();
                        coords_prd = AddConditional(coords, atomsMovable, moves, kk * h, leastMove);
                    }
                    else
                    {
                        // same to the steepest descent for the first iteration
                        h  = forces;
                        kk = k.Value;
                        double hNormInf = NormInf(h, atomsMovable);
                        if (kk * hNormInf > max_atom_movement)
                        {
                            // make the maximum movement as atomsMovable
                            kk = max_atom_movement / (hNormInf);
                        }
                        //double kk = (k*h.NormsInf().NormInf() < max_atom_movement) ? k : (max_atom_movement/h.NormsInf().NormInf());
                        //double   kk = (k.Value*NormInf(h,atomsMovable) < max_atom_movement)? k.Value : (max_atom_movement/NormInf(h, atomsMovable));
                        moves      = moves0.Clone();
                        coords_prd = AddConditional(coords, atomsMovable, moves, kk * h, leastMove);
                    }
                }
                // 5. Predict energy or forces on atoms
                Vectors forces_prd = forces.Clone();
                double  energy_prd = GetPotentialUpdated(frcflds, energy, coords, forces, coords_prd, forces_prd, ref nonbondeds); iter++;
                //double energy_prd = GetPotential(frcflds, coords_prd, out forces_prd, cache); iter++;

                double forces_prd_NormInf = NormInf(forces_prd, atomsMovable);
                double forces_prd_Norm1   = Norm(1, forces_prd, atomsMovable);
                double forces_prd_Norm2   = Norm(2, forces_prd, atomsMovable);
                // 6. Check if the predicted forces or energy will exceed over the limit
                //    , and goto 1 if no
                doSteepDeescent = true;
                //if((doSteepDeescent == false) || ((energy_prd <= energy) && (forces_prd_NormInf < forces_NormInf+1.0))
                if ((energy_prd < energy + 0.1) && (forces_prd_NormInf < forces_NormInf + 0.0001))
                {
                    energy0        = energy;
                    forces0        = forces;
                    moves0         = moves;
                    coords         = coords_prd;
                    forces         = forces_prd;
                    energy         = energy_prd;
                    forces_NormInf = forces_prd_NormInf;
                    forces_Norm1   = forces_prd_Norm1;
                    forces_Norm2   = forces_prd_Norm2;
                    continue;
                }
                if (logger != null)
                {
                    logger.log(iter, coords_prd, energy_prd, forces_prd, atomsMovable, "will do steepest");
                }
                // 7. Back to saved configuration
                // 8. Move atoms with simple gradient
                {
                    // same to the steepest descent
                    h  = forces;
                    kk = k.Value;
                    double hNormInf = NormInf(h, atomsMovable);
                    if (kk * hNormInf > max_atom_movement)
                    {
                        // make the maximum movement as atomsMovable
                        kk = max_atom_movement / (hNormInf);
                    }
                    moves      = moves0.Clone();
                    coords_prd = AddConditional(coords, atomsMovable, moves, kk * h, leastMove);
                }
                //energy_prd = GetPotential(frcflds, coords_prd, out forces_prd, cache);
                energy_prd         = GetPotentialUpdated(frcflds, energy, coords, forces, coords_prd, forces_prd, ref nonbondeds);
                forces_prd_NormInf = NormInf(forces_prd, atomsMovable);
                forces_prd_Norm1   = Norm(1, forces_prd, atomsMovable);
                forces_prd_Norm2   = Norm(2, forces_prd, atomsMovable);

                energy0        = energy;
                forces0        = forces;
                moves0         = moves;
                coords         = coords_prd;
                forces         = forces_prd;
                energy         = energy_prd;
                forces_NormInf = forces_prd_NormInf;
                forces_Norm1   = forces_prd_Norm1;
                forces_Norm2   = forces_prd_Norm2;
                // 9. goto 1
            }
        }
Beispiel #26
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);
            }
Beispiel #27
0
            public static Trans3 GetTrans(IList <Vector> C1, IList <Anisou> anisou1, IList <Vector> C2, HPack <double> optEnergy = null)
            {
                int size = C1.Count;

                HDebug.Assert(size == C1.Count, size == C2.Count);

                Vector[] C1s   = C1.ToArray().Clone(3);
                Vector[] C2s   = C2.ToArray().Clone(3);
                double[] W1s   = new double[size * 3];
                double[] enrgs = new double[size * 3];
                for (int i = 0; i < size; i++)
                {
                    HDebug.Assert(anisou1[i].eigvals[0] >= 0); W1s[i * 3 + 0] = (anisou1[i].eigvals[0] <= 0) ? 0 : 1 / anisou1[i].eigvals[0];
                    HDebug.Assert(anisou1[i].eigvals[1] >= 0); W1s[i * 3 + 1] = (anisou1[i].eigvals[1] <= 0) ? 0 : 1 / anisou1[i].eigvals[1];
                    HDebug.Assert(anisou1[i].eigvals[2] >= 0); W1s[i * 3 + 2] = (anisou1[i].eigvals[2] <= 0) ? 0 : 1 / anisou1[i].eigvals[2];
                    enrgs[i * 3 + 0] = enrgs[i * 3 + 1] = enrgs[i * 3 + 2] = double.NaN;
                }

                //Trans3 trans = ICP3.OptimalTransform(C2, C1);
                Trans3 trans    = new Trans3(new double[] { 0, 0, 0 }, 1, Quaternion.UnitRotation);// = transICP3.OptimalTransformWeighted(C2, C1, W1s);
                int    iter     = 0;
                int    iter_max = 1000;

                //double enrg = double.NaN;
                while (iter < iter_max)
                {
                    iter++;
                    Vector[] C2sUpdated = trans.GetTransformed(C2s);

                    //for(int i=0; i<size; i++)
                    System.Threading.Tasks.Parallel.For(0, size, delegate(int i)
                    {
                        for (int j = 0; j < 3; j++)
                        {
                            Vector planeNormal = anisou1[i].axes[j];
                            Vector planeBase   = C1[i];
                            Vector query       = C2sUpdated[i * 3 + j];
                            Vector closest     = query - LinAlg.DotProd(planeNormal, query - planeBase) * planeNormal;
                            HDebug.AssertTolerance(0.00001, LinAlg.DotProd(closest - planeBase, planeNormal));
                            C1s[i * 3 + j]   = closest;
                            enrgs[i * 3 + j] = W1s[i * 3 + j] * (query - closest).Dist2;
                        }
                    });
                    Trans3 dtrans = ICP3.OptimalTransformWeighted(C2sUpdated, C1s, W1s);
                    trans = Trans3.AppendTrans(trans, dtrans);
                    double max_dtrans_matrix = (dtrans.TransformMatrix - LinAlg.Eye(4)).ToArray().HAbs().HMax();
                    if (max_dtrans_matrix < 0.0000001)
                    {
                        break;
                    }
                }

                if (optEnergy != null)
                {
                    optEnergy.value = enrgs.Sum() / size;
                }

                return(trans);
            }
Beispiel #28
0
            public static void Align(ref List <Vector>[] ensemble
                                     , int maxiteration = int.MaxValue
                                     , HPack <List <Trans3[]> > outTrajTrans = null
                                     )
            {
                List <Vector>[] lensemble = ensemble.HClone <List <Vector> >();

                int size = lensemble[0].Count;

                for (int i = 1; i < lensemble.Length; i++)
                {
                    HDebug.Assert(size == lensemble[i].Count);
                }

                // initial alignment using RMSD
                Trans3[] transs = new Trans3[lensemble.Length];
                transs[0] = Trans3.UnitTrans;

                Vector[] coords             = new Vector[size];
                Anisou[] anisous            = new Anisou[size];
                double   anisou_eigvalthres = 0.00001 * 0.00001;

                double[] bfactors = new double[size];
                {
                    // set ensemble[0] as the initial mean structure
                    for (int i = 0; i < size; i++)
                    {
                        coords[i] = lensemble[0][0].Clone();
                    }
                    // set anisou as sphere (with radii as one)
                    Anisou U0 = Anisou.FromMatrix(new double[3, 3] {
                        { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }
                    });
                    for (int i = 0; i < anisous.Length; i++)
                    {
                        anisous[i] = U0;
                    }
                    // set bfactor as one
                    for (int i = 0; i < bfactors.Length; i++)
                    {
                        bfactors[i] = 1;
                    }
                }

                //List<double>[] bfactorss = new List<double>[ensemble.Length];
                //for(int i=0; i<bfactorss.Length; i++)
                //    bfactorss[i] = new List<double>(bfactors);
                //Pdb.ToFile("ensemble.000.pdb", null, lensemble, bfactorss);

                System.Console.WriteLine("begin iterative alignment");

                double move2 = double.PositiveInfinity;
                //double thres = 0.00001;// *size * lensemble.Length;
                double thres = 0.00001;// *size * lensemble.Length;

                //List<Pdb.Atom> atoms = null;
                //while(thres < move2)
                for (int iter = 0; iter < maxiteration; iter++)
                {
                    transs = new Trans3[ensemble.Length];
                    move2  = Align(lensemble, coords, anisous, transs);

                    if (outTrajTrans != null)
                    {
                        outTrajTrans.value.Add(transs);
                    }

                    System.Console.WriteLine(iter + "th alignment done: (move " + move2 + " Å)");
                    if (move2 < thres)
                    {
                        break;
                    }

                    DetermineMeanConf(lensemble, coords);
                    DetermineThrmlFluc(lensemble, coords, anisous, null, anisou_eigvalthres);
                }

                ensemble = lensemble;
            }
        public static Vector[] GenerateEnsemble(IList <Vector> coords, Mode[] modes, IList <double> mass, double temperature = 300, bool normalize = true, HPack <Vector> optOutRandNorms = null)
        {
            double[] invsqrtm = new double[mass.Count];
            {
                for (int i = 0; i < mass.Count; i++)
                {
                    invsqrtm[i] = 1.0 / Math.Sqrt(mass[i]);
                }
            }

            modes = modes.HRemoveAllNull().ToArray();

            Vector randnorms;

            {
                Random rand = new Random();
                randnorms = rand.NextNormalVector(modes.Length, 1);
                if (normalize)
                {
                    randnorms = randnorms.UnitVector();
                }
            }
            if (optOutRandNorms != null)
            {
                optOutRandNorms.value = randnorms;
            }

            int size = mass.Count;

            Vector[] ensemble = new Vector[size];
            for (int i = 0; i < size; i++)
            {
                ensemble[i] = coords[i].Clone();
            }

            for (int m = 0; m < modes.Length; m++)
            {
                double   eigval = modes[m].eigval;
                Vector[] eigvec = modes[m].GetEigvecsOfAtoms();
                HDebug.Assert(eigvec.Length == size);

                double rfac = Math.Sqrt(3.0 * BOLTZ * temperature / eigval);
                double disp = rfac * randnorms[m];
                //for(int i=0; i<size; i++)
                System.Threading.Tasks.Parallel.For(0, size, delegate(int i)
                {
                    ensemble[i] += disp * eigvec[i] * invsqrtm[i];
                });
            }

            return(ensemble);
        }
Beispiel #30
0
            public static Trans3 GetTrans(IList <Vector> C1, IList <Vector> C2, HPack <int> optIter = null, HPack <List <double> > optListWeightSum = null)
            {
                HDebug.Assert(false);
                HDebug.Assert(C1.Count == C2.Count);
                int size = C1.Count;

                if (optIter != null)
                {
                    optIter.value = 0;
                }

                int    iter   = 0;
                Trans3 trans0 = new Trans3(new double[3], 1, Quaternion.UnitRotation);
                Trans3 trans1 = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1);

                if (optListWeightSum != null)
                {
                    optListWeightSum.value = new List <double>();
                }
                double maxdist = 0;

                for (int i = 0; i < size; i++)
                {
                    Vector diff = C1[i] - trans1.DoTransform(C2[i]); maxdist = Math.Max(maxdist, diff.Dist);
                }
                while ((trans0.TransformMatrix - trans1.TransformMatrix).ToArray().HAbs().HMax() > 0.00000001)
                {
                    iter++;
                    if (optIter != null)
                    {
                        optIter.value++;
                    }
                    Vector[] C2trans = trans1.GetTransformed(C2).ToArray();

                    Vector dist2s = new double[size];
                    Vector dists  = new double[size];
                    for (int i = 0; i < size; i++)
                    {
                        double dist2 = (C1[i] - C2trans[i]).Dist2;
                        dist2     = HMath.Between(0.00001, dist2, double.PositiveInfinity);
                        dist2s[i] = dist2;
                        dists[i]  = Math.Sqrt(dist2);
                    }
                    //int[] idxsort = dist2s.ToArray().IdxSorted().Reverse();
                    Vector weight = dists.Clone() / dists.ToArray().Max();
                    for (int i = 0; i < size; i++)
                    {
                        double w = weight[i];
                        //w = (w*2-1)*4;
                        w         = (w - 1) * 4;
                        w         = 1 / (1 + Math.Exp(-1 * w));
                        weight[i] = w;
                    }
                    //weight[idxsort[i]] = (i <= 6) ? 1 : 0;
                    if (optListWeightSum != null)
                    {
                        optListWeightSum.value.Add(weight.Sum());
                    }

                    trans0 = trans1;
                    trans1 = Geometry.AlignPointPoint.MinRMSD.GetTrans(C2, C1, weight.ToArray());

                    maxdist = 0;
                    for (int i = 0; i < size; i++)
                    {
                        Vector diff = C1[i] - trans1.DoTransform(C2[i]); maxdist = Math.Max(maxdist, diff.Dist);
                    }
                }

                return(trans1);
            }