bool operator<(ibex::Interval const & a, ibex::Interval const & b) { if (a.is_empty() || b.is_empty()) { return false; } return a.ub() < b.lb(); return false; }
ibex::Interval Tube::getY(const ibex::Interval& intv_t) { if(!m_intv_t.intersects(intv_t)) return ibex::Interval::EMPTY_SET; else if(isSlice() || intv_t.is_unbounded() || intv_t.is_superset(m_intv_t)) return m_intv_y; else return m_first_subtube->getY(intv_t) | m_second_subtube->getY(intv_t); }
pair<ibex::Interval,ibex::Interval> Tube::getEnclosedBounds(const ibex::Interval& intv_t) const { if(!intv_t.is_empty() && m_intv_t.intersects(intv_t)) { if(isSlice() || intv_t.is_superset(m_intv_t)) return m_enclosed_bounds; else { pair<ibex::Interval,ibex::Interval> ui_past = m_first_subtube->getEnclosedBounds(intv_t); pair<ibex::Interval,ibex::Interval> ui_future = m_second_subtube->getEnclosedBounds(intv_t); return make_pair(ui_past.first | ui_future.first, ui_past.second | ui_future.second); } } return make_pair(ibex::Interval::EMPTY_SET, ibex::Interval::EMPTY_SET); }
Interval Tube::operator[](const ibex::Interval& intv_t) const { // Write access is not allowed for this operator: // a further call to computeTree() is needed when values change, // this call cannot be garanteed with a direct access to m_intv_y // For write access: use setY() if(intv_t.lb() == intv_t.ub()) return (*this)[intv_t.lb()]; Interval intersection = m_intv_t & intv_t; if(intersection.is_empty()) return 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_intv_y; } else { Interval inter_firstsubtube = m_first_subtube->getT() & intersection; Interval inter_secondsubtube = m_second_subtube->getT() & intersection; if(inter_firstsubtube == inter_secondsubtube) return (*m_first_subtube)[inter_firstsubtube.lb()] & (*m_second_subtube)[inter_secondsubtube.lb()]; else if(inter_firstsubtube.lb() == inter_firstsubtube.ub() && inter_secondsubtube.lb() != inter_secondsubtube.ub()) return (*m_second_subtube)[inter_secondsubtube]; else if(inter_firstsubtube.lb() != inter_firstsubtube.ub() && inter_secondsubtube.lb() == inter_secondsubtube.ub()) return (*m_first_subtube)[inter_firstsubtube]; else return (*m_first_subtube)[inter_firstsubtube] | (*m_second_subtube)[inter_secondsubtube]; } }
Tube::Tube(const ibex::Interval &intv_t, unsigned int slices_number) { if((slices_number == 0) || (slices_number & (slices_number - 1))) // decrement and compare cout << "Warning Tube::Tube(): slices number (" << slices_number << ") not a power of 2." << endl; m_intv_t = intv_t; m_intv_y = ibex::Interval::EMPTY_SET; m_slices_number = slices_number; if(slices_number == 1) { m_first_subtube = NULL; m_second_subtube = NULL; } else { pair<ibex::Interval,ibex::Interval> bisection = intv_t.bisect(0.5); m_first_subtube = new Tube(bisection.first, slices_number / 2); m_second_subtube = new Tube(bisection.second, slices_number / 2); } update(); }
tuple<int, box, box> box::bisect_int_at(int const i) const { assert(0 <= i && i < m_values.size()); assert(!m_values[i].is_empty()); assert(m_values[i].is_bisectable()); box b1(*this); box b2(*this); ibex::Interval const iv = ibex::integer(b1.m_values[i]); double const lb = iv.lb(); double const ub = iv.ub(); double const mid = iv.mid(); double const mid_floor = floor(mid); double const mid_ceil = ceil(mid); if (!iv.is_bisectable()) { DREAL_LOG_FATAL << "NOT BISECTABLE = " << iv; } pair<ibex::Interval, ibex::Interval> new_intervals = iv.bisect(); b1.m_values[i] = ibex::Interval(lb, mid_floor); b2.m_values[i] = ibex::Interval(mid_ceil, ub); b1.m_idx_last_branched = i; b2.m_idx_last_branched = i; DREAL_LOG_DEBUG << "box::bisect on " << (*m_vars)[i] << " : int = " << m_values[i] << " into " << b1.m_values[i] << " and " << b2.m_values[i]; return make_tuple(i, b1, b2); }
friend bool operator ==(ibex::Interval lhs, ApproxIntv const& rhs) { double e = rhs.m_epsilon; return lhs == rhs.m_value || (fabs(lhs.lb() - rhs.m_value.lb()) < e && fabs(lhs.ub() - rhs.m_value.ub()) < e); }