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);
        }
Exemple #2
0
        public HessMatrix SubMatrixByAtomsImpl0(IList <int> idxColAtoms, IList <int> idxRowAtoms)
        {
            if (SubMatrixByAtomsImpl0_selftest2)
            {
                SubMatrixByAtomsImpl0_selftest2 = false;
                Matrix thess1 = 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 thess2 = HessMatrixDense.FromMatrix(thess1);
                HessMatrix thess3 = thess2.SubMatrixByAtomsImpl0(new int[] { 0 }, new int[] { 1 });
                Matrix     thess4 = new double[, ] {
                    { 3, 4, 5 }
                    , { 4, 5, 6 }
                    , { 5, 6, 7 }
                };
                HDebug.AssertToleranceMatrix(0, thess3 - thess4);
            }
            HessMatrix nhess = Zeros(idxColAtoms.Count * 3, idxRowAtoms.Count * 3);

            for (int nbc = 0; nbc < idxColAtoms.Count; nbc++)
            {
                for (int nbr = 0; nbr < idxRowAtoms.Count; nbr++)
                {
                    int bc = idxColAtoms[nbc]; if (bc < 0)
                    {
                        continue;
                    }
                    int br = idxRowAtoms[nbr]; if (br < 0)
                    {
                        continue;
                    }
                    if (HasBlock(bc, br) == false)
                    {
                        continue;
                    }
                    MatrixByArr block = GetBlock(bc, br).CloneT(); // hessian matrix for interaction between atom i and j
                    HDebug.Assert(block.IsZero() == false);
                    nhess.SetBlock(nbc, nbr, block);
                }
            }

            return(nhess);
        }
                private static HessMatrix GetHessCoarseResiIterImpl_Matlab_IterLowerTri_Get_BInvDC
                    (HessMatrix A
                    , HessMatrix C
                    , HessMatrix D
                    , bool process_disp_console
                    , string[] options
                    , double?thld_BinvDC = null
                    , bool parallel      = false
                    )
                {
                    HessMatrix            B_invD_C;
                    Dictionary <int, int> Cbr_CCbr = new Dictionary <int, int>();
                    List <int>            CCbr_Cbr = new List <int>();

                    foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in C.EnumBlocks())
                    {
                        int Cbr = bc_br_bval.Item2;
                        if (Cbr_CCbr.ContainsKey(Cbr) == false)
                        {
                            HDebug.Assert(Cbr_CCbr.Count == CCbr_Cbr.Count);
                            int CCbr = Cbr_CCbr.Count;
                            Cbr_CCbr.Add(Cbr, CCbr);
                            CCbr_Cbr.Add(Cbr);
                            HDebug.Assert(CCbr_Cbr[CCbr] == Cbr);
                        }
                    }

                    HessMatrix CC = HessMatrixSparse.ZerosSparse(C.ColSize, Cbr_CCbr.Count * 3);

                    {
                        Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval)
                        {
                            int Cbc = bc_br_bval.Item1; int CCbc = Cbc;
                            int Cbr = bc_br_bval.Item2; int CCbr = Cbr_CCbr[Cbr];
                            var bval = bc_br_bval.Item3;
                            lock (CC)
                                CC.SetBlock(CCbc, CCbr, bval);
                        };

                        if (parallel)
                        {
                            Parallel.ForEach(C.EnumBlocks(), func);
                        }
                        else
                        {
                            foreach (var bc_br_bval in C.EnumBlocks())
                            {
                                func(bc_br_bval);
                            }
                        }
                    }
                    if (process_disp_console)
                    {
                        System.Console.Write("squeezeC({0,6}->{1,6} blk), ", C.RowBlockSize, CC.RowBlockSize);
                    }
                    {
                        /// If a diagonal element of D is null, that row and column should be empty.
                        /// This assume that the atom is removed. In this case, the removed diagonal block
                        /// is replace as the 3x3 identity matrix.
                        ///
                        ///  [B1  0] [ A 0 ]^-1 [C1 C2 C3] = [B1  0] [ A^-1  0    ] [C1 C2 C3]
                        ///  [B2  0] [ 0 I ]    [ 0  0  0]   [B2  0] [ 0     I^-1 ] [ 0  0  0]
                        ///  [B3  0]                         [B3  0]
                        ///                                = [B1.invA  0] [C1 C2 C3]
                        ///                                  [B2.invA  0] [ 0  0  0]
                        ///                                  [B3.invA  0]
                        ///                                = [B1.invA.C1  B1.invA.C2  B1.invA.C3]
                        ///                                  [B2.invA.C1  B2.invA.C2  B2.invA.C3]
                        ///                                  [B3.invA.C1  B3.invA.C2  B3.invA.C3]
                        ///
                        {
                            //HDebug.Exception(D.ColBlockSize == D.RowBlockSize);
                            for (int bi = 0; bi < D.ColBlockSize; bi++)
                            {
                                if (D.HasBlock(bi, bi) == true)
                                {
                                    continue;
                                }
                                //for(int bc=0; bc< D.ColBlockSize; bc++) HDebug.Exception( D.HasBlock(bc, bi) == false);
                                //for(int br=0; br< D.RowBlockSize; br++) HDebug.Exception( D.HasBlock(bi, br) == false);
                                //for(int br=0; br<CC.RowBlockSize; br++) HDebug.Exception(CC.HasBlock(bi, br) == false);
                                D.SetBlock(bi, bi, new double[3, 3] {
                                    { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }
                                });
                            }
                        }

                        HessMatrix BB_invDD_CC;
                        using (new Matlab.NamedLock(""))
                        {
                            Matlab.Execute("clear;");                                                               if (process_disp_console)
                            {
                                System.Console.Write("matlab(");
                            }
                            Matlab.PutMatrix("C", CC);                                                              if (process_disp_console)
                            {
                                System.Console.Write("C");                                                                                                              //Matlab.PutSparseMatrix("C", CC.GetMatrixSparse(), 3, 3);
                            }
                            Matlab.PutMatrix("D", D);                                                               if (process_disp_console)
                            {
                                System.Console.Write("D");
                            }
                            {   // Matlab.Execute("BinvDC = (C' / D) * C;");
                                if (options != null && options.Contains("pinv(D)"))
                                {
                                    string msg = Matlab.Execute("BinvDC = (C' / D) * C;", true);
                                    if (msg != "")
                                    {
                                        Matlab.Execute("BinvDC = C' * pinv(D) * C;");
                                    }
                                }
                                else
                                {
                                    Matlab.Execute("BinvDC = (C' / D) * C;");
                                }
                            }                                                                                       if (process_disp_console)
                            {
                                System.Console.Write("X");
                            }
                            /// » whos
                            ///   Name         Size                 Bytes  Class     Attributes
                            ///                                                                                 //   before compressing C matrix
                            ///   C         1359x507              5512104  double                               //   C         1359x1545            16797240  double
                            ///   CC        1359x507               198464  double    sparse                     //   CC        1359x1545              206768  double    sparse
                            ///   D         1359x1359            14775048  double                               //   D         1359x1359            14775048  double
                            ///   DD        1359x1359              979280  double    sparse                     //   DD        1359x1359              979280  double    sparse
                            ///   ans          1x1                      8  double
                            ///
                            /// » tic; for i=1:30; A=(C' / D) * C; end; toc         dense  * dense  * dense  => 8.839463 seconds. (win)
                            /// Elapsed time is 8.839463 seconds.
                            /// » tic; for i=1:30; AA=(CC' / DD) * CC; end; toc     sparse * sparse * sparse => 27.945534 seconds.
                            /// Elapsed time is 27.945534 seconds.
                            /// » tic; for i=1:30; AAA=(C' / DD) * C; end; toc      sparse * dense  * sparse => 29.136144 seconds.
                            /// Elapsed time is 29.136144 seconds.
                            /// »
                            /// » tic; for i=1:30; A=(C' / D) * C; end; toc         dense  * dense  * dense  => 8.469071 seconds. (win)
                            /// Elapsed time is 8.469071 seconds.
                            /// » tic; for i=1:30; AA=(CC' / DD) * CC; end; toc     sparse * sparse * sparse => 28.309953 seconds.
                            /// Elapsed time is 28.309953 seconds.
                            /// » tic; for i=1:30; AAA=(C' / DD) * C; end; toc      sparse * dense  * sparse => 28.586375 seconds.
                            /// Elapsed time is 28.586375 seconds.
                            //Matrix BBinvDDCC = Matlab.GetMatrix("BinvDC", true);
                            if (thld_BinvDC != null)
                            {
                                Matlab.Execute("BinvDC(find(BinvDC < " + thld_BinvDC.ToString() + ")) = 0;");
                            }
                            if (Matlab.GetValue("nnz(BinvDC)/numel(BinvDC)") > 0.5)
                            {
                                double[,] arr = Matlab.GetMatrix("BinvDC", true);
                                BB_invDD_CC   = HessMatrixDense.FromMatrix(arr);
                                if (process_disp_console)
                                {
                                    System.Console.Write("Y), ");
                                }
                            }
                            else
                            {
                                Matlab.Execute("[i,j,s] = find(sparse(BinvDC));");
                                TVector <int>    listi = Matlab.GetVectorLargeInt("i", true);
                                TVector <int>    listj = Matlab.GetVectorLargeInt("j", true);
                                TVector <double> lists = Matlab.GetVectorLarge("s", true);
                                int colsize            = Matlab.GetValueInt("size(BinvDC,1)");
                                int rowsize            = Matlab.GetValueInt("size(BinvDC,2)");

                                Dictionary <ValueTuple <int, int>, MatrixByArr> lst_bc_br_bval = new Dictionary <ValueTuple <int, int>, MatrixByArr>();
                                for (long i = 0; i < listi.SizeLong; i++)
                                {
                                    int    c = listi[i] - 1; int bc = c / 3; int ic = c % 3;
                                    int    r = listj[i] - 1; int br = r / 3; int ir = r % 3;
                                    double v = lists[i];
                                    ValueTuple <int, int> bc_br = new ValueTuple <int, int>(bc, br);
                                    if (lst_bc_br_bval.ContainsKey(bc_br) == false)
                                    {
                                        lst_bc_br_bval.Add(bc_br, new double[3, 3]);
                                    }
                                    lst_bc_br_bval[bc_br][ic, ir] = v;
                                }

                                //  Matrix BBinvDDCC = Matrix.Zeros(colsize, rowsize);
                                //  for(int i=0; i<listi.Length; i++)
                                //      BBinvDDCC[listi[i]-1, listj[i]-1] = lists[i];
                                //  //GC.Collect(0);
                                BB_invDD_CC = HessMatrixSparse.ZerosSparse(colsize, rowsize);
                                foreach (var bc_br_bval in lst_bc_br_bval)
                                {
                                    int bc   = bc_br_bval.Key.Item1;
                                    int br   = bc_br_bval.Key.Item2;
                                    var bval = bc_br_bval.Value;
                                    BB_invDD_CC.SetBlock(bc, br, bval);
                                }
                                if (process_disp_console)
                                {
                                    System.Console.Write("Z), ");
                                }

                                if (HDebug.IsDebuggerAttached)
                                {
                                    for (int i = 0; i < listi.Size; i++)
                                    {
                                        int    c = listi[i] - 1;
                                        int    r = listj[i] - 1;
                                        double v = lists[i];
                                        HDebug.Assert(BB_invDD_CC[c, r] == v);
                                    }
                                }
                            }
                            Matlab.Execute("clear;");
                        }
                        //GC.Collect(0);

                        B_invD_C = HessMatrixSparse.ZerosSparse(C.RowSize, C.RowSize);
                        {
                            //  for(int bcc=0; bcc<CCbr_Cbr.Count; bcc++)
                            //  {
                            //      int bc = CCbr_Cbr[bcc];
                            //      for(int brr=0; brr<CCbr_Cbr.Count; brr++)
                            //      {
                            //          int br   = CCbr_Cbr[brr];
                            //          HDebug.Assert(B_invD_C.HasBlock(bc, br) == false);
                            //          if(BB_invDD_CC.HasBlock(bcc, brr) == false)
                            //              continue;
                            //          var bval = BB_invDD_CC.GetBlock(bcc, brr);
                            //          B_invD_C.SetBlock(bc, br, bval);
                            //          HDebug.Exception(A.HasBlock(bc, bc));
                            //          HDebug.Exception(A.HasBlock(br, br));
                            //      }
                            //  }
                            Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bcc_brr_bval)
                            {
                                int bcc  = bcc_brr_bval.Item1;
                                int brr  = bcc_brr_bval.Item2;
                                var bval = bcc_brr_bval.Item3;

                                int bc = CCbr_Cbr[bcc];
                                int br = CCbr_Cbr[brr];
                                lock (B_invD_C)
                                    B_invD_C.SetBlock(bc, br, bval);
                            };

                            if (parallel)
                            {
                                Parallel.ForEach(BB_invDD_CC.EnumBlocks(), func);
                            }
                            else
                            {
                                foreach (var bcc_brr_bval in BB_invDD_CC.EnumBlocks())
                                {
                                    func(bcc_brr_bval);
                                }
                            }
                        }
                    }
                    GC.Collect(0);
                    return(B_invD_C);
                }
Exemple #4
0
        public HessMatrix SubMatrixByAtomsImpl
            (bool ignNegIdx         // [false]
            , IList <int> idxColAtoms
            , IList <int> idxRowAtoms
            , bool bCloneBlock
            , bool parallel = false
            )
        {
            Dictionary <int, int[]> col_idx2nidx = new Dictionary <int, int[]>();
            HashSet <int>           col_idxs     = new HashSet <int>();

            for (int nidx = 0; nidx < idxColAtoms.Count; nidx++)
            {
                int idx = idxColAtoms[nidx];
                if (idx < 0)
                {
                    if (ignNegIdx)
                    {
                        continue;
                    }
                    throw new IndexOutOfRangeException();
                }
                if (col_idx2nidx.ContainsKey(idx) == false)
                {
                    col_idx2nidx.Add(idx, new int[0]);
                }
                col_idx2nidx[idx] = col_idx2nidx[idx].HAdd(nidx);
                col_idxs.Add(idx);
            }
            Dictionary <int, int[]> row_idx2nidx = new Dictionary <int, int[]>();

            for (int nidx = 0; nidx < idxRowAtoms.Count; nidx++)
            {
                int idx = idxRowAtoms[nidx];
                if (idx < 0)
                {
                    if (ignNegIdx)
                    {
                        continue;
                    }
                    throw new IndexOutOfRangeException();
                }
                if (row_idx2nidx.ContainsKey(idx) == false)
                {
                    row_idx2nidx.Add(idx, new int[0]);
                }
                row_idx2nidx[idx] = row_idx2nidx[idx].HAdd(nidx);
            }

            HessMatrix nhess = Zeros(idxColAtoms.Count * 3, idxRowAtoms.Count * 3);

            {
                Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval)
                {
                    int bc = bc_br_bval.Item1; if (col_idx2nidx.ContainsKey(bc) == false)
                    {
                        return;
                    }
                    int br = bc_br_bval.Item2; if (row_idx2nidx.ContainsKey(br) == false)
                    {
                        return;
                    }
                    var bval = bc_br_bval.Item3;
                    if (bCloneBlock)
                    {
                        foreach (int nbc in col_idx2nidx[bc])
                        {
                            foreach (int nbr in row_idx2nidx[br])
                            {
                                lock (nhess)
                                    nhess.SetBlock(nbc, nbr, bval.CloneT());
                            }
                        }
                    }
                    else
                    {
                        foreach (int nbc in col_idx2nidx[bc])
                        {
                            foreach (int nbr in row_idx2nidx[br])
                            {
                                lock (nhess)
                                    nhess.SetBlock(nbc, nbr, bval);
                            }
                        }
                    }
                };

                if (parallel)
                {
                    Parallel.ForEach(EnumBlocksInCols(col_idxs.ToArray()), func);
                }
                else
                {
                    foreach (var bc_br_bval in EnumBlocksInCols(col_idxs.ToArray()))
                    {
                        func(bc_br_bval);
                    }
                }
            }
            if (SubMatrixByAtomsImpl_selftest2)
            {
                SubMatrixByAtomsImpl_selftest2 = false;
                HessMatrix tnhess = SubMatrixByAtomsImpl0(idxColAtoms, idxRowAtoms);
                HDebug.Assert(HessMatrix.HessMatrixSparseEqual(nhess, tnhess));
                //////////////////////////////////////////
                Matrix thess1 = 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 thess2 = HessMatrixDense.FromMatrix(thess1);
                HessMatrix thess3 = thess2.SubMatrixByAtomsImpl(false, new int[] { 0 }, new int[] { 1 }, true);
                Matrix     thess4 = new double[, ] {
                    { 3, 4, 5 }
                    , { 4, 5, 6 }
                    , { 5, 6, 7 }
                };
                HDebug.AssertToleranceMatrix(0, thess3 - thess4);
            }

            return(nhess);
        }