Exemplo n.º 1
0
            public HessInfo GetSubHessInfo(IList <int> idxSele)
            {
                Dictionary <int, int> whole2sele = idxSele.HToDictionaryAsValueIndex();

                Vector submass = (mass == null) ? null : mass.ToArray().HSelectByIndex(idxSele);

                object[]   subatoms  = (atoms == null) ? null : atoms.HSelectByIndex(idxSele);
                Vector[]   subcoords = (coords == null) ? null : coords.HSelectByIndex(idxSele);
                int        subsize   = idxSele.Count;
                HessMatrix subhess   = hess.Zeros(subsize * 3, subsize * 3);

                foreach (var bc_br_bval in hess.EnumBlocks())
                {
                    int bc = bc_br_bval.Item1; if (whole2sele.ContainsKey(bc) == false)
                    {
                        continue;
                    }
                    int nbc = whole2sele[bc];
                    int br  = bc_br_bval.Item2; if (whole2sele.ContainsKey(br) == false)
                    {
                        continue;
                    }
                    int nbr  = whole2sele[br];
                    var bval = bc_br_bval.Item3;
                    subhess.SetBlock(nbc, nbr, bval.CloneT());
                }
                return(new HessInfo
                {
                    mass = submass,
                    atoms = subatoms,
                    coords = subcoords,
                    hess = subhess,
                    numZeroEigval = null,
                });
            }
Exemplo n.º 2
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);
            }
        }
Exemplo n.º 3
0
        public static bool HessMatrixSparseEqual(HessMatrix hess, HessMatrix equal)
        {
            if (hess.ColSize != equal.ColSize)
            {
                return(false);
            }
            if (hess.RowSize != equal.RowSize)
            {
                return(false);
            }

            foreach (var bc_br_bval in hess.EnumBlocks())
            {
                int bc  = bc_br_bval.Item1;
                int br  = bc_br_bval.Item2;
                var bv  = bc_br_bval.Item3;
                var bv0 = equal.GetBlock(bc, br);
                if (bv0 == null)
                {
                    return(false);
                }
                if ((bv - bv0).HAbsMax() != 0)
                {
                    return(false);
                }
            }

            foreach (var bc_br_bval in equal.EnumBlocks())
            {
                int bc  = bc_br_bval.Item1;
                int br  = bc_br_bval.Item2;
                var bv  = bc_br_bval.Item3;
                var bv0 = hess.GetBlock(bc, br);
                if (bv0 == null)
                {
                    return(false);
                }
                if ((bv - bv0).HAbsMax() != 0)
                {
                    return(false);
                }
            }

            return(true);
        }
            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
                )
            {
                if (options == null)
                {
                    options = new string[0];
                }

                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 = C.Zeros(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.Contains("pinv(D)"))
                            {
                                Matlab.Execute("BinvDC = C' * pinv(D) * C;");
                            }
                            if (options.Contains("/D -> pinv(D)"))
                            {
                                string msg = Matlab.Execute("BinvDC = (C' / D) * C;", true);
                                if (msg != "")
                                {
                                    Matlab.Execute("BinvDC = C' * pinv(D) * C;");
                                }
                            }
                            else if (options.Contains("/D"))
                            {
                                Matlab.Execute("BinvDC = (C' / D) * C;");
                            }
                            else
                            {
                                Matlab.Execute("BinvDC = (C' / D) * C;");
                            }
                        }
                        if (process_disp_console)
                        {
                            System.Console.Write("X");
                        }

                        //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 || HDebug.True)
                        {
                            Func <int, int, HessMatrix> Zeros = delegate(int colsize, int rowsize)
                            {
                                return(HessMatrixDense.ZerosDense(colsize, rowsize));
                            };
                            BB_invDD_CC = Matlab.GetMatrix("BinvDC", Zeros, true);
                            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 = D.Zeros(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 = A.Zeros(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.SetBlockLock(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);
            }
            public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_Matlab_IterLowerTri
                (object[] atoms
                , HessMatrix H
                , List <int>[] lstNewIdxRemv
                , double thres_zeroblk
                , ILinAlg ila
                , bool cloneH
                , string[] options // { "pinv(D)" }
                )
            {
                ila = null;
                if (cloneH)
                {
                    H = H.CloneHess();
                }

                bool process_disp_console = true;

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

                bool parallel = true;

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

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

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

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

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

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

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

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

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

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

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

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

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

                            H.SetBlock(bc, br, null);
                            if (bc > iremv_max)
                            {
                                HDebug.Assert(false); continue;
                            }
                            if (br > iremv_max)
                            {
                                HDebug.Assert(false); continue;
                            }
                            if (br < iremv_min)
                            {
                                int nc = bc - iremv_min;
                                int nr = br;
                                HDebug.Assert(C.HasBlock(nc, nr) == false);
                                C.SetBlock(nc, nr, bval.CloneT());
                            }
                            else
                            {
                                int nc = bc - iremv_min;
                                int nr = br - iremv_min;
                                HDebug.Assert(D.HasBlock(nc, nr) == false);
                                D.SetBlock(nc, nr, bval);
                                if (nc != nr)
                                {
                                    HDebug.Assert(D.HasBlock(nr, nc) == false);
                                    D.SetBlock(nr, nc, bval.Tr());
                                }
                            }
                        }
                        HDebug.Assert(H.EnumBlocksInCols(idxremv).Count() == 0);
                    }
                    if (process_disp_console)
                    {
                        process_time.Add(DateTime.UtcNow);
                        int ptc = process_time.Count;
                        System.Console.Write("CD({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes);
                    }

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

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

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

                        //foreach(var bc_br_bval in other.EnumBlocks())
                        Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval)
                        {
                            _count[0]++;
                            int         bc         = bc_br_bval.Item1;
                            int         br         = bc_br_bval.Item2;
                            MatrixByArr other_bmat = bc_br_bval.Item3;
                            if (bc < br)
                            {
                                return; // continue;
                            }
                            if (other_bmat.HAbsMax() <= _thres_NearZeroBlock)
                            {
                                /// other_bmat = other_bmat    -other_bmat;
                                /// other_diag = other_diag - (-other_bmat) = other_diag + other_bmat;
                                ///  this_diag =  this_diat - B_invD_C
                                ///            =  this_diat - other_diag
                                ///            =  this_diat - (other_diag + other_bmat)
                                ///            =  this_diat - other_diag  - other_bmat
                                ///            = (this_diat - other_bmat) - other_diag
                                ///            = (this_diat - other_bmat) - (processed later)
                                ///            = (this_diat - other_bmat)
                                MatrixByArr this_diag = __this.GetBlock(bc, bc);
                                MatrixByArr new_diag  = this_diag - other_bmat;
                                __this.SetBlockLock(bc, bc, new_diag);
                                other_bmat = null;
                                lock (_count_ignored)
                                    _count_ignored[0]++;
                            }
                            if (other_bmat != null)
                            {
                                MatrixByArr this_bmat = __this.GetBlock(bc, br);
                                if (this_bmat == null)
                                {
                                    this_bmat = new double[3, 3];
                                }
                                MatrixByArr new_bmat = this_bmat - other_bmat;
                                __this.SetBlockLock(bc, br, new_bmat);
                            }
                        };
                        if (parallel)
                        {
                            HParallel.ForEach(other.EnumBlocks(), func);
                        }
                        else
                        {
                            foreach (var bc_br_bval in other.EnumBlocks())
                            {
                                func(bc_br_bval);
                            }
                        }

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

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

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

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

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

                return(new CGetHessCoarseResiIterImpl
                {
                    iterinfos = iterinfos,
                    H = H,
                });
            }
                public static CGetHessCoarseResiIterImpl Do
                    (object[] atoms
                    , HessMatrix H
                    , List <int>[] lstNewIdxRemv
                    , double thres_zeroblk
                    , ILinAlg ila
                    , bool cloneH
                    , string[] options
                    )
                {
                    //HDebug.ToDo();

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

                    bool process_disp_console = true;

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

                    bool parallel = false;

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

                    DateTime[] process_time = new DateTime[6];

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

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

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

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

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

                            double threshold = thres_zeroblk / lstNewIdxRemv.Length;

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

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

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

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

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

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

                            //GC.Collect(0);

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

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

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

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

                    return(new CGetHessCoarseResiIterImpl
                    {
                        iterinfos = iterinfos,
                        H = H,
                    });
                }
Exemplo n.º 7
0
            private static HessMatrix Get_BInvDC
                (HessMatrix A
                , HessMatrix C
                , HessMatrix D
                , bool process_disp_console
                , string[] options
                , 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 }
                            });
                        }
                    }

                    HessMatrixSparse 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 (process_disp_console)
                        {
                            System.Console.Write("Y");
                        }
                        //Matlab.Execute("[i,j,s] = find(sparse(BinvDC));");
                        //int[] listi = Matlab.GetVectorInt("i");
                        //int[] listj = Matlab.GetVectorInt("j");
                        //double[] lists = Matlab.GetVector("s");
                        //int colsize = Matlab.GetValueInt("size(BinvDC,1)");
                        //int rowsize = Matlab.GetValueInt("size(BinvDC,2)");
                        //Matrix BBinvDDCC = Matrix.Zeros(colsize, rowsize);
                        //for(int i=0; i<listi.Length; i++)
                        //    BBinvDDCC[listi[i], listj[i]] = lists[i];
                        //GC.Collect(0);
                        BB_invDD_CC = HessMatrixSparse.FromMatrix(BBinvDDCC, parallel);                         if (process_disp_console)
                        {
                            System.Console.Write("Z), ");
                        }
                        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);
            }
Exemplo n.º 8
0
            public static HessInfoCoarseResiIter GetHessCoarseResiIter
                (Hess.HessInfo hessinfo
                , Vector[] coords
                , FuncGetIdxKeepListRemv GetIdxKeepListRemv
                , ILinAlg ila
                , double thres_zeroblk = 0.001
                , IterOption iteropt   = IterOption.Matlab_experimental
                , string[] options     = null
                )
            {
                bool rediag = true;

                HessMatrix H = null;

                List <int>[] lstNewIdxRemv = null;
                int          numca         = 0;

                double[] reMass   = null;
                object[] reAtoms  = null;
                Vector[] reCoords = null;
                Tuple <int[], int[][]> idxKeepRemv = null;

                //System.Console.WriteLine("begin re-indexing hess");
                {
                    object[] atoms = hessinfo.atoms;
                    idxKeepRemv = GetIdxKeepListRemv(atoms, coords);
                    int[]   idxKeep  = idxKeepRemv.Item1;
                    int[][] idxsRemv = idxKeepRemv.Item2;
                    {
                        List <int> check = new List <int>();
                        check.AddRange(idxKeep);
                        foreach (int[] idxRemv in idxsRemv)
                        {
                            check.AddRange(idxRemv);
                        }
                        check = check.HToHashSet().ToList();
                        if (check.Count != coords.Length)
                        {
                            throw new Exception("the re-index contains the duplicated atoms or the missing atoms");
                        }
                    }
                    List <int> idxs = new List <int>();
                    idxs.AddRange(idxKeep);
                    foreach (int[] idxRemv in idxsRemv)
                    {
                        idxs.AddRange(idxRemv);
                    }
                    HDebug.Assert(idxs.Count == idxs.HToHashSet().Count);

                    H        = hessinfo.hess.ReshapeByAtom(idxs);
                    numca    = idxKeep.Length;
                    reMass   = hessinfo.mass.ToArray().HSelectByIndex(idxs);
                    reAtoms  = hessinfo.atoms.ToArray().HSelectByIndex(idxs);
                    reCoords = coords.HSelectByIndex(idxs);

                    int nidx = idxKeep.Length;
                    lstNewIdxRemv = new List <int> [idxsRemv.Length];
                    for (int i = 0; i < idxsRemv.Length; i++)
                    {
                        lstNewIdxRemv[i] = new List <int>();
                        foreach (var idx in idxsRemv[i])
                        {
                            lstNewIdxRemv[i].Add(nidx);
                            nidx++;
                        }
                    }
                    HDebug.Assert(nidx == lstNewIdxRemv.Last().Last() + 1);
                    HDebug.Assert(nidx == idxs.Count);
                }
                GC.Collect(0);
                HDebug.Assert(numca == H.ColBlockSize - lstNewIdxRemv.HListCount().Sum());

                //if(bool.Parse("false"))
                {
                    if (bool.Parse("false"))
                    #region
                    {
                        int[]      idxKeep  = idxKeepRemv.Item1;
                        int[][]    idxsRemv = idxKeepRemv.Item2;
                        Pdb.Atom[] pdbatoms = hessinfo.atomsAsUniverseAtom.ListPdbAtoms();
                        Pdb.ToFile(@"C:\temp\coarse-keeps.pdb", pdbatoms.HSelectByIndex(idxKeep), false);
                        if (HFile.Exists(@"C:\temp\coarse-graining.pdb"))
                        {
                            HFile.Delete(@"C:\temp\coarse-graining.pdb");
                        }
                        foreach (int[] idxremv in idxsRemv.Reverse())
                        {
                            List <Pdb.Element> delatoms = new List <Pdb.Element>();
                            foreach (int idx in idxremv)
                            {
                                if (pdbatoms[idx] == null)
                                {
                                    continue;
                                }
                                string   line    = pdbatoms[idx].GetUpdatedLine(coords[idx]);
                                Pdb.Atom delatom = Pdb.Atom.FromString(line);
                                delatoms.Add(delatom);
                            }
                            Pdb.ToFile(@"C:\temp\coarse-graining.pdb", delatoms.ToArray(), true);
                        }
                    }
                    #endregion

                    if (bool.Parse("false"))
                    #region
                    {
                        // export matrix to matlab, so the matrix can be checked in there.
                        int[] idxca  = HEnum.HEnumCount(numca).ToArray();
                        int[] idxoth = HEnum.HEnumFromTo(numca, coords.Length - 1).ToArray();
                        Matlab.Register(@"C:\temp\");
                        Matlab.PutSparseMatrix("H", H.GetMatrixSparse(), 3, 3);
                        Matlab.Execute("figure; spy(H)");
                        Matlab.Clear();
                    }
                    #endregion

                    if (bool.Parse("false"))
                    #region
                    {
                        HDirectory.CreateDirectory(@"K:\temp\$coarse-graining\");
                        {   // export original hessian matrix
                            List <int> cs = new List <int>();
                            List <int> rs = new List <int>();
                            foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in hessinfo.hess.EnumBlocks())
                            {
                                cs.Add(bc_br_bval.Item1);
                                rs.Add(bc_br_bval.Item2);
                            }
                            Matlab.Clear();
                            Matlab.PutVector("cs", cs.ToArray());
                            Matlab.PutVector("rs", rs.ToArray());
                            Matlab.Execute("hess = sparse(cs+1, rs+1, ones(size(cs)));");
                            Matlab.Execute("hess = float(hess);");
                            Matlab.Execute("figure; spy(hess)");
                            Matlab.Execute("cs = int32(cs+1);");
                            Matlab.Execute("rs = int32(rs+1);");
                            Matlab.Execute(@"save('K:\temp\$coarse-graining\hess-original.mat', 'cs', 'rs', '-v6');");
                            Matlab.Clear();
                        }
                        {   // export reshuffled hessian matrix
                            List <int> cs = new List <int>();
                            List <int> rs = new List <int>();
                            foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in H.EnumBlocks())
                            {
                                cs.Add(bc_br_bval.Item1);
                                rs.Add(bc_br_bval.Item2);
                            }
                            Matlab.Clear();
                            Matlab.PutVector("cs", cs.ToArray());
                            Matlab.PutVector("rs", rs.ToArray());
                            Matlab.Execute("H = sparse(cs+1, rs+1, ones(size(cs)));");
                            Matlab.Execute("H = float(H);");
                            Matlab.Execute("figure; spy(H)");
                            Matlab.Execute("cs = int32(cs+1);");
                            Matlab.Execute("rs = int32(rs+1);");
                            Matlab.Execute(@"save('K:\temp\$coarse-graining\hess-reshuffled.mat', 'cs', 'rs', '-v6');");
                            Matlab.Clear();
                        }
                    }
                    #endregion

                    if (bool.Parse("false"))
                    #region
                    {
                        int[] idxca  = HEnum.HEnumCount(numca).ToArray();
                        int[] idxoth = HEnum.HEnumFromTo(numca, coords.Length - 1).ToArray();

                        HessMatrix A = H.SubMatrixByAtoms(false, idxca, idxca);
                        HessMatrix B = H.SubMatrixByAtoms(false, idxca, idxoth);
                        HessMatrix C = H.SubMatrixByAtoms(false, idxoth, idxca);
                        HessMatrix D = H.SubMatrixByAtoms(false, idxoth, idxoth);
                        Matlab.Clear();
                        Matlab.PutSparseMatrix("A", A.GetMatrixSparse(), 3, 3);
                        Matlab.PutSparseMatrix("B", B.GetMatrixSparse(), 3, 3);
                        Matlab.PutSparseMatrix("C", C.GetMatrixSparse(), 3, 3);
                        Matlab.PutSparseMatrix("D", D.GetMatrixSparse(), 3, 3);
                        Matlab.Clear();
                    }
                    #endregion
                }

                List <HessCoarseResiIterInfo> iterinfos = null;
                {
                    object[] atoms = reAtoms; // reAtoms.HToType(null as Universe.Atom[]);
                    CGetHessCoarseResiIterImpl info = null;
                    switch (iteropt)
                    {
                    case IterOption.ILinAlg_20150329: info = GetHessCoarseResiIterImpl_ILinAlg_20150329(H, lstNewIdxRemv, thres_zeroblk, ila, false);                    break;

                    case IterOption.ILinAlg: info = GetHessCoarseResiIterImpl_ILinAlg(H, lstNewIdxRemv, thres_zeroblk, ila, false);                             break;

                    case IterOption.Matlab: info = GetHessCoarseResiIterImpl_Matlab(atoms, H, lstNewIdxRemv, thres_zeroblk, ila, false, options);              break;

                    case IterOption.Matlab_experimental: info = GetHessCoarseResiIterImpl_Matlab_experimental(atoms, H, lstNewIdxRemv, thres_zeroblk, ila, false, options); break;

                    case IterOption.Matlab_IterLowerTri: info = GetHessCoarseResiIterImpl_Matlab_IterLowerTri(atoms, H, lstNewIdxRemv, thres_zeroblk, ila, false, options); break;

                    case IterOption.LinAlg_IterLowerTri: info = GetHessCoarseResiIterImpl_LinAlg_IterLowerTri.Do(atoms, H, lstNewIdxRemv, thres_zeroblk, ila, false, options); break;
                    }
                    ;
                    H         = info.H;
                    iterinfos = info.iterinfos;
                }
                //{
                //    var info = GetHessCoarseResiIterImpl_Matlab(H, lstNewIdxRemv, thres_zeroblk);
                //    H = info.H;
                //}
                GC.Collect(0);

                if (HDebug.IsDebuggerAttached)
                {
                    int   nidx  = 0;
                    int[] ikeep = idxKeepRemv.Item1;
                    foreach (int idx in ikeep)
                    {
                        bool equal = object.ReferenceEquals(hessinfo.atoms[idx], reAtoms[nidx]);
                        if (equal == false)
                        {
                            HDebug.Assert(false);
                        }
                        HDebug.Assert(equal);
                        nidx++;
                    }
                }

                if (rediag)
                {
                    H = H.CorrectHessDiag();
                }
                //System.Console.WriteLine("finish fixing diag");

                return(new HessInfoCoarseResiIter
                {
                    hess = H,
                    mass = reMass.HSelectCount(numca),
                    atoms = reAtoms.HSelectCount(numca),
                    coords = reCoords.HSelectCount(numca),
                    numZeroEigval = 6,
                    iterinfos = iterinfos,
                });
            }
Exemplo n.º 9
0
            public static HessInfo GetHessSbNMA
                (Universe univ
                , IList <Vector> coords
                , double nbondMaxDist // =12
                , double?maxAbsSpring
                , bool b_bonds
                , bool b_angles
                , bool b_impropers
                , bool b_dihedrals
                , bool b_nonbondeds
                , bool b_nonbonded14s
                , double?sca_bonds
                , double?sca_angles
                , double?sca_impropers
                , double?sca_dihedrals
                , double?sca_nonbondeds
                , double?sca_nonbonded14s
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, double> collectorBond
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, double, double> collectorAngle
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, double, double> collectorImproper
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, Universe.Atom, Vector, double, double> collectorDihedral
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, double> collectorNonbonded
                , Action <Universe.Atom, Vector, Universe.Atom, Vector, double> collectorNonbonded14
                , Func <HessSpr.CustomKijInfo, double> GetCustomKij = null
                , params string[] options
                )
            {
                IEnumerable <Universe.Nonbonded>   nonbondeds   = null;
                IEnumerable <Universe.Nonbonded14> nonbonded14s = univ.nonbonded14s.GetEnumerable();

                if (options.Contains("TIP3P: tetrahedral hydrogen bonds"))
                {
                    nonbondeds = EnumNonbondeds(univ.atoms, coords, univ.size, nbondMaxDist, ListTip3pTetraHBond, options);
                }
                else if (options.Contains("TIP3P: near waters"))
                {
                    nonbondeds = EnumNonbondeds(univ.atoms, coords, univ.size, nbondMaxDist, ListTip3pNears, options);
                }
                else
                {
                    nonbondeds = EnumNonbondeds(univ.atoms, coords, univ.size, nbondMaxDist);
                }

                bool   vdW       = true;                    // use vdW
                bool   elec      = false;                   // ignore electrostatic
                double D         = double.PositiveInfinity; // dielectric constant for Tinker is "1"
                bool   ignNegSpr = true;                    // ignore negative spring (do not add the spring into hessian matrix)

                double?K_r     = null;                      // null for sbNMA, and 340.00  for ssNMA
                double?K_theta = null;                      // null for sbNMA, and 45.00   for ssNMA
                double?K_ub    = null;                      // null for sbNMA, and 10.00   for ssNMA
                double?K_psi   = null;                      // null for sbNMA, and 70.00   for ssNMA
                double?K_chi   = null;                      // null for sbNMA, and 1.00    for ssNMA
                double?n       = null;                      // null for sbNMA, and 1       for ssNMA
                string K_nbnd  = null;                      // null for sbNMA, and "Unif"  for ssNMA

                if (options.Contains("TIP3P: (vdW+elec) for OH,OO,HH"))
                {
                    K_nbnd = "TIP3P: (vdW+elec) for OH,OO,HH";
                }
                if (options.Contains("TIP3P: (vdW+elec) for OH"))
                {
                    K_nbnd = "TIP3P: (vdW+elec) for OH";
                }
                if (options.Contains("vdW:L79"))
                {
                    K_nbnd = "L79";
                }
                if (options.Contains("vdW:UnifSgn"))
                {
                    K_nbnd = "UnifSgn";
                }
                if (options.Contains("K_chi:1"))
                {
                    K_chi = 1;
                }

                HessMatrix hess = null;

                if (b_bonds)
                {
                    hess = STeM.GetHessBond(coords, univ.bonds, K_r: K_r, hessian: hess, collector: collectorBond);
                }
                if (b_angles)
                {
                    hess = STeM.GetHessAngle(coords, univ.angles, true, K_theta: K_theta, K_ub: K_ub, hessian: hess, collector: collectorAngle);
                }
                if (b_impropers)
                {
                    hess = STeM.GetHessImproper(coords, univ.impropers, K_psi: K_psi, hessian: hess, useArnaud96: true, collector: collectorImproper);
                }
                if (b_dihedrals)
                {
                    hess = STeM.GetHessDihedral(coords, univ.dihedrals, K_chi: K_chi, n: n, hessian: hess, useAbsSpr: true, useArnaud96: true, collector: collectorDihedral);
                }
                if (b_nonbondeds)
                {
                    hess = HessSpr.GetHessNonbond(coords, nonbondeds, D, K_nbnd: K_nbnd, hessian: hess, vdW: vdW, elec: elec, ignNegSpr: ignNegSpr, maxAbsSpring: maxAbsSpring, collector: collectorNonbonded, GetCustomKij: GetCustomKij);
                }
                if (b_nonbonded14s)
                {
                    hess = HessSpr.GetHessNonbond(coords, nonbonded14s, D, K_nbnd: K_nbnd, hessian: hess, vdW: vdW, elec: elec, ignNegSpr: ignNegSpr, maxAbsSpring: maxAbsSpring, collector: collectorNonbonded14, GetCustomKij: GetCustomKij);
                }

                if (sca_bonds != null)
                {
                    if (sca_bonds.Value != 1)
                    {
                        hess += (sca_bonds.Value - 1) * STeM.GetHessBond(coords, univ.bonds, K_r: K_r, hessian: null);
                    }
                }
                if (sca_angles != null)
                {
                    if (sca_angles.Value != 1)
                    {
                        hess += (sca_angles.Value - 1) * STeM.GetHessAngle(coords, univ.angles, true, K_theta: K_theta, K_ub: K_ub, hessian: null);
                    }
                }
                if (sca_impropers != null)
                {
                    if (sca_impropers.Value != 1)
                    {
                        hess += (sca_impropers.Value - 1) * STeM.GetHessImproper(coords, univ.impropers, K_psi: K_psi, hessian: null, useArnaud96: true);
                    }
                }
                if (sca_dihedrals != null)
                {
                    if (sca_dihedrals.Value != 1)
                    {
                        hess += (sca_dihedrals.Value - 1) * STeM.GetHessDihedral(coords, univ.dihedrals, K_chi: K_chi, n: n, hessian: null, useAbsSpr: true, useArnaud96: true);
                    }
                }
                if (sca_nonbondeds != null)
                {
                    if (sca_nonbondeds.Value != 1)
                    {
                        hess += (sca_nonbondeds.Value - 1) * HessSpr.GetHessNonbond(coords, nonbondeds, D, K_nbnd: K_nbnd, hessian: null, vdW: vdW, elec: elec, ignNegSpr: ignNegSpr, maxAbsSpring: maxAbsSpring);
                    }
                }
                if (sca_nonbonded14s != null)
                {
                    if (sca_nonbonded14s.Value != 1)
                    {
                        hess += (sca_nonbonded14s.Value - 1) * HessSpr.GetHessNonbond(coords, nonbonded14s, D, K_nbnd: K_nbnd, hessian: null, vdW: vdW, elec: elec, ignNegSpr: ignNegSpr, maxAbsSpring: maxAbsSpring);
                    }
                }

                //Hess.UpdateHessNaN(hess, coords);
                {
                    foreach (var bc_br_bval in hess.EnumBlocks())
                    {
                        int bc   = bc_br_bval.Item1;
                        int br   = bc_br_bval.Item2;
                        var bval = bc_br_bval.Item3;

                        if (coords[bc] == null)
                        {
                            throw new HException("have hess block for null-coord");
                        }
                        if (coords[br] == null)
                        {
                            throw new HException("have hess block for null-coord");
                        }
                        if (bval == null)
                        {
                            throw new HException();
                        }
                        for (int c = 0; c < bval.ColSize; c++)
                        {
                            for (int r = 0; r < bval.RowSize; r++)
                            {
                                double val = bval[c, r];
                                if (double.IsNaN(val))
                                {
                                    throw new HException("hess has nan element");
                                }
                                if (double.IsPositiveInfinity(val))
                                {
                                    throw new HException("hess has pos-inf element");
                                }
                                if (double.IsNegativeInfinity(val))
                                {
                                    throw new HException("hess has neg-inf element");
                                }
                            }
                        }
                    }
                }

                return(new HessInfo
                {
                    hess = hess,
                    mass = univ.GetMasses(),
                    atoms = univ.atoms.ToArray(),
                    coords = coords.HCloneVectors().ToArray(),
                    numZeroEigval = 6,
                });
            }
Exemplo n.º 10
0
            public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_Matlab_experimental
                (object[] atoms
                , HessMatrix H
                , List <int>[] lstNewIdxRemv
                , double thres_zeroblk
                , ILinAlg ila
                , bool cloneH
                , string[] options
                )
            {
                ila = null;
                if (cloneH)
                {
                    H = H.CloneHess();
                }

                bool process_disp_console = true;

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

                bool parallel = true;

                GC.Collect(0);

                DateTime[] process_time = new DateTime[6];

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

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

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

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

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

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

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


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

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

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


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

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

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

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

                    GC.Collect(0);
                }

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

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

                return(new CGetHessCoarseResiIterImpl
                {
                    iterinfos = iterinfos,
                    H = H,
                });
            }
Exemplo n.º 11
0
        public int UpdateAdd(HessMatrix other, double mul_other, IList <int> idxOther, double thres_NearZeroBlock, bool parallel = false)
        {
            Matrix debug_updateadd = null;

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

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

            int count         = 0;
            int count_ignored = 0;

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

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

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

            return(count_ignored);
        }
Exemplo n.º 12
0
        public static double GetSprScalar(Vector[] coords, HessMatrix hess, int atm1, int atm2, IList <int> atms, ILinAlg ila)
        {
            HDebug.Assert(atms.Count == atms.HUnion().Length);

            int[] idxs = atms.HUnion();
            idxs = idxs.HRemoveAll(atm1);
            idxs = idxs.HRemoveAll(atm2);
            idxs = idxs.HInsert(0, atm2);
            idxs = idxs.HInsert(0, atm1);
            HDebug.Assert(idxs.HExcept(atms).HExcept(atm1, atm2).Length == 0);
            HDebug.Assert(idxs[0] == atm1);
            HDebug.Assert(idxs[1] == atm2);

            HessMatrix H = hess.ReshapeByAtom(idxs);

            H = Hess.GetHessFixDiag(H);
            HDebug.Assert(H.ColSize == H.RowSize, H.RowSize == idxs.Length * 3);
            // H should have 6 zero eigenvalues !!
            // since it is the original hessian matrix.

            // return "0" spring if there is no connect between atm1 and atm2
            {
                Graph <int, object> g = new Graph <int, object>();
                for (int i = 0; i < H.ColBlockSize; i++)
                {
                    g.AddNode(i);
                }
                foreach (var bc_br_bval in H.EnumBlocks())
                {
                    int bc = bc_br_bval.Item1;
                    int br = bc_br_bval.Item2;
                    if (bc > br)
                    {
                        continue;
                    }
                    g.AddEdge(bc, br, new object());
                    //g.AddEdge(br, bc, new object()); // g is bi-directional graph
                }
                var paths = g.FindPathShortest(g.GetNode(0), new Graph <int, object> .Node[] { g.GetNode(1) });
                if (paths == null)
                {
                    // if there is no path between 0 <-> 1, then there is no spring
                    return(0);
                }
            }

            Vector u12 = (coords[atm2] - coords[atm1]).UnitVector();
            Matrix S12 = new double[idxs.Length * 3, 1];

            S12[0, 0] = u12[0];    S12[1, 0] = u12[1];    S12[2, 0] = u12[2];
            S12[3, 0] = -u12[0];    S12[4, 0] = -u12[1];    S12[5, 0] = -u12[2];

            Matrix invkij = GetInvSprTensorSymm(H, S12, ila);

            HDebug.Assert(invkij.ColSize == 1, invkij.RowSize == 1);
            HDebug.Assert(invkij[0, 0] > 0);

            double kij = 1 / invkij[0, 0];

            return(kij);
        }
            private static ValueTuple <HessMatrix, Vector> Get_BInvDC_BInvDG_WithSqueeze
                (HessMatrix C
                , HessMatrix D
                , Vector G
                , bool process_disp_console
                , string[] options
                , double?thld_BinvDC    // =null
                , bool parallel         // =false
                )
            {
                if (options == null)
                {
                    options = new string[0];
                }

                HessMatrix            B_invD_C;
                Vector                B_invD_G;
                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 = C.Zeros(C.ColSize, Cbr_CCbr.Count * 3);

                {
                    Action <ValueTuple <int, int, MatrixByArr>, HessMatrix, Dictionary <int, int> > func =
                        delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval, HessMatrix _CC, Dictionary <int, int> _Cbr_CCbr)
                    {
                        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)
                    {
                        HParallel.ForEach(C.EnumBlocks(), func, CC, Cbr_CCbr);
                    }
                    else
                    {
                        foreach (var bc_br_bval in C.EnumBlocks())
                        {
                            func(bc_br_bval, CC, Cbr_CCbr);
                        }
                    }
                }
                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;
                    Vector     BB_invDD_GG;
                    {
                        var BBInvDDCC_BBInvDDGG = Get_BInvDC_BInvDG(CC, D, G, process_disp_console, options, thld_BinvDC, parallel);
                        BB_invDD_CC = BBInvDDCC_BBInvDDGG.Item1;
                        BB_invDD_GG = BBInvDDCC_BBInvDDGG.Item2;
                    }

                    B_invD_C = C.Zeros(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>, HessMatrix, List <int> > func =
                            delegate(ValueTuple <int, int, MatrixByArr> bcc_brr_bval, HessMatrix _B_invD_C, List <int> _CCbr_Cbr)
                        {
                            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.SetBlockLock(bc, br, bval);
                        };

                        if (parallel)
                        {
                            HParallel.ForEach(BB_invDD_CC.EnumBlocks(), func, B_invD_C, CCbr_Cbr);
                        }
                        else
                        {
                            foreach (var bcc_brr_bval in BB_invDD_CC.EnumBlocks())
                            {
                                func(bcc_brr_bval, B_invD_C, CCbr_Cbr);
                            }
                        }
                    }
                    B_invD_G = new double[C.RowSize];
                    {
                        HDebug.Assert(BB_invDD_GG.Size % 3 == 0);
                        /////////////////////////////////////////////////////////////////////////////////////
                        // Double Check Later
                        if (CCbr_Cbr.Count == 0)
                        {
                            // this is the case that a molecule is isolated.
                            //HDebug.Assert(B_invD_C.NumUsedBlocks == 0);
                            //HDebug.Assert(B_invD_G.Dist2 == 0);
                        }

                        for (int bii = 0; bii < CCbr_Cbr.Count; bii++)
                        //for(int bii=0; bii<BB_invDD_GG.Size/3; bii++)
                        /////////////////////////////////////////////////////////////////////////////////////
                        {
                            int bi = CCbr_Cbr[bii];
                            B_invD_G[bi * 3 + 0] = BB_invDD_GG[bii * 3 + 0];
                            B_invD_G[bi * 3 + 1] = BB_invDD_GG[bii * 3 + 1];
                            B_invD_G[bi * 3 + 2] = BB_invDD_GG[bii * 3 + 2];
                        }
                    }
                }
                GC.Collect(0);
                return(new ValueTuple <HessMatrix, Vector>
                           (B_invD_C
                           , B_invD_G
                           ));
            }