コード例 #1
0
 public static void SelfTest()
 {
     if (HDebug.Selftest())
     {
         Random rand       = new Random(0);
         int    colblksize = 3;
         int    rowblksize = 10;
         int    layersize  = 3;
         var    mat        = Matrix.Zeros(colblksize * 3, rowblksize * 3);
         var    hess       = new HessMatrixLayeredArray(colblksize * 3, rowblksize * 3, layersize);
         HDebug.Assert(mat.ColSize == hess.ColSize);
         HDebug.Assert(mat.RowSize == hess.RowSize);
         int count = mat.ColSize * mat.RowSize * 10;
         for (int i = 0; i < count; i++)
         {
             int    c = rand.NextInt(0, colblksize * 3 - 1);
             int    r = rand.NextInt(0, rowblksize * 3 - 1);
             double v = rand.NextDouble();
             mat[c, r]  = v;
             hess[c, r] = v;
             HDebug.AssertTolerance(double.Epsilon, (mat - hess).ToArray());
         }
         for (int i = 0; i < 700; i++)
         {
             int    c = rand.NextInt(0, colblksize * 3 - 1);
             int    r = rand.NextInt(0, rowblksize * 3 - 1);
             double v = 0;
             mat[c, r]  = v;
             hess[c, r] = v;
             HDebug.AssertTolerance(double.Epsilon, (mat - hess).ToArray());
         }
     }
 }
コード例 #2
0
        //////////////////////////////////////////////////////////////////////////////////////////////////
        // HessMatrix
        HessMatrixLayeredArray(int colsize, int rowsize, int layersize)
        {
            if (HDebug.Selftest())
            {
                SelfTest();
            }

            HDebug.Assert(colsize % 3 == 0);
            HDebug.Assert(rowsize % 3 == 0);
            this.colblksize = colsize / 3;
            this.rowblksize = rowsize / 3;
            this.layersize  = layersize;

            int br2_size = rowblksize % layersize;
            int br1_size = (rowblksize - br2_size) / layersize + 1;

            diag          = new List <double    [, ]>(colblksize);
            offdiag       = new List <double[][][, ]>(colblksize);
            offdiag_count = new List <int   []>(colblksize);
            for (int bc = 0; bc < colblksize; bc++)
            {
                diag.Add(null);
                offdiag.Add(new double[br1_size][][, ]);
                offdiag_count.Add(new int   [br1_size]);
                for (int br1 = 0; br1 < br1_size; br1++)
                {
                    offdiag      [bc][br1] = null;
                    offdiag_count[bc][br1] = 0;
                }
            }
        }
コード例 #3
0
ファイル: Mode.cs プロジェクト: htna/explsolv
 public void GetHessian(MatrixByArr hess)
 {
     if (HDebug.Selftest())
     {
         Mode tmode = new Mode();
         tmode.eigval = 2;
         tmode.eigvec = new double[] { 1, 2, 3 };
         MatrixByArr thess0 = new double[, ] {
             { 2, 4, 6 }
             , { 4, 8, 12 }
             , { 6, 12, 18 }
         };
         MatrixByArr thess1 = new double[3, 3];
         tmode.GetHessian(thess1);
         HDebug.AssertTolerance(0.00000001, thess0 - thess1);
     }
     HDebug.Assert(hess.RowSize == eigvec.Size, hess.ColSize == eigvec.Size);
     //unsafe
     {
         double[] pvec = eigvec._data;
         {
             for (int c = 0; c < eigvec.Size; c++)
             {
                 for (int r = 0; r < eigvec.Size; r++)
                 {
                     hess[c, r] += eigval * pvec[c] * pvec[r];
                 }
             }
         }
     }
 }
コード例 #4
0
ファイル: Mode.cs プロジェクト: htna/explsolv
        public Mode GetNormalized()
        {
            if (HDebug.Selftest())
            {
                Mode lmode0 = new Mode {
                    eigval = 0.123, eigvec = new double[] { 1, 2, 3, 2, 3, 4, 3, 4, 5 }
                };
                Mode lmode1 = lmode0.GetNormalized();
                HDebug.Assert(lmode0.eigvec.Size == lmode1.eigvec.Size);
                MatrixByArr lhess0 = new double[lmode0.eigvec.Size, lmode0.eigvec.Size];
                MatrixByArr lhess1 = new double[lmode1.eigvec.Size, lmode1.eigvec.Size];
                lmode0.GetHessian(lhess0);
                lmode1.GetHessian(lhess1);
                double tolbase = Math.Max(lhess0.ToArray().HMax(), lhess1.ToArray().HMax());
                HDebug.AssertTolerance(tolbase * 0.00000001, lhess0 - lhess1);
            }

            /// H = sum vi' * di * vi
            ///   = sum (vi/|vi|)'  * (di |vi|^2) * (vi/|vi|)
            double leigvec = eigvec.Dist;
            Vector neigvec = eigvec.UnitVector();

            return(new Mode
            {
                th = th,
                eigval = eigval * leigvec * leigvec,
                eigvec = neigvec
            });
        }
コード例 #5
0
        static void UpdateMassWeightedHess(HessMatrix hess, Vector mass)
        {
            if (hess.ColSize < 15000)
            {
                if (HDebug.Selftest())
                {
                    Matrix tmat0 = hess.ToArray();
                    UpdateMassWeightedHess(tmat0, mass);
                    HessMatrix tmat1 = hess.CloneHess();
                    UpdateMassWeightedHess(tmat1, mass);
                    double absmax = (tmat0 - tmat1).HAbsMax();
                    HDebug.Exception(absmax < 0.00000001);
                }
            }

            HDebug.Exception(mass.Size % 3 == 0);
            double[] mass03sqrt = new double[mass.Size / 3];
            for (int i = 0; i < mass03sqrt.Length; i++)
            {
                HDebug.Exception(mass[i * 3 + 0] == mass[i * 3 + 1]);
                HDebug.Exception(mass[i * 3 + 0] == mass[i * 3 + 2]);
                mass03sqrt[i] = mass[i * 3 + 0];
            }
            mass03sqrt = mass03sqrt.HSqrt();

            foreach (var bc_br_bval in hess.EnumBlocks().ToArray())
            {
                int bc   = bc_br_bval.Item1;
                int br   = bc_br_bval.Item2;
                var bval = bc_br_bval.Item3;
                bval = bval / (mass03sqrt[bc] * mass03sqrt[br]);

                hess.SetBlock(bc, br, bval);
            }
        }
コード例 #6
0
        public static Matrix GetMassWeightedHessGnm(Matrix hess, Vector mass)
        {
            if (HDebug.Selftest())
            //#region selftest
            {
            }
            //#endregion

            HDebug.Assert(hess.ColSize == hess.RowSize, hess.RowSize == mass.Size);
            Vector mass05 = mass.ToArray().HSqrt();

            // mass weighted hessian
            // MH = M^(-1/2) * H * M^(-1/2)
            // MH_ij = H_IJ * sqrt(M[i] * M[j])
            Matrix mwhess = hess.Clone();

            {
                // mass weighted block hessian
                for (int c = 0; c < hess.ColSize; c++)
                {
                    for (int r = 0; r < hess.RowSize; r++)
                    {
                        mwhess[c, r] = hess[c, r] / (mass05[c] * mass05[r]);
                    }
                }
            }

            return(mwhess);
        }
コード例 #7
0
            static public void MV(HessMatrixSparse M, Vector V, Vector mv, Vector bvec, Vector bmv)
            {
                HDebug.Exception(V.Size == M.RowSize);
                HDebug.Exception(mv.Size == M.ColSize); //Vector mv = new double[M.ColSize];
                HDebug.Exception(bvec.Size == 3);       //Vector bvec = new double[3];
                HDebug.Exception(bmv.Size == 3);        //Vector bmv = new double[3];
                foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in M.EnumBlocks())
                {
                    int bc   = bc_br_bval.Item1;
                    int br   = bc_br_bval.Item2;
                    var bmat = bc_br_bval.Item3;
                    bvec[0] = V[br * 3 + 0];
                    bvec[1] = V[br * 3 + 1];
                    bvec[2] = V[br * 3 + 2];
                    HTLib2.LinAlg.MV(bmat, bvec, bmv);
                    mv[bc * 3 + 0] += bmv[0];
                    mv[bc * 3 + 1] += bmv[1];
                    mv[bc * 3 + 2] += bmv[2];
                }

                if (HDebug.Selftest())
                {
                    Matlab.Clear();
                    Matlab.PutSparseMatrix("M", M.GetMatrixSparse(), 3, 3);
                    Matlab.PutVector("V", V);
                    Matlab.Execute("MV = M*V;");
                    Matlab.PutVector("MV1", mv);
                    Vector err     = Matlab.GetVector("MV-MV1");
                    double err_max = err.ToArray().HAbs().Max();
                    HDebug.Assert(err_max < 0.00000001);
                }
            }
コード例 #8
0
ファイル: Tinker.Int.cs プロジェクト: htna/explsolv
            public static Int FromLines(IList <string> lines)
            {
                if (HDebug.Selftest())
                #region MyRegion
                {
                }
                #endregion

                if (lines == null)
                {
                    return(null);
                }
                if (lines.Count == 0)
                {
                    return(null);
                }

                Element[] elements = new Element[lines.Count];
                elements[0] = new Header(lines[0]);
                for (int i = 1; i < lines.Count; i++)
                {
                    elements[i] = new Atom(lines[i]);
                }

                Int intrnl = new Int();
                intrnl.elements = elements;

                return(intrnl);
            }
コード例 #9
0
ファイル: Hess.HessMatrix.Oper.cs プロジェクト: htna/explsolv
        public static HessMatrix GetMulImpl(ILinAlg ila, bool warning, params HessMatrix[] mats)
        {
            if (ila != null)
            {
                if (HDebug.Selftest())
                {
                    Matrix h0 = 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 h1 = HessMatrixDense.FromMatrix(h0);
                    HessMatrix h2 = HessMatrixSparse.FromMatrix(h0);
                    Matrix     t0 = Matrix.GetMul(Matrix.GetMul(h1, h1), h1);
                    {
                        Matrix t1 = GetMulImpl(ila, false, h1, h1, h1); double d1 = (t0 - t1).HAbsMax(); HDebug.Assert(0 == d1);
                        Matrix t2 = GetMulImpl(ila, false, h1, h1, h2); double d2 = (t0 - t2).HAbsMax(); HDebug.Assert(0 == d2);
                        Matrix t3 = GetMulImpl(ila, false, h1, h2, h1); double d3 = (t0 - t3).HAbsMax(); HDebug.Assert(0 == d3);
                        Matrix t4 = GetMulImpl(ila, false, h1, h2, h2); double d4 = (t0 - t4).HAbsMax(); HDebug.Assert(0 == d4);
                        Matrix t5 = GetMulImpl(ila, false, h2, h1, h1); double d5 = (t0 - t5).HAbsMax(); HDebug.Assert(0 == d5);
                        Matrix t6 = GetMulImpl(ila, false, h2, h1, h2); double d6 = (t0 - t6).HAbsMax(); HDebug.Assert(0 == d6);
                        Matrix t7 = GetMulImpl(ila, false, h2, h2, h1); double d7 = (t0 - t7).HAbsMax(); HDebug.Assert(0 == d7);
                        Matrix t8 = GetMulImpl(ila, false, h2, h2, h2); double d8 = (t0 - t8).HAbsMax(); HDebug.Assert(0 == d8);
                    }
                    {
                        Matrix t1 = GetMulImpl(null, false, h1, h1, h1); double d1 = (t0 - t1).HAbsMax(); HDebug.Assert(0 == d1);
                        Matrix t2 = GetMulImpl(null, false, h1, h1, h2); double d2 = (t0 - t2).HAbsMax(); HDebug.Assert(0 == d2);
                        Matrix t3 = GetMulImpl(null, false, h1, h2, h1); double d3 = (t0 - t3).HAbsMax(); HDebug.Assert(0 == d3);
                        Matrix t4 = GetMulImpl(null, false, h1, h2, h2); double d4 = (t0 - t4).HAbsMax(); HDebug.Assert(0 == d4);
                        Matrix t5 = GetMulImpl(null, false, h2, h1, h1); double d5 = (t0 - t5).HAbsMax(); HDebug.Assert(0 == d5);
                        Matrix t6 = GetMulImpl(null, false, h2, h1, h2); double d6 = (t0 - t6).HAbsMax(); HDebug.Assert(0 == d6);
                        Matrix t7 = GetMulImpl(null, false, h2, h2, h1); double d7 = (t0 - t7).HAbsMax(); HDebug.Assert(0 == d7);
                        Matrix t8 = GetMulImpl(null, false, h2, h2, h2); double d8 = (t0 - t8).HAbsMax(); HDebug.Assert(0 == d8);
                    }
                }
            }

            HessMatrix mul = null;

            foreach (HessMatrix mat in mats)
            {
                if (mul == null)
                {
                    mul = mat;
                }
                else
                {
                    mul = GetMulImpl(mul, mat, ila, warning);
                }
            }
            return(mul);
        }
コード例 #10
0
            private static List <Tuple <int, int> > GetIndexCommon(string[] lstName1, int[] lstResSeq1, string[] lstName2, int[] lstResSeq2)
            {
                if (HDebug.Selftest())
                #region selftest
                {
                    List <int> idx1, idx2;
                    {
                        HDebug.Assert(lstName1.Length == lstResSeq1.Length);
                        int size1 = lstName1.Length;
                        List <Tuple <string, int> > name_resseq_1 = new List <Tuple <string, int> >(size1);
                        for (int i = 0; i < size1; i++)
                        {
                            string name   = new string(lstName1[i].HToArray().HSort().ToArray());
                            int    resseq = lstResSeq1[i];
                            name_resseq_1.Add(new Tuple <string, int>(name, resseq));
                        }

                        HDebug.Assert(lstName2.Length == lstResSeq2.Length);
                        int size2 = lstName2.Length;
                        List <Tuple <string, int> > name_resseq_2 = new List <Tuple <string, int> >(size2);
                        for (int i = 0; i < size2; i++)
                        {
                            string name   = new string(lstName2[i].HToArray().HSort().ToArray());
                            int    resseq = lstResSeq2[i];
                            name_resseq_2.Add(new Tuple <string, int>(name, resseq));
                        }

                        idx1 = new List <int>();
                        idx2 = new List <int>();
                        for (int i = 0; i < name_resseq_1.Count; i++)
                        {
                            int j = name_resseq_2.IndexOf(name_resseq_1[i]);
                            if (j != -1)
                            {
                                idx1.Add(i);
                                idx2.Add(j);
                            }
                        }
                    }
                    List <Tuple <int, int> > idx12 = GetIndexCommon(lstName1, lstResSeq1, lstName2, lstResSeq2);
                    HDebug.Assert(idx12.Count == idx1.Count);
                }
                #endregion

                lstName1 = lstName1.HTrim().ToArray();
                lstName2 = lstName2.HTrim().ToArray();
                List <Tuple <string, int> > lstNameResseq1 = lstName1.HToIListTuple(lstResSeq1).ToList();
                List <Tuple <string, int> > lstNameResseq2 = lstName2.HToIListTuple(lstResSeq2).ToList();

                List <Tuple <int, int> > lstIdxCommon = lstNameResseq1.HListIndexCommon(lstNameResseq2);
                return(lstIdxCommon);
            }
コード例 #11
0
        static void UpdateMassWeightedHess(Matrix hess, Vector mass)
        {
            if (HDebug.Selftest())
            //if(GetMassWeightedHess_selftest1)
            #region selftest
            {
                //HDebug.ToDo("replace examplt not to use blocked hessian matrix");
                //GetMassWeightedHess_selftest1 = false;
                MatrixByArr[,] _bhess = new MatrixByArr[2, 2];
                _bhess[0, 0]          = new double[3, 3] {
                    { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }
                };
                _bhess[0, 1] = _bhess[0, 0] + 10;
                _bhess[1, 0] = _bhess[0, 0] + 20;
                _bhess[1, 1] = _bhess[0, 0] + 30;
                Vector _mass = new double[2] {
                    2, 3
                };
                MatrixByArr _hess = MatrixByArr.FromMatrixArray(_bhess);

                Matrix _mwhess = GetMassWeightedHess(_hess, _mass);
                MatrixByArr[,] _mwbhess = GetMassWeightedHess(_bhess, _mass);

                HDebug.AssertTolerance(0.00000001, MatrixByArr.FromMatrixArray(_mwbhess) - _mwhess.ToArray());
            }
            #endregion

            HDebug.Exception(hess.ColSize == mass.Size);
            HDebug.Assert(hess.ColSize == hess.RowSize);
            HDebug.Assert(hess.ColSize % 3 == 0);

            Vector mass05 = mass.ToArray().HSqrt();

            // mass weighted hessian
            // MH = M^(-1/2) * H * M^(-1/2)
            // MH_ij = H_IJ * sqrt(M[i] * M[j])
            {
                // mass weighted block hessian
                for (int i = 0; i < hess.ColSize; i++)
                {
                    for (int j = 0; j < hess.RowSize; j++)
                    {
                        //if(i == j) continue;
                        hess[i, j] = hess[i, j] / (mass05[i] * mass05[j]);
                        //mbhess[i, i] -= mbhess[i, j];
                    }
                }
            }
        }
コード例 #12
0
        public static Matrix GetCorrMatrix(this IList <Mode> modes)
        {
            if (HDebug.Selftest())
            {
                HDebug.Assert(GetCorrMatrix_SelfTest(modes, GetCorrMatrix));
            }

            Vector[][] eigvecs = new Vector[modes.Count][];
            double[]   eigvals = new double[modes.Count];
            for (int i = 0; i < modes.Count; i++)
            {
                eigvals[i] = modes[i].eigval;
                eigvecs[i] = modes[i].GetEigvecsOfAtoms();
            }

            int    size = modes[0].size;
            Matrix Dij  = Matrix.Zeros(size, size);
            Vector Dii  = new double[size];

            for (int i = 0; i < eigvals.Length; i++)
            {
                Vector[] eigvec = eigvecs[i];
                double   eigval = eigvals[i];
                for (int c = 0; c < size; c++)
                {
                    for (int r = 0; r < size; r++)
                    {
                        Dij[c, r] += (LinAlg.VtV(eigvec[c], eigvec[r]) / eigval);
                    }
                    Dii[c] += (LinAlg.VtV(eigvec[c], eigvec[c]) / eigval);
                }
            }
            Dij = Dij / modes.Count;
            Dii = Dii / modes.Count;

            // Cij
            for (int c = 0; c < size; c++)
            {
                for (int r = 0; r < size; r++)
                {
                    Dij[c, r] /= Math.Sqrt(Dii[c] * Dii[r]);
                }
            }

            return(Dij);
        }
コード例 #13
0
        public static Matrix GetCorrMatrixMatlab(this IList <Mode> modes)
        {
            if (HDebug.Selftest())
            {
                HDebug.Assert(GetCorrMatrix_SelfTest(modes, GetCorrMatrixMatlab));
            }

            //  Dii = zeros(n, 1);
            //  For[i=1, i<=nmodes, i++,
            //      Dii = Dii + Table[Dot[vec,vec],{vec,modei}]/eigvi;
            //      ];
            //  Dij = zeros(n, n);
            //  For[i=1, i<=nmodes, i++,
            //      Dijx = Dijx + modei_x.Transpose[modei_x] / eigvi;
            //      Dijy = Dijy + modei_y.Transpose[modei_y] / eigvi;
            //      Dijz = Dijz + modei_z.Transpose[modei_z] / eigvi;
            //      Dii = Dii + Table[Dot[vec,vec],{vec,modei}]/eigvi;
            //      ];
            //  Dij = Dij / nmodes;
            //  Dii = Dii / nmodes;
            //  Cij = Dij / Sqrt[Transpose[{Dii}].{Dii}];
            //  corr = Cij;

            Matrix MD = modes.ListEigvec().ToMatrix();
            Vector EV = modes.ListEigval().ToArray();
            Matrix corrmat;

            using (new Matlab.NamedLock(""))
            {
                Matlab.Clear();
                Matlab.PutMatrix("MD", MD, true);
                Matlab.PutVector("EV", EV);
                Matlab.Execute("nmodes = length(EV);");
                Matlab.Execute("iEV   = diag(1 ./ EV);");
                Matlab.Execute("Dijx = MD(1:3:end,:); Dijx = Dijx*iEV*Dijx'; Dij=    Dijx; clear Dijx;");
                Matlab.Execute("Dijy = MD(2:3:end,:); Dijy = Dijy*iEV*Dijy'; Dij=Dij+Dijy; clear Dijy;");
                Matlab.Execute("Dijz = MD(3:3:end,:); Dijz = Dijz*iEV*Dijz'; Dij=Dij+Dijz; clear Dijz;");
                Matlab.Execute("clear MD; clear EV; clear iEV;");
                Matlab.Execute("Dij = Dij / nmodes;");
                Matlab.Execute("Dii = diag(Dij);");
                Matlab.Execute("Dij = Dij ./ sqrt(Dii*Dii');");
                corrmat = Matlab.GetMatrix("Dij", true);
            }
            return(corrmat);
        }
コード例 #14
0
            public static double[] GetBFactor(Mode[] modes, double[] mass = null)
            {
                if (HDebug.Selftest())
                #region selftest
                {
                    using (new Matlab.NamedLock("SELFTEST"))
                    {
                        Matlab.Clear("SELFTEST");
                        Matlab.Execute("SELFTEST.hess = rand(30);");
                        Matlab.Execute("SELFTEST.hess = SELFTEST.hess + SELFTEST.hess';");
                        Matlab.Execute("SELFTEST.invhess = inv(SELFTEST.hess);");
                        Matlab.Execute("SELFTEST.bfactor3 = diag(SELFTEST.invhess);");
                        Matlab.Execute("SELFTEST.bfactor = SELFTEST.bfactor3(1:3:end) + SELFTEST.bfactor3(2:3:end) + SELFTEST.bfactor3(3:3:end);");
                        MatrixByArr selftest_hess    = Matlab.GetMatrix("SELFTEST.hess");
                        Mode[]      selftest_mode    = Hess.GetModesFromHess(selftest_hess);
                        Vector      selftest_bfactor = BFactor.GetBFactor(selftest_mode);
                        Vector      selftest_check   = Matlab.GetVector("SELFTEST.bfactor");
                        Vector      selftest_diff    = selftest_bfactor - selftest_check;
                        HDebug.AssertTolerance(0.00000001, selftest_diff);
                        Matlab.Clear("SELFTEST");
                    }
                }
                #endregion

                int size = modes[0].size;
                if (mass != null)
                {
                    HDebug.Assert(size == mass.Length);
                }
                double[] bfactor = new double[size];
                for (int i = 0; i < size; i++)
                {
                    foreach (Mode mode in modes)
                    {
                        bfactor[i] += mode.eigvec[i * 3 + 0] * mode.eigvec[i * 3 + 0] / mode.eigval;
                        bfactor[i] += mode.eigvec[i * 3 + 1] * mode.eigvec[i * 3 + 1] / mode.eigval;
                        bfactor[i] += mode.eigvec[i * 3 + 2] * mode.eigvec[i * 3 + 2] / mode.eigval;
                    }
                    if (mass != null)
                    {
                        bfactor[i] /= mass[i];
                    }
                }
                return(bfactor);
            }
コード例 #15
0
        //public static IEnumerable<Tuple<int, int, double>> EnumHessAnmSpr_obsolete(IList<Vector> coords, double cutoff, double sprcst)
        //{
        //    int size = coords.Count;
        //    double cutoff2 = cutoff*cutoff;
        //    //Matrix Kij = Matrix.Zeros(size, size);
        //    int num_springs = 0;
        //    for(int c=0; c<size; c++)
        //    {
        //        if(coords[c] == null) continue;
        //        for(int r=c+1; r<size; r++)
        //        {
        //            if(coords[r] == null) continue;
        //            double dist2 = (coords[c] - coords[r]).Dist2;
        //            if(dist2 <= cutoff2)
        //            {
        //                yield return new Tuple<int, int, double>(c, r, sprcst);  //Kij[c, r] = sprcst;
        //                yield return new Tuple<int, int, double>(r, c, sprcst);  //Kij[r, c] = sprcst;
        //                num_springs += 2;
        //            }
        //        }
        //    }
        //    double ratio_springs = ((double)num_springs) / (size*size);
        //    //return Kij;
        //}
        public static MatrixSparse <double> GetHessAnmBmat(IList <Vector> coords, double cutoff)
        {
            if (HDebug.Selftest())
            {
                var    _coords = Pdb._smallest_protein_cacoords;
                Matrix _Bmat   = Hess.GetHessAnmBmat(_coords, 13).ToArray();
                Matrix _BB     = _Bmat * _Bmat.Tr();
                Matrix _ANM    = Hess.GetHessAnm(_coords, 13);
                double _err    = (_BB - _ANM).HAbsMax();
                HDebug.Assert(_err < 0.00000001);
            }

            List <Tuple <int, int, double> > sprs = EnumHessAnmSpr(coords, cutoff, 1).ToList();
            MatrixSparse <double>            Bmat = new MatrixSparse <double>(3 * coords.Count, sprs.Count);
            int spr_count = 0;

            for (int ij = 0; ij < sprs.Count; ij++)
            {
                var spr = sprs[ij];
                int ai  = spr.Item1;
                int aj  = spr.Item2;
                if (ai >= aj)
                {
                    continue;
                }
                double kij    = spr.Item3;
                Vector coordi = coords[ai];
                Vector coordj = coords[aj];
                double sij    = (coordi - coordj).Dist;
                double xij    = (coordj[0] - coordi[0]) / sij;
                double yij    = (coordj[1] - coordi[1]) / sij;
                double zij    = (coordj[2] - coordi[2]) / sij;
                Bmat[(ai * 3 + 0), spr_count] = xij;
                Bmat[(ai * 3 + 1), spr_count] = yij;
                Bmat[(ai * 3 + 2), spr_count] = zij;
                Bmat[(aj * 3 + 0), spr_count] = -xij;
                Bmat[(aj * 3 + 1), spr_count] = -yij;
                Bmat[(aj * 3 + 2), spr_count] = -zij;
                spr_count++;
            }
            return(Bmat.GetSubMatrix(3 * coords.Count, spr_count));
        }
コード例 #16
0
ファイル: MinWRMSD.cs プロジェクト: htna/explsolv
            public static Trans3 GetTrans(IList <Vector> C1
                                          , IList <Vector> C2
                                          , IList <double> weight
                                          //, Pack<List<Vector>> C2new = null
                                          )
            {
                if (HDebug.Selftest())
                {
                    double[] tweight = new double[weight.Count];
                    for (int i = 0; i < tweight.Length; i++)
                    {
                        tweight[i] = 0.2;
                    }
                    Trans3 ttrans0 = GetTrans(C1, C2, tweight);
                    Trans3 ttrans1 = MinRMSD.GetTrans(C1, C2);
                    HDebug.AssertTolerance(0.0001, ttrans0.ds - ttrans1.ds);
                    HDebug.AssertTolerance(0.0001, ttrans0.dt - ttrans1.dt);
                    HDebug.AssertTolerance(0.0001, new Vector(ttrans0.dr.ToArray()) - ttrans1.dr.ToArray());
                    HDebug.AssertTolerance(0.0001, (ttrans0.TransformMatrix - ttrans1.TransformMatrix));
                }
                HDebug.Assert(C1.Count == C2.Count);
                HDebug.Assert(C1.Count == weight.Count);
                //Trans3 trans = ICP3.OptimalTransform(C2, C1);
                Trans3 trans = ICP3.OptimalTransformWeighted(C2, C1, weight);

                if (HDebug.IsDebuggerAttached)
                {
                    Vector[] C2updated = trans.GetTransformed(C2).ToArray();
                    double   RMSD0     = 0;
                    double   RMSD1     = 0;
                    for (int i = 0; i < C1.Count; i++)
                    {
                        RMSD0 += (C1[i] - C2[i]).Dist2;
                        RMSD1 += (C1[i] - C2updated[i]).Dist2;
                    }
                    //Debug.AssertTolerance(0.00000001, Math.Abs(RMSD1 - RMSD0));
                }
                return(trans);
            }
コード例 #17
0
ファイル: Tinker.Vibrate.cs プロジェクト: htna/explsolv
            public static Vibrate FromLines(IList <string> lines)
            {
                if (HDebug.Selftest())
                #region MyRegion
                {
                    Vibrate tvib  = FromLines(selftest);
                    Vector  tmass = new double[tvib.idx2freq_mode.First().Value.Item2.Length];
                    tmass.SetValue(1);
                    tvib.ToModes(tmass.ToArray());
                }
                #endregion
                if (lines == null)
                {
                    return(null);
                }

                try
                {
                    List <string> llines = new List <string>(lines);
                    for (int i = 0; i < llines.Count; i++)
                    {
                        string line = llines[i];
                        int    idx  = line.IndexOf('#');
                        if (idx >= 0)
                        {
                            line = line.Substring(0, idx);
                        }
                        line      = line.TrimEnd(' ');
                        llines[i] = line;
                    }
                    llines = llines.HRemoveAll("").ToList();
                    List <List <string> > groups = FromLines_CollectGroup(llines);

                    Dictionary <int, double> idx2eigval = null;
                    Dictionary <int, double> idx2freq   = null;
                    Dictionary <int, Tuple <double, Tuple <int, Vector>[]> > idx2freq_mode = new Dictionary <int, Tuple <double, Tuple <int, Vector>[]> >();
                    foreach (List <string> group in groups)
                    {
                        string header = group[0];

                        if (header.Contains("Eigenvalues"))
                        {
                            idx2eigval = FromLines_GetKeyValue(group);
                            continue;
                        }
                        if (header.Contains("Frequencies"))
                        {
                            idx2freq = FromLines_GetKeyValue(group);
                            foreach (int idx in idx2freq.Keys)
                            {
                                idx2freq_mode.Add(idx, null);
                            }
                            continue;
                        }
                        if (header.Contains("Mode"))
                        {
                            Tuple <int, Tuple <double, Tuple <int, Vector>[]> > idx_freq_mode = FromLines_GetMode(group);
                            int    idx  = idx_freq_mode.Item1;
                            double freq = idx_freq_mode.Item2.Item1;
                            Tuple <int, Vector>[] modevecs = idx_freq_mode.Item2.Item2;
                            if (modevecs.Length * 3 != idx2freq.Count)
                            {
                                throw new Exception("mode vector size is not matching");
                            }
                            HDebug.Assert(idx2freq != null);
                            HDebug.Assert(idx2freq[idx] == freq);
                            if (idx2freq_mode.ContainsKey(idx) == false)
                            {
                                throw new Exception("idx2freq_mode.ContainsKey(idx) == false");
                            }
                            if (idx2freq_mode[idx] != null)
                            {
                                throw new Exception("double assign idx2freq_mode[idx]");
                            }
                            HDebug.Assert(idx2freq_mode[idx] == null);
                            idx2freq_mode[idx] = idx_freq_mode.Item2;
                            continue;
                        }
                    }

                    foreach (int idx in idx2freq_mode.Keys)
                    {
                        if (idx2freq_mode[idx] == null)
                        {
                            throw new Exception("(idx2freq_mode[idx] == null) ==> exist not-assigned mode vector");
                        }
                    }

                    Vibrate vibrate = new Vibrate();
                    vibrate.idx2eigval    = idx2eigval;
                    vibrate.idx2freq      = idx2freq;
                    vibrate.idx2freq_mode = idx2freq_mode;

                    return(vibrate);
                }
                catch (Exception)
                {
                    HDebug.Assert(false);
                    return(null);
                }
            }
コード例 #18
0
        public static IEnumerable <Tuple <int, int, double> > EnumHessAnmSpr(IList <Vector> coords, double cutoff, double sprcst)
        {
            if (HDebug.Selftest())
            {
                Vector[] _coords = Pdb.FromLines(SelftestData.lines_1L2Y_pdb).atoms.SelectByName("CA").ListCoord().ToArray().HSelectCount(10);
                HashSet <Tuple <int, int, double> > sprs0 = //EnumHessAnmSpr_obsolete(_coords, 7, 1).HToHashSet();
                                                            new HashSet <Tuple <int, int, double> >
                {
                    new Tuple <int, int, double>(0, 1, 1), new Tuple <int, int, double>(1, 0, 1), new Tuple <int, int, double>(0, 2, 1), new Tuple <int, int, double>(2, 0, 1), new Tuple <int, int, double>(0, 3, 1),
                    new Tuple <int, int, double>(3, 0, 1), new Tuple <int, int, double>(0, 4, 1), new Tuple <int, int, double>(4, 0, 1), new Tuple <int, int, double>(1, 2, 1), new Tuple <int, int, double>(2, 1, 1),
                    new Tuple <int, int, double>(1, 3, 1), new Tuple <int, int, double>(3, 1, 1), new Tuple <int, int, double>(1, 4, 1), new Tuple <int, int, double>(4, 1, 1), new Tuple <int, int, double>(1, 5, 1),
                    new Tuple <int, int, double>(5, 1, 1), new Tuple <int, int, double>(2, 3, 1), new Tuple <int, int, double>(3, 2, 1), new Tuple <int, int, double>(2, 4, 1), new Tuple <int, int, double>(4, 2, 1),
                    new Tuple <int, int, double>(2, 5, 1), new Tuple <int, int, double>(5, 2, 1), new Tuple <int, int, double>(2, 6, 1), new Tuple <int, int, double>(6, 2, 1), new Tuple <int, int, double>(3, 4, 1),
                    new Tuple <int, int, double>(4, 3, 1), new Tuple <int, int, double>(3, 5, 1), new Tuple <int, int, double>(5, 3, 1), new Tuple <int, int, double>(3, 6, 1), new Tuple <int, int, double>(6, 3, 1),
                    new Tuple <int, int, double>(3, 7, 1), new Tuple <int, int, double>(7, 3, 1), new Tuple <int, int, double>(4, 5, 1), new Tuple <int, int, double>(5, 4, 1), new Tuple <int, int, double>(4, 6, 1),
                    new Tuple <int, int, double>(6, 4, 1), new Tuple <int, int, double>(4, 7, 1), new Tuple <int, int, double>(7, 4, 1), new Tuple <int, int, double>(4, 8, 1), new Tuple <int, int, double>(8, 4, 1),
                    new Tuple <int, int, double>(5, 6, 1), new Tuple <int, int, double>(6, 5, 1), new Tuple <int, int, double>(5, 7, 1), new Tuple <int, int, double>(7, 5, 1), new Tuple <int, int, double>(5, 8, 1),
                    new Tuple <int, int, double>(8, 5, 1), new Tuple <int, int, double>(6, 7, 1), new Tuple <int, int, double>(7, 6, 1), new Tuple <int, int, double>(6, 8, 1), new Tuple <int, int, double>(8, 6, 1),
                    new Tuple <int, int, double>(6, 9, 1), new Tuple <int, int, double>(9, 6, 1), new Tuple <int, int, double>(7, 8, 1), new Tuple <int, int, double>(8, 7, 1), new Tuple <int, int, double>(7, 9, 1),
                    new Tuple <int, int, double>(9, 7, 1), new Tuple <int, int, double>(8, 9, 1), new Tuple <int, int, double>(9, 8, 1),
                };
                HashSet <Tuple <int, int, double> > sprs1 = EnumHessAnmSpr(_coords, 7, 1).HToHashSet();
                HDebug.Exception(sprs0.Count == sprs1.Count);
                foreach (var spr in sprs0)
                {
                    HDebug.Exception(sprs1.Contains(spr));
                }
            }

            KDTreeDLL.KDTree <object> kdtree = new KDTreeDLL.KDTree <object>(3);
            for (int i = 0; i < coords.Count; i++)
            {
                kdtree.insert(coords[i], i);
            }

            int    size        = coords.Count;
            double cutoff2     = cutoff * cutoff;
            int    num_springs = 0;

            for (int c = 0; c < coords.Count; c++)
            {
                Vector lowk = coords[c] - (new double[] { cutoff, cutoff, cutoff });
                Vector uppk = coords[c] + (new double[] { cutoff, cutoff, cutoff });
                foreach (int r in kdtree.range(lowk, uppk))
                {
                    if (c >= r)
                    {
                        continue;
                    }
                    double dist2 = (coords[c] - coords[r]).Dist2;
                    if (dist2 < cutoff2)
                    {
                        yield return(new Tuple <int, int, double>(c, r, sprcst));

                        yield return(new Tuple <int, int, double>(r, c, sprcst));

                        num_springs += 2;
                    }
                }
            }
            double ratio_springs = ((double)num_springs) / (size * size);
        }
コード例 #19
0
        public static bool GetHessAnmSelfTest()
        {
            if (HDebug.Selftest() == false)
            {
                return(true);
            }

            string pdbpath = @"C:\Users\htna\svn\htnasvn_htna\VisualStudioSolutions\Library2\HTLib2.Bioinfo\Bioinfo.Data\pdb\1MJC.pdb";

            if (HFile.Exists(pdbpath) == false)
            {
                return(false);
            }

            Pdb pdb = Pdb.FromFile(pdbpath);

            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", Matrix.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 [anm,xij,normxij] = baseHess(x,cx)
                                % Basic Hessian Matrix
                                % Author: Guang Song
                                % Created: Feb 23, 2005
                                % Rev: 11/09/06
                                %
                                % cx is the contact map. Also with gama info (new! 02/23/05)
                                dim = size(x,1);
                                nx = x(:,:,ones(1,dim));
                                xij = permute(nx,[3,1,2]) - permute(nx,[1,3,2]); % xj - xi for any i j
                                normxij = squareform(pdist(x)) + diag(ones(1,dim)); % + diag part added to avoid divided by zero.
                                anm = zeros(3*dim,3*dim);
                                for i=1:3
                                  for j=1:3
                                     tmp = xij(:,:,i).*xij(:,:,j).*cx./normxij.^2;
                                     tmp = diag(sum(tmp)) - tmp;
                                     anm(i:3:3*dim,j:3:3*dim) = tmp;
                                  end
                                end

                                % if dR is scalar, then dR = 1, back to GNM.
                                %if abs(i-j) == 1 % virtual bonds. should stay around 3.81 A
                                %   K33 = K33*100;
                                %end 
                                anm = (anm+anm')/2; % make sure return matrix is symmetric (fix numeric error)
                            ");
            Matrix anm_gsong = Matlab.GetMatrix("anm");

            Matlab.Execute("clear;");

            Matrix anm = GetHessAnm(coords.ToArray(), cutoff);

            if (anm_gsong.RowSize != anm.RowSize)
            {
                HDebug.Assert(false); return(false);
            }
            if (anm_gsong.ColSize != anm.ColSize)
            {
                HDebug.Assert(false); return(false);
            }

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

            return(true);
        }
コード例 #20
0
ファイル: HBioinfo.CSO.cs プロジェクト: htna/explsolv
        public static double[] CSO(Vector mode1, Vector mass, IList <Vector> mode2s, double?tolDebugAssertOrthogonal = 0.00000001)
        {
            if (HDebug.Selftest())
            {
            }

            Vector mass3sqrt = null;

            if ((mass != null) && (mass._data != null))
            {
                mass3sqrt = new double[mass.Size * 3];
                for (int i = 0; i < mass.Size; i++)
                {
                    double massisqrt = Math.Sqrt(mass[i]);
                    mass3sqrt[i * 3 + 0] = massisqrt;
                    mass3sqrt[i * 3 + 1] = massisqrt;
                    mass3sqrt[i * 3 + 2] = massisqrt;
                }
            }

            Vector nmode1 = mode1;

            if (mass3sqrt != null)
            {
                nmode1 = Vector.PtwiseMul(mass3sqrt, nmode1);
            }
            nmode1 = mode1.UnitVector();


            Vector[] nmode2s = new Vector[mode2s.Count];
            {
                // orthogonalize modes2
                nmode2s = new Vector[mode2s.Count];
                for (int i = 0; i < mode2s.Count; i++)
                {
                    Vector nmode2i = mode2s[i];
                    if (mass3sqrt != null)
                    {
                        nmode2i = Vector.PtwiseMul(mass3sqrt, nmode2i);
                    }
                    nmode2i    = nmode2i.UnitVector();
                    nmode2s[i] = nmode2i;
                }
            }
            if (tolDebugAssertOrthogonal != null)
            {
                for (int i = 0; i < nmode2s.Length; i++)
                {
                    for (int j = 0; j < i; j++)
                    {
                        double dot = LinAlg.VtV(nmode2s[i], nmode2s[j]);
                        HDebug.AssertTolerance(tolDebugAssertOrthogonal.Value, dot);
                    }
                }
            }

            double[] SO = new double[nmode2s.Length];
            for (int i = 0; i < SO.Length; i++)
            {
                double vtv = LinAlg.VtV(nmode1, nmode2s[i]);
                SO[i] += vtv * vtv;
            }
            //SO = SO.HSort().HReverse();

            double[] CSO = new double[nmode2s.Length];
            for (int i = 0; i < CSO.Length; i++)
            {
                CSO[i]  = (i == 0) ? 0 : CSO[i - 1];
                CSO[i] += SO[i];
            }

            return(CSO);
        }
コード例 #21
0
ファイル: Hess.GetHessGnm.cs プロジェクト: htna/explsolv
        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);
        }
コード例 #22
0
ファイル: Hess.HessMatrix.Oper.cs プロジェクト: htna/explsolv
        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);
        }
コード例 #23
0
ファイル: Hess.GetHessRTB.cs プロジェクト: htna/explsolv
            public static Vector[] GetRotTran(Vector[] coords, double[] masses)
            {
                #region source rtbProjection.m
                /// rtbProjection.m
                //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                /// function [P, xyz] = rtbProjection(xyz, mass)
                /// % the approach is to find the inertia. compute the principal axes. and then use them to determine directly translation or rotation.
                ///
                /// n = size(xyz, 1); % n: the number of atoms
                /// if nargin == 1
                ///     mass = ones(n,1);
                /// end
                ///
                /// M = sum(mass);
                /// % find the mass center.
                /// m3 = repmat(mass, 1, 3);
                /// center = sum (xyz.*m3)/M;
                /// xyz = xyz - center(ones(n, 1), :);
                ///
                /// mwX = sqrt (m3).*xyz;
                /// inertia = sum(sum(mwX.^2))*eye(3) - mwX'*mwX;
                /// [V,D] = eig(inertia);
                /// tV = V'; % tV: transpose of V. Columns of V are principal axes.
                /// for i=1:3
                ///     trans{i} = tV(ones(n,1)*i, :); % the 3 translations are along principal axes
                /// end
                /// P = zeros(n*3, 6);
                /// for i=1:3
                ///     rotate{i} = cross(trans{i}, xyz);
                ///     temp = mat2vec(trans{i});
                ///     P(:,i) = temp/norm(temp);
                ///     temp = mat2vec(rotate{i});
                ///     P(:,i+3) = temp/norm(temp);
                /// end
                /// m3 = mat2vec(sqrt(m3));
                /// P = repmat (m3(:),1,size(P,2)).*P;
                /// % now normalize columns of P
                /// P = P*diag(1./normMat(P,1));
                ///
                /// function vec = mat2vec(mat)
                /// % convert a matrix to a vector, extracting data *row-wise*.
                /// vec = reshape(mat',1,prod(size(mat)));
                //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                #endregion

                if (HDebug.Selftest())
                #region selftest
                {
                    // get test coords and masses
                    Vector[] tcoords = Pdb.FromLines(SelftestData.lines_1EVC_pdb).atoms.ListCoord().ToArray();
                    double[] tmasses = new double[tcoords.Length];
                    for (int i = 0; i < tmasses.Length; i++)
                    {
                        tmasses[i] = 1;
                    }
                    // get test rot/trans RTB vectors
                    Vector[] trottra = GetRotTran(tcoords, tmasses);
                    HDebug.Assert(trottra.Length == 6);
                    // get test ANM
                    var tanm = Hess.GetHessAnm(tcoords);
                    // size of vec_i == 1
                    for (int i = 0; i < trottra.Length; i++)
                    {
                        double dist = trottra[i].Dist;
                        HDebug.Assert(Math.Abs(dist - 1) < 0.00000001);
                    }
                    // vec_i and vec_j must be orthogonal
                    for (int i = 0; i < trottra.Length; i++)
                    {
                        for (int j = i + 1; j < trottra.Length; j++)
                        {
                            double dot = LinAlg.VtV(trottra[i], trottra[j]);
                            HDebug.Assert(Math.Abs(dot) < 0.00000001);
                        }
                    }
                    // vec_i' * ANM * vec_i == 0
                    for (int i = 0; i < trottra.Length; i++)
                    {
                        double eigi = LinAlg.VtMV(trottra[i], tanm, trottra[i]);
                        HDebug.Assert(Math.Abs(eigi) < 0.00000001);
                        Vector tvecx = trottra[i].Clone();
                        tvecx[1] += (1.0 / tvecx.Size) * Math.Sign(tvecx[1]);
                        tvecx     = tvecx.UnitVector();
                        double eigix = LinAlg.VtMV(tvecx, tanm, tvecx);
                        HDebug.Assert(Math.Abs(eigix) > 0.00000001);
                    }
                }
                #endregion

                Vector[] rottran;
                using (new Matlab.NamedLock(""))
                {
                    Matlab.PutMatrix("xyz", coords.ToMatrix(), true);
                    Matlab.Execute("xyz = xyz';");
                    Matlab.PutVector("mass", masses);
                    //Matlab.Execute("function [P, xyz] = rtbProjection(xyz, mass)                                                                                        ");
                    //Matlab.Execute("% the approach is to find the inertia. compute the principal axes. and then use them to determine directly translation or rotation. ");
                    Matlab.Execute("                                                                                 ");
                    Matlab.Execute("n = size(xyz, 1); % n: the number of atoms                                       ");
                    //Matlab.Execute("if nargin == 1;                                                                  ");
                    //Matlab.Execute("    mass = ones(n,1);                                                            ");
                    //Matlab.Execute("end                                                                              ");
                    Matlab.Execute("                                                                                 ");
                    Matlab.Execute("M = sum(mass);                                                                   ");
                    Matlab.Execute("% find the mass center.                                                          ");
                    Matlab.Execute("m3 = repmat(mass, 1, 3);                                                         ");
                    Matlab.Execute("center = sum (xyz.*m3)/M;                                                        ");
                    Matlab.Execute("xyz = xyz - center(ones(n, 1), :);                                               ");
                    Matlab.Execute("                                                                                 ");
                    Matlab.Execute("mwX = sqrt (m3).*xyz;                                                            ");
                    Matlab.Execute("inertia = sum(sum(mwX.^2))*eye(3) - mwX'*mwX;                                    ");
                    Matlab.Execute("[V,D] = eig(inertia);                                                            ");
                    Matlab.Execute("tV = V'; % tV: transpose of V. Columns of V are principal axes.                  ");
                    Matlab.Execute("for i=1:3                                                                        \n"
                                   + "    trans{i} = tV(ones(n,1)*i, :); % the 3 translations are along principal axes \n"
                                   + "end                                                                              \n");
                    Matlab.Execute("P = zeros(n*3, 6);                                                               ");
                    Matlab.Execute("mat2vec = @(mat) reshape(mat',1,prod(size(mat)));                                ");
                    Matlab.Execute("for i=1:3                                                                        \n"
                                   + "    rotate{i} = cross(trans{i}, xyz);                                            \n"
                                   + "    temp = mat2vec(trans{i});                                                    \n"
                                   + "    P(:,i) = temp/norm(temp);                                                    \n"
                                   + "    temp = mat2vec(rotate{i});                                                   \n"
                                   + "    P(:,i+3) = temp/norm(temp);                                                  \n"
                                   + "end                                                                              ");
                    Matlab.Execute("m3 = mat2vec(sqrt(m3));                                                          ");
                    Matlab.Execute("P = repmat (m3(:),1,size(P,2)).*P;                                               ");
                    //Matlab.Execute("% now normalize columns of P                                                     "); // already normalized
                    //Matlab.Execute("normMat = @(x) sqrt(sum(x.^2,2));                                                "); // already normalized
                    //Matlab.Execute("P = P*diag(1./normMat(P,1));                                                     "); // already normalized
                    //Matlab.Execute("                                                                                 "); // already normalized
                    //////////////////////////////////////////////////////////////////////////////////////////////////////
                    //Matlab.Execute("function vec = mat2vec(mat)                                                      ");
                    //Matlab.Execute("% convert a matrix to a vector, extracting data *row-wise*.                      ");
                    //Matlab.Execute("vec = reshape(mat',1,prod(size(mat)));                                           ");
                    //////////////////////////////////////////////////////////////////////////////////////////////////////
                    //Matlab.Execute("function amp = normMat(x)                                                        ");
                    //Matlab.Execute("amp = sqrt(sum(x.^2,2));                                                         ");

                    Matrix xyz = Matlab.GetMatrix("xyz", true);
                    Matrix P   = Matlab.GetMatrix("P", true);
                    rottran = P.GetColVectorList();
                }
                return(rottran);
            }
コード例 #24
0
                public static void SelfTest()
                {
                    if (HDebug.Selftest() == false)
                    {
                        return;
                    }

                    string temppath            = @"K:\temp\";
                    string tinkerpath_testgrad = "\"" + @"C:\Program Files\Tinker\bin-win64-8.2.1\testgrad.exe" + "\"";
                    string tinkerpath_testhess = "\"" + @"C:\Program Files\Tinker\bin-win64-8.2.1\testhess.exe" + "\"";

                    var xyz  = Tinker.Xyz.FromLines(SelftestData.lines_1L2Y_xyz);
                    var prm  = Tinker.Prm.FromLines(SelftestData.lines_charmm22_prm);
                    var univ = Universe.Build(xyz, prm);

                    var testhess = Tinker.Run.Testhess(tinkerpath_testhess, xyz, prm, temppath
                                                       , HessMatrixZeros: HessMatrixLayeredArray.ZerosHessMatrixLayeredArray
                                                       );
                    var testgrad = Tinker.Run.Testgrad(tinkerpath_testgrad, xyz, prm, temppath);
                    var hessinfo = Hess.HessInfo.FromTinker(xyz, prm, testhess.hess);

                    var hessforcinfo = HessForc.Coarse.HessForcInfo.From(hessinfo);

                    hessforcinfo.forc = testgrad.anlyts.GetForces(xyz.atoms);
                    var coarseinfo_debug = HessForc.Coarse.GetCoarseHessForc
                                               (hessforcinfo
                                               , coords: hessinfo.coords
                                               , GetIdxKeepListRemv: GetIdxKeepListRemv
                                               , ila: null
                                               , thres_zeroblk: double.Epsilon
                                               , options: new string[] { "Debug" }
                                               );

                    var coarseinfo_simple = HessForc.Coarse.GetCoarseHessForc
                                                (hessforcinfo
                                                , coords: hessinfo.coords
                                                , GetIdxKeepListRemv: GetIdxKeepListRemv
                                                , ila: null
                                                , thres_zeroblk: double.Epsilon
                                                , options: new string[] { "SubSimple" }
                                                );
                    double absmax_simple = (coarseinfo_debug.hess - coarseinfo_simple.hess).HAbsMax();

                    HDebug.Assert(Math.Abs(absmax_simple) < 0.00000001);
                    double absmax_simple_forc = (coarseinfo_debug.forc.ToVector() - coarseinfo_simple.forc.ToVector()).ToArray().MaxAbs();

                    HDebug.Assert(Math.Abs(absmax_simple_forc) < 0.00000001);

                    var coarseinfo_1iter = HessForc.Coarse.GetCoarseHessForc
                                               (hessforcinfo
                                               , coords: hessinfo.coords
                                               , GetIdxKeepListRemv: GetIdxKeepListRemv
                                               , ila: null
                                               , thres_zeroblk: double.Epsilon
                                               , options: new string[] { "OneIter" }
                                               );
                    double absmax_1iter = (coarseinfo_debug.hess - coarseinfo_1iter.hess).HAbsMax();

                    HDebug.Assert(Math.Abs(absmax_1iter) < 0.00000001);
                    double absmax_1iter_forc = (coarseinfo_debug.forc.ToVector() - coarseinfo_1iter.forc.ToVector()).ToArray().MaxAbs();

                    HDebug.Assert(Math.Abs(absmax_1iter_forc) < 0.00000001);

                    var coarseinfo_iter = HessForc.Coarse.GetCoarseHessForc
                                              (hessforcinfo
                                              , coords: hessinfo.coords
                                              , GetIdxKeepListRemv: GetIdxKeepListRemv
                                              , ila: null
                                              , thres_zeroblk: double.Epsilon
                                              , options: null
                                              );
                    double absmax_iter = (coarseinfo_debug.hess - coarseinfo_iter.hess).HAbsMax();

                    HDebug.Assert(Math.Abs(absmax_iter) < 0.00000001);
                    double absmax_iter_forc = (coarseinfo_debug.forc.ToVector() - coarseinfo_iter.forc.ToVector()).ToArray().MaxAbs();

                    HDebug.Assert(Math.Abs(absmax_iter_forc) < 0.00000001);

                    double tolerance = 1.0E-6; // 0.00001;
                    var    coarseinfo_1iter_tolerant = HessForc.Coarse.GetCoarseHessForc
                                                           (hessforcinfo
                                                           , coords: hessinfo.coords
                                                           , GetIdxKeepListRemv: GetIdxKeepListRemv
                                                           , ila: null
                                                           , thres_zeroblk: tolerance
                                                           , options: new string[] { "OneIter" }
                                                           );
                    double absmax_1iter_tolerant = (coarseinfo_debug.hess - coarseinfo_1iter_tolerant.hess).HAbsMax();

                    HDebug.Assert(Math.Abs(absmax_1iter_tolerant) < tolerance * 10);
                    double absmax_1iter_tolerant_forc = (coarseinfo_debug.forc.ToVector() - coarseinfo_1iter_tolerant.forc.ToVector()).ToArray().MaxAbs();

                    HDebug.Assert(Math.Abs(absmax_1iter_tolerant_forc) < tolerance * 10);

                    var coarseinfo_iter_tolerant = HessForc.Coarse.GetCoarseHessForc
                                                       (hessforcinfo
                                                       , coords: hessinfo.coords
                                                       , GetIdxKeepListRemv: GetIdxKeepListRemv
                                                       , ila: null
                                                       , thres_zeroblk: tolerance
                                                       , options: null
                                                       );
                    double absmax_iter_tolerant = (coarseinfo_debug.hess - coarseinfo_iter_tolerant.hess).HAbsMax();

                    HDebug.Assert(Math.Abs(absmax_iter_tolerant) < tolerance * 10);
                    double absmax_iter_tolerant_forc = (coarseinfo_debug.forc.ToVector() - coarseinfo_iter_tolerant.forc.ToVector()).ToArray().MaxAbs();

                    HDebug.Assert(Math.Abs(absmax_iter_tolerant_forc) < tolerance * 10);

                    string tempfilepath = HFile.GetTempPath(temppath, "test_serialzation_CoarseHessForc.dat");

                    HSerialize.Serialize(tempfilepath, null, coarseinfo_iter_tolerant);
                    var    coarseinfo_iter_tolerant2 = HSerialize.Deserialize <HessForcInfo>(tempfilepath, null);
                    double absmax_iter_tolerant_file = (coarseinfo_iter_tolerant.hess - coarseinfo_iter_tolerant.hess).HAbsMax();

                    HDebug.Assert(Math.Abs(absmax_iter_tolerant_file) == 0);
                    double absmax_iter_tolerant_file_forc = (coarseinfo_iter_tolerant.forc.ToVector() - coarseinfo_iter_tolerant.forc.ToVector()).ToArray().MaxAbs();

                    HDebug.Assert(Math.Abs(absmax_iter_tolerant_file_forc) == 0);
                    HFile.Delete(tempfilepath);
                }
コード例 #25
0
ファイル: Mode.Static.Funcs.cs プロジェクト: htna/explsolv
        public static Tuple <List <Mode>, List <Mode> > SeparateTolerants(this List <Mode> modes
                                                                          , double thres_idxmax_ratio_avgsrt = 1000
                                                                          , double thres_idx_idnsrt_nonzero  = 0.0000000001
                                                                          )
        {
            if (HDebug.Selftest())
            {
                IList <Mode> tmodes;
                Tuple <List <Mode>, List <Mode> > tmdNonzeroZero;

                tmodes = new Mode[] { new Mode {
                                          eigval = 0
                                      }, new Mode {
                                          eigval = 0
                                      }, new Mode {
                                          eigval = 0
                                      }, new Mode {
                                          eigval = 0.00001
                                      } };
                tmdNonzeroZero = SeparateTolerants(tmodes.ToList());
                HDebug.Assert(tmdNonzeroZero.Item1.Count == 1, tmdNonzeroZero.Item2.Count == 3);

                tmodes = new Mode[] { new Mode {
                                          eigval = -0.2
                                      }, new Mode {
                                          eigval = 0.1
                                      }, new Mode {
                                          eigval = 0
                                      }, new Mode {
                                          eigval = -10
                                      } };
                tmdNonzeroZero = SeparateTolerants(tmodes.ToList());
                HDebug.Assert(tmdNonzeroZero.Item1.Count == 3, tmdNonzeroZero.Item2.Count == 1);

                tmodes = new Mode[] { new Mode {
                                          eigval = 0.000000000002
                                      }, new Mode {
                                          eigval = 0.1
                                      }, new Mode {
                                          eigval = -0.000000001
                                      }, new Mode {
                                          eigval = -10
                                      } };
                tmdNonzeroZero = SeparateTolerants(tmodes.ToList());
                HDebug.Assert(tmdNonzeroZero.Item1.Count == 2);
                HDebug.Assert(tmdNonzeroZero.Item2.Count == 2);
            }

            modes = new List <Mode>(modes);
            Func <double, double> sqrt = Math.Sqrt;

            double[] eigvals         = modes.ListEigval().ToArray();
            double[] abs_eigvals     = eigvals.HAbs();
            double[] srt_abs_eigvals = eigvals.HAbs().HSort().ToArray();
            int   [] idxsrt          = abs_eigvals.HIdxSorted();

            double[] sumsrt_1_n       = new double[abs_eigvals.Length]; sumsrt_1_n[0] = abs_eigvals[idxsrt[0]];
            double[] avgsrt_1_n       = new double[abs_eigvals.Length]; avgsrt_1_n[0] = abs_eigvals[idxsrt[0]];
            double[] ratio_avgsrt_1_n = new double[abs_eigvals.Length]; ratio_avgsrt_1_n[0] = 0;
            List <Tuple <int, double> > idxmax_ratio_avgsrt = new List <Tuple <int, double> >();

            for (int i = 1; i < abs_eigvals.Length; i++)
            {
                sumsrt_1_n[i]      += sumsrt_1_n[i - 1] + abs_eigvals[idxsrt[i]];
                avgsrt_1_n[i]       = sumsrt_1_n[i] / i;
                ratio_avgsrt_1_n[i] = avgsrt_1_n[i] / (avgsrt_1_n[i - 1] == 0 ? double.Epsilon : avgsrt_1_n[i - 1]);
                if (ratio_avgsrt_1_n[i] > thres_idxmax_ratio_avgsrt)
                {
                    idxmax_ratio_avgsrt.Add(new Tuple <int, double>(i, ratio_avgsrt_1_n[i]));
                }
                //if(ratio_avgsrt_1_n[i] > ratio_avgsrt_1_n[idxmax_ratio_avgsrt])
                //{
                //    if(double.IsInfinity(ratio_avgsrt_1_n[i]) == false)
                //        idxmax_ratio_avgsrt = i;
                //    else
                //    {
                //        bool bAllZero = true;
                //        for(int j=0; j<i; j++)
                //            if(ratio_avgsrt_1_n[j]!=0)
                //                bAllZero = false;
                //        if(bAllZero)
                //            idxmax_ratio_avgsrt = i;
                //    }
                //}
            }

            int?idx_idnsrt_nonzero = null;

            foreach (var idxmax in idxmax_ratio_avgsrt)
            {
                if (idx_idnsrt_nonzero != null)
                {
                    continue;
                }
                double abs_eigvals_i = abs_eigvals[idxmax.Item1];
                if (abs_eigvals_i > thres_idx_idnsrt_nonzero)
                {
                    idx_idnsrt_nonzero = idxmax.Item1;
                }
            }

            if (idx_idnsrt_nonzero == null)
            {
                HDebug.Assert(false);
                System.Console.Error.WriteLine("cannot find separation index regarding zero modes");
                return(null);
            }

            //int idx_idnsrt_nonzero = idxmax_ratio_avgsrt;
            //int idx_idnsrt_nonzero = 0;
            List <Mode> modesNonzero = new List <Mode>();
            List <Mode> modesZero    = new List <Mode>();

            for (int i = 0; i < modes.Count; i++)
            {
                if (i < idx_idnsrt_nonzero.Value)
                {
                    modesZero.Add(modes[idxsrt[i]]); modes[idxsrt[i]] = null;
                }
                if (i >= idx_idnsrt_nonzero.Value)
                {
                    modesNonzero.Add(modes[idxsrt[i]]); modes[idxsrt[i]] = null;
                }
            }
            modes = modes.HRemoveAllNull(false).ToList();
            HDebug.Assert(modes.Count == 0);

            return(new Tuple <List <Mode>, List <Mode> >(modesNonzero, modesZero));
        }
コード例 #26
0
ファイル: HBioinfo.RMSIP.cs プロジェクト: htna/explsolv
        public static ORMSIP RMSIP(IList <Vector> modes1, Vector mass1, Vector mass2, IList <Vector> modes2, bool bDebugAssertOrthogonal = true)
        {
            if (HDebug.Selftest())
            {
                List <Vector> tPs = new List <Vector>();
                tPs.Add(new double[6] {
                    1, 2, 3, 4, 5, 6
                });
                tPs.Add(new double[6] {
                    2, 3, 4, 5, 6, 7
                });
                List <Vector> tMs = new List <Vector>();
                tMs.Add(new double[6] {
                    3, 4, 5, 6, 7, 8
                });
                tMs.Add(new double[6] {
                    4, 5, 6, 7, 8, 9
                });
                Vector tPmasses = new double[2] {
                    3, 4
                };
                Vector tMmasses = new double[2] {
                    1, 2
                };
                double trmsip = RMSIP(tPs, tPmasses, tMmasses, tMs, false).rmsip;
                /// [1 2]t  [ 3           ]   [ 1           ]   [3 4]      [1 2]t  [ 3  4]
                /// [2 3]   [   3         ]   [   1         ]   [4 5]      [2 3]   [ 4  5]
                /// [3 4] * [     3       ] * [     1       ] * [5 6]  ==  [3 4] * [ 5  6]  ==  [  934 1072 ]
                /// [4 5]   [       4     ]   [       2     ]   [6 7]      [4 5]   [12 14]      [ 1138 1309 ]
                /// [5 6]   [         4   ]   [         2   ]   [7 8]      [5 6]   [14 16]
                /// [6 7]   [           4 ]   [           2 ]   [8 9]      [6 7]   [16 18]
                ///
                ///   => 240^2 + 276^2 + 294^2 + 339^2 = 335133
                ///   => sqrt(335133 / 2) = 409.3489
                double trmsip0 = Math.Sqrt(5030065.0 / 2);
                HDebug.AssertTolerance(0.00000001, trmsip - trmsip0);
            }

            Vector[] nmodes1;
            if (mass1 == null)
            {
                nmodes1 = modes1.ToArray();
            }
            else
            {
                // orthogonalize modes1
                nmodes1 = new Vector[modes1.Count];
                Vector masses = new double[mass1.Size * 3];
                for (int i = 0; i < mass1.Size; i++)
                {
                    masses[i * 3 + 0] = masses[i * 3 + 1] = masses[i * 3 + 2] = mass1[i];
                }
                for (int i = 0; i < nmodes1.Length; i++)
                {
                    nmodes1[i] = Vector.PtwiseMul(masses, modes1[i]);
                }
            }
            if (bDebugAssertOrthogonal)
            {
                for (int i = 0; i < nmodes1.Length; i++)
                {
                    for (int j = 0; j < i; j++)
                    {
                        double dot = LinAlg.VtV(nmodes1[i], nmodes1[j]);
                        HDebug.AssertTolerance(0.000001, dot);
                    }
                }
            }

            Vector[] nmodes2;
            if (mass2 == null)
            {
                nmodes2 = modes2.ToArray();
            }
            else
            {
                // orthogonalize modes2
                nmodes2 = new Vector[modes2.Count];
                Vector masses = new double[mass2.Size * 3];
                for (int i = 0; i < mass2.Size; i++)
                {
                    masses[i * 3 + 0] = masses[i * 3 + 1] = masses[i * 3 + 2] = mass2[i];
                }
                for (int i = 0; i < nmodes2.Length; i++)
                {
                    nmodes2[i] = Vector.PtwiseMul(masses, modes2[i]);
                }
            }
            if (bDebugAssertOrthogonal)
            {
                for (int i = 0; i < nmodes2.Length; i++)
                {
                    for (int j = 0; j < i; j++)
                    {
                        double dot = LinAlg.VtV(nmodes2[i], nmodes2[j]);
                        HDebug.AssertTolerance(0.00000001, dot);
                    }
                }
            }


            int    I     = nmodes1.Length;
            int    J     = nmodes2.Length;
            double rmsip = 0;

            double[,] rmsip_ij = new double[I, J];

            for (int i = 0; i < I; i++)
            {
                for (int j = 0; j < J; j++)
                {
                    double PiMj = LinAlg.VtV(nmodes1[i], nmodes2[j]);
                    rmsip         += (PiMj * PiMj);
                    rmsip_ij[i, j] = PiMj;
                }
            }
            rmsip = Math.Sqrt(rmsip / I);

            return(new ORMSIP
            {
                rmsip = rmsip,
                rmsip_ij = rmsip_ij,
            });
        }