Beispiel #1
0
            //internal RaiseRule<Expr> haltRule;
            public VarInfo(STBuilderZ3 stb, Symtab stab, iterexpr ie, Sort charsort)
            {
                this.stab     = stab;
                this.charsort = charsort;
                this.stb      = stb;
                this.binder   = ie.binder;
                binderid      = stab.Get(ie.binder).id;
                bekVarIds     = new List <int>();
                bekVarVals    = new List <Expr>();
                bekVarSorts   = new List <Sort>();

                proj = new Dictionary <int, int>();

                int regPosNr = 0;

                foreach (iterassgn ia in IterInfo.Initializers(ie, stab))
                {
                    proj[stab.Get(ia.lhs).id] = regPosNr;
                    bekVarIds.Add(stab.Get(ia.lhs).id);
                    bekVarVals.Add(MkExpr(stab.Get(ia.lhs).type, ia.rhs));
                    bekVarSorts.Add(BekTypeToSort(stab.Get(ia.lhs).type));
                    regPosNr += 1;
                }

                K = bekVarSorts.Count;

                //register sort
                regSort = (K == 0 ? stb.Solver.UnitSort : (K == 1 ? bekVarSorts[0] : stb.Solver.MkTupleSort(bekVarSorts.ToArray())));

                //initial register value
                initReg = (K == 0 ? stb.Solver.UnitConst : (K == 1 ? bekVarVals[0] : stb.Solver.MkTuple(bekVarVals.ToArray())));

                //input character variable
                c = this.stb.MkInputVariable(charsort);

                //register variable
                r = this.stb.MkRegister(regSort);

                //maps variable identifiers used in the bek program to corresponding term variables
                varMap           = new Dictionary <int, Expr>();
                varMap[binderid] = c;                              //input character variable

                for (int i = 0; i < K; i++)                        //bek pgm variables
                {
                    varMap[bekVarIds[i]] = (K == 1 ? r : stb.Solver.MkProj(i, r));
                }

                //haltRule = new RaiseRule<Expr>();
            }
            public static HessForcInfo GetCoarseHessForcSubSimple
                (object[] atoms
                , HessMatrix hess
                , Vector[]   forc
                , List <int>[] lstNewIdxRemv
                , double thres_zeroblk
                , ILinAlg ila
                , bool cloneH
                , string[] options // { "pinv(D)" }
                )
            {
                HessMatrix H = hess;
                Vector     F = forc.ToVector();

                if (cloneH)
                {
                    H = H.CloneHess();
                }

                bool process_disp_console = false;
                bool parallel             = true;

                for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; 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);

                    IterInfo iterinfo = new IterInfo();
                    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.SubMatrixByAtoms(false, idxkeep, idxkeep);
                    HessMatrix B = H.SubMatrixByAtoms(false, idxkeep, idxremv);
                    HessMatrix C = H.SubMatrixByAtoms(false, idxremv, idxkeep);
                    HessMatrix D = H.SubMatrixByAtoms(false, idxremv, idxremv);
                    Vector     nF;
                    Vector     nG;
                    {
                        nF = new double[idxkeep.Length * 3];
                        nG = new double[idxremv.Length * 3];
                        for (int i = 0; i < idxkeep.Length * 3; i++)
                        {
                            nF[i] = F[i];
                        }
                        for (int i = 0; i < idxremv.Length * 3; i++)
                        {
                            nG[i] = F[i + nF.Size];
                        }
                    }

                    Matlab.PutMatrix("A", A, true);
                    Matlab.PutMatrix("B", B, true);
                    Matlab.PutMatrix("C", C, true);
                    Matlab.PutMatrix("D", D, true);
                    Matlab.PutVector("F", nF);
                    Matlab.PutVector("G", nG);

                    ////////////////////////////////////////////////////////////////////////////////////////
                    // Get B.inv(D).C
                    //
                    // var BInvDC_BInvDG = Get_BInvDC_BInvDG_WithSqueeze(C, D, nG, process_disp_console
                    //     , options
                    //     , thld_BinvDC: thres_zeroblk/lstNewIdxRemv.Length
                    //     , parallel: parallel
                    //     );
                    // HessMatrix B_invD_C = BInvDC_BInvDG.Item1;
                    // Vector     B_invD_G = BInvDC_BInvDG.Item2;
                    // GC.Collect(0);
                    Matlab.Execute("BinvD = B * inv(D);");
                    Matlab.Execute("clear B, D;");
                    Matlab.Execute("BinvDC = BinvD * C;");
                    Matlab.Execute("BinvDG = BinvD * G;");

                    ////////////////////////////////////////////////////////////////////////////////////////
                    // Get A - B.inv(D).C
                    //     F - B.inv(D).G
                    Matlab.Execute("HH = A - BinvDC;");
                    Matlab.Execute("FF = F - BinvDG;");

                    ////////////////////////////////////////////////////////////////////////////////////////
                    // Replace A -> H
                    H = Matlab.GetMatrix("HH", H.Zeros, true);
                    F = Matlab.GetVector("FF");
                    Matlab.Execute("clear;");

                    {
                        ValueTuple <HessMatrix, Vector> BBInvDDCC_BBInvDDGG = Get_BInvDC_BInvDG_Simple
                                                                                  (C
                                                                                  , D
                                                                                  , nG
                                                                                  , process_disp_console: process_disp_console
                                                                                  , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length
                                                                                  , parallel: parallel
                                                                                  );
                        HessMatrix HH     = A - BBInvDDCC_BBInvDDGG.Item1;
                        Vector     FF     = nF - BBInvDDCC_BBInvDDGG.Item2;
                        double     dbg_HH = (HH - H).HAbsMax();
                        double     dbg_FF = (FF - F).ToArray().MaxAbs();
                        HDebug.Assert(Math.Abs(dbg_HH) < 0.00000001);
                        HDebug.Assert(Math.Abs(dbg_FF) < 0.00000001);
                    }
                    {
                        ValueTuple <HessMatrix, Vector> BBInvDDCC_BBInvDDGG = Get_BInvDC_BInvDG
                                                                                  (C
                                                                                  , D
                                                                                  , nG
                                                                                  , process_disp_console: process_disp_console
                                                                                  , options: new string[0]
                                                                                  , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length
                                                                                  , parallel: parallel
                                                                                  );
                        HessMatrix HH     = A - BBInvDDCC_BBInvDDGG.Item1;
                        Vector     FF     = nF - BBInvDDCC_BBInvDDGG.Item2;
                        double     dbg_HH = (HH - H).HAbsMax();
                        double     dbg_FF = (FF - F).ToArray().MaxAbs();
                        HDebug.Assert(Math.Abs(dbg_HH) < 0.00000001);
                        HDebug.Assert(Math.Abs(dbg_FF) < 0.00000001);
                    }
                    {
                        ValueTuple <HessMatrix, Vector> BBInvDDCC_BBInvDDGG = Get_BInvDC_BInvDG_WithSqueeze
                                                                                  (C
                                                                                  , D
                                                                                  , nG
                                                                                  , process_disp_console: process_disp_console
                                                                                  , options: new string[0]
                                                                                  , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length
                                                                                  , parallel: parallel
                                                                                  );
                        HessMatrix HH     = A - BBInvDDCC_BBInvDDGG.Item1;
                        Vector     FF     = nF - BBInvDDCC_BBInvDDGG.Item2;
                        double     dbg_HH = (HH - H).HAbsMax();
                        double     dbg_FF = (FF - F).ToArray().MaxAbs();
                        HDebug.Assert(Math.Abs(dbg_HH) < 0.00000001);
                        HDebug.Assert(Math.Abs(dbg_FF) < 0.00000001);
                    }

                    GC.Collect();
                }

                HDebug.Assert(H.ColSize == H.RowSize);
                HDebug.Assert(H.ColSize == F.Size);
                return(new HessForcInfo
                {
                    hess = H,
                    forc = F.ToVectors(3),
                });
            }
Beispiel #3
0
            //public class CGetHessCoarseResiIterImpl
            //{
            //    public List<IterInfo> iterinfos = null;
            //    public HessMatrix H = null;
            //    public Vector     F = null;
            //};
            public static HessForcInfo GetCoarseHessForcSubIter
                (object[] atoms
                , HessMatrix hess
                , Vector[]   forc
                , List <int>[] lstNewIdxRemv
                , double thres_zeroblk
                , ILinAlg ila
                , bool cloneH
                , string[] options // { "pinv(D)" }
                )
            {
                HessMatrix H = hess;
                Vector     F = forc.ToVector();

                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 <IterInfo> iterinfos = new List <IterInfo>();

                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);

                    IterInfo iterinfo = new IterInfo();
                    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);
                    Vector     nF;
                    Vector     nG;
                    {
                        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;
                            if (bc < br)
                            {
                                HDebug.Assert(false);
                                continue;
                            }

                            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);

                        nF = new double[idxkeep.Length * 3];
                        nG = new double[idxremv.Length * 3];
                        for (int i = 0; i < idxkeep.Length * 3; i++)
                        {
                            nF[i] = F[i];
                        }
                        for (int i = 0; i < idxremv.Length * 3; i++)
                        {
                            nG[i] = F[i + nF.Size];
                        }
                    }
                    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;
                    Vector     B_invD_G;
                    {
                        {
                            var BInvDC_BInvDG = Get_BInvDC_BInvDG_WithSqueeze(C, D, nG, process_disp_console
                                                                              , options
                                                                              , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length
                                                                              , parallel: parallel
                                                                              );
                            B_invD_C = BInvDC_BInvDG.Item1;
                            B_invD_G = BInvDC_BInvDG.Item2;
                        }
                        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>, object> func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval, object func_param)
                        {
                            _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)
                            {
                                //if(HDebug.IsDebuggerAttached)
                                //{
                                //    double trace = other_bmat.Trace();
                                //    if(bc != br && bc<2059 && br<2059 && Math.Abs(trace) > 100)
                                //        HDebug.Assert();
                                //}

                                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, null);
                        }
                        else
                        {
                            foreach (var bc_br_bval in other.EnumBlocks())
                            {
                                func(bc_br_bval, null);
                            }
                        }

                        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;
                    F = nF - B_invD_G;

                    ////////////////////////////////////////////////////////////////////////////////////////
                    // 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);
                }
                {
                    var list_bc_br_bval = H.EnumBlocks().ToArray();

                    Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval)
                    {
                        int bc   = bc_br_bval.Item1;
                        int br   = bc_br_bval.Item2;
                        var bval = bc_br_bval.Item3;
                        HDebug.Assert(bc >= br);
                        if (bc == br)
                        {
                            return;
                        }
                        MatrixByArr bval_tr = bval.Tr();
                        H.SetBlockLock(br, bc, bval_tr);
                        HDebug.Assert(H.GetBlockLock(bc, br) == bval);
                    };
                    if (parallel)
                    {
                        HParallel.ForEach(list_bc_br_bval, func);
                    }
                    else
                    {
                        foreach (var bc_br_bval in list_bc_br_bval)
                        {
                            func(bc_br_bval);
                        }
                    }
                }
                GC.Collect();
                //System.Console.WriteLine("finish resizing");

                HDebug.Assert(H.ColSize == H.RowSize);
                HDebug.Assert(H.ColSize == F.Size);
                return(new HessForcInfoIter
                {
                    iterinfos = iterinfos,
                    hess = H,
                    forc = F.ToVectors(3),
                });
            }
Beispiel #4
0
        public override STModel Convert(iterexpr ie, Symtab stab)
        {
            var solver   = stb.Solver;
            int binderid = stab.Get(ie.binder).id;

            List <int>            bekVarIds   = new List <int>();
            List <Expr>           bekVarVals  = new List <Expr>();
            List <Sort>           bekVarSorts = new List <Sort>();
            Dictionary <int, int> proj        = new Dictionary <int, int>();

            foreach (iterassgn ia in IterInfo.Initializers(ie, stab))
            {
                proj[stab.Get(ia.lhs).id] = bekVarIds.Count;
                bekVarIds.Add(stab.Get(ia.lhs).id);
                bekVarVals.Add(MkExpr(stab.Get(ia.lhs).type, ia.rhs));
                bekVarSorts.Add(BekTypeToSort(stab.Get(ia.lhs).type));
            }

            int K = bekVarSorts.Count;

            //register sort
            Sort regSort = (K == 0 ? solver.UnitSort :
                            (K == 1 ? bekVarSorts[0] : solver.MkTupleSort(bekVarSorts.ToArray())));

            //initial register value
            Expr initReg = (K == 0 ? solver.UnitConst :
                            (K == 1 ? bekVarVals[0] : solver.MkTuple(bekVarVals.ToArray())));

            //input character variable
            Expr c = this.stb.MkInputVariable(charsort);

            //register variable
            Expr r = this.stb.MkRegister(regSort);

            //maps variable identifiers used in the bek program to corresponding term variables
            Dictionary <int, Expr> varMap = new Dictionary <int, Expr>();

            varMap[binderid] = c;
            for (int i = 0; i < K; i++)
            {
                varMap[bekVarIds[i]] = (K == 1 ? r : solver.MkProj(i, r));
            }

            List <Move <Rulez3> > moves = new List <Move <Rulez3> >();

            Expr previousCaseNegated = solver.True;

            foreach (itercase curcase in ie.GetNormalCases())
            {
                if (!solver.IsSatisfiable(previousCaseNegated))
                {
                    break;
                }

                //initial symbolic values are the previous register values
                Expr[] regs0 = new Expr[K];
                for (int i = 0; i < K; i++)
                {
                    regs0[i] = varMap[bekVarIds[i]];
                }

                Expr[] regs = new Expr[K];
                for (int i = 0; i < K; i++)
                {
                    regs[i] = regs0[i];
                }


                //gets the current symbolic value of ident
                Func <ident, Expr> idents = x =>
                {
                    SymtabElt se = stab.Get(x);
                    if (se.id == binderid)
                    {
                        return(c);              //the input character
                    }
                    return(regs0[proj[se.id]]); //the current sybolic value of x
                };

                //current condition is the case condition and not the previous case conditions
                Expr casecond     = this.expr_handler.Convert(curcase.cond, idents);
                Expr guard        = stb.And(previousCaseNegated, casecond);
                Expr not_casecond = stb.Not(casecond);
                previousCaseNegated = stb.And(previousCaseNegated, solver.MkNot(casecond));
                List <Expr> yields = new List <Expr>();
                if (solver.IsSatisfiable(guard))
                {
                    #region iterate over the iter statements in the body
                    foreach (iterstmt ist in curcase.body)
                    {
                        //gets the current symbolic value of ident
                        //note that the symbolic value may have been updated by a previous assignment
                        Func <ident, Expr> idents1 = x =>
                        {
                            SymtabElt se = stab.Get(x);
                            if (se.id == binderid)
                            {
                                return(c);              //the input character
                            }
                            return(regs0[proj[se.id]]); //the current sybolic value of x
                        };

                        iterassgn a = ist as iterassgn;
                        if (a != null)
                        {
                            var v = expr_handler.Convert(a.rhs, idents1);
                            regs[proj[stab.Get(a.lhs).id]] = v;
                        }
                        else
                        {
                            yieldstmt y = ist as yieldstmt;
                            if (y != null)
                            {
                                foreach (var e in y.args)
                                {
                                    strconst s = e as strconst;
                                    if (s == null)
                                    {
                                        yields.Add(expr_handler.Convert(e, idents1));
                                    }
                                    else
                                    {
                                        foreach (int sc in s.content)
                                        {
                                            yields.Add(solver.MkNumeral(sc, charsort));
                                        }
                                    }
                                }
                            }
                            else
                            {
                                throw new BekException(); //TBD: undefined case
                            }
                        }
                    }
                    #endregion
                    Expr upd = (K == 0 ? solver.UnitConst : (K == 1 ? regs[0] : solver.MkTuple(regs)));
                    moves.Add(stb.MkRule(0, 0, guard, upd, yields.ToArray()));
                }
            }

            previousCaseNegated = solver.True;
            bool noEndCases = true;

            foreach (itercase curcase in ie.GetEndCases())
            {
                noEndCases = false;

                if (!solver.IsSatisfiable(previousCaseNegated))
                {
                    break;
                }

                //initial symbolic values are the previous register values
                Expr[] regs = new Expr[K];
                for (int i = 0; i < K; i++)
                {
                    regs[i] = varMap[bekVarIds[i]];
                }

                //gets the current symbolic value of ident
                Func <ident, Expr> idents = x =>
                {
                    SymtabElt se = stab.Get(x);
                    if (se.id == binderid)
                    {
                        throw new BekException("Input var must not occur in an end case");
                    }
                    return(regs[proj[se.id]]); //the current sybolic value of x
                };

                //current condition is the case condition and not the previous case conditions
                Expr casecond     = this.expr_handler.Convert(curcase.cond, idents);
                Expr guard        = stb.And(previousCaseNegated, casecond);
                Expr not_casecond = stb.Not(casecond);
                previousCaseNegated = stb.And(previousCaseNegated, solver.MkNot(casecond));
                List <Expr> yields = new List <Expr>();
                if (solver.IsSatisfiable(guard))
                {
                    #region iterate over the iter statements in the body
                    foreach (iterstmt ist in curcase.body)
                    {
                        //gets the current symbolic value of ident
                        //note that the symbolic value may have been updated by a previous assignment
                        Func <ident, Expr> idents1 = x =>
                        {
                            SymtabElt se = stab.Get(x);
                            if (se.id == binderid)
                            {
                                throw new BekException("Input var must not occur in an end case");
                            }
                            return(regs[proj[se.id]]); //the current sybolic value of x
                        };

                        iterassgn a = ist as iterassgn;
                        if (a != null)
                        {
                            var v = expr_handler.Convert(a.rhs, idents1);
                            regs[proj[stab.Get(a.lhs).id]] = v;
                        }
                        else
                        {
                            yieldstmt y = ist as yieldstmt;
                            if (y != null)
                            {
                                foreach (var e in y.args)
                                {
                                    strconst s = e as strconst;
                                    if (s == null)
                                    {
                                        yields.Add(expr_handler.Convert(e, idents1));
                                    }
                                    else
                                    {
                                        foreach (int sc in s.content)
                                        {
                                            yields.Add(solver.MkNumeral(sc, charsort));
                                        }
                                    }
                                }
                            }
                            else
                            {
                                throw new BekException(); //TBD: undefined case
                            }
                        }
                    }
                    #endregion
                    moves.Add(stb.MkFinalOutput(0, guard, yields.ToArray()));
                }
            }

            //if no end cases were given, assume default true end case with empty yield
            if (noEndCases)
            {
                moves.Add(stb.MkFinalOutput(0, solver.True));
            }

            STModel iterST = STModel.Create(solver, "iter", initReg, charsort, charsort, regSort, 0, moves);
            iterST.Simplify();
            return(iterST);
        }