Пример #1
0
            public static double Corr(Vector bfactor1, Vector bfactor2, bool ignore_nan = false)
            {
                double hcorr = HMath.HCorr(bfactor1, bfactor2, ignore_nan);

                if (HDebug.IsDebuggerAttached)
                {
                    double corr = double.NaN;
                    using (new Matlab.NamedLock("CORR"))
                    {
                        Matlab.Clear("CORR");
                        Matlab.PutVector("CORR.bfactor1", bfactor1);
                        Matlab.PutVector("CORR.bfactor2", bfactor2);
                        if (ignore_nan)
                        {
                            Matlab.Execute("CORR.idxnan = isnan(CORR.bfactor1) | isnan(CORR.bfactor2);");
                            Matlab.Execute("CORR.bfactor1 = CORR.bfactor1(~CORR.idxnan);");
                            Matlab.Execute("CORR.bfactor2 = CORR.bfactor2(~CORR.idxnan);");
                        }
                        if (Matlab.GetValueInt("min(size(CORR.bfactor1))") != 0)
                        {
                            corr = Matlab.GetValue("corr(CORR.bfactor1, CORR.bfactor2)");
                        }
                        Matlab.Clear("CORR");
                    }
                    if ((double.IsNaN(hcorr) && double.IsNaN(corr)) == false)
                    {
                        HDebug.AssertTolerance(0.00000001, hcorr - corr);
                    }
                    //HDebug.ToDo("use HMath.HCorr(...) instead");
                }
                return(hcorr);
            }
            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);
            }
Пример #3
0
            public static CGetHessCoarseResiIterImpl GetHessCoarseResiIterImpl_Matlab(HessMatrix H, List <int>[] lstNewIdxRemv, double thres_zeroblk)
            {
                HessMatrix CGH = null;
                List <HessCoarseResiIterInfo> iterinfos = new List <HessCoarseResiIterInfo>();

                using (new Matlab.NamedLock("CGHessIter"))
                {
                    Matlab.PutSparseMatrix("CG.H", H.GetMatrixSparse(), 3, 3);
                    Matlab.PutValue("CG.th", thres_zeroblk);
                    Matlab.PutValue("CG.iter", lstNewIdxRemv.Length);
                    for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--)
                    {
                        int[] iremv   = lstNewIdxRemv[iter].ToArray();
                        int[] idxkeep = HEnum.HEnumFromTo(0, iremv.Min() - 1).ToArray();
                        int[] idxremv = HEnum.HEnumFromTo(iremv.Min(), iremv.Max()).ToArray();
                        Matlab.PutVector("CG.idxkeep", idxkeep);
                        Matlab.PutVector("CG.idxremv", idxremv);
                        Matlab.Execute("CG.idxkeep = sort([CG.idxkeep*3+1; CG.idxkeep*3+2; CG.idxkeep*3+3]);");
                        Matlab.Execute("CG.idxremv = sort([CG.idxremv*3+1; CG.idxremv*3+2; CG.idxremv*3+3]);");

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

                        if (HDebug.IsDebuggerAttached)
                        {
                            int maxkeep = Matlab.GetValueInt("max(CG.idxkeep)");
                            int minremv = Matlab.GetValueInt("min(CG.idxremv)");
                            HDebug.Assert(maxkeep + 1 == minremv);
                            int maxremv = Matlab.GetValueInt("max(CG.idxremv)");
                            int Hsize   = Matlab.GetValueInt("max(size(CG.H))");
                            HDebug.Assert(Hsize == maxremv);
                            int idxsize = Matlab.GetValueInt("length(union(CG.idxkeep,CG.idxremv))");
                            HDebug.Assert(Hsize == idxsize);
                        }
                        Matlab.Execute("CG.A = CG.H(CG.idxkeep, CG.idxkeep);");
                        Matlab.Execute("CG.B = CG.H(CG.idxkeep, CG.idxremv);");
                        //Matlab.Execute("CG.C = CG.H(CG.idxremv, CG.idxkeep);");
                        Matlab.Execute("CG.D = CG.H(CG.idxremv, CG.idxremv);");
                        HDebug.Assert(false);
                        Matlab.Execute("CG.B(abs(CG.B) < CG.th) = 0;");     /// matlab cannot handle this call. Matlab try to use 20G memory.
                        Matlab.Execute("CG.BDC = CG.B * inv(full(CG.D)) * CG.B';");
                        Matlab.Execute("CG.BDC = sparse(CG.BDC);");
                        Matlab.Execute("CG.BDC(abs(CG.BDC) < (CG.th / CG.iter)) = 0;");
                        Matlab.Execute("CG.H = CG.A - sparse(CG.BDC);");

                        iterinfo.numSetZeroBlock = -1;
                        iterinfo.numNonZeroBlock = -1;
                        iterinfo.numAddIgnrBlock = -1;
                        iterinfo.usedMemoryByte  = -1;
                        iterinfo.time1           = DateTime.UtcNow;
                        iterinfos.Add(iterinfo);

                        System.Console.WriteLine(" - {0:000} : makezero {1,5}, nonzero {2,5}, numIgnMul {3,7}, numRemvAtoms {4,3}, {5,5:0.00} sec, {6} mb, {7}x{7}"
                                                 , iter
                                                 , iterinfo.numSetZeroBlock
                                                 , iterinfo.numNonZeroBlock
                                                 , iterinfo.numAddIgnrBlock
                                                 , iterinfo.numAtomsRemoved
                                                 , iterinfo.compSec
                                                 , iterinfo.usedMemoryByte / (1024 * 1024)
                                                 , (idxkeep.Length * 3)
                                                 );
                    }
                    Matrix CG_H = Matlab.GetMatrix("CG.H");
                    CGH = new HessMatrixDense {
                        hess = CG_H
                    };
                }

                return(new CGetHessCoarseResiIterImpl
                {
                    iterinfos = iterinfos,
                    H = CGH,
                });
            }
Пример #4
0
        public static HessMatrixDense GetHessCoarseBlkmat(HessMatrix hess, IList <int> idx_heavy, string invopt = "inv")
        {
            /// Hess = [ HH HL ] = [ A B ]
            ///        [ LH LL ]   [ C D ]
            ///
            /// Hess_HH = HH - HL * LL^-1 * LH
            ///         = A  - B  *  D^-1 * C

            Matrix hess_HH;

            using (new Matlab.NamedLock(""))
            {
                Matlab.Clear();
                if (hess is HessMatrixSparse)
                {
                    Matlab.PutSparseMatrix("H", hess.GetMatrixSparse(), 3, 3);
                }
                else
                {
                    Matlab.PutMatrix("H", hess, true);
                }

                Matlab.Execute("H = (H + H')/2;");

                int[] idx0 = new int[idx_heavy.Count * 3];
                for (int i = 0; i < idx_heavy.Count; i++)
                {
                    idx0[i * 3 + 0] = idx_heavy[i] * 3 + 0;
                    idx0[i * 3 + 1] = idx_heavy[i] * 3 + 1;
                    idx0[i * 3 + 2] = idx_heavy[i] * 3 + 2;
                }
                Matlab.PutVector("idx0", idx0);
                Matlab.Execute("idx0 = idx0+1;");
                Matlab.PutValue("idx1", hess.ColSize);
                Matlab.Execute("idx1 = setdiff(1:idx1, idx0)';");
                HDebug.Assert(Matlab.GetValueInt("length(union(idx0,idx1))") == hess.ColSize);

                Matlab.Execute("A = full(H(idx0,idx0));");
                Matlab.Execute("B =      H(idx0,idx1) ;");
                Matlab.Execute("C =      H(idx1,idx0) ;");
                Matlab.Execute("D = full(H(idx1,idx1));");
                Matlab.Execute("clear H;");

                object linvopt = null;
                switch (invopt)
                {
                case  "B/D":
                    Matlab.Execute("bhess = A -(B / D)* C;");
                    break;

                case  "inv":
                    Matlab.Execute("D =  inv(D);");
                    Matlab.Execute("bhess = A - B * D * C;");
                    break;

                case "pinv":
                    Matlab.Execute("D = pinv(D);");
                    Matlab.Execute("bhess = A - B * D * C;");
                    break;

                case "_eig":
                    bool bCheckInv = false;
                    if (bCheckInv)
                    {
                        Matlab.Execute("Dbak = D;");
                    }
                    Matlab.Execute("[D,DD] = eig(D);");
                    if (HDebug.False)
                    {
                        Matlab.Execute("DD(abs(DD)<" + linvopt + ") = 0;");
                        Matlab.Execute("DD = pinv(DD);");
                    }
                    else
                    {
                        Matlab.Execute("DD = diag(DD);");
                        Matlab.Execute("DDidx = abs(DD)<" + linvopt + ";");
                        Matlab.Execute("DD = 1./DD;");
                        Matlab.Execute("DD(DDidx) = 0;");
                        Matlab.Execute("DD = diag(DD);");
                        Matlab.Execute("clear DDidx;");
                    }
                    Matlab.Execute("D = D * DD * D';");
                    if (bCheckInv)
                    {
                        double err0 = Matlab.GetValue("max(max(abs(eye(size(D)) - Dbak * D)))");
                    }
                    if (bCheckInv)
                    {
                        double err1 = Matlab.GetValue("max(max(abs(eye(size(D)) - D * Dbak)))");
                    }
                    if (bCheckInv)
                    {
                        Matlab.Execute("clear Dbak;");
                    }
                    Matlab.Execute("clear DD;");
                    Matlab.Execute("bhess = A - B * D * C;");
                    break;

                default:
                {
                    if (invopt.StartsWith("eig(threshold:") && invopt.EndsWith(")"))
                    {
                        // ex: "eig(threshold:0.000000001)"
                        linvopt = invopt.Replace("eig(threshold:", "").Replace(")", "");
                        linvopt = double.Parse(linvopt as string);
                        goto case "_eig";
                    }
                }
                    throw new HException();
                }

                Matlab.Execute("clear A; clear B; clear C; clear D;");
                Matlab.Execute("bhess = (bhess + bhess')/2;");
                hess_HH = Matlab.GetMatrix("bhess", Matrix.Zeros, true);

                Matlab.Clear();
            }
            return(new HessMatrixDense {
                hess = hess_HH
            });
        }