Пример #1
0
        public List <State> SplitDiscreteAll(int dim)
        {
            List <State> result = new List <State>();

            var next = new FPIntegerInterval[discreteState.axes.Length];

            for (int i = 0; i < discreteState.axes.Length; ++i)
            {
                next[i] = discreteState.axes[i];
            }
            var bits     = discreteState.axes[dim].bits;
            var decimals = discreteState.axes[dim].decimals;
            int L        = discreteState.axes[dim].left;
            int R        = discreteState.axes[dim].right;

            for (int value = L; value <= R; ++value)
            {
                next[dim] = new FPIntegerInterval(value, value, bits, decimals);
                result.Add(new State(step, continuousNames, continuousState, discreteNames, new FPIntegerBoundingBox(next)));
            }
            return(result);
        }
Пример #2
0
        static public List <State> SplitDiscrete(List <State> states, int dim, int divs)
        {
            State[] result = new State[divs];

            foreach (State s in states)
            {
                List <DoubleInterval[]> sec = new List <DoubleInterval[]>(divs);
                var bits     = s.discreteState.axes[dim].bits;
                var decimals = s.discreteState.axes[dim].decimals;
                int dimL     = s.discreteState.axes[dim].left;
                int dimR     = s.discreteState.axes[dim].right;
                var next     = new FPIntegerInterval[s.discreteState.axes.Length];
                for (int i = 0; i < s.discreteState.axes.Length; ++i)
                {
                    next[i] = s.discreteState.axes[i];
                }
                int prevR = dimL;
                for (int j = 1; j < divs; ++j)
                {
                    int R = (dimR - dimL) * j / divs + dimL;
                    next[dim] = new FPIntegerInterval(prevR, R, bits, decimals);
                    // intermix the results for faster coverage
                    int index = (j % 2 == 1) ? (j / 2 + 1) : (divs - j / 2);
                    result[index] = new State(s.step, s.continuousNames, s.continuousState, s.discreteNames, new FPIntegerBoundingBox(next));
                    prevR         = R;
                }
                next[dim] = new FPIntegerInterval(prevR, dimR, bits, decimals);
                result[0] = new State(s.step, s.continuousNames, s.continuousState, s.discreteNames, new FPIntegerBoundingBox(next));
            }
            List <State> list = new List <State>(divs);

            foreach (var s in result)
            {
                list.Add(s);
            }
            return(list);
        }
Пример #3
0
 public bool Subseteq(FPIntegerInterval A)
 {
     Contract.Requires(A.bits == this.bits);
     Contract.Requires(A.decimals == this.decimals);
     return(left >= A.left && right <= A.right);
 }
Пример #4
0
        public FormulaSystem(string filename, Plot3d plotter)
            : base()
        {
            axisValue[0] = new REAL(0.0);
            axisValue[1] = new REAL(0.0);
            axisValue[2] = new REAL(0.0);
            Load(filename, "M");

            string[]            cNames   = new string[cVariables.Count];
            string[]            dNames   = new string[dVariables.Count];
            DoubleInterval[]    cInitial = new DoubleInterval[cVariables.Count];
            FPIntegerInterval[] dInitial = new FPIntegerInterval[dVariables.Count];
            int i = 0;

            foreach (var kvp in cVariables)
            {
                cNames[i]   = kvp.Key.name;
                cInitial[i] = kvp.Value.Clone();
                i++;
            }
            i = 0;
            foreach (var kvp in dVariables)
            {
                dNames[i]   = kvp.Key.Expr;
                dInitial[i] = kvp.Value.Clone();
                i++;
            }

            // build the ODEs
            ode = new List <AST>();
            foreach (var kvp in cVariables)
            {
                AST f;
                if (odes.TryGetValue(kvp.Key.name, out f))
                {
                    ode.Add(f);
                }
            }

            Print(Log.Output);
            Print(Log.Debug);

            Initialize(cNames, cInitial, dNames, dInitial, order, period);

            if (IsPolynomial)
            {
                Log.WriteLine("Using polynomial solver");
            }
            else if (ContainsSqrt)
            {
                Log.WriteLine("Using approximate Taylor expansion solver");
            }
            else
            {
                Log.WriteLine("Using non-polynomial Taylor model solver");
            }

            // look for lower and upper bounds
            foreach (var kvp in dVariables)
            {
                FixedPointNumber fp = kvp.Key;
                int lo     = -(1 << ((int)fp.bits - 1));
                int up     = (1 << ((int)fp.bits - 1)) - 1;
                var solver = ctx.MkSimpleSolver();
                AddController(ctx, solver, kvp.Key.Expr);
                lo = LowerBound(ctx, solver, fp.Expr, fp.bits, lo, up);
                up = UpperBound(ctx, solver, fp.Expr, fp.bits, lo, up);
                var ival = new FPIntegerInterval(lo, up, fp.bits, fp.decimals);
                controlBounds.Add(fp.Expr, ival);
                Log.Debug.WriteLine("Control variable '{0}' always in {1}", kvp.Key, ival);
            }

            Dictionary <string, DoubleInterval> initialValues = GetSystemState(initialState); // initialState.ToDictionary();

            if (!timeAxis)
            {
                axisInitialValue[0] = axisValue[0].Eval(initialValues);
            }
            axisInitialValue[1] = axisValue[1].Eval(initialValues);
            if (!searchIndexAxis)
            {
                axisInitialValue[2] = axisValue[2].Eval(initialValues);
            }

            this.plotter = plotter;
            if (plotter != null)
            {
                plotter.SetMinMax(axisMin[0], axisMax[0], axisMin[1], axisMax[1], axisMin[2], axisMax[2]);
                plotter.DefaultSettings();
                plotter.DrawEvent += Draw;
            }
        }
Пример #5
0
        /// <summary>
        /// Calculate bounds for the control variables by branch-and-bound
        /// </summary>
        /// <param name="q">Current state</param>
        /// <returns>Bounds for discrete variables</returns>
        private FPIntegerBoundingBox ControllerBounds(State q)
        {
            // branch and bound
            Dictionary <string, FPIntegerInterval> measuredData = Sample(q);

            Log.Debug.WriteLine("Controller measures");
            foreach (var kvp in measuredData)
            {
                Log.Debug.WriteLine("\t{0} = {1}", kvp.Key, kvp.Value);
            }

            FPIntegerInterval[] result = new FPIntegerInterval[q.discreteNames.Length];
            for (int i = 0; i < q.discreteNames.Length; ++i)
            {
                solver.Reset();
                Solver solverOverflow = ctx.MkSimpleSolver();

                // Add controller code
                AddController(ctx, solver, q.discreteNames[i]);
                AddControllerOverflow(ctx, solverOverflow, q.discreteNames[i]);

                // Add measured data
                foreach (var data in measuredData)
                {
                    var bits     = data.Value.bits;
                    var decimals = data.Value.decimals;
                    solver.Assert(
                        ctx.MkFPSBetween(
                            ctx.MkFPConst(data.Key, bits, decimals),
                            ctx.MkFPscaled(data.Value.left, bits, decimals),
                            ctx.MkFPscaled(data.Value.right, bits, decimals)).bv);
                    solverOverflow.Assert(
                        ctx.MkFPSBetween(
                            ctx.MkFPConst(data.Key, bits, decimals),
                            ctx.MkFPscaled(data.Value.left, bits, decimals),
                            ctx.MkFPscaled(data.Value.right, bits, decimals)).bv);
                }
                // Add discrete values from previous state
                for (int j = 0; j < q.discreteNames.Length; ++j)
                {
                    if (i != j)
                    {
                        var data     = q.discreteState.axes[j];
                        var bits     = data.bits;
                        var decimals = data.decimals;
                        solver.Assert(
                            ctx.MkFPSBetween(
                                ctx.MkFPConst(q.discreteNames[j], bits, decimals),
                                ctx.MkFPscaled(data.left, bits, decimals),
                                ctx.MkFPscaled(data.right, bits, decimals)).bv);
                        solverOverflow.Assert(
                            ctx.MkFPSBetween(
                                ctx.MkFPConst(q.discreteNames[j], bits, decimals),
                                ctx.MkFPscaled(data.left, bits, decimals),
                                ctx.MkFPscaled(data.right, bits, decimals)).bv);
                    }
                }

                uint qbits     = q.discreteState.axes[i].bits;
                uint qdecimals = q.discreteState.axes[i].decimals;

                // Ask lower and upper bound for controller variable
                int lo    = ControllerLowerBound(q.discreteNames[i]);
                int up    = ControllerUpperBound(q.discreteNames[i]);
                int lower = LowerBound(ctx, solver, q.discreteNames[i], qbits, lo, up);
                int upper = UpperBound(ctx, solver, q.discreteNames[i], qbits, lower, up);

                result[i] = new FPIntegerInterval(lower, upper, qbits, qdecimals);
                Log.Debug.WriteLine("Control variable '{0}' between {1} and {2}", q.discreteNames[i], result[i].left, result[i].right);
                Log.Debug.WriteLine(solver.ToString());

                var check = solverOverflow.Check();
                if (check == Status.SATISFIABLE)
                {
                    Log.WriteLine("Overflow error at state:");
                    q.Print(Log.Output);
                    Log.WriteLine(q.discreteNames[i]);
                    Log.WriteLine(solverOverflow.ToString());
                    Log.WriteLine(solverOverflow.Model.ToString());
                    Log.Debug.Flush();
                    throw new Exception("Controller overflow detected");
                }
            }

            return(new FPIntegerBoundingBox(result));
        }