double Interval::delta(const Interval& x) const { if (is_empty()) return 0; if (x.is_empty()) return diam(); // ** warning ** // checking if *this or x is infinite by // testing if the lower/upper bounds are -oo/+oo // is not enough because diam() may return +oo even // with finite bounds (e.g, very large intervals like [-DBL_MAX,DBL_MAX]). // ("almost-unboundedness") volatile double d=diam(); volatile double dx=x.diam(); // furthermore, if these variables are not declared volatile // conditions like d==POS_INFINITY are evaluated // to FALSE for intervals like [-DBL_MAX,DBL_MAX] (with -O3 option) // while the returned expression (d-dx) evaluates to +oo (instead of 0). if (d==POS_INFINITY) { //cout << "d=" << d << " dx=" << dx << endl; if (dx==POS_INFINITY) { double left=(x.lb()==NEG_INFINITY? 0 : x.lb()-lb()); double right=(x.ub()==POS_INFINITY? 0 : ub()-x.ub()); //cout << "left=" << left << " right=" << right << endl; return left+right; } else return POS_INFINITY; } else return d-dx; }
void TestIbex::check(const Interval& y_actual, const Interval& y_expected) { //cout << "TestIbex::check: " << y_expected << " (expected) " << y_actual << " (actual)"<< endl; if (y_expected.is_empty()) { TEST_ASSERT(y_actual.is_empty()); return; } TEST_ASSERT(!y_actual.is_empty()); TEST_ASSERT(!isnan(y_actual.lb())); TEST_ASSERT(!isnan(y_actual.ub())); TEST_ASSERT_DELTA(y_actual.lb(),y_expected.lb(),ERROR); TEST_ASSERT_DELTA(y_actual.ub(),y_expected.ub(),ERROR); }
CtcPolytopeHull::CtcPolytopeHull(LinearRelax& lr, ctc_mode cmode, int max_iter, int time_out, double eps, Interval limit_diam, bool init_lp) : Ctc(lr.sys.nb_var), lr(lr), sys(lr.sys), goal_var(-1), cmode(cmode), limit_diam_box(eps>limit_diam.lb()? eps : limit_diam.lb(), limit_diam.ub()) { if (dynamic_cast<const ExtendedSystem*>(&lr.sys)) { (int&) goal_var=((const ExtendedSystem&) lr.sys).goal_var(); } mylinearsolver = NULL; if (init_lp) mylinearsolver = new LinearSolver(nb_var, lr.sys.nb_ctr, max_iter, time_out, eps); }
bool TestIbex::almost_eq(const Interval& y_actual, const Interval& y_expected, double err) { if (y_actual.is_empty() && y_expected.is_empty()) return true; if (y_actual.lb()==NEG_INFINITY) if (y_expected.lb()!=NEG_INFINITY) return false; else; else if (fabs(y_actual.lb()-y_expected.lb())> err) return false; if (y_actual.ub()==POS_INFINITY) if (y_expected.ub()!=POS_INFINITY) return false; else; else if (fabs(y_actual.ub()-y_expected.ub())> err) return false; return true; }
Interval Tube::at(const Interval& time) const { assert(time.lb()>=_t0 && time.ub()<=_tf); Interval temp(Interval::EMPTY_SET); int first_idx=(int)round(time.lb()/_deltaT); int last_idx=(int)round(time.ub()/_deltaT); for(int i=first_idx;i<last_idx;i++) { temp=temp|(*this)[i]; } /* for(double t=time.lb();t<time.ub();t+=_deltaT){ temp=temp|(*this)[(int)round((t-_t0)/_deltaT)]; } */ return temp; }
const pair<Interval,Interval> Tube::getEnclosedBounds(const Interval& intv_t) const { if(intv_t.lb() == intv_t.ub()) return make_pair(Interval((*this)[intv_t.lb()].lb()), Interval((*this)[intv_t.lb()].ub())); Interval intersection = m_intv_t & intv_t; if(intersection.is_empty()) return make_pair(Interval::EMPTY_SET, Interval::EMPTY_SET); else if(isSlice() || intv_t == m_intv_t || intv_t.is_unbounded() || intv_t.is_superset(m_intv_t)) { if(m_tree_computation_needed) computeTree(); return m_enclosed_bounds; // pre-computed } else { Interval inter_firstsubtube = m_first_subtube->getT() & intersection; Interval inter_secondsubtube = m_second_subtube->getT() & intersection; if(inter_firstsubtube.lb() == inter_firstsubtube.ub() && inter_secondsubtube.lb() == inter_secondsubtube.ub()) return make_pair((*m_first_subtube)[inter_firstsubtube.lb()] & (*m_second_subtube)[inter_secondsubtube.lb()], (*m_first_subtube)[inter_firstsubtube.ub()] & (*m_second_subtube)[inter_secondsubtube.ub()]); else if(inter_firstsubtube.is_empty() || inter_firstsubtube.lb() == inter_firstsubtube.ub()) return m_second_subtube->getEnclosedBounds(inter_secondsubtube); else if(inter_secondsubtube.is_empty() || inter_secondsubtube.lb() == inter_secondsubtube.ub()) return m_first_subtube->getEnclosedBounds(inter_firstsubtube); else { pair<Interval,Interval> ui_past = m_first_subtube->getEnclosedBounds(inter_firstsubtube); pair<Interval,Interval> ui_future = m_second_subtube->getEnclosedBounds(inter_secondsubtube); return make_pair(ui_past.first | ui_future.first, ui_past.second | ui_future.second); } } }
Affine2Main<AF_iAF>::Affine2Main(const Interval & itv): _n (0), _elt (NULL,0.0) { if (itv.is_empty()) { _n = -1; _elt._err = itv; } else if (itv.ub()>= POS_INFINITY && itv.lb()<= NEG_INFINITY ) { _n = -2; _elt._err = itv; } else if (itv.ub()>= POS_INFINITY ) { _n = -3; _elt._err = itv; } else if (itv.lb()<= NEG_INFINITY ) { _n = -4; _elt._err = itv; } else { _n = 0; _elt._val = new Interval[1]; _elt._val[0] = itv.mid(); _elt._err = itv.rad(); } }
Tube::Tube(const Interval &intv_t, double time_step, const Interval& default_value) { double lb, ub = intv_t.lb(); vector<Interval> vector_dt; // a vector of slices is created only once do { lb = ub; // we guarantee all slices are adjacent ub = lb + time_step; vector_dt.push_back(Interval(lb, ub)); } while(ub < intv_t.ub()); createFromSlicesVector(vector_dt, default_value); m_dt = time_step; }
void Tube::setInversion(const Interval& intv_y, vector<Interval> &v_intv_t, bool concatenate_results) const { v_intv_t.clear(); Interval intv_t = setInversion(intv_y); if(!intv_t.is_empty()) { pair<Interval,Interval> enc_bounds = getEnclosedBounds(intv_t); if(!concatenate_results) { if(enc_bounds.first.ub() > intv_y.ub() || enc_bounds.second.lb() < intv_y.lb()) { // Bisection is needed vector<Interval> v1; m_first_subtube->setInversion(intv_y, v1, false); v_intv_t.insert(v_intv_t.end(), v1.begin(), v1.end()); vector<Interval> v2; m_second_subtube->setInversion(intv_y, v2, false); v_intv_t.insert(v_intv_t.end(), v2.begin(), v2.end()); } else v_intv_t.push_back(intv_t); } else { vector<Interval> v; setInversion(intv_y, v, false); // Concatenation (solutions may be adjacent) int i = 0; while(i < v.size()) { int j = i; while(j + 1 < v.size() && v[i].ub() == v[j + 1].lb()) j ++; v_intv_t.push_back(v[i] | v[j]); i = j + 1; } } } }
void div2(const Interval& num, const Interval& div, Interval& out1, Interval& out2) { if (num.is_empty() || div.is_empty()) { out1.set_empty(); out2.set_empty(); return; } const double& a(num.lb()); const double& b(num.ub()); const double& c(div.lb()); const double& d(div.ub()); // notice : we do not consider 0/0=0 but 0/0=emptyset if (c==0 && d==0) { out1.set_empty(); out2.set_empty(); return; } if (a==0 && b==0) { out1 = num; out2.set_empty(); return; } if (c>0 || d<0) { out1 = num/div; out2.set_empty(); return; } if (b<=0 && d==0) { if (c==NEG_INFINITY) out1 = Interval::POS_REALS; else out1 = Interval(INF_DIV(b,c), POS_INFINITY); out2.set_empty(); return; } if (b<=0 && c<0 && d>0) { if (b==0 || (c==NEG_INFINITY && d==POS_INFINITY)) { out1 = Interval::ALL_REALS; out2.set_empty(); return; } else { out1 = Interval(NEG_INFINITY, d==POS_INFINITY? 0 : SUP_DIV(b,d)); out2 = Interval(c==NEG_INFINITY? 0 : INF_DIV(b,c), POS_INFINITY); return; } } if (b<=0 && c==0) { if (d==POS_INFINITY) out1 = Interval::NEG_REALS; else out1 = Interval(NEG_INFINITY, SUP_DIV(b,d)); out2.set_empty(); return; } if (a>=0 && d==0) { if (c==NEG_INFINITY) out1 = Interval::NEG_REALS; else out1 = Interval(NEG_INFINITY, SUP_DIV(a,c)); out2.set_empty(); return; } if (a>=0 && c<0 && d>0) { if (a==0 || (c==NEG_INFINITY && d==POS_INFINITY)) { out1 = Interval::ALL_REALS; out2.set_empty(); return; } else { out1 = Interval(NEG_INFINITY, c==NEG_INFINITY? 0 : SUP_DIV(a,c)); out2 = Interval(d==POS_INFINITY? 0 : INF_DIV(a,d), POS_INFINITY); return; } } if (a>=0 && c==0) { if (d==POS_INFINITY) out1 = Interval::POS_REALS; else out1 = Interval(INF_DIV(a,d), POS_INFINITY); out2.set_empty(); return; } out1 = Interval::ALL_REALS; out2.set_empty(); }
CtcNotIn::CtcNotIn(Function& f, const Interval& y) : Ctc(f.nb_var()), f(f), d1(Dim()), d2(Dim()) { assert(f.expr().dim.is_scalar()); d1.i()=Interval(NEG_INFINITY,y.lb()); d2.i()=Interval(y.ub(),POS_INFINITY); }
bool compare(const Interval& intv1, const Interval& intv2) { return intv1 == intv2 || fabs(intv1.lb() - intv2.lb()) < 1.0e-10 && fabs(intv1.ub() - intv2.ub()) < 1.0e-10; }
void Tube::setY(const Interval& intv_y, const Interval& intv_t) { if(intv_t == ibex::Interval::ALL_REALS || (m_intv_t.intersects(intv_t) && m_intv_t.lb() != intv_t.ub() && m_intv_t.ub() != intv_t.lb())) { if(isSlice()) m_intv_y = intv_y; else { m_first_subtube->setY(intv_y, intv_t); m_second_subtube->setY(intv_y, intv_t); } requestFutureTreeComputation(); } }
QString interval2String(Interval &i){ QString s; s+= "[" + QString::number(i.lb()) + "," + QString::number(i.ub()) + "]"; return s; }