示例#1
0
        public static Mode[] PCA(IList <Vector[]> confs, ref Vector[] meanconf, ILinAlg ila)
        {
            if (meanconf == null)
            {
                meanconf = new Vector[confs[0].Length];
                for (int i = 0; i < meanconf.Length; i++)
                {
                    Vector meancoord = new double[3];
                    foreach (Vector[] conf in confs)
                    {
                        meancoord += conf[i];
                    }
                    meancoord  /= confs.Count;
                    meanconf[i] = meancoord;
                }
            }

            int    size      = meanconf.Length;
            int    size3     = size * 3;
            int    num       = confs.Count;
            Matrix mconfs    = Matrix.Zeros(size3, num);
            Vector vmeanconf = Vector.FromBlockvector(meanconf);

            for (int r = 0; r < num; r++)
            {
                Vector vconf  = Vector.FromBlockvector(confs[r]);
                Vector dvconf = vconf - vmeanconf;
                for (int c = 0; c < size3; c++)
                {
                    mconfs[c, r] = dvconf[c];
                }
            }

            Matrix cov = null;
            {
                var CONFS = ila.ToILMat(mconfs);
                var COV   = CONFS * CONFS.Tr;
                cov = COV.ToArray();
                CONFS.Dispose();
                COV.Dispose();
            }

            Func <Matrix, Tuple <Matrix, Vector> > fnEig = delegate(Matrix A)
            {
                var    AA   = ila.ToILMat(A);
                var    VVDD = ila.EigSymm(AA);
                var    VV   = VVDD.Item1;
                Vector D    = VVDD.Item2;
                Matrix V    = VV.ToArray();
                AA.Dispose();
                VV.Dispose();
                return(new Tuple <Matrix, Vector>(V, D));
            };

            return(PCA(cov, confs.Count, fnEig));
        }
示例#2
0
        public static Mode[] GetModesFromHess(Matrix hess, ILinAlg la)
        {
            List <Mode> modes;

            {
                Matrix V;
                Vector D;
                switch (la)
                {
                case null:
                    using (new Matlab.NamedLock(""))
                    {
                        Matlab.PutMatrix("H", hess, true);
                        Matlab.Execute("H = (H + H')/2;");
                        Matlab.Execute("[V,D] = eig(H);");
                        Matlab.Execute("D = diag(D);");
                        V = Matlab.GetMatrix("V", true);
                        D = Matlab.GetVector("D", true);
                    }
                    break;

                default:
                {
                    var H = la.ToILMat(hess);
                    H = (H + H.Tr) / 2;
                    var VD = la.EigSymm(H);
                    V = VD.Item1.ToMatrix();
                    D = VD.Item2;
                    H.Dispose();
                    VD.Item1.Dispose();
                }
                break;
                }

                int[] idxs = D.ToArray().HAbs().HIdxSorted();
                modes = new List <Mode>(idxs.Length);
                //foreach(int idx in idxs)
                for (int th = 0; th < idxs.Length; th++)
                {
                    int  idx  = idxs[th];
                    Mode mode = new Mode
                    {
                        th     = (th + 1),
                        eigval = D[idx],
                        eigvec = V.GetColVector(idx)
                    };
                    modes.Add(mode);
                }
            }
            System.GC.Collect();
            return(modes.ToArray());
        }
示例#3
0
        public static Matrix GetInvSprTensorSymm(Matrix H, Matrix S, ILinAlg ila)
        {
            // check H be symmetric
            HDebug.AssertToleranceMatrix(0.00000001, H - H.Tr());

            Matrix invK = GetInvSprTensor(H, S, ila);

            if (HDebug.IsDebuggerAttached && ila != null)
            {
                HDebug.AssertToleranceMatrix(0.00000001, invK - invK.Tr()); // check symmetric
                var invKK = ila.ToILMat(invK);
                var VVDD  = ila.EigSymm(invKK);
                foreach (double d in VVDD.Item2)
                {
                    HDebug.Assert(d > -0.00000001);
                }
            }
            return(invK);
        }
示例#4
0
        public static Matrix GetInvSprTensor(Matrix H, Matrix S, ILinAlg ila)
        {
            Matrix invH;
            string optInvH = "EigSymmTol";

            optInvH += ((ila == null) ? "-matlab" : "-ilnum");
            switch (optInvH)
            {
            case "InvSymm-ilnum":
                HDebug.Assert(false);
                invH = ila.InvSymm(H);
                break;

            case "PInv-ilnum":
                invH = ila.PInv(H);
                break;

            case "EigSymm-ilnum":
            {
                var HH   = ila.ToILMat(H);
                var VVDD = ila.EigSymm(HH);
                var VV   = VVDD.Item1;
                for (int i = 0; i < VVDD.Item2.Length; i++)
                {
                    VVDD.Item2[i] = 1 / VVDD.Item2[i];
                }
                for (int i = 0; i < 6; i++)
                {
                    VVDD.Item2[i] = 0;
                }
                var DD    = ila.ToILMat(VVDD.Item2).Diag();
                var invHH = ila.Mul(VV, DD, VV.Tr);
                invH = invHH.ToArray();
                //var check = (H * invH).ToArray();
                GC.Collect();
            }
            break;

            case "EigSymmTol-matlab":
            {
                using (new Matlab.NamedLock(""))
                {
                    Matlab.PutMatrix("invHH.HH", H);
                    Matlab.Execute("invHH.HH = (invHH.HH + invHH.HH')/2;");
                    Matlab.Execute("[invHH.VV, invHH.DD] = eig(invHH.HH);");
                    Matlab.Execute("invHH.DD = diag(invHH.DD);");
                    Matlab.Execute("invHH.DD(abs(invHH.DD)<0.00001) = 0;");
                    Matlab.Execute("invHH.DD = pinv(diag(invHH.DD));");
                    Matlab.Execute("invHH = invHH.VV * invHH.DD * invHH.VV';");
                    invH = Matlab.GetMatrix("invHH");
                    Matlab.Execute("clear invHH;");
                }
                GC.Collect();
            }
            break;

            case "EigSymmTol-ilnum":
            {
                var HH   = ila.ToILMat(H);
                var VVDD = ila.EigSymm(HH);
                var VV   = VVDD.Item1;
                for (int i = 0; i < VVDD.Item2.Length; i++)
                {
                    if (Math.Abs(VVDD.Item2[i]) < 0.00001)
                    {
                        VVDD.Item2[i] = 0;
                    }
                    else
                    {
                        VVDD.Item2[i] = 1 / VVDD.Item2[i];
                    }
                }
                var DD    = ila.ToILMat(VVDD.Item2).Diag();
                var invHH = ila.Mul(VV, DD, VV.Tr);
                invH = invHH.ToArray();
                //var check = (H * invH).ToArray();
                GC.Collect();
            }
            break;

            default:
                throw new NotImplementedException();
            }

            Matrix invkij = 0.5 * (S.Tr() * invH * S);

            //HDebug.Assert(invkij >= 0);

            return(invkij);
        }
示例#5
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, ...
            }