// 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; }
void addition_inverse(interval& z, interval& x, interval& y) { x.intersect(z-y); y.intersect(z-x); z.intersect(x+y); }
bool division_inverse(interval& z, interval& x, interval& y, interval& gap) { // z = x/y --> x = z*y x.intersect(z*y); // y = x/z bool has_gap = extended_division(x, z, y, gap); z.intersect(x/y); 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); }
// z = x*y void propagate_mult(interval& z, interval& x, interval& y) { // TODO Eliminate propagate_mult, only used by envelopes // if (!x.contains(0)) { // y = z/x // // y.intersect(z/x); // } interval gap; extended_division(z, x, y, gap); // if (!y.contains(0)) { // x = z/y // // x.intersect(z/y); // } extended_division(z, y, x, gap); // z = x*y z.intersect(x*y); }
void interval::less_than_or_equal_to(interval& rhs) { ASSERT2(rhs.lb <= rhs.ub, rhs); ASSERT2(lb <= ub, *this); // this <= rhs // [a, b] <= [c, d] const double a = lb; const double d = rhs.ub; if (a > d) { throw infeasible_problem(); } intersect(a, d); // b <= d; b is modified appropriately rhs.intersect(a, d); // a <= c; c is modified appropriately }
void log_inverse(interval& z, interval& x) { x.intersect(exp(z)); z.intersect(log(x)); }