interval interval_relation_plugin::meet(interval const& src1, interval const& src2, bool& isempty) { isempty = false; if (is_empty(0, src1) || is_infinite(src2)) { return src1; } if (is_empty(0, src2) || is_infinite(src1)) { return src2; } bool l_open = src1.is_lower_open(); bool r_open = src1.is_upper_open(); ext_numeral low = src1.inf(); ext_numeral high = src1.sup(); if (src2.inf() > low || (src2.inf() == low && !l_open)) { low = src2.inf(); l_open = src2.is_lower_open(); } if (src2.sup() < high || (src2.sup() == high && !r_open)) { high = src2.sup(); r_open = src2.is_upper_open(); } if (low > high || (low == high && (l_open || r_open))) { isempty = true; return interval(dep()); } else { return interval(dep(), low, l_open, nullptr, high, r_open, nullptr); } }
interval interval_relation_plugin::unite(interval const& src1, interval const& src2) { bool l_open = src1.is_lower_open(); bool r_open = src1.is_upper_open(); ext_numeral low = src1.inf(); ext_numeral high = src1.sup(); if (src2.inf() < low || (src2.inf() == low && l_open)) { low = src2.inf(); l_open = src2.is_lower_open(); } if (src2.sup() > high || (src2.sup() == high && r_open)) { high = src2.sup(); r_open = src2.is_upper_open(); } return interval(dep(), low, l_open, nullptr, high, r_open, nullptr); }
// FIXME It actually performs intersection which is inconsistent with intersect bool sqr_inverse(interval& z, interval& x, interval& gap) { bool has_gap = false; const interval x_1 = sqrt(z); const interval x_2 = -x_1; interval x_image; if (disjoint(x, x_2)) { x_image = x_1; } else if (disjoint(x, x_1)) { x_image = x_2; } else { gap = interval(x_2.sup(), x_1.inf()); has_gap = gap.diameter() > IMPROVEMENT_TOL; // FIXME GAP_SQRT_TOL ? x_image = hull_of(x_1, x_2); } x.intersect(x_image); z.intersect(sqr(x)); return has_gap; }
// Returns true and sets gap if a gap is generated, otherwise gap is undefined bool extended_division(const interval& x, const interval& y, interval& z, interval& gap) { gap = interval(); if (z.is_narrow()) { // if narrow, don't do anything // TODO Actually, feasibility could be checked return false; } if (!y.contains(0)) { // trivial case z.intersect(x/y); return false; } // y.contains(0)==true if (x.contains(0)) { // no progress case return false; } // (!x.contains(0) && y.contains(0)) == true if (y.inf()==0 && y.sup()==0) { // undefined case // FIXME Is it safe to declare it infeasible? Or should we just signal no progress? //ASSERT2(false, "undefined result; x, z: "<<x<<", "<<z); throw infeasible_problem(); } return true_extended_division(x, y, z, gap); }
interval interval_relation_plugin::widen(interval const& src1, interval const& src2) { bool l_open = src1.is_lower_open(); bool r_open = src1.is_upper_open(); ext_numeral low = src1.inf(); ext_numeral high = src1.sup(); if (src2.inf() < low || (low == src2.inf() && l_open && !src2.is_lower_open())) { low = ext_numeral(false); l_open = true; } if (high < src2.sup() || (src2.sup() == high && !r_open && src2.is_upper_open())) { high = ext_numeral(true); r_open = true; } return interval(dep(), low, l_open, nullptr, high, r_open, nullptr); }
// FIXME Performs intersection which is inconsistent with intersect! bool save_gap_if_any(const double l, const double u, interval& z, interval& gap) { ASSERT2( l <= u, "l, u: " << l << ", " << u ); const double zL = z.inf(), zU = z.sup(); bool ret_val = false; if (zL <= l && u <= zU) { // zL--l u--zU gap = interval(l, u); ret_val = true; } else if (l < zL && zU < u) { // --l zL--zU u-- throw infeasible_problem(); } else if (zU <= l) { // zL--zU--l u-- ; // no progress } else if (u <= zL) { // --l u--zL--zU ; // no progress } else if (zL <= l && zU < u) { // zL--l zU u-- z = interval(zL, l); } else if (l < zL && u <= zU) { // --l zL u--zU z = interval(u, zU); } else { ASSERT(false); } ASSERT(z.subset_of(interval(zL, zU))); return ret_val; }
bool interval_relation_plugin::is_empty(unsigned, interval const& i) { return i.sup() < i.inf(); }