示例#1
0
        static HessMatrix GetMulImpl(HessMatrix left, HessMatrix right, ILinAlg ila, bool warning)
        {
            if (HDebug.Selftest())
            {
                Matrix h1 = new double[, ] {
                    { 0, 1, 2, 3, 4, 5 }
                    , { 1, 2, 3, 4, 5, 6 }
                    , { 2, 3, 4, 5, 6, 7 }
                    , { 3, 4, 5, 6, 7, 8 }
                    , { 4, 5, 6, 7, 8, 9 }
                    , { 5, 6, 7, 8, 9, 0 }
                };
                HessMatrix h2    = HessMatrixSparse.FromMatrix(h1);
                Matrix     h11   = Matrix.GetMul(h1, h1);
                HessMatrix h22   = HessMatrix.GetMulImpl(h2, h2, null, false);
                Matrix     hdiff = h11 - h22;
                HDebug.AssertToleranceMatrix(0, hdiff);
            }
            if ((left is HessMatrixDense) && (right is HessMatrixDense))
            {
                if (ila != null)
                {
                    return(new HessMatrixDense {
                        hess = ila.Mul(left, right)
                    });
                }
                if (warning)
                {
                    HDebug.ToDo("Check (HessMatrixDense * HessMatrixDense) !!!");
                }
            }

            Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > > left_ic_rows = new Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > >();

            foreach (var ic_row in left.EnumRowBlocksAll())
            {
                left_ic_rows.Add(ic_row.Item1, ic_row.Item2.HToDictionaryWithKeyItem2());
            }

            Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > > right_ir_cols = new Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > >();

            foreach (var ir_col in right.EnumColBlocksAll())
            {
                right_ir_cols.Add(ir_col.Item1, ir_col.Item2.HToDictionaryWithKeyItem1());
            }

            HessMatrix mul = null;

            if ((left is HessMatrixDense) && (right is HessMatrixDense))
            {
                mul = HessMatrixDense.ZerosDense(left.ColSize, right.RowSize);
            }
            else
            {
                mul = HessMatrixSparse.ZerosSparse(left.ColSize, right.RowSize);
            }
            for (int ic = 0; ic < left.ColBlockSize; ic++)
            {
                var left_row = left_ic_rows[ic];
                if (left_row.Count == 0)
                {
                    continue;
                }
                for (int ir = 0; ir < right.RowBlockSize; ir++)
                {
                    var right_col = right_ir_cols[ir];
                    if (right_col.Count == 0)
                    {
                        continue;
                    }
                    foreach (var left_ck in left_row)
                    {
                        int ik = left_ck.Key;
                        HDebug.Assert(ic == left_ck.Value.Item1);
                        HDebug.Assert(ik == left_ck.Value.Item2);
                        if (right_col.ContainsKey(ik))
                        {
                            var right_kr = right_col[ik];
                            HDebug.Assert(ik == right_kr.Item1);
                            HDebug.Assert(ir == right_kr.Item2);
                            MatrixByArr mul_ckr = mul.GetBlock(ic, ir) + left_ck.Value.Item3 * right_kr.Item3;
                            mul.SetBlock(ic, ir, mul_ckr);
                        }
                    }
                }
            }

            return(mul);
        }
示例#2
0
        public int UpdateAdd(HessMatrix other, double mul_other, IList <int> idxOther, double thres_NearZeroBlock, bool parallel = false)
        {
            Matrix debug_updateadd = null;

            if (UpdateAdd_SelfTest && idxOther == null && thres_NearZeroBlock == 0)
            {
                if ((100 < ColBlockSize) && (ColBlockSize < 1000) &&
                    (100 < RowBlockSize) && (RowBlockSize < 1000) &&
                    (other.NumUsedBlocks > 20))
                {
                    UpdateAdd_SelfTest = false;
                    debug_updateadd    = this.ToArray();
                    debug_updateadd.UpdateAdd(other, mul_other);
                }
            }

            int[] idx_other;
            if (idxOther == null)
            {
                //HDebug.Exception(ColSize == other.ColSize);
                //HDebug.Exception(RowSize == other.RowSize);
                idx_other = HEnum.HEnumCount(other.ColSize).ToArray();
            }
            else
            {
                idx_other = idxOther.ToArray();
            }

            int count         = 0;
            int count_ignored = 0;

            object _lock         = new object();
            object _lock_ignored = new object();
            Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval)
            {
                count++;
                int         other_bc   = bc_br_bval.Item1;
                int         other_br   = bc_br_bval.Item2;
                MatrixByArr other_bmat = bc_br_bval.Item3;
                if (other_bmat.HAbsMax() <= thres_NearZeroBlock)
                {
                    lock (_lock_ignored)
                        count_ignored++;
                    //continue;
                    return;
                }
                int bc = idx_other[other_bc];
                int br = idx_other[other_br];
                lock (_lock)
                {
                    MatrixByArr this_bmat = GetBlock(bc, br);
                    MatrixByArr new_bmat;
                    if (this_bmat == null)
                    {
                        if (other_bmat == null)
                        {
                            new_bmat = null;
                        }
                        else
                        {
                            new_bmat = mul_other * other_bmat;
                        }
                    }
                    else
                    {
                        if (other_bmat == null)
                        {
                            new_bmat = this_bmat.CloneT();
                        }
                        else
                        {
                            new_bmat = this_bmat + mul_other * other_bmat;
                        }
                    }
                    SetBlock(bc, br, new_bmat);
                }
            };

            if (parallel)
            {
                Parallel.ForEach(other.EnumBlocks(), func);
            }
            else
            {
                foreach (var bc_br_bval in other.EnumBlocks())
                {
                    func(bc_br_bval);
                }
            }

            if (debug_updateadd != null)
            {
                Matrix debug_diff   = debug_updateadd - this;
                double debug_absmax = debug_diff.HAbsMax();
                HDebug.AssertToleranceMatrix(0, debug_diff);
            }

            return(count_ignored);
        }
示例#3
0
            public int SteepestDescent(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);
                MatrixByArr hessian = null;

                energy = univ.GetPotential(frcflds, coords, ref forces._vecs, ref hessian, 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
                        }

                        {
                            // 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
                    {
                        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;
                    }
                }
            }
示例#4
0
 private void GetPotentialAndTorForce(List <ForceField.IForceField> frcflds, Vector[] coords
                                      , out double energy, out Vector[] forces, out MatrixByArr hessian
                                      , Dictionary <string, object> cache)
 {
     double[] dtor;
     GetPotentialAndTorForce(frcflds, coords, out energy, out forces, out hessian, out dtor, cache);
 }
示例#5
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
                }
            }
示例#6
0
        public void __MinimizeTNM(List <ForceField.IForceField> frcflds)
        {
            HDebug.Assert(false);
            // do not use this, because not finished yet

            Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = this.BuildFlexibilityGraph();
            List <Universe.RotableInfo>            univ_rotinfos  = this.GetRotableInfo(univ_flexgraph);

            Vector[] coords      = this.GetCoords();
            double   tor_normInf = double.PositiveInfinity;

            //double maxRotAngle = 0.1;
            Vector[]    forces          = null;
            MatrixByArr hessian         = null;
            double      forces_normsInf = 1;
            int         iter            = 0;
            double      scale           = 1;

            this._SaveCoordsToPdb(iter.ToString("0000") + ".pdb", coords);

            while (true)
            {
                iter++;
                forces  = this.GetVectorsZero();
                hessian = new double[size * 3, size *3];
                Dictionary <string, object> cache = new Dictionary <string, object>();
                double energy = this.GetPotential(frcflds, coords, ref forces, ref hessian, cache);
                forces_normsInf = (new Vectors(forces)).NormsInf().ToArray().Max();
                //System.Console.WriteLine("iter {0:###}: frcnrminf {1}, energy {2}, scale {3}", iter, forces_normsInf, energy, scale);

                //if(forces_normsInf < 0.001)
                //{
                //    break;
                //}
                Vector torz    = null;
                double maxcarz = 1;
                Vector car     = null;
                //double
                using (new Matlab.NamedLock("TEST"))
                {
                    MatrixByArr H = hessian;
                    MatrixByArr J = Paper.TNM.GetJ(this, this.GetCoords(), univ_rotinfos);
                    Vector      m = this.GetMasses(3);
                    Matlab.PutVector("TEST.F", Vector.FromBlockvector(forces));
                    Matlab.PutMatrix("TEST.J", J);
                    Matlab.PutMatrix("TEST.H", H);
                    Matlab.PutVector("TEST.M", m);
                    Matlab.Execute("TEST.M = diag(TEST.M);");
                    Matlab.Execute("TEST.JMJ = TEST.J' * TEST.M * TEST.J;");
                    Matlab.Execute("TEST.JHJ = TEST.J' * TEST.H * TEST.J;");
                    // (J' H J) tor = J' F
                    // (V' D V) tor = J' F  <= (V,D) are (eigvec,eigval) of generalized eigenvalue problem with (A = JHJ, B = JMJ)
                    // tor = inv(V' D V) J' F
                    Matlab.Execute("[TEST.V, TEST.D] = eig(TEST.JHJ, TEST.JMJ);");
                    //Matlab.Execute("TEST.zidx = 3:end;");

                    Matlab.Execute("TEST.invJHJ  = TEST.V * pinv(TEST.D ) * TEST.V';");
                    Matlab.Execute("TEST.tor  = TEST.invJHJ * TEST.J' * TEST.F;");
                    Matlab.Execute("TEST.car  = TEST.J * TEST.tor;");
                    car = Matlab.GetVector("TEST.car");

                    Matlab.Execute("[TEST.DS, TEST.DSI] = sort(abs(diag(TEST.D)));");
                    Matlab.Execute("TEST.zidx = TEST.DSI(6:end);");
                    Matlab.Execute("TEST.Dz = TEST.D;");
                    //Matlab.Execute("TEST.Dz(TEST.zidx,TEST.zidx) = 0;");
                    Matlab.Execute("TEST.invJHJz = TEST.V * pinv(TEST.Dz) * TEST.V';");
                    Matlab.Execute("TEST.torz = TEST.invJHJz * TEST.J' * TEST.F;");
                    Matlab.Execute("TEST.carz = TEST.J * TEST.torz;");
                    torz    = Matlab.GetVector("TEST.torz");
                    maxcarz = Matlab.GetValue("max(max(abs(TEST.carz)))");
                    scale   = 1;
                    if (maxcarz > 0.01)
                    {
                        scale = scale * 0.01 / maxcarz;
                    }
                    Matlab.Clear("TEST");
                };
                tor_normInf = torz.NormInf();
                double frcnrinf = car.ToArray().HAbs().Max();
                if (maxcarz < 0.001)
                {
                    break;
                }
                System.Console.WriteLine("iter {0:###}: frcnrminf {1}, tor(frcnrinf) {2}, energy {3}, scale {4}", iter, forces_normsInf, frcnrinf, energy, scale);

                HDebug.Assert(univ_rotinfos.Count == torz.Size);
                for (int i = 0; i < univ_rotinfos.Count; i++)
                {
                    Universe.RotableInfo rotinfo = univ_rotinfos[i];
                    Vector rotOrigin             = coords[rotinfo.bondedAtom.ID];
                    double rotAngle = torz[i] * scale;   // (maxRotAngle / tor_normInf);
                    if (rotAngle == 0)
                    {
                        continue;
                    }
                    Vector      rotAxis = coords[rotinfo.bond.atoms[1].ID] - coords[rotinfo.bond.atoms[0].ID];
                    Quaternion  rot     = new Quaternion(rotAxis, rotAngle);
                    MatrixByArr rotMat  = rot.RotationMatrix;
                    foreach (Atom atom in rotinfo.rotAtoms)
                    {
                        int    id    = atom.ID;
                        Vector coord = rotMat * (coords[id] - rotOrigin) + rotOrigin;
                        coords[id] = coord;
                    }
                }
                this._SaveCoordsToPdb(iter.ToString("0000") + ".pdb", coords);
            }
        }
示例#7
0
                public static Vector GetAa(Vector ea, Vector R, Vector Ra, Vector sa, double Ma, MatrixByArr invI, MatrixByArr Ia)
                {
                    Vector ea_Rasa = LinAlg.CrossProd3(ea, Ra - sa);
                    Vector IAa     = -LinAlg.MV(Ia, ea) + Ma * LinAlg.CrossProd3(R - Ra, ea_Rasa);
                    Vector Aa      = LinAlg.MV(invI, IAa);

                    return(Aa);
                }
示例#8
0
        public static void ToFile(string filepath
                                  , IList <Atom> atoms
                                  , IList <Vector> coords       = null
                                  , IList <MatrixByArr> anisous = null
                                  , double?anisouScale          = null
                                  , IList <double> bfactors     = null
                                  , bool append            = false
                                  , IList <string> headers = null
                                  , int?modelidx           = null
                                  )
        {
            List <string> lines = new List <string>();
            int           size  = atoms.Count;

            if (coords != null)
            {
                HDebug.Assert(size == coords.Count);
            }
            if (anisous != null)
            {
                HDebug.Assert(size == anisous.Count);
            }
            //if(anisouScale != null) Debug.Assert(size == anisouScale.Count);
            if (headers != null)
            {
                lines.AddRange(headers);
            }
            {
                //           1         2         3         4         5         6         7         8
                //  12345678901234567890123456789012345678901234567890123456789012345678901234567890
                // "MODEL        1                                                                  "
                string line = "MODEL        1                                                                  ";
                if (modelidx != null)
                {
                    line.Replace("1", modelidx.Value.ToString());
                }
                line = line.Substring(0, 80);
                lines.Add(line);
            }

            for (int i = 0; i < size; i++)
            {
                Atom atom = atoms[i];
                if (atom == null)
                {
                    continue;
                }
                {
                    if (coords != null)
                    {
                        double x = coords[i][0];
                        double y = coords[i][1];
                        double z = coords[i][2];
                        atom = Atom.FromString(atom.GetUpdatedLine(x, y, z));
                    }
                    if (bfactors != null)
                    {
                        atom = Atom.FromString(atom.GetUpdatedLineTempFactor(bfactors[i]));
                    }
                    lines.Add(atom.line);
                }
                {
                    if (anisous != null)
                    {
                        MatrixByArr U = anisous[i];
                        if (anisouScale != null)
                        {
                            U = U * anisouScale.Value;
                        }
                        Anisou anisou = Anisou.FromAtom(atom, U.ToArray().HToInt());
                        string line   = anisou.line; //anisou.GetUpdatedU(anisous[i])
                        lines.Add(line);
                    }
                }
            }
            lines.Add("ENDMDL                                                                          ");
            //int idx = 0;
            //foreach(Element element in elements)
            //{
            //    string line = element.line;
            //    if(typeof(Atom).IsInstanceOfType(element))
            //    {
            //        double x = coords[idx][0];
            //        double y = coords[idx][1];
            //        double z = coords[idx][2];
            //        Atom atom = (Atom)element;
            //        line = atom.GetUpdatedLine(x, y, z);
            //        idx++;
            //    }
            //    lines.Add(line);
            //}
            if (append == false)
            {
                HFile.WriteAllLines(filepath, lines);
            }
            else
            {
                StringBuilder text = new StringBuilder();
                foreach (string line in lines)
                {
                    text.AppendLine(line);
                }
                HFile.AppendAllText(filepath, text.ToString());
            }
        }
示例#9
0
                public static void GetMaRaMaraITa(IList <Atom> atoms, Vector[] coords, ref double Ma, ref Vector Ra, ref Vector MaRa, ref MatrixByArr ITa)
                {
                    ////////////////////////////////////////////////////////////////////////
                    // http://en.wikipedia.org/wiki/Moment_of_inertia_tensor#Definition   //
                    //                                                                    //
                    // I = [Ixx Ixy Ixz]                                                  //
                    //     [Iyx Iyy Iyz]                                                  //
                    //     [Izx Izy Izz]                                                  //
                    // Ixx = sum(i=1..n}{ mi (yi^2 + zi^2) }                              //
                    // Iyy = sum{i=1..n}{ mi (xi^2 + zi^2) }                              //
                    // Izz = sum{i=1..n}{ mi (xi^2 + yi^2) }                              //
                    // Ixy = Iyx = sum{i=1..n}{ - mi xi yi }                              //
                    // Ixz = Izx = sum{i=1..n}{ - mi xi zi }                              //
                    // Iyz = Izy = sum{i=1..n}{ - mi yi zi }                              //
                    ////////////////////////////////////////////////////////////////////////
                    Ma = 0;
                    HDebug.Assert(ITa.ColSize == 3, ITa.RowSize == 3); ITa[0, 0] = ITa[0, 1] = ITa[0, 2] = ITa[1, 0] = ITa[1, 1] = ITa[1, 2] = ITa[2, 0] = ITa[2, 1] = ITa[2, 2] = 0;
                    HDebug.Assert(Ra.Size == 3);   Ra[0]   = Ra[1] = Ra[2] = 0;
                    HDebug.Assert(MaRa.Size == 3); MaRa[0] = MaRa[1] = MaRa[2] = 0;
                    foreach (Atom atom in atoms)
                    {
                        double m  = atom.Mass;
                        double x  = coords[atom.ID][0];
                        double y  = coords[atom.ID][1];
                        double z  = coords[atom.ID][2];
                        double xx = m * (y * y + z * z);
                        double yy = m * (x * x + z * z);
                        double zz = m * (x * x + y * y);
                        double xy = -m * x * y;
                        double xz = -m * x * z;
                        double yz = -m * y * z;

                        Ma        += m;
                        Ra[0]     += x;   Ra[1] += y;   Ra[2] += z;
                        MaRa[0]   += m * x; MaRa[1] += m * y; MaRa[2] += m * z;
                        ITa[0, 0] += xx; ITa[0, 1] += xy; ITa[0, 2] += xz;
                        ITa[1, 0] += xy; ITa[1, 1] += yy; ITa[1, 2] += yz;
                        ITa[2, 0] += xz; ITa[2, 1] += yz; ITa[2, 2] += zz;
                    }
                }
示例#10
0
                public unsafe static MatrixByArr GetJ(Universe univ, Vector[] coords, List <RotableInfo> rotInfos)
                {
                    HDebug.Assert(rotInfos.ListMolecule().HUnion().Length == 1);
                    Dictionary <Universe.Molecule, Dictionary <string, object> > moleMRI = new Dictionary <Universe.Molecule, Dictionary <string, object> >();

                    int         n = univ.atoms.Count;
                    int         m = rotInfos.Count;
                    MatrixByArr J = new double[3 * n, m];

                    double[] _Ja = new double[3 * n];
                    for (int a = 0; a < m; a++)
                    {
                        var mole = rotInfos[a].mole;
                        if (moleMRI.ContainsKey(rotInfos[a].mole) == false)
                        {
                            double      _M  = 0;
                            Vector      _R  = new double[3];
                            Vector      _MR = new double[3];
                            MatrixByArr _I  = new double[3, 3];
                            GetMaRaMaraITa(mole.atoms.ToArray(), coords, ref _M, ref _R, ref _MR, ref _I);
                            MatrixByArr _invI = LinAlg.Inv3x3(_I);

                            MatrixByArr _MRx    = GetSSMatrix(_MR);
                            MatrixByArr _MRxt   = _MRx.Tr();
                            MatrixByArr _III    = _I - (1.0 / _M) * _MRx * _MRxt; // { MI - 1/M * [MR]x * [MR]x^t }
                            MatrixByArr _invIII = LinAlg.Inv3x3(_III);

                            moleMRI.Add(mole, new Dictionary <string, object>());
                            moleMRI[mole].Add("invI", _invI);
                            moleMRI[mole].Add("invIII", _invIII);
                            moleMRI[mole].Add("MR", _MR);
                            moleMRI[mole].Add("R", _R);
                            moleMRI[mole].Add("M", _M);
                        }
                        MatrixByArr invI   = moleMRI[mole]["invI"] as MatrixByArr;
                        MatrixByArr invIII = moleMRI[mole]["invIII"] as MatrixByArr;
                        Vector      MR     = moleMRI[mole]["MR"] as Vector;
                        Vector      R      = moleMRI[mole]["R"] as Vector;
                        double      M      = (double)(moleMRI[mole]["M"]);



                        RotableInfo rotInfo = rotInfos[a];
                        double      Ma      = 0;
                        Vector      Ra      = new double[3];
                        Vector      MaRa    = new double[3];
                        MatrixByArr Ia      = new double[3, 3];
                        GetMaRaMaraITa(rotInfo.rotAtoms, coords, ref Ma, ref Ra, ref MaRa, ref Ia);

                        HDebug.Assert(rotInfo.rotAtoms.Contains(rotInfo.bondedAtom));
                        Vector sa = coords[rotInfo.bondedAtom.ID];
                        Vector ea;
                        {
                            Atom bondatom = null;
                            HDebug.Assert(rotInfo.bond.atoms.Length == 2);
                            if (rotInfo.bond.atoms[0] == rotInfo.bondedAtom)
                            {
                                bondatom = rotInfo.bond.atoms[1];
                            }
                            else
                            {
                                bondatom = rotInfo.bond.atoms[0];
                            }
                            HDebug.Assert(rotInfo.rotAtoms.Contains(bondatom) == false);
                            ea = (sa - coords[bondatom.ID]).UnitVector();
                        }

                        Vector Aa;
                        {
                            Vector ea_Rasa = LinAlg.CrossProd3(ea, Ra - sa);
                            Vector IAa     = -LinAlg.MV(Ia, ea) + LinAlg.CrossProd3(Ma * R - MaRa, ea_Rasa);
                            Aa = LinAlg.MV(invI, IAa);
                        }
                        {
                            //Vector ea_MaRa_Masa = Vector.CrossProd3(ea, MaRa-Ma*sa);
                            //Vector ea_sa = Vector.CrossProd3(ea, sa);
                            Vector IAa = new double[3];
                            IAa += -LinAlg.MV(Ia, ea);
                            IAa += LinAlg.CrossProd3(MaRa, LinAlg.CrossProd3(ea, sa));
                            IAa += LinAlg.CrossProd3(MR, LinAlg.CrossProd3(ea, MaRa - Ma * sa)) / M;
                            Aa   = LinAlg.MV(invIII, IAa);
                        }
                        Vector ta = new double[3];
                        {
                            //Aa = new double[3]; // check "translational Eckart condition" only
                            //ta += (-1/M) * Vector.CrossProd3(Aa, MMR);
                            ta += (-1 / M) * LinAlg.CrossProd3(Aa, MR);
                            ta += (-1 / M) * LinAlg.CrossProd3(ea, MaRa - Ma * sa);
                        }

                        fixed(double *Ja = _Ja)
                        {
                            //for(int i=0; i<n; i++)
                            foreach (Atom iaa in mole.atoms)
                            {
                                int    i   = iaa.ID;
                                double mi  = univ.atoms[i].Mass;
                                Vector ri  = coords[univ.atoms[i].ID];
                                Vector Jia = new double[3];
                                //Jia += Vector.CrossProd3(Aa, ri*mi);
                                Jia += LinAlg.CrossProd3(Aa, ri);
                                Jia += ta;
                                //J[i, a] = Jia.ToColMatrix();
                                Ja[i * 3 + 0] = Jia[0];
                                Ja[i * 3 + 2] = Jia[2];
                                Ja[i * 3 + 1] = Jia[1];
                            }
                            foreach (Atom ira in rotInfo.rotAtoms)
                            {
                                int    i   = ira.ID;
                                Vector ri  = coords[univ.atoms[i].ID];
                                Vector Jia = LinAlg.CrossProd3(ea, ri - sa);
                                //J[i, a] += Jia.ToColMatrix();
                                Ja[i * 3 + 0] += Jia[0];
                                Ja[i * 3 + 1] += Jia[1];
                                Ja[i * 3 + 2] += Jia[2];
                            }
                            //for(int i=0; i<n; i++)
                            foreach (Atom iaa in mole.atoms)
                            {
                                int i = iaa.ID;
                                J[i * 3 + 0, a] = Ja[i * 3 + 0];
                                J[i * 3 + 1, a] = Ja[i * 3 + 1];
                                J[i * 3 + 2, a] = Ja[i * 3 + 2];
                            }
                        }

                        if (HDebug.IsDebuggerAttached)
                        {
                            // check Eckart condition
                            // http://en.wikipedia.org/wiki/Eckart_conditions
                            //////////////////////////////////////////////////////////////////////
                            // 1. translational Eckart condition
                            //    sum{i=1..n}{mi * Jia} = 0
                            Vector mJ = new double[3];
                            //for(int i=0; i<n; i++)
                            foreach (Atom iaa in mole.atoms)
                            {
                                int    i  = iaa.ID;
                                double mi = univ.atoms[i].Mass;
                                //Vector Jia = J[i, a].ToVector();
                                Vector Jia = new double[3] {
                                    J[i * 3 + 0, a], J[i * 3 + 1, a], J[i * 3 + 2, a]
                                };
                                mJ += mi * Jia;
                            }
                            HDebug.AssertTolerance(0.00000001, mJ);
                            //////////////////////////////////////////////////////////////////////
                            // 1. rotational Eckart condition
                            //    sum{i=1..n}{mi * r0i x Jia} = 0,
                            //    where 'x' is the cross product
                            Vector mrJ = new double[3];
                            //for(int i=0; i<n; i++)
                            foreach (Atom iaa in mole.atoms)
                            {
                                int    i  = iaa.ID;
                                double mi = univ.atoms[i].Mass;
                                Vector ri = coords[univ.atoms[i].ID];
                                //Vector Jia = J[i, a].ToVector();
                                Vector Jia = new double[3] {
                                    J[i * 3 + 0, a], J[i * 3 + 1, a], J[i * 3 + 2, a]
                                };
                                mrJ += mi * LinAlg.CrossProd3(ri, Jia);
                            }
                            HDebug.AssertTolerance(0.0000001, mrJ);
                        }
                    }
                    return(J);
                }
示例#11
0
            public static void Validate(Vibrate vibrate, MatrixByArr hess, Vector mass, ILinAlg la)
            {
                /// tested with "1I2T"
                int size = mass.Size;

                Vector mass05 = new double[size];
                {
                    for (int i = 0; i < size; i++)
                    {
                        mass05[i] = Math.Sqrt(mass[i]);
                    }
                }
                /// mass05 = {Vector [968] {3.74259, 3.46569, 3.46569, 3.99987, 1.00399, 1.00399, 1.00399, 1.00399, 3.46569, 3.46569, 3.74259, 3.46569, 3.46569, 3.74259, 1.00399, 1.00399, 1.00399, 1.00399, 1.00399, 1.00399, 3.74259, 3.46569, 3.46569, 3.99987, 1.00399, 1.00399, 3.46569,...

                Vector vibrateEigval;
                Vector vibrateFreq;

                Vector[]    vibrateEigvec;
                Vector      vibrateEigvecDist;
                MatrixByArr vibrateEigvecDot;

                {
                    int[] idxs = vibrate.idx2eigval.Keys.ToArray().HSort().ToArray();
                    HDebug.Assert(vibrate.idx2eigval.Count == size * 3);
                    HDebug.Assert(vibrate.idx2freq.Count == size * 3);
                    HDebug.Assert(vibrate.idx2freq_mode.Count == size * 3);
                    vibrateEigval = new double[size * 3];
                    vibrateFreq   = new double[size * 3];
                    vibrateEigvec = new Vector[size * 3];
                    for (int i = 0; i < size * 3; i++)
                    {
                        int idx = idxs[i];
                        vibrateEigval[i] = vibrate.idx2eigval[idx];
                        vibrateFreq[i]   = vibrate.idx2freq[idx];
                        Vector[] eigvec = new Vector[size];
                        foreach (var ia_vec in vibrate.idx2freq_mode[idx].Item2)
                        {
                            eigvec[ia_vec.Item1 - 1] = ia_vec.Item2;
                        }
                        vibrateEigvec[i] = eigvec.ToVector();
                        HDebug.Assert(vibrateEigvec[i].Size == size * 3);
                    }

                    var _V   = la.ToILMat(vibrateEigvec.ToMatrix());
                    var _VtV = _V.Tr * _V;
                    vibrateEigvecDot = _VtV.ToArray();
                    for (int i = 0; i < size * 3; i++)
                    {
                        vibrateEigvecDot[i, i] = 0;
                    }
                    _V.Dispose();
                    _VtV.Dispose();

                    vibrateEigvecDist = new double[size * 3];
                    for (int i = 0; i < size * 3; i++)
                    {
                        vibrateEigvecDist[i] = vibrateEigvec[i].Dist;
                    }
                }
                /// vibrateEigval     = Vector [2904] { 0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.01900,  0.02600,  0.03200,  0.04200,  0.05800,  0.06800,  0.07700,  0.08200,  0.08800,  0.08900,  0.10400,  0.12100,  0.12500,  0.13100,  0.15000,  0.16100,  0.16600,  0.18000, ...
                /// vibrateFreq       = Vector [2904] {-0.01900, -0.01400, -0.00800,  0.00000,  0.00000,  0.00100,  5.97000,  6.71700,  7.78700,  9.02500, 10.48100, 11.23200, 11.86700, 12.47600, 12.78600, 14.07900, 15.24600, 15.46200, 15.73700, 16.34300, 16.82800, 17.57300, 18.04300, 18.67400, ...
                /// vibrateEigvec[ 0] = Vector [2904] {-0.00394, -0.06017, -0.00576, -0.00632, -0.05673, -0.00295, -0.00450, -0.05276, -0.00406, -0.00552, -0.05206, -0.00297, -0.00530, -0.06312, -0.00493, -0.00239, -0.05843, -0.00695, -0.00233, -0.06123, -0.00745, -0.00733, -0.05510, -0.00174, ...
                /// vibrateEigvec[ 1] = Vector [2904] { 0.00730, -0.01099,  0.00744,  0.00414, -0.00792,  0.00451,  0.00615, -0.00426,  0.00541,  0.00562,  0.00042,  0.00420,  0.00594, -0.01300,  0.00675,  0.00824, -0.01384,  0.00864,  0.00999, -0.00856,  0.00907,  0.00196, -0.01082,  0.00335, ...
                /// vibrateEigvec[ 2] = Vector [2904] { 0.04084, -0.01332,  0.04505,  0.03959, -0.01264,  0.04154,  0.03911, -0.01186,  0.03638,  0.04150, -0.01180,  0.03316,  0.04167, -0.01391,  0.04842,  0.03775, -0.01289,  0.04551,  0.04367, -0.01360,  0.04376,  0.03608, -0.01223,  0.04266, ...
                /// vibrateEigvec[ 3] = Vector [2904] { 0.00893, -0.03084, -0.00143,  0.00893, -0.03084, -0.00143,  0.00893, -0.03084, -0.00143,  0.00893, -0.03084, -0.00143,  0.00893, -0.03084, -0.00143,  0.00893, -0.03084, -0.00143,  0.00893, -0.03084, -0.00143,  0.00893, -0.03084, -0.00143, ...
                /// vibrateEigvec[ 4] = Vector [2904] { 0.01849,  0.00415,  0.02596,  0.01849,  0.00415,  0.02596,  0.01849,  0.00415,  0.02596,  0.01849,  0.00415,  0.02596,  0.01849,  0.00415,  0.02596,  0.01849,  0.00415,  0.02596,  0.01849,  0.00415,  0.02596,  0.01849,  0.00415,  0.02596, ...
                /// vibrateEigvec[ 5] = Vector [2904] {-0.02473, -0.00803,  0.01890, -0.02473, -0.00803,  0.01890, -0.02473, -0.00803,  0.01890, -0.02473, -0.00803,  0.01890, -0.02473, -0.00803,  0.01890, -0.02473, -0.00803,  0.01890, -0.02473, -0.00803,  0.01890, -0.02473, -0.00803,  0.01890, ...
                /// vibrateEigvec[ 6] = Vector [2904] {-0.06781, -0.03888, -0.07685, -0.06685, -0.03630, -0.06009, -0.06096, -0.03343, -0.03323, -0.07658, -0.03381, -0.01218, -0.07491, -0.04028, -0.09513, -0.04916, -0.04365, -0.07857, -0.07827, -0.03504, -0.06911, -0.05202, -0.04051, -0.06630, ...
                /// vibrateEigvec[ 7] = Vector [2904] { 0.03161,  0.02115,  0.03936,  0.03104,  0.02005,  0.03134,  0.02924,  0.01891,  0.02376,  0.03471,  0.02148,  0.01541,  0.03384,  0.02216,  0.04418,  0.02552,  0.02031,  0.04109,  0.03526,  0.02170,  0.03866,  0.02581,  0.01924,  0.03217, ...
                /// vibrateEigvec[ 8] = Vector [2904] { 0.03021,  0.00406,  0.03089,  0.03006,  0.00293,  0.02496,  0.02767,  0.00156,  0.01482,  0.03339,  0.00061,  0.00757,  0.03282,  0.00471,  0.03739,  0.02347,  0.00580,  0.03149,  0.03379,  0.00262,  0.02810,  0.02467,  0.00479,  0.02741, ...
                /// vibrateEigvec[ 9] = Vector [2904] {-0.06629,  0.00026, -0.05240, -0.06201, -0.00132, -0.03691, -0.06003, -0.00365, -0.01796, -0.07120, -0.01011, -0.00037, -0.06995,  0.00149, -0.06501, -0.05369, -0.00009, -0.05497, -0.07695,  0.00040, -0.04852, -0.04857, -0.00130, -0.04028, ...
                /// vibrateEigvec[10] = Vector [2904] { 0.00818,  0.03787,  0.01628,  0.00657,  0.03785,  0.00764,  0.00619,  0.03720,  0.00652,  0.00847,  0.04099,  0.00194,  0.00861,  0.03853,  0.01640,  0.00574,  0.03272,  0.01931,  0.01109,  0.04177,  0.01940,  0.00305,  0.03318,  0.00576, ...
                ///                     ...
                /// vibrateEigvecDist = Vector [2904] { 1.00000,  1.00000,  1.00000,  0.99999,  0.99999,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000,  1.00000, ...
                /// vibrateEigvecDot  = Matrix [2904,2904] {{ 0.00000, -0.01485,  0.00001,  0.01752, -0.00421,  0.00847, -0.00656, -0.00295,  0.00356, -0.00522,  0.01579, -0.01792, -0.00070, -0.00707,  0.02013,  0.00371,  0.00914,  0.03035, -0.02114, -0.00362, -0.00913, -0.00568,  0.00833, -0.00252, -0.00904,  0.00400, -0.00919, ...
                ///                                        ,{-0.01485,  0.00000,  0.01000, -0.01121,  0.00223, -0.00495,  0.01197,  0.01521, -0.01948, -0.01693, -0.00648, -0.02468,  0.00928, -0.01702,  0.00342,  0.02020,  0.00512, -0.01993, -0.02434, -0.00910, -0.00043, -0.01359,  0.00281,  0.01066, -0.00091, -0.00113, -0.01498, ...
                ///                                        ,{ 0.00001,  0.01000,  0.00000,  0.01739,  0.01857,  0.03472,  0.00842, -0.01255, -0.01425, -0.01602,  0.02960,  0.01683, -0.01402,  0.00583,  0.00893, -0.05121,  0.02122,  0.02011,  0.03181,  0.01768,  0.01980,  0.01491, -0.01098, -0.00655,  0.02637,  0.02226,  0.01920, ...
                ///                                        ,{ 0.01752, -0.01121,  0.01739,  0.00000,  0.00001,  0.00001, -0.00032, -0.02216,  0.02828,  0.00288,  0.02392,  0.01872, -0.01179, -0.00516, -0.00306, -0.01100,  0.00863,  0.02967, -0.00337,  0.00510,  0.01070, -0.00051, -0.01931, -0.00691, -0.00043, -0.00015, -0.00532, ...
                ///                                        ,{-0.00421,  0.00223,  0.01857,  0.00001,  0.00000,  0.00001,  0.01531,  0.01124, -0.00910,  0.01547,  0.00651,  0.00388,  0.02127,  0.01495,  0.01143, -0.01195, -0.00747, -0.00166, -0.03168,  0.00453,  0.01475, -0.02963,  0.00326, -0.02032,  0.00063,  0.00535,  0.00091, ...
                ///                                        ,{ 0.00847, -0.00495,  0.03472,  0.00001,  0.00001,  0.00000, -0.00846,  0.00057, -0.01390, -0.01859,  0.00969,  0.01731,  0.00026, -0.00321,  0.00537,  0.01203,  0.00221,  0.00119,  0.01690,  0.00005, -0.00702, -0.00638,  0.01118,  0.00489,  0.00875, -0.00975, -0.01986, ...
                ///                                        ,{-0.00656,  0.01197,  0.00842, -0.00032,  0.01531, -0.00846,  0.00000, -0.03024, -0.04005,  0.02021,  0.00542,  0.03616,  0.02653,  0.02007,  0.00238, -0.01524,  0.01094, -0.02750,  0.01223, -0.04935,  0.00435,  0.00496, -0.00377,  0.02044, -0.00450, -0.02870,  0.01467, ...
                ///                                        ,{-0.00295,  0.01521, -0.01255, -0.02216,  0.01124,  0.00057, -0.03024,  0.00000, -0.00478,  0.01508, -0.00418, -0.00935, -0.00450, -0.03316, -0.01132,  0.03958, -0.05918,  0.01136,  0.00087, -0.02228, -0.00603,  0.00367,  0.01700,  0.01592, -0.02086, -0.01957,  0.00634, ...
                ///                                        ,{ 0.00356, -0.01948, -0.01425,  0.02828, -0.00910, -0.01390, -0.04005, -0.00478,  0.00000,  0.04574,  0.01629, -0.00962,  0.02596, -0.01312, -0.02689,  0.02066,  0.00827, -0.01266,  0.01362,  0.00747,  0.00746, -0.01274, -0.00248,  0.01370,  0.00041,  0.00077,  0.03418, ...
                ///                                        ,{-0.00522, -0.01693, -0.01602,  0.00288,  0.01547, -0.01859,  0.02021,  0.01508,  0.04574,  0.00000,  0.03420, -0.01509,  0.00495, -0.03103, -0.01061, -0.00449,  0.00189,  0.01069, -0.00097, -0.04002,  0.06662, -0.02209, -0.02746, -0.00327, -0.00542,  0.01026,  0.03653, ...
                ///                                        ,{ 0.01579, -0.00648,  0.02960,  0.02392,  0.00651,  0.00969,  0.00542, -0.00418,  0.01629,  0.03420,  0.00000, -0.00570,  0.01489, -0.00290,  0.03163, -0.04236,  0.02447,  0.02609, -0.02314,  0.00057,  0.01577, -0.00808,  0.00852,  0.01132,  0.02774,  0.05619,  0.05177, ...
                ///                                        ... }

                Vector[]    mwvibrateEigvec;
                Vector      mwvibrateEigvecDist;
                MatrixByArr mwvibrateEigvecDot;

                {
                    mwvibrateEigvec = new Vector[size * 3];
                    for (int im = 0; im < size * 3; im++)
                    {
                        mwvibrateEigvec[im] = new double[size * 3];
                        for (int i = 0; i < size * 3; i++)
                        {
                            mwvibrateEigvec[im][i] = vibrateEigvec[im][i] * mass05[i / 3];
                        }
                    }

                    var _V   = la.ToILMat(mwvibrateEigvec.ToMatrix());
                    var _VtV = _V.Tr * _V;
                    mwvibrateEigvecDot = _VtV.ToArray();
                    for (int i = 0; i < size * 3; i++)
                    {
                        mwvibrateEigvecDot[i, i] = 0;
                    }
                    _V.Dispose();
                    _VtV.Dispose();

                    mwvibrateEigvecDist = new double[size * 3];
                    for (int i = 0; i < size * 3; i++)
                    {
                        mwvibrateEigvecDist[i] = mwvibrateEigvec[i].Dist;
                    }
                }
                /// mwvibrateEigvec[ 0] = Vector [2904] {-0.01473, -0.22519, -0.02156, -0.02190, -0.19660, -0.01023, -0.01558, -0.18284, -0.01407, -0.02209, -0.20822, -0.01189, -0.00532, -0.06337, -0.00495, -0.00240, -0.05867, -0.00698, -0.00234, -0.06148, -0.00748, -0.00736, -0.05532, -0.00174, -0.03280, -0.20514, -0.00122, ...
                /// mwvibrateEigvec[ 1] = Vector [2904] { 0.02732, -0.04112,  0.02784,  0.01435, -0.02746,  0.01563,  0.02131, -0.01478,  0.01875,  0.02248,  0.00168,  0.01681,  0.00596, -0.01305,  0.00677,  0.00827, -0.01390,  0.00868,  0.01003, -0.00860,  0.00911,  0.00196, -0.01087,  0.00336,  0.00510, -0.01633,  0.00669, ...
                /// mwvibrateEigvec[ 2] = Vector [2904] { 0.15284, -0.04984,  0.16861,  0.13720, -0.04380,  0.14395,  0.13553, -0.04110,  0.12608,  0.16598, -0.04720,  0.13263,  0.04184, -0.01397,  0.04862,  0.03790, -0.01294,  0.04569,  0.04384, -0.01365,  0.04394,  0.03622, -0.01228,  0.04283,  0.14978, -0.04586,  0.14431, ...
                /// mwvibrateEigvec[ 3] = Vector [2904] { 0.03341, -0.11543, -0.00535,  0.03094, -0.10689, -0.00495,  0.03094, -0.10689, -0.00495,  0.03571, -0.12337, -0.00572,  0.00896, -0.03097, -0.00143,  0.00896, -0.03097, -0.00143,  0.00896, -0.03097, -0.00143,  0.00896, -0.03097, -0.00143,  0.03094, -0.10689, -0.00495, ...
                /// mwvibrateEigvec[ 4] = Vector [2904] { 0.06919,  0.01553,  0.09717,  0.06407,  0.01438,  0.08998,  0.06407,  0.01438,  0.08998,  0.07395,  0.01660,  0.10384,  0.01856,  0.00417,  0.02607,  0.01856,  0.00417,  0.02607,  0.01856,  0.00417,  0.02607,  0.01856,  0.00417,  0.02607,  0.06407,  0.01438,  0.08998, ...
                /// mwvibrateEigvec[ 5] = Vector [2904] {-0.09254, -0.03007,  0.07072, -0.08570, -0.02784,  0.06549, -0.08570, -0.02784,  0.06549, -0.09890, -0.03213,  0.07558, -0.02483, -0.00807,  0.01897, -0.02483, -0.00807,  0.01897, -0.02483, -0.00807,  0.01897, -0.02483, -0.00807,  0.01897, -0.08570, -0.02784,  0.06549, ...
                /// mwvibrateEigvec[ 6] = Vector [2904] {-0.25378, -0.14551, -0.28761, -0.23168, -0.12582, -0.20824, -0.21127, -0.11587, -0.11515, -0.30630, -0.13523, -0.04871, -0.07521, -0.04044, -0.09551, -0.04935, -0.04383, -0.07889, -0.07858, -0.03518, -0.06938, -0.05223, -0.04067, -0.06656, -0.31267, -0.10855, -0.21408, ...
                /// mwvibrateEigvec[ 7] = Vector [2904] { 0.11831,  0.07917,  0.14730,  0.10757,  0.06950,  0.10860,  0.10135,  0.06555,  0.08236,  0.13883,  0.08592,  0.06162,  0.03397,  0.02225,  0.04436,  0.02562,  0.02039,  0.04126,  0.03540,  0.02179,  0.03882,  0.02592,  0.01931,  0.03230,  0.13407,  0.07328,  0.10201, ...
                /// mwvibrateEigvec[ 8] = Vector [2904] { 0.11305,  0.01520,  0.11560,  0.10416,  0.01015,  0.08649,  0.09590,  0.00539,  0.05138,  0.13354,  0.00244,  0.03027,  0.03295,  0.00473,  0.03754,  0.02356,  0.00582,  0.03162,  0.03392,  0.00263,  0.02821,  0.02476,  0.00481,  0.02752,  0.13548,  0.00227,  0.08985, ...
                /// mwvibrateEigvec[ 9] = Vector [2904] {-0.24809,  0.00098, -0.19612, -0.21492, -0.00459, -0.12793, -0.20803, -0.01266, -0.06223, -0.28479, -0.04045, -0.00147, -0.07023,  0.00150, -0.06527, -0.05390, -0.00009, -0.05519, -0.07725,  0.00040, -0.04871, -0.04876, -0.00131, -0.04044, -0.26445, -0.00370, -0.12262, ...
                /// mwvibrateEigvec[10] = Vector [2904] { 0.03062,  0.14174,  0.06091,  0.02278,  0.13118,  0.02647,  0.02145,  0.12891,  0.02259,  0.03387,  0.16394,  0.00776,  0.00864,  0.03868,  0.01647,  0.00577,  0.03285,  0.01938,  0.01114,  0.04194,  0.01948,  0.00306,  0.03332,  0.00578,  0.03239,  0.15042,  0.00838, ...
                ///                     ...
                /// mwvibrateEigvecDist	= Vector [2904] { 2.63914,  2.64117,  2.60684,  2.63907,  2.63908,  2.63909,  2.54591,  2.61693,  2.50533,  2.46113,  2.51293,  2.54366,  2.57329,  2.51375,  2.53133,  2.31010,  2.40230,  2.47630,  2.49624,  2.33080,  2.48450,  2.49505,  2.41665,  2.54134,  2.55567,  2.45052,  2.41150, ...
                /// mwvibrateEigvecDot	= Matrix [2904,2904] {{ 0.00000,  0.00020, -0.00082,  0.00002,  0.00000,  0.00003,        0.00000,  0.00000,  0.00000,  0.00000,  0.00001,  0.00000,  0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00001, -0.00001,  0.00001,  0.00000, -0.00001,  0.00000,  0.00000,  0.00000, -0.00001, ...
                ///                                           { 0.00020,  0.00000,  0.12062,  0.00002,  0.00002, -0.00007,        0.00000,  0.00000, -0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00001,  0.00000,  0.00000,  0.00000,  0.00000, -0.00001,  0.00000,  0.00000,  0.00000, ...
                ///                                           {-0.00082,  0.12062,  0.00000,  0.04691,  0.01196,  0.34243,        0.00000,  0.00000, -0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000, -0.00001,  0.00000, -0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000, -0.00001, -0.00001,  0.00000, ...
                ///                                           { 0.00002,  0.00002,  0.04691,  0.00000,  0.00004,  0.00004,        0.00001,  0.00000,  0.00001, -0.00001,  0.00001, -0.00002,  0.00001,  0.00000,  0.00003,  0.00000,  0.00001,  0.00000,  0.00000,  0.00001,  0.00000,  0.00000, -0.00001,  0.00000,  0.00000,  0.00001,  0.00000,  0.00000,  0.00002, ...
                ///                                           { 0.00000,  0.00002,  0.01196,  0.00004,  0.00000,  0.00004,       -0.00002,  0.00001,  0.00000,  0.00000,  0.00001,  0.00003,  0.00001,  0.00001,  0.00000, -0.00001,  0.00001,  0.00000,  0.00000,  0.00000, -0.00001,  0.00000,  0.00000, -0.00001,  0.00000,  0.00000, -0.00001,  0.00000,  0.00000, ...
                ///                                           { 0.00003, -0.00007,  0.34243,  0.00004,  0.00004,  0.00000,       -0.00001, -0.00001,  0.00000, -0.00001,  0.00000,  0.00000,  0.00000, -0.00001,  0.00001,  0.00000,  0.00000,  0.00001,  0.00000,  0.00000,  0.00001,  0.00000,  0.00000,  0.00000,  0.00000, -0.00001,  0.00000,  0.00000, -0.00001, ...
                ///                         (7th eigenvector) { 0.00000,  0.00000,  0.00000,  0.00001, -0.00002, -0.00001,        0.00000, -0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00001,  0.00001,  0.00000, ...
                ///                                           { 0.00000,  0.00000,  0.00000,  0.00000,  0.00001, -0.00001,       -0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000, -0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000, -0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000, ...
                ///                                           { 0.00000, -0.00001, -0.00001,  0.00001,  0.00000,  0.00000,        0.00000,  0.00000,  0.00000,  0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00001, -0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000, ...
                ///                                           { 0.00000,  0.00000,  0.00000, -0.00001,  0.00000, -0.00001,        0.00000,  0.00000,  0.00001,  0.00000,  0.00000, -0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000, -0.00001,  0.00000, -0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000, ...
                ///                                           { 0.00001,  0.00000,  0.00000,  0.00001,  0.00001,  0.00000,        0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00001,  0.00000,  0.00000,  0.00000, -0.00001,  0.00000,  0.00001,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000,  0.00000, -0.00001,  0.00000,  0.00000,  0.00000, ...
                ///                                           ... }

                Tuple <Vector, double>[] hessEig;
                MatrixByArr hessEigvecDot;
                double      hessEigvecDotMaxAbs;

                {
                    hessEig = new Tuple <Vector, double> [size * 3];
                    var         _hess = la.ToILMat(hess);
                    var         _VD   = la.EigSymm(_hess);
                    MatrixByArr V     = _VD.Item1.ToArray();
                    Vector      D     = _VD.Item2;
                    for (int i = 0; i < size * 3; i++)
                    {
                        double eigval = D[i];
                        Vector eigvec = V.GetColVector(i);
                        hessEig[i] = new Tuple <Vector, double>(eigvec, eigval);
                    }

                    var _V   = _VD.Item1;
                    var _VtV = _V.Tr * _V;
                    hessEigvecDot = _VtV.ToArray();
                    for (int i = 0; i < size * 3; i++)
                    {
                        hessEigvecDot[i, i] = 0;
                    }
                    hessEigvecDotMaxAbs = hessEigvecDot.ToArray().HAbs().HMax();

                    _hess.Dispose();
                    _VD.Item1.Dispose();
                    _V.Dispose();
                    _VtV.Dispose();
                }
                Vector[] hessEigVec = hessEig.HListItem1().ToArray();
                Vector   hessEigVal = hessEig.HListItem2().ToArray();
                /// hessEigVal          = Vector [2904] {-0.00010, -0.00006, -0.00005, -0.00001,  0.00005,  0.00010,  0.01944,  0.02618,  0.03199,  0.04183,  0.05824,  0.06837,  0.07660,  0.08224,  0.08755,  0.08917,  0.10386,  0.12144,  0.12444,  0.13126,  0.15030,  0.16139,  0.16551,  0.17947,  0.19501,  0.20400,  0.21379,  0.22191,  0.22934,  0.24248,  0.24686, ...
                /// hessEigvecDot = Matrix [2904,2904] {{0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                     {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                     {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                     {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                     {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                     {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                     {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                     {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                     {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                     {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                     {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                     ...}
                /// hessEigvecDotMaxAbs = 0.0000000000010620164686905853

                Matrix mwHess;

                Tuple <Vector, double>[] mwHessEig;
                Matrix mwhessEigvecDot;
                double mwhessEigvecDotMaxAbs;

                Mode[] mwMode;
                {
                    mwHess    = Hess.GetMassWeightedHess(hess, mass);
                    mwHessEig = new Tuple <Vector, double> [size * 3];
                    mwMode    = new Mode[size * 3];
                    var         _mwhess = la.ToILMat(mwHess);
                    var         _VD     = la.EigSymm(_mwhess);
                    MatrixByArr V       = _VD.Item1.ToArray();
                    Vector      D       = _VD.Item2;
                    for (int i = 0; i < size * 3; i++)
                    {
                        double eigval = D[i];
                        Vector eigvec = V.GetColVector(i);
                        mwHessEig[i]     = new Tuple <Vector, double>(eigvec, eigval);
                        mwMode[i]        = new Mode();
                        mwMode[i].eigval = eigval;
                        mwMode[i].eigvec = eigvec;
                    }

                    var _V   = _VD.Item1;
                    var _VtV = _V.Tr * _V;
                    mwhessEigvecDot = _VtV.ToArray();
                    for (int i = 0; i < size * 3; i++)
                    {
                        mwhessEigvecDot[i, i] = 0;
                    }
                    mwhessEigvecDotMaxAbs = mwhessEigvecDot.ToArray().HAbs().HMax();

                    _mwhess.Dispose();
                    _VD.Item1.Dispose();

                    //Vector[] xxx = mwhessEigvecDot.GetRowVectorList();
                }
                Vector[] mwHessEigVec = mwHessEig.HListItem1().ToArray();
                Vector   mwHessEigVal = mwHessEig.HListItem2().ToArray();

                /// mwHessEigVal = Vector [2904] {-0.00001, -0.00001, -0.00001,  0.00000,  0.00001,  0.00001,  0.00302,  0.00382,  0.00515,  0.00690,  0.00933,  0.01070,  0.01194,  0.01320,  0.01386,  0.01682,  0.01970,  0.02027,  0.02101,  0.02264,  0.02401,  0.02619,  0.02760,  0.02957,  0.03047,  0.03368,  0.03644,  0.03660,  0.03897,  0.04051,  0.04351, ...
                /// mwhessEigvecDot = Matrix [2904,2904] {{0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                       {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                       {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                       {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                       {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                       {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                       {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                       {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                       {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                       {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                       {0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, ...
                ///                                       ...}
                /// mwhessEigvecDotMaxAbs = 0.0000000000026275308697473049

                Mode[] mrMode     = mwMode.GetMassReduced(mass.ToArray()).ToArray();
                Mode[] mrModeNorm = mrMode.GetNormalized();

                Vector ratFreqMode1;
                Vector ratFreqMode2;
                Vector ratFreqMode3;
                Vector ratFreqMode4;
                Vector ratFreqMode5;
                Vector ratFreqMode6;
                {
                    /// reference
                    /// * eq. (14) in http://www3.nd.edu/~csweet1/NormalMode7.pdf
                    /// * http://en.wikipedia.org/wiki/Boltzmann_constant
                    /// * http://www.charmm.org/documentation/c34b1/subst.html

                    ratFreqMode1 = new double[size * 3];
                    ratFreqMode2 = new double[size * 3];
                    ratFreqMode3 = new double[size * 3];
                    ratFreqMode4 = new double[size * 3];
                    ratFreqMode5 = new double[size * 3];
                    ratFreqMode6 = new double[size * 3];
                    double kB     = 0.0019872041; /// kcal/mol/K, http://en.wikipedia.org/wiki/Boltzmann_constant, http://www.charmm.org/documentation/c34b1/subst.html
                    double T3     = 310.0;        /// temperature in kelvin. 14 is the adjustment to make the ratio close to 1
                    double T4     = 310.0;        /// temperature in kelvin. 14 is the adjustment to make the ratio close to 1
                    double T5     = 310.0 - 13.0; /// temperature in kelvin. 14 is the adjustment to make the ratio close to 1
                    double scale1 = 10000;        /// manually searched
                    double scale2 = 10000;        /// manually searched
                    double scale3 = 10000;        /// manually searched
                    double scale4 = 10000;        /// manually searched
                    double scale5 = 10000;        /// manually searched
                    double scale6 = 100000;       /// manually searched
                    for (int im = 0; im < size * 3; im++)
                    {
                        ratFreqMode1[im] = (vibrateFreq[im] * vibrateFreq[im]) / (scale1 * vibrateEigval[im]);
                        ratFreqMode2[im] = (vibrateFreq[im] * vibrateFreq[im]) / (scale2 * hessEigVal[im]);
                        ratFreqMode3[im] = (vibrateFreq[im] * vibrateFreq[im]) / (scale3 * mwvibrateEigvecDist[im] * (2 * mwMode[im].eigval * kB * T3));
                        ratFreqMode4[im] = (vibrateFreq[im] * vibrateFreq[im]) / (scale4 * (2 * mwMode[im].eigval * kB * T4));
                        ratFreqMode5[im] = (vibrateFreq[im] * vibrateFreq[im]) / (scale5 * (2 * mwMode[im].eigval * kB * T5));
                        ratFreqMode6[im] = (vibrateFreq[im] * vibrateFreq[im]) / (scale6 * mrModeNorm[im].eigval);
                    }
                    StringBuilder outs = new StringBuilder();
                    { var vals = ratFreqMode1.ToArray().HSelectFromCount(6, size * 3 - 6).ToArray(); outs.Append(string.Format("{0,9:0.000000}  {0,9:0.000000}  {0,9:0.000000}  {0,9:0.000000}\n", vals.Min(), vals.Average(), vals.Max(), vals.Variance())); }
                    { var vals = ratFreqMode2.ToArray().HSelectFromCount(6, size * 3 - 6).ToArray(); outs.Append(string.Format("{0,9:0.000000}  {0,9:0.000000}  {0,9:0.000000}  {0,9:0.000000}\n", vals.Min(), vals.Average(), vals.Max(), vals.Variance())); }
                    { var vals = ratFreqMode3.ToArray().HSelectFromCount(6, size * 3 - 6).ToArray(); outs.Append(string.Format("{0,9:0.000000}  {0,9:0.000000}  {0,9:0.000000}  {0,9:0.000000}\n", vals.Min(), vals.Average(), vals.Max(), vals.Variance())); }
                    { var vals = ratFreqMode4.ToArray().HSelectFromCount(6, size * 3 - 6).ToArray(); outs.Append(string.Format("{0,9:0.000000}  {0,9:0.000000}  {0,9:0.000000}  {0,9:0.000000}\n", vals.Min(), vals.Average(), vals.Max(), vals.Variance())); }
                    { var vals = ratFreqMode5.ToArray().HSelectFromCount(6, size * 3 - 6).ToArray(); outs.Append(string.Format("{0,9:0.000000}  {0,9:0.000000}  {0,9:0.000000}  {0,9:0.000000}\n", vals.Min(), vals.Average(), vals.Max(), vals.Variance())); }
                    { var vals = ratFreqMode6.ToArray().HSelectFromCount(6, size * 3 - 6).ToArray(); outs.Append(string.Format("{0,9:0.000000}  {0,9:0.000000}  {0,9:0.000000}  {0,9:0.000000}\n", vals.Min(), vals.Average(), vals.Max(), vals.Variance())); }
                }
                /// ratFreqMode1 = tinkFreq^2 / ( 10000 * tinkEigval )   Vector [2904] {Infinity, Infinity, Infinity,      NaN,      NaN, Infinity,  0.18758,  0.17353,  0.18949,  0.19393,  0.18940,  0.18553,  0.18289,  0.18982,  0.18577,  0.22272,  0.22350,  0.19758,  0.19812,  0.20389,  0.18879,  0.19181,  0.19611,  0.19373,  0.18427,  0.19463,  0.20089,  0.19443,  0.20073,  0.19660,  0.20774,  0.19878,  0.19981,  0.20473,  0.20848,  0.20524,  0.20610,  0.20544, ...
                /// ratFreqMode2 = tinkFreq^2 / ( 10000 * hessEigval )   Vector [2904] {-0.00035, -0.00032, -0.00013,  0.00000,  0.00000,  0.00000,  0.18333,  0.17235,  0.18953,  0.19470,  0.18861,  0.18452,  0.18384,  0.18927,  0.18672,  0.22229,  0.22381,  0.19687,  0.19901,  0.20349,  0.18841,  0.19135,  0.19669,  0.19431,  0.18426,  0.19463,  0.20108,  0.19451,  0.20044,  0.19702,  0.20785,  0.19852,  0.20019,  0.20506,  0.20835,  0.20506,  0.20621,  0.20561, ...
                /// ratFreqMode3 = tinkFreq^2 / ( 10000 *                Vector [2904] {-0.00076, -0.00068, -0.00028,  0.00000,  0.00000,  0.00000,  0.37598,  0.36591,  0.38171,  0.38948,  0.38030,  0.37608,  0.37197,  0.38080,  0.37831,  0.41414,  0.39858,  0.38660,  0.38329,  0.41078,  0.38533,  0.38361,  0.39613,  0.37669,  0.37453,  0.39045,  0.39708,  0.39297,  0.40276,  0.39117,  0.37568,  0.38563,  0.38705,  0.40232,  0.41826,  0.39828,  0.39591,  0.39734, ...
                /// ratFreqMode4 = tinkFreq^2 / ( 10000 *                Vector [2904] {-0.00202, -0.00180, -0.00074,  0.00000,  0.00000,  0.00001,  0.95720,  0.95757,  0.95632,  0.95855,  0.95567,  0.95663,  0.95718,  0.95725,  0.95763,  0.95670,  0.95750,  0.95734,  0.95679,  0.95746,  0.95735,  0.95712,  0.95732,  0.95731,  0.95718,  0.95681,  0.95757,  0.95709,  0.95731,  0.95720,  0.95712,  0.95731,  0.95703,  0.95721,  0.95715,  0.95709,  0.95727,  0.95707, ...
                /// ratFreqMode5 = tinkFreq^2 / ( 10000 *                Vector [2904] {-0.00210, -0.00188, -0.00077,  0.00000,  0.00000,  0.00001,  0.99910,  0.99948,  0.99818,  1.00051,  0.99750,  0.99850,  0.99908,  0.99915,  0.99954,  0.99857,  0.99941,  0.99925,  0.99867,  0.99937,  0.99925,  0.99902,  0.99922,  0.99921,  0.99907,  0.99869,  0.99948,  0.99899,  0.99921,  0.99910,  0.99901,  0.99921,  0.99892,  0.99911,  0.99905,  0.99898,  0.99917,  0.99896, ...
                /// ratFreqMode6 = tinkFreq^2 / (100000 *                Vector [2904] {-0.00174, -0.00156, -0.00064,  0.00000,  0.00000,  0.00000,  0.76481,  0.80792,  0.73961,  0.71527,  0.74349,  0.76241,  0.78110,  0.74524,  0.75597,  0.62897,  0.68103,  0.72307,  0.73431,  0.64111,  0.72797,  0.73423,  0.68870,  0.76232,  0.76976,  0.70769,  0.68559,  0.70019,  0.66656,  0.70610,  0.76526,  0.72679,  0.72086,  0.66728,  0.61773,  0.68114,  0.68943,  0.68425, ...

                ///                 min        average    max        variance
                /// ratFreqMode1    0.157480   0.157480   0.157480   0.157480
                /// ratFreqMode2    0.157480   0.157480   0.157480   0.157480
                /// ratFreqMode3    0.296715   0.296715   0.296715   0.296715
                /// ratFreqMode4    0.955668   0.955668   0.955668   0.955668
                /// ratFreqMode5    0.997499   0.997499   0.997499   0.997499
                /// ratFreqMode6    0.122140   0.122140   0.122140   0.122140

                /// Tinker Eigenvalue: determined using the original hessian matrix
                ///                    [V, D] = eig(H)
                ///                    eig := diag(D)
                /// Tinker Frequency : determined using the mass-weighted hessian matrix
                ///                    [V, D] = eig(M^-0.5 H M^-0.5)
                ///                    freq := sqrt(scale * 2 * diag(D) * kB * T)
                ///                               where scale = 10000
                ///                                     kB    = 0.0019872041 [kcal/mol/K]
                ///                                     T     = approx. 310
                /// Tinker Mode      : determined using the normalized mass-reduced eigenvalue of mass-weighted hessian matrix,
                ///                    [V0, D] = eig(M^-0.5 H M^-0.5)
                ///                     V1 = M^-0.5 * V0
                ///                     V2i = V1i / sqrt(V1i' * V1i)
                ///                     mode: = V2i

                Vector dot_vibrateEigvec_hessEig;
                Vector dot_vibrateEigvec_mrModeNorm;
                {
                    dot_vibrateEigvec_hessEig    = new double[size * 3];
                    dot_vibrateEigvec_mrModeNorm = new double[size * 3];
                    for (int i = 0; i < size * 3; i++)
                    {
                        Vector v0 = vibrateEigvec[i].UnitVector();
                        Vector v1 = hessEig[i].Item1.UnitVector();
                        Vector v2 = mrModeNorm[i].eigvec;
                        dot_vibrateEigvec_hessEig   [i] = Math.Abs(LinAlg.VtV(v0, v1));
                        dot_vibrateEigvec_mrModeNorm[i] = Math.Abs(LinAlg.VtV(v0, v2));
                    }
                }
                /// dot_vibrateEigvec_hessEig    = Vector [2904] {0.48985, 0.13230, 0.44747, 0.04888, 0.07929, 0.52681, 0.99419, 0.99184, 0.97989, 0.97002, 0.98092, 0.98450, 0.84740, 0.80494, 0.03774, 0.08663, 0.75053, 0.88493, 0.11468, 0.12843, 0.83637, 0.73307, 0.69806, 0.39251, 0.52766, 0.47411, 0.84648, 0.32370, 0.60035, 0.37242, 0.08106, 0.34824, 0.31312, 0.00374, 0.10264, 0.53659, 0.52061, 0.00238, 0.01090, 0.42059, 0.18661, 0.57478, 0.11763, 0.16953, 0.01308, 0.15673, 0.29348, ...
                /// dot_vibrateEigvec_mrModeNorm = Vector [2904] {0.48193, 0.12355, 0.45875, 0.04765, 0.08948, 0.52432, 0.99998, 0.99998, 0.99999, 0.99999, 0.99999, 0.99999, 0.99998, 0.99999, 0.99998, 0.99999, 0.99999, 0.99998, 0.99993, 0.99996, 0.99997, 0.99999, 0.99999, 0.99994, 0.99994, 1.00000, 0.99993, 0.99993, 0.99999, 1.00000, 1.00000, 1.00000, 0.99999, 0.99998, 0.99999, 0.99999, 1.00000, 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 0.99999, 0.99999, ...
            }
示例#12
0
        public double GetPotential(List <ForceField.IForceField> frcflds, Vector[] coords, ref Vector[] forces, ref MatrixByArr hessian, Dictionary <string, object> cache, Vector[,] forceij = null, double[,] pwfrc = null, double[,] pwspr = null)
        {
            //forceij = new Vector[size, size];
            MatrixByArr[,] hess = null;
            if (hessian != null)
            {
                int size = coords.GetLength(0);
                hess = LinAlg.CreateMatrixArray(size, size, new double[3, 3]);
            }

            double energy            = 0;
            double energy_bonds      = GetPotentialBonds(frcflds, coords, ref forces, ref hess, cache, forceij, pwfrc, pwspr); energy += energy_bonds;
            double energy_angles     = GetPotentialAngles(frcflds, coords, ref forces, ref hess, cache, forceij, pwfrc, pwspr); energy += energy_angles;
            double energy_dihedrals  = GetPotentialDihedrals(frcflds, coords, ref forces, ref hess, cache, forceij, pwfrc, pwspr); energy += energy_dihedrals;
            double energy_impropers  = GetPotentialImpropers(frcflds, coords, ref forces, ref hess, cache, forceij, pwfrc, pwspr); energy += energy_impropers;
            double energy_nonbondeds = GetPotentialNonbondeds(frcflds, coords, ref forces, ref hess, cache, forceij, pwfrc, pwspr); energy += energy_nonbondeds;
            double energy_customs    = GetPotentialCustoms(frcflds, coords, ref forces, ref hess, cache, forceij, pwfrc, pwspr); energy += energy_customs;

            if (hess != null)
            {
                GetPotentialBuildHessian(coords, hess, ref hessian);
            }

            if (cache != null)
            {
                if (cache.ContainsKey("energy_bonds     ") == false)
                {
                    cache.Add("energy_bonds     ", 0);
                }
                cache["energy_bonds     "] = energy_bonds;
                if (cache.ContainsKey("energy_angles    ") == false)
                {
                    cache.Add("energy_angles    ", 0);
                }
                cache["energy_angles    "] = energy_angles;
                if (cache.ContainsKey("energy_dihedrals ") == false)
                {
                    cache.Add("energy_dihedrals ", 0);
                }
                cache["energy_dihedrals "] = energy_dihedrals;
                if (cache.ContainsKey("energy_impropers ") == false)
                {
                    cache.Add("energy_impropers ", 0);
                }
                cache["energy_impropers "] = energy_impropers;
                if (cache.ContainsKey("energy_nonbondeds") == false)
                {
                    cache.Add("energy_nonbondeds", 0);
                }
                cache["energy_nonbondeds"] = energy_nonbondeds;
                if (cache.ContainsKey("energy_customs   ") == false)
                {
                    cache.Add("energy_customs   ", 0);
                }
                cache["energy_customs   "] = energy_customs;
            }
            return(energy);
        }
示例#13
0
 public double GetPotential(List <ForceField.IForceField> frcflds, ref Vector[] forces, ref MatrixByArr hessian, Dictionary <string, object> cache, Vector[,] forceij = null, double[,] pwfrc = null, double[,] pwspr = null)
 {
     Vector[] coords = new Vector[size];
     foreach (Atom atom in atoms)
     {
         HDebug.Assert(coords[atom.ID] == null);
         coords[atom.ID] = atom.Coord;
     }
     return(GetPotential(frcflds, coords, ref forces, ref hessian, cache, forceij, pwfrc, pwspr));
 }
示例#14
0
            public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_Matlab_experimental
                (object[] atoms
                , HessMatrix H
                , List <int>[] lstNewIdxRemv
                , double thres_zeroblk
                , ILinAlg ila
                , bool cloneH
                , string[] options
                )
            {
                ila = null;
                if (cloneH)
                {
                    H = H.CloneHess();
                }

                bool process_disp_console = true;

                if (options != null && options.Contains("print process"))
                {
                    process_disp_console = true;
                }

                bool parallel = true;

                GC.Collect(0);

                DateTime[] process_time = new DateTime[6];

                //System.Console.WriteLine("begin coarse-graining");
                List <HessCoarseResiIterInfo> iterinfos = new List <HessCoarseResiIterInfo>();

                for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--)
                {
                    if (process_disp_console)
                    {
                        process_time[0] = DateTime.UtcNow;
                        System.Console.Write(" - {0:000} : ", iter);
                    }

                    //int[] ikeep = lstNewIdxRemv[iter].Item1;
                    int[] iremv = lstNewIdxRemv[iter].ToArray();
                    HDebug.Assert(H.ColBlockSize == H.RowBlockSize);
                    int blksize = H.ColBlockSize;
                    //HDebug.Assert(ikeep.Max() < blksize);
                    //HDebug.Assert(iremv.Max() < blksize);
                    //HDebug.Assert(iremv.Max()+1 == blksize);
                    //HDebug.Assert(iremv.Max() - iremv.Min() + 1 == iremv.Length);

                    int[] idxkeep = HEnum.HEnumFromTo(0, iremv.Min() - 1).ToArray();
                    int[] idxremv = HEnum.HEnumFromTo(iremv.Min(), iremv.Max()).ToArray();
                    //HDebug.Assert(idxkeep.HUnionWith(idxremv).Length == blksize);

                    HessCoarseResiIterInfo iterinfo = new HessCoarseResiIterInfo();
                    iterinfo.sizeHessBlkMat  = idxremv.Max() + 1; // H.ColBlockSize;
                    iterinfo.numAtomsRemoved = idxremv.Length;
                    iterinfo.time0           = DateTime.UtcNow;
                    double C_density0 = double.NaN;
                    double C_density1 = double.NaN;
                    {
                        //HessMatrix    A = H.SubMatrixByAtoms(false, idxkeep, idxkeep);
                        HessMatrix A = H;
                        //HessMatrix    B = H.SubMatrixByAtoms(false, idxkeep, idxremv);

                        HessMatrix C, D;
                        /// HessMatrix    C = H.SubMatrixByAtoms(false, idxremv, idxkeep, parallel:parallel);
                        /// HessMatrix    D = H.SubMatrixByAtoms(false, idxremv, idxremv, parallel:parallel);
                        {
                            C = H.Zeros(idxremv.Length * 3, idxkeep.Length * 3);
                            D = H.Zeros(idxremv.Length * 3, idxremv.Length * 3);
                            int iremv_min = iremv.Min();
                            int iremv_max = iremv.Max();

                            foreach (var bc_br_bval in H.EnumBlocksInCols(idxremv))
                            {
                                int bc   = bc_br_bval.Item1;
                                int br   = bc_br_bval.Item2;
                                var bval = bc_br_bval.Item3;


                                if (bc > iremv_max)
                                {
                                    continue;
                                }
                                if (br > iremv_max)
                                {
                                    continue;
                                }
                                if (br < iremv_min)
                                {
                                    int nc = bc - iremv_min;
                                    int nr = br;
                                    C.SetBlock(nc, nr, bval.CloneT());
                                }
                                else
                                {
                                    int nc = bc - iremv_min;
                                    int nr = br - iremv_min;
                                    D.SetBlock(nc, nr, bval.CloneT());
                                }
                            }
                        }
                        if (process_disp_console)
                        {
                            process_time[1] = process_time[2] = DateTime.UtcNow;
                            System.Console.Write("CD({0:00.00} min), ", (process_time[2] - process_time[0]).TotalMinutes);
                        }

                        // make B,C sparse
                        //int B_cntzero = B.MakeNearZeroBlockAsZero(thres_zeroblk);
                        C_density0 = C.RatioUsedBlocks;
                        /// iterinfo.numSetZeroBlock = C.MakeNearZeroBlockAsZero(thres_zeroblk);
                        {
                            double thres_absmax = thres_zeroblk;

                            List <Tuple <int, int> > lstIdxToMakeZero = new List <Tuple <int, int> >();
                            foreach (var bc_br_bval in C.EnumBlocks())
                            {
                                int    bc          = bc_br_bval.Item1;
                                int    br          = bc_br_bval.Item2;
                                var    bval        = bc_br_bval.Item3;
                                double absmax_bval = bval.HAbsMax();
                                if (absmax_bval < thres_absmax)
                                {
                                    lstIdxToMakeZero.Add(new Tuple <int, int>(bc, br));
                                }
                            }
                            foreach (var bc_br in lstIdxToMakeZero)
                            {
                                int cc   = bc_br.Item1;
                                int cr   = bc_br.Item2;
                                var Cval = C.GetBlock(cc, cr);
                                C.SetBlock(cc, cr, null);
                                var Dval = D.GetBlock(cc, cc);              // nCval = Cval    -Cval
                                D.SetBlock(cc, cc, Dval + Cval);            // nDval = Dval - (-Cval) = Dval + Cval
                                int bc   = cr;
                                int br   = cc;
                                var Bval = Cval.Tr();
                                var Aval = A.GetBlock(bc, bc);              // nBval = Bval    -Bval
                                A.SetBlock(bc, bc, Aval + Bval);            // nAval = Aval - (-Bval) = Aval + Bval
                            }
                            iterinfo.numSetZeroBlock = lstIdxToMakeZero.Count;
                        }
                        //int B_nzeros = B.NumUsedBlocks; double B_nzeros_ = Math.Sqrt(B_nzeros);
                        iterinfo.numNonZeroBlock = C.NumUsedBlocks;
                        C_density1 = C.RatioUsedBlocks;


                        HessMatrix B_invD_C = Get_BInvDC(A, C, D, process_disp_console
                                                         , options
                                                         , parallel: parallel
                                                         );
                        if (process_disp_console)
                        {
                            process_time[4] = DateTime.UtcNow;
                            System.Console.Write("B.invD.C({0:00.00} min), ", (process_time[4] - process_time[3]).TotalMinutes);
                        }

                        /// iterinfo.numAddIgnrBlock = A.UpdateAdd(B_invD_C, -1, null, thres_zeroblk/lstNewIdxRemv.Length, parallel:parallel);
                        {
                            HessMatrix _this = A;
                            HessMatrix other = B_invD_C;
                            double     thres_NearZeroBlock = thres_zeroblk / lstNewIdxRemv.Length;

                            int count         = 0;
                            int count_ignored = 0;
                            foreach (var bc_br_bval in other.EnumBlocks())
                            {
                                count++;
                                int         bc         = bc_br_bval.Item1;
                                int         br         = bc_br_bval.Item2;
                                MatrixByArr other_bmat = bc_br_bval.Item3;
                                if (other_bmat.HAbsMax() <= thres_NearZeroBlock)
                                {
                                    // other_bmat = other_bmat    -other_bmat;
                                    // other_diag = other_diag - (-other_bmat) = other_diag + other_bmat;
                                    //  this_diag =  this_diat - B_invD_C
                                    //            =  this_diat - other_diag
                                    //            =  this_diat - (other_diag + other_bmat)
                                    //            =  this_diat - other_diag  - other_bmat
                                    //            = (this_diat - other_bmat) - other_diag
                                    //            = (this_diat - other_bmat) - (processed later)
                                    //            = (this_diat - other_bmat)
                                    MatrixByArr this_diag = _this.GetBlock(bc, bc);
                                    MatrixByArr new_diag  = this_diag - other_bmat;
                                    _this.SetBlock(bc, bc, new_diag);
                                    other_bmat = null;
                                    count_ignored++;
                                }
                                if (other_bmat != null)
                                {
                                    MatrixByArr this_bmat = _this.GetBlock(bc, br);
                                    MatrixByArr new_bmat  = this_bmat - other_bmat;
                                    _this.SetBlock(bc, br, new_bmat);
                                }
                            }
                            iterinfo.numAddIgnrBlock = count_ignored;
                        }
                        //HessMatrix nH = A - B_invD_C;
                        //nH = ((nH + nH.Tr())/2).ToHessMatrix();
                        H = A;
                    }
                    iterinfo.usedMemoryByte = GC.GetTotalMemory(false);
                    iterinfo.time1          = DateTime.UtcNow;
                    iterinfos.Add(iterinfo);

                    if (process_disp_console)
                    {
                        System.Console.WriteLine("summary(makezero {0,5}, nonzero {1,5}, numIgnMul {2,7}, numRemvAtoms {3,3}, {4,5:0.00} sec, {5} mb, {6}x{6}, nzeroBlk/Atom {7:0.00})"
                                                 , iterinfo.numSetZeroBlock
                                                 , iterinfo.numNonZeroBlock
                                                 , iterinfo.numAddIgnrBlock
                                                 , iterinfo.numAtomsRemoved
                                                 , iterinfo.compSec
                                                 , iterinfo.usedMemoryByte / (1024 * 1024)
                                                 , (idxkeep.Length * 3)
                                                 , ((double)iterinfo.numNonZeroBlock / idxremv.Length)
                                                 );
                    }

                    GC.Collect(0);
                }

                int numca = H.ColBlockSize - lstNewIdxRemv.HListCount().Sum();

                //System.Console.WriteLine("finish coarse-graining");
                {
                    int[] idxkeep = HEnum.HEnumCount(numca).ToArray();
                    H = H.SubMatrixByAtoms(false, idxkeep, idxkeep, false);
                }
                {
                    H.MakeNearZeroBlockAsZero(thres_zeroblk);
                }
                GC.Collect(0);
                //System.Console.WriteLine("finish resizing");

                return(new CGetHessCoarseResiIterImpl
                {
                    iterinfos = iterinfos,
                    H = H,
                });
            }
示例#15
0
                public static MatrixByArr[,] GetJ(Universe univ, Vector[] coords, List <RotableInfo> rotInfos, Func <MatrixByArr, MatrixByArr> fnInv3x3 = null)
                {
                    if (fnInv3x3 == null)
                    {
                        fnInv3x3 = delegate(MatrixByArr A)
                        {
                            using (new Matlab.NamedLock("GetJ"))
                            {
                                return(LinAlg.Inv3x3(A));
                            }
                        }
                    }
                    ;

                    MatrixByArr I    = GetITa(univ.atoms.ToArray(), coords);
                    MatrixByArr invI = fnInv3x3(I);

                    Vector      R      = GetRa(univ.atoms.ToArray(), coords);
                    double      M      = GetMa(univ.atoms.ToArray());
                    Vector      MR     = GetMaRa(univ.atoms.ToArray(), coords);
                    MatrixByArr MRx    = GetSSMatrix(MR);
                    MatrixByArr MRxt   = MRx.Tr();
                    MatrixByArr III    = I - (1.0 / M) * MRx * MRxt; // { MI - 1/M * [MR]x * [MR]x^t }
                    MatrixByArr invIII = fnInv3x3(III);
                    //Vector MMR = GetMaMaRa(univ.atoms.ToArray());

                    int n = univ.atoms.Count;
                    int m = rotInfos.Count;

                    MatrixByArr[,] J = new MatrixByArr[n, m];
                    for (int a = 0; a < m; a++)
                    {
                        RotableInfo rotInfo = rotInfos[a];
                        Vector      Ra      = GetRa(rotInfo.rotAtoms, coords);
                        double      Ma      = GetMa(rotInfo.rotAtoms);
                        Vector      MaRa    = GetMaRa(rotInfo.rotAtoms, coords);
                        MatrixByArr Ia      = GetITa(rotInfo.rotAtoms, coords);

                        HDebug.Assert(rotInfo.rotAtoms.Contains(rotInfo.bondedAtom));
                        Vector sa = coords[rotInfo.bondedAtom.ID];
                        //Vector Sa = sa * rotInfos[a].rotAtoms.Length;
                        Vector ea;
                        {
                            HashSet <Atom> bondatoms = new HashSet <Atom>(rotInfo.bond.atoms);
                            bondatoms.Remove(rotInfo.bondedAtom);
                            HDebug.Assert(bondatoms.Count == 1);
                            HDebug.Assert(rotInfo.rotAtoms.Contains(bondatoms.First()) == false);
                            ea = (sa - coords[bondatoms.First().ID]).UnitVector();
                        }

                        Vector Aa;
                        {
                            Vector ea_Rasa = LinAlg.CrossProd3(ea, Ra - sa);
                            Vector IAa     = -LinAlg.MV(Ia, ea) + LinAlg.CrossProd3(Ma * R - MaRa, ea_Rasa);
                            Aa = LinAlg.MV(invI, IAa);
                        }
                        {
                            //Vector ea_MaRa_Masa = Vector.CrossProd3(ea, MaRa-Ma*sa);
                            //Vector ea_sa = Vector.CrossProd3(ea, sa);
                            Vector IAa = new double[3];
                            IAa += -LinAlg.MV(Ia, ea);
                            IAa += LinAlg.CrossProd3(MaRa, LinAlg.CrossProd3(ea, sa));
                            IAa += LinAlg.CrossProd3(MR, LinAlg.CrossProd3(ea, MaRa - Ma * sa)) / M;
                            Aa   = LinAlg.MV(invIII, IAa);
                        }
                        Vector ta = new double[3];
                        {
                            //Aa = new double[3]; // check "translational Eckart condition" only
                            //ta += (-1/M) * Vector.CrossProd3(Aa, MMR);
                            ta += (-1 / M) * LinAlg.CrossProd3(Aa, MR);
                            ta += (-1 / M) * LinAlg.CrossProd3(ea, MaRa - Ma * sa);
                        }

                        for (int i = 0; i < n; i++)
                        {
                            double mi  = univ.atoms[i].Mass;
                            Vector ri  = coords[univ.atoms[i].ID];
                            Vector Jia = new double[3];
                            //Jia += Vector.CrossProd3(Aa, ri*mi);
                            Jia    += LinAlg.CrossProd3(Aa, ri);
                            Jia    += ta;
                            J[i, a] = Jia.ToColMatrix();
                        }
                        foreach (Atom ira in rotInfo.rotAtoms)
                        {
                            int    i   = ira.ID;
                            Vector ri  = coords[univ.atoms[i].ID];
                            Vector Jia = LinAlg.CrossProd3(ea, ri - sa);
                            J[i, a] += Jia.ToColMatrix();
                        }

                        //if(Debug.IsDebuggerAttached)
                        //{
                        //    // check Eckart condition
                        //    // http://en.wikipedia.org/wiki/Eckart_conditions
                        //    //////////////////////////////////////////////////////////////////////
                        //    // 1. translational Eckart condition
                        //    //    sum{i=1..n}{mi * Jia} = 0
                        //    Vector mJ  = EckartConditionTrans(univ, J, a);
                        //    Debug.AssertTolerance(0.00000001, mJ);
                        //    // 2. rotational Eckart condition
                        //    //    sum{i=1..n}{mi * r0i x Jia} = 0,
                        //    //    where 'x' is the cross product
                        //    Vector mrJ = EckartConditionRotat(univ, coords, J, a);
                        //    Debug.AssertTolerance(0.00000001, mrJ);
                        //}
                    }
                    return(J);
                }
示例#16
0
        public void ToFile(string filepath, IList <Vector> coords = null, IList <double> bfactors = null, IList <MatrixByArr> anisous = null, double anisous_scale = 1, bool append = false)
        {
            List <string> lines = new List <string>();

            if (coords == null)
            {
                coords = this.atoms.ListCoord();
            }
            //Debug.Assert(atoms.Length == coords.Count);
            int idx = 0;

            foreach (Element element in elements)
            {
                //string line = element.line;
                if (typeof(Atom).IsInstanceOfType(element))
                {
                    double x = coords[idx][0];
                    double y = coords[idx][1];
                    double z = coords[idx][2];

                    Atom atom = (Atom)element;
                    atom = Atom.FromString(atom.GetUpdatedLine(x, y, z));

                    if (bfactors != null)
                    {
                        atom = Atom.FromString(atom.GetUpdatedLineTempFactor(bfactors[idx]));
                    }

                    lines.Add(atom.line);

                    if (anisous != null)
                    {
                        MatrixByArr anisoui = anisous[idx] * anisous_scale;
                        int[,] U = new int[3, 3] {
                            { (int)anisoui[0, 0], (int)anisoui[0, 1], (int)anisoui[0, 2], },
                            { (int)anisoui[1, 0], (int)anisoui[1, 1], (int)anisoui[1, 2], },
                            { (int)anisoui[2, 0], (int)anisoui[2, 1], (int)anisoui[2, 2], },
                        };
                        Anisou anisou = Anisou.FromAtom(atom, U);
                        lines.Add(anisou.line);
                    }

                    idx++;
                }
                else if (typeof(Anisou).IsInstanceOfType(element) && anisous != null)
                {
                    // skip because it is handled in the "Atom" part
                }
                else
                {
                    lines.Add(element.line);
                }
            }

            if (append == false)
            {
                HFile.WriteAllLines(filepath, lines);
            }
            else
            {
                StringBuilder text = new StringBuilder();
                foreach (string line in lines)
                {
                    text.AppendLine(line);
                }
                HFile.AppendAllText(filepath, text.ToString());
            }
        }
示例#17
0
            //public class CGetHessCoarseResiIterImpl
            //{
            //    public List<IterInfo> iterinfos = null;
            //    public HessMatrix H = null;
            //    public Vector     F = null;
            //};
            public static HessForcInfo GetCoarseHessForcSubIter
                (object[] atoms
                , HessMatrix hess
                , Vector[]   forc
                , List <int>[] lstNewIdxRemv
                , double thres_zeroblk
                , ILinAlg ila
                , bool cloneH
                , string[] options // { "pinv(D)" }
                )
            {
                HessMatrix H = hess;
                Vector     F = forc.ToVector();

                ila = null;
                if (cloneH)
                {
                    H = H.CloneHess();
                }

                bool process_disp_console = true;

                if (options != null && options.Contains("print process"))
                {
                    process_disp_console = true;
                }

                bool parallel = true;

                /// keep only lower triangle of H (lower block triangles)
                {
                    HashSet <Tuple <int, int, MatrixByArr> > lstUppTrig = new HashSet <Tuple <int, int, MatrixByArr> >();
                    foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in H.EnumBlocks())
                    {
                        int bc = bc_br_bval.Item1;
                        int br = bc_br_bval.Item2;
                        if (bc < br)
                        {
                            lstUppTrig.Add(bc_br_bval.ToTuple());
                        }
                    }
                    foreach (Tuple <int, int, MatrixByArr> bc_br_bval in lstUppTrig)
                    {
                        int bc = bc_br_bval.Item1;
                        int br = bc_br_bval.Item2;
                        HDebug.Assert(bc < br);
                        H.SetBlock(bc, br, null);
                    }
                }
                GC.Collect();

                List <DateTime> process_time = new List <DateTime>();

                //System.Console.WriteLine("begin coarse-graining");
                List <IterInfo> iterinfos = new List <IterInfo>();

                for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--)
                {
                    process_time.Clear();
                    if (process_disp_console)
                    {
                        process_time.Add(DateTime.UtcNow);
                        System.Console.Write(" - {0:000} : ", iter);
                    }

                    //int[] ikeep = lstNewIdxRemv[iter].Item1;
                    int[] iremv     = lstNewIdxRemv[iter].ToArray();
                    int   iremv_min = iremv.Min();
                    int   iremv_max = iremv.Max();

                    HDebug.Assert(H.ColBlockSize == H.RowBlockSize);
                    int blksize = H.ColBlockSize;
                    //HDebug.Assert(ikeep.Max() < blksize);
                    //HDebug.Assert(iremv.Max() < blksize);
                    //HDebug.Assert(iremv.Max()+1 == blksize);
                    //HDebug.Assert(iremv.Max() - iremv.Min() + 1 == iremv.Length);

                    int[] idxkeep = HEnum.HEnumFromTo(0, iremv_min - 1).ToArray();
                    int[] idxremv = HEnum.HEnumFromTo(iremv_min, iremv_max).ToArray();
                    //HDebug.Assert(idxkeep.HUnionWith(idxremv).Length == blksize);

                    IterInfo iterinfo = new IterInfo();
                    iterinfo.sizeHessBlkMat  = idxremv.Max() + 1; // H.ColBlockSize;
                    iterinfo.numAtomsRemoved = idxremv.Length;
                    iterinfo.time0           = DateTime.UtcNow;

                    ////////////////////////////////////////////////////////////////////////////////////////
                    // make C sparse
                    double C_density0;
                    double C_density1;
                    {
                        double thres_absmax = thres_zeroblk;

                        C_density0 = 0;
                        List <Tuple <int, int> > lstIdxToMakeZero = new List <Tuple <int, int> >();
                        foreach (var bc_br_bval in H.EnumBlocksInCols(idxremv))
                        {
                            int bc   = bc_br_bval.Item1;
                            int br   = bc_br_bval.Item2;
                            var bval = bc_br_bval.Item3;
                            if (br >= iremv_min)
                            {
                                // bc_br is in D, not in C
                                continue;
                            }

                            C_density0++;
                            double absmax_bval = bval.HAbsMax();
                            if (absmax_bval < thres_absmax)
                            {
                                lstIdxToMakeZero.Add(new Tuple <int, int>(bc, br));
                            }
                        }
                        C_density1 = C_density0 - lstIdxToMakeZero.Count;
                        foreach (var bc_br in lstIdxToMakeZero)
                        {
                            int bc = bc_br.Item1;
                            int br = bc_br.Item2;
                            HDebug.Assert(bc > br);
                            var Cval = H.GetBlock(bc, br);
                            var Dval = H.GetBlock(bc, bc);
                            var Aval = H.GetBlock(br, br);
                            var Bval = Cval.Tr();
                            H.SetBlock(bc, br, null);           // nCval = Cval    -Cval
                            H.SetBlock(bc, bc, Dval + Cval);    // nDval = Dval - (-Cval) = Dval + Cval
                                                                // nBval = Bval    -Bval
                            H.SetBlock(br, br, Aval + Bval);    // nAval = Aval - (-Bval) = Aval + Bval
                        }
                        iterinfo.numSetZeroBlock = lstIdxToMakeZero.Count;
                        iterinfo.numNonZeroBlock = (int)C_density1;
                        C_density0 /= (idxkeep.Length * idxremv.Length);
                        C_density1 /= (idxkeep.Length * idxremv.Length);
                    }

                    ////////////////////////////////////////////////////////////////////////////////////////
                    // get A, B, C, D
                    HessMatrix A = H;       // HessMatrix    A = H.SubMatrixByAtoms(false, idxkeep, idxkeep);
                                            // HessMatrix    B = H.SubMatrixByAtoms(false, idxkeep, idxremv);
                    HessMatrix C;           // HessMatrix    C = H.SubMatrixByAtoms(false, idxremv, idxkeep, parallel:parallel);
                    HessMatrix D;           // HessMatrix    D = H.SubMatrixByAtoms(false, idxremv, idxremv, parallel:parallel);
                    Vector     nF;
                    Vector     nG;
                    {
                        C = H.Zeros(idxremv.Length * 3, idxkeep.Length * 3);
                        D = H.Zeros(idxremv.Length * 3, idxremv.Length * 3);

                        //List<Tuple<int, int, MatrixByArr>> lst_bc_br_bval = H.EnumBlocksInCols(idxremv).ToList();
                        //foreach(var bc_br_bval in lst_bc_br_bval)
                        foreach (var bc_br_bval in H.EnumBlocksInCols(idxremv))
                        {
                            int bc   = bc_br_bval.Item1;
                            int br   = bc_br_bval.Item2;
                            var bval = bc_br_bval.Item3;
                            if (bc < br)
                            {
                                HDebug.Assert(false);
                                continue;
                            }

                            H.SetBlock(bc, br, null);
                            if (bc > iremv_max)
                            {
                                HDebug.Assert(false); continue;
                            }
                            if (br > iremv_max)
                            {
                                HDebug.Assert(false); continue;
                            }
                            if (br < iremv_min)
                            {
                                int nc = bc - iremv_min;
                                int nr = br;
                                HDebug.Assert(C.HasBlock(nc, nr) == false);
                                C.SetBlock(nc, nr, bval.CloneT());
                            }
                            else
                            {
                                int nc = bc - iremv_min;
                                int nr = br - iremv_min;
                                HDebug.Assert(D.HasBlock(nc, nr) == false);
                                D.SetBlock(nc, nr, bval);
                                if (nc != nr)
                                {
                                    HDebug.Assert(D.HasBlock(nr, nc) == false);
                                    D.SetBlock(nr, nc, bval.Tr());
                                }
                            }
                        }
                        HDebug.Assert(H.EnumBlocksInCols(idxremv).Count() == 0);

                        nF = new double[idxkeep.Length * 3];
                        nG = new double[idxremv.Length * 3];
                        for (int i = 0; i < idxkeep.Length * 3; i++)
                        {
                            nF[i] = F[i];
                        }
                        for (int i = 0; i < idxremv.Length * 3; i++)
                        {
                            nG[i] = F[i + nF.Size];
                        }
                    }
                    if (process_disp_console)
                    {
                        process_time.Add(DateTime.UtcNow);
                        int ptc = process_time.Count;
                        System.Console.Write("CD({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes);
                    }

                    ////////////////////////////////////////////////////////////////////////////////////////
                    // Get B.inv(D).C
                    HessMatrix B_invD_C;
                    Vector     B_invD_G;
                    {
                        {
                            var BInvDC_BInvDG = Get_BInvDC_BInvDG_WithSqueeze(C, D, nG, process_disp_console
                                                                              , options
                                                                              , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length
                                                                              , parallel: parallel
                                                                              );
                            B_invD_C = BInvDC_BInvDG.Item1;
                            B_invD_G = BInvDC_BInvDG.Item2;
                        }
                        if (process_disp_console)
                        {
                            process_time.Add(DateTime.UtcNow);
                            int ptc = process_time.Count;
                            System.Console.Write("B.invD.C({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes);
                        }
                        GC.Collect(0);
                    }

                    ////////////////////////////////////////////////////////////////////////////////////////
                    // Get A - B.inv(D).C
                    /// iterinfo.numAddIgnrBlock = A.UpdateAdd(B_invD_C, -1, null, thres_zeroblk/lstNewIdxRemv.Length, parallel:parallel);
                    {
                        HessMatrix __this = A;
                        HessMatrix other  = B_invD_C;
                        double     _thres_NearZeroBlock = thres_zeroblk / lstNewIdxRemv.Length;

                        int[] _count         = new int[1];
                        int[] _count_ignored = new int[1];

                        //foreach(var bc_br_bval in other.EnumBlocks())
                        Action <ValueTuple <int, int, MatrixByArr>, object> func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval, object func_param)
                        {
                            _count[0]++;
                            int         bc         = bc_br_bval.Item1;
                            int         br         = bc_br_bval.Item2;
                            MatrixByArr other_bmat = bc_br_bval.Item3;
                            if (bc < br)
                            {
                                return; // continue;
                            }
                            if (other_bmat.HAbsMax() <= _thres_NearZeroBlock)
                            {
                                /// other_bmat = other_bmat    -other_bmat;
                                /// other_diag = other_diag - (-other_bmat) = other_diag + other_bmat;
                                ///  this_diag =  this_diat - B_invD_C
                                ///            =  this_diat - other_diag
                                ///            =  this_diat - (other_diag + other_bmat)
                                ///            =  this_diat - other_diag  - other_bmat
                                ///            = (this_diat - other_bmat) - other_diag
                                ///            = (this_diat - other_bmat) - (processed later)
                                ///            = (this_diat - other_bmat)
                                MatrixByArr this_diag = __this.GetBlock(bc, bc);
                                MatrixByArr new_diag  = this_diag - other_bmat;
                                __this.SetBlockLock(bc, bc, new_diag);
                                other_bmat = null;
                                lock (_count_ignored)
                                    _count_ignored[0]++;
                            }
                            if (other_bmat != null)
                            {
                                //if(HDebug.IsDebuggerAttached)
                                //{
                                //    double trace = other_bmat.Trace();
                                //    if(bc != br && bc<2059 && br<2059 && Math.Abs(trace) > 100)
                                //        HDebug.Assert();
                                //}

                                MatrixByArr this_bmat = __this.GetBlock(bc, br);
                                if (this_bmat == null)
                                {
                                    this_bmat = new double[3, 3];
                                }
                                MatrixByArr new_bmat = this_bmat - other_bmat;
                                __this.SetBlockLock(bc, br, new_bmat);
                            }
                        };
                        if (parallel)
                        {
                            HParallel.ForEach(other.EnumBlocks(), func, null);
                        }
                        else
                        {
                            foreach (var bc_br_bval in other.EnumBlocks())
                            {
                                func(bc_br_bval, null);
                            }
                        }

                        iterinfo.numAddIgnrBlock = _count_ignored[0];
                    }
                    if (process_disp_console)
                    {
                        process_time.Add(DateTime.UtcNow);
                        int ptc = process_time.Count;
                        System.Console.Write("A-BinvDC({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes);
                    }
                    //HessMatrix nH = A - B_invD_C;
                    //nH = ((nH + nH.Tr())/2).ToHessMatrix();
                    ////////////////////////////////////////////////////////////////////////////////////////
                    // Replace A -> H
                    H = A;
                    F = nF - B_invD_G;

                    ////////////////////////////////////////////////////////////////////////////////////////
                    // print iteration log
                    iterinfo.usedMemoryByte = GC.GetTotalMemory(false);
                    iterinfo.time1          = DateTime.UtcNow;
                    iterinfos.Add(iterinfo);

                    if (process_disp_console)
                    {
                        System.Console.Write("summary(makezero {0,5}, nonzero {1,5}, numIgnMul {2,7}, numRemvAtoms {3,3}, {4,5:0.00} min, {5} mb, {6}x{6}, nzeroBlk/Atom {7:0.00}), GC("
                                             , iterinfo.numSetZeroBlock
                                             , iterinfo.numNonZeroBlock
                                             , iterinfo.numAddIgnrBlock
                                             , iterinfo.numAtomsRemoved
                                             , iterinfo.compTime.TotalMinutes
                                             , iterinfo.usedMemoryByte / (1024 * 1024)
                                             , (idxkeep.Length * 3)
                                             , ((double)iterinfo.numNonZeroBlock / idxremv.Length)
                                             );
                    }
                    GC.Collect();
                    if (process_disp_console)
                    {
                        System.Console.WriteLine(")");
                    }
                }

                int numca = H.ColBlockSize - lstNewIdxRemv.HListCount().Sum();

                //System.Console.WriteLine("finish coarse-graining");
                {
                    int[] idxkeep = HEnum.HEnumCount(numca).ToArray();
                    H = H.SubMatrixByAtoms(false, idxkeep, idxkeep, false);
                }
                {
                    H.MakeNearZeroBlockAsZero(thres_zeroblk);
                }
                {
                    var list_bc_br_bval = H.EnumBlocks().ToArray();

                    Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval)
                    {
                        int bc   = bc_br_bval.Item1;
                        int br   = bc_br_bval.Item2;
                        var bval = bc_br_bval.Item3;
                        HDebug.Assert(bc >= br);
                        if (bc == br)
                        {
                            return;
                        }
                        MatrixByArr bval_tr = bval.Tr();
                        H.SetBlockLock(br, bc, bval_tr);
                        HDebug.Assert(H.GetBlockLock(bc, br) == bval);
                    };
                    if (parallel)
                    {
                        HParallel.ForEach(list_bc_br_bval, func);
                    }
                    else
                    {
                        foreach (var bc_br_bval in list_bc_br_bval)
                        {
                            func(bc_br_bval);
                        }
                    }
                }
                GC.Collect();
                //System.Console.WriteLine("finish resizing");

                HDebug.Assert(H.ColSize == H.RowSize);
                HDebug.Assert(H.ColSize == F.Size);
                return(new HessForcInfoIter
                {
                    iterinfos = iterinfos,
                    hess = H,
                    forc = F.ToVectors(3),
                });
            }
示例#18
0
        public static HessMatrix GetHessAnm(IList <Vector> coords, IEnumerable <Tuple <int, int, double> > enumKij)
        {
            if (GetHessAnm_selftest)
            {
                GetHessAnm_selftest = false;
                Vector[] tcoords = new Vector[]
                {
                    new Vector(0, 0, 0),
                    new Vector(1, 0, 0),
                    new Vector(0, 2, 0),
                    new Vector(0, 0, 3),
                    new Vector(4, 5, 0),
                    new Vector(0, 6, 7),
                    new Vector(8, 0, 9),
                    new Vector(-1, -1, -1),
                };
                Matrix tKij = Matrix.Ones(8, 8);
                for (int i = 0; i < 8; i++)
                {
                    tKij[i, i] = 0;
                }
                HessMatrix hess0 = GetHessAnm_debug(tcoords, tKij);
                HessMatrix hess1 = GetHessAnm(tcoords, tKij.HEnumNonZeros());
                HDebug.Assert((hess0 - hess1).HAbsMax() == 0);
            }
            //Debug.Assert(AnmHessianSelfTest());

            int        n    = coords.Count;
            HessMatrix hess = null;

            if (n < 100)
            {
                hess = HessMatrixDense.ZerosDense(n * 3, n * 3);
            }
            else
            {
                hess = HessMatrixSparse.ZerosSparse(n * 3, n * 3);
            }
            int numset = 0;

            foreach (var kij in enumKij)
            {
                int    i    = kij.Item1;
                int    j    = kij.Item2;
                double k_ij = kij.Item3;
                {
                    if (i == j)
                    {
                        HDebug.Assert(k_ij == 0);
                        continue;
                    }
                    if (coords[j] == null)
                    {
                        continue;
                    }
                    Vector vec_ij  = coords[j] - coords[i];
                    Vector unit_ij = vec_ij.UnitVector();
                    HDebug.Assert(double.IsNaN(k_ij) == false);
                    if (k_ij == 0)
                    {
                        continue;
                    }
                    MatrixByArr hessij = new double[3, 3];
                    hessij[0, 0] = -k_ij * unit_ij[0] * unit_ij[0];
                    hessij[0, 1] = -k_ij * unit_ij[0] * unit_ij[1];
                    hessij[0, 2] = -k_ij * unit_ij[0] * unit_ij[2];
                    hessij[1, 0] = -k_ij * unit_ij[1] * unit_ij[0];
                    hessij[1, 1] = -k_ij * unit_ij[1] * unit_ij[1];
                    hessij[1, 2] = -k_ij * unit_ij[1] * unit_ij[2];
                    hessij[2, 0] = -k_ij * unit_ij[2] * unit_ij[0];
                    hessij[2, 1] = -k_ij * unit_ij[2] * unit_ij[1];
                    hessij[2, 2] = -k_ij * unit_ij[2] * unit_ij[2];
                    hess.SetBlock(i, j, hessij);
                    MatrixByArr hessii = hess.GetBlock(i, i) - hessij;
                    hess.SetBlock(i, i, hessii);
                    numset++;
                }
            }

            return(hess);
        }
示例#19
0
 public abstract void SetBlockLock(int bc, int br, MatrixByArr bval);
                public static CGetHessCoarseResiIterImpl Do
                    (object[] atoms
                    , HessMatrix H
                    , List <int>[] lstNewIdxRemv
                    , double thres_zeroblk
                    , ILinAlg ila
                    , bool cloneH
                    , string[] options
                    )
                {
                    //HDebug.ToDo();

                    ila    = null;
                    cloneH = true;
                    if (cloneH)
                    {
                        H = H.CloneHess();
                    }

                    bool process_disp_console = true;

                    if (options != null && options.Contains("print process"))
                    {
                        process_disp_console = true;
                    }

                    bool parallel = false;

                    /// keep only lower triangle of H (lower block triangles)
                    {
                        HashSet <Tuple <int, int, MatrixByArr> > lstUppTrig = new HashSet <Tuple <int, int, MatrixByArr> >();
                        foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in H.EnumBlocks())
                        {
                            int bc = bc_br_bval.Item1;
                            int br = bc_br_bval.Item2;
                            if (bc < br)
                            {
                                lstUppTrig.Add(bc_br_bval.ToTuple());
                            }
                        }
                        foreach (Tuple <int, int, MatrixByArr> bc_br_bval in lstUppTrig)
                        {
                            int bc = bc_br_bval.Item1;
                            int br = bc_br_bval.Item2;
                            HDebug.Assert(bc < br);
                            H.SetBlock(bc, br, null);
                        }
                    }
                    GC.Collect();

                    DateTime[] process_time = new DateTime[6];

                    //System.Console.WriteLine("begin coarse-graining");
                    List <HessCoarseResiIterInfo> iterinfos = new List <HessCoarseResiIterInfo>();

                    for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--)
                    {
                        bool lprocess_disp_console = (process_disp_console && iter % 5 == 0);
                        lprocess_disp_console = true;
                        if (lprocess_disp_console)
                        {
                            process_time[0] = DateTime.UtcNow;
                            System.Console.Write(" - {0:000} : ", iter);
                        }

                        //int[] ikeep = lstNewIdxRemv[iter].Item1;

                        HessCoarseResiIterInfo iterinfo = new HessCoarseResiIterInfo();
                        iterinfo.sizeHessBlkMat  = 1;
                        iterinfo.numAtomsRemoved = 1;
                        iterinfo.time0           = DateTime.UtcNow;
                        int _count_update = 0;
                        {
                            HDebug.Assert(lstNewIdxRemv[iter].Count == 1);
                            int iremv = lstNewIdxRemv[iter][0];

                            HessMatrix         A         = H;
                            MatrixByArr        D         = null;
                            double             D_absmin  = 0;
                            List <int>         C_lstbr   = new List <int>();
                            List <MatrixByArr> C_lstbval = new List <MatrixByArr>();
                            {
                                // get C and D
                                foreach (var(bc, br, bval) in H.EnumBlocksInCols(new int[] { iremv }))
                                {
                                    HDebug.Assert(iremv == bc);
                                    if (bc == br)
                                    {
                                        HDebug.Assert(D == null);
                                        D        = bval;
                                        D_absmin = D.HAbsMin();
                                    }
                                    else
                                    {
                                        if (bval.HAbsMin() >= thres_zeroblk)
                                        {
                                            C_lstbr.Add(br);
                                            C_lstbval.Add(bval);
                                        }
                                    }
                                }
                                // remove C and D
                                {
                                    int bc = iremv;
                                    H.SetBlock(bc, bc, null);
                                    foreach (int br in C_lstbr)
                                    {
                                        H.SetBlock(bc, br, null);
                                    }
                                }
                            }
                            if (lprocess_disp_console)
                            {
                                process_time[1] = process_time[2] = DateTime.UtcNow;
                                System.Console.Write("CD({0:00.00} min), ", (process_time[2] - process_time[0]).TotalMinutes);
                            }

                            double threshold = thres_zeroblk / lstNewIdxRemv.Length;

                            //  DD ={ { d00,d01,d02},{ d10,d11,d12},{ d20,d21,d22} }; MatrixForm[DD]
                            //  BB ={ { b00,b01,b02},{ b10,b11,b12},{ b20,b21,b22} }; MatrixForm[BB]
                            //  CC ={ { c00,c01,c02},{ c10,c11,c12},{ c20,c21,c22} }; MatrixForm[CC]
                            //  object[]    dbginfo = null; // new object[] { iremv, atoms, H, D, C_lstbr, C_lstbval };

                            Action <ValueTuple <int, int, MatrixByArr, MatrixByArr> > Update_A_B_invD_C = delegate(ValueTuple <int, int, MatrixByArr, MatrixByArr> info)
                            {
                                int         bc = info.Item1; // bc
                                int         br = info.Item2; // br
                                MatrixByArr DC = info.Item3; // invDD_CC  // XX ={ { x00,x01,x02},{ x10,x11,x12},{ x20,x21,x22} }; MatrixForm[CC]
                                MatrixByArr B  = info.Item4; // BB        // BB ={ { b00,b01,b02},{ b10,b11,b12},{ b20,b21,b22} }; MatrixForm[BB]
                                //var _iremv                      = (int)dbginfo[0];
                                //var _atoms                      = dbginfo[1] as Universe.Atom[]  ;
                                //var _H                          = dbginfo[2] as HessMatrix       ;
                                //var _D                          = dbginfo[3] as MatrixByArr      ;
                                //var _C_lstbr                    = dbginfo[4] as List<int>        ;
                                //var _C_lstbval                  = dbginfo[5] as List<MatrixByArr>;

                                //MatrixByArr BB_invDD_CC = BB * invDD_CC;
                                double _BDC00 = 0 - B[0, 0] * DC[0, 0] - B[0, 1] * DC[1, 0] - B[0, 2] * DC[2, 0]; // { { b00 x00 +b01 x10 + b02 x20
                                double _BDC01 = 0 - B[0, 0] * DC[0, 1] - B[0, 1] * DC[1, 1] - B[0, 2] * DC[2, 1]; //   , b00 x01 +b01 x11 + b02 x21
                                double _BDC02 = 0 - B[0, 0] * DC[0, 2] - B[0, 1] * DC[1, 2] - B[0, 2] * DC[2, 2]; //   , b00 x02 +b01 x12 + b02 x22
                                double _BDC10 = 0 - B[1, 0] * DC[0, 0] - B[1, 1] * DC[1, 0] - B[1, 2] * DC[2, 0]; // },{ b10 x00 +b11 x10 + b12 x20
                                double _BDC11 = 0 - B[1, 0] * DC[0, 1] - B[1, 1] * DC[1, 1] - B[1, 2] * DC[2, 1]; //   , b10 x01 +b11 x11 + b12 x21
                                double _BDC12 = 0 - B[1, 0] * DC[0, 2] - B[1, 1] * DC[1, 2] - B[1, 2] * DC[2, 2]; //   , b10 x02 +b11 x12 + b12 x22
                                double _BDC20 = 0 - B[2, 0] * DC[0, 0] - B[2, 1] * DC[1, 0] - B[2, 2] * DC[2, 0]; // },{ b20 x00 +b21 x10 + b22 x20
                                double _BDC21 = 0 - B[2, 0] * DC[0, 1] - B[2, 1] * DC[1, 1] - B[2, 2] * DC[2, 1]; //   , b20 x01 +b21 x11 + b22 x21
                                double _BDC22 = 0 - B[2, 0] * DC[0, 2] - B[2, 1] * DC[1, 2] - B[2, 2] * DC[2, 2]; //   , b20 x02 +b21 x12 + b22 x22 }}

                                if (A.HasBlockLock(bc, br))
                                {
                                    MatrixByArr A_bc_br = A.GetBlockLock(bc, br);
                                    A_bc_br[0, 0] += _BDC00; // A = A + (-B.invD.C)
                                    A_bc_br[0, 1] += _BDC01; // A = A + (-B.invD.C)
                                    A_bc_br[0, 2] += _BDC02; // A = A + (-B.invD.C)
                                    A_bc_br[1, 0] += _BDC10; // A = A + (-B.invD.C)
                                    A_bc_br[1, 1] += _BDC11; // A = A + (-B.invD.C)
                                    A_bc_br[1, 2] += _BDC12; // A = A + (-B.invD.C)
                                    A_bc_br[2, 0] += _BDC20; // A = A + (-B.invD.C)
                                    A_bc_br[2, 1] += _BDC21; // A = A + (-B.invD.C)
                                    A_bc_br[2, 2] += _BDC22; // A = A + (-B.invD.C)
                                    // (small && small && small) == !(large || large || large)
                                    bool toosmall = !(Math.Abs(A_bc_br[0, 0]) > threshold || Math.Abs(A_bc_br[0, 1]) > threshold || Math.Abs(A_bc_br[0, 2]) > threshold ||
                                                      Math.Abs(A_bc_br[1, 0]) > threshold || Math.Abs(A_bc_br[1, 1]) > threshold || Math.Abs(A_bc_br[1, 2]) > threshold ||
                                                      Math.Abs(A_bc_br[2, 0]) > threshold || Math.Abs(A_bc_br[2, 1]) > threshold || Math.Abs(A_bc_br[2, 2]) > threshold);
                                    if (toosmall)
                                    {
                                        HDebug.Assert(bc != br);
                                        A.SetBlockLock(bc, br, null);
                                    }
                                }
                                else
                                {
                                    // (small && small && small) == !(large || large || large)
                                    bool toosmall = !(Math.Abs(_BDC00) > threshold || Math.Abs(_BDC01) > threshold || Math.Abs(_BDC02) > threshold ||
                                                      Math.Abs(_BDC10) > threshold || Math.Abs(_BDC11) > threshold || Math.Abs(_BDC12) > threshold ||
                                                      Math.Abs(_BDC20) > threshold || Math.Abs(_BDC21) > threshold || Math.Abs(_BDC22) > threshold);
                                    if (!toosmall)
                                    {
                                        MatrixByArr A_bc_br = new double[3, 3]
                                        {
                                            { _BDC00, _BDC01, _BDC02 }   // A = 0 + (-B.invD.C)
                                            , { _BDC10, _BDC11, _BDC12 } // A = 0 + (-B.invD.C)
                                            , { _BDC20, _BDC21, _BDC22 } // A = 0 + (-B.invD.C)
                                        };
                                        A.SetBlockLock(bc, br, A_bc_br);
                                    }
                                }

                                System.Threading.Interlocked.Increment(ref _count_update);
                            };

                            var lstCompInfo = EnumComput(D, C_lstbr, C_lstbval, threshold);
                            if (parallel)
                            {
                                Parallel.ForEach(lstCompInfo, Update_A_B_invD_C);
                            }
                            else
                            {
                                foreach (var info in lstCompInfo)
                                {
                                    Update_A_B_invD_C(info);
                                }
                            }

                            //GC.Collect(0);

                            if (lprocess_disp_console)
                            {
                                process_time[4] = DateTime.UtcNow;
                                System.Console.Write("B.invD.C({0:00.00} min), ", (process_time[4] - process_time[3]).TotalMinutes);
                            }

                            H = A;
                        }
                        iterinfo.usedMemoryByte = GC.GetTotalMemory(false);
                        iterinfo.time1          = DateTime.UtcNow;
                        iterinfos.Add(iterinfo);

                        if (lprocess_disp_console)
                        {
                            System.Console.WriteLine("summary(makezero {0,5}, nonzero {1,5}, numIgnMul {2,7}, numRemvAtoms {3,3}, {4,5:0.00} sec, {5} mb, {6}x{6}, nzeroBlk/Atom {7:0.00}, cntUpdateBlk({8}))"
                                                     , iterinfo.numSetZeroBlock
                                                     , iterinfo.numNonZeroBlock
                                                     , iterinfo.numAddIgnrBlock
                                                     , iterinfo.numAtomsRemoved
                                                     , iterinfo.compSec
                                                     , iterinfo.usedMemoryByte / (1024 * 1024)
                                                     , (0 * 3)
                                                     , 0//((double)iterinfo.numNonZeroBlock / idxremv.Length)
                                                     , _count_update
                                                     );
                        }
                    }
                    int numca = H.ColBlockSize - lstNewIdxRemv.HListCount().Sum();

                    //System.Console.WriteLine("finish coarse-graining");
                    {
                        int[] idxkeep = HEnum.HEnumCount(numca).ToArray();
                        H = H.SubMatrixByAtoms(false, idxkeep, idxkeep, false);
                    }
                    {
                        H.MakeNearZeroBlockAsZero(thres_zeroblk);
                    }
                    GC.Collect(0);
                    //System.Console.WriteLine("finish resizing");

                    return(new CGetHessCoarseResiIterImpl
                    {
                        iterinfos = iterinfos,
                        H = H,
                    });
                }
示例#21
0
            private void GetPotentialAndTorForce(List <ForceField.IForceField> frcflds, Vector[] coords
                                                 , out double energy, out Vector[] forces, out MatrixByArr hessian, out double[] dtor
                                                 , 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();
                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);
            }
示例#22
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);
            }
示例#23
0
        public static bool GetHessGnmSelfTest()
        {
            if (HDebug.Selftest() == false)
            {
                return(true);
            }

            Pdb pdb = Pdb.FromPdbid("1MJC");

            for (int i = 0; i < pdb.atoms.Length; i++)
            {
                HDebug.Assert(pdb.atoms[0].altLoc == pdb.atoms[i].altLoc);
                HDebug.Assert(pdb.atoms[0].chainID == pdb.atoms[i].chainID);
            }
            List <Vector> coords = pdb.atoms.ListCoord();
            double        cutoff = 13;

            Matlab.Execute("clear");
            Matlab.PutMatrix("x", MatrixByArr.FromRowVectorList(coords).ToArray());
            Matlab.PutValue("cutoffR", cutoff);
            Matlab.Execute(@"%  function cx = contactsNew(x, cutoffR)
                                % Contact matrix within cutoff distance.
                                % Author: Guang Song
                                % New: 10/25/2006
                                %

                                %n = size(x,1); 
                                % Method 1: slow
                                %for i=1:n
                                %  center = x(i,:);
                                %  distSqr(:,i) = sum((x-center(ones(n,1),:)).^2,2);
                                %end
                                %cx = sparse(distSqr<=cutoffR^2);

                                % Method 2: fast! about 28 times faster when array size is 659x3
                                %tot = zeros(n,n);
                                %for i=1:3
                                %  xi = x(:,ones(n,1)*i);
                                %  %tmp = (xi - xi.').^2;
                                %  %tot = tot + tmp;
                                %  tot = tot +  (xi - xi.').^2;
                                %end
                                %cx = sparse(tot<=cutoffR^2);

                                % Method 3: this implementation is the shortest! but sligtly slower than 
                                % method 2
                                %xn = x(:,:,ones(n,1)); % create n copy x
                                %xnp = permute(xn,[3,2,1]);
                                %tot = sum((xn-xnp).^2,2); % sum along x, y, z
                                %cx = sparse(permute(tot,[1,3,2])<=cutoffR^2);
                                % put it into one line like below actually slows it down. Don't do that.
                                %cx =  sparse(permute(sum((xn-permute(xn,[3,2,1])).^2,2),[1,3,2])<=cutoffR^2);

                                %Method 4: using function pdist, which I just know
                                % this one line implementation is even faster. 2 times than method 2.
                                cx = sparse(squareform(pdist(x)<=cutoffR));
                            ");
            Matlab.Execute(@"%  function gnm = kirchhoff(cx)
                                % the returned gnm provide the kirchhoff matrix
                                % cx is the contact map.
                                % Guang Song
                                % 11/09/06
                                gnm = diag(sum(cx)) - cx;
                            ");
            Matlab.Execute("gnm = full(gnm);");
            Matrix gnm_gsong = Matlab.GetMatrix("gnm");

            Matlab.Execute("clear;");

            Matrix gnm = GetHessGnm(coords.ToArray(), cutoff);

            if (gnm_gsong.RowSize != gnm.RowSize)
            {
                HDebug.Assert(false); return(false);
            }
            if (gnm_gsong.ColSize != gnm.ColSize)
            {
                HDebug.Assert(false); return(false);
            }

            for (int c = 0; c < gnm.ColSize; c++)
            {
                for (int r = 0; r < gnm.RowSize; r++)
                {
                    if (Math.Abs(gnm_gsong[c, r] - gnm[c, r]) >= 0.00000001)
                    {
                        HDebug.Assert(false); return(false);
                    }
                }
            }

            return(true);
        }