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); }
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); }
public bool Subseteq(FPIntegerInterval A) { Contract.Requires(A.bits == this.bits); Contract.Requires(A.decimals == this.decimals); return(left >= A.left && right <= A.right); }
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; } }
/// <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)); }