// 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::intersect( const interval& pOther ) const { if( !(*this).contains(pOther.mMin) && !(*this).contains(pOther.mMax) && !pOther.contains(mMin) && !pOther.contains(mMax) ) { return interval( ggl::nan() ); } else { return interval( std::max(mMin, pOther.mMin), std::min(mMax, pOther.mMax) ); } }
void r_search(Node *root, const interval<T>& i, ivec& vec, int mode) { if (root == NULL) return; if (mode == OVERLAP && root->m_interval->overlaps(i)) vec.push_back(*(root->m_interval)); if (mode == CONTAIN && root->m_interval->contains(i)) vec.push_back(*(root->m_interval)); if (mode == CONTAINED && i.contains(*(root->m_interval))) vec.push_back(*(root->m_interval)); if (root->left != NULL && i.overlaps(root->left->min, root->left->max)) r_search(root->left, i, vec, mode); if (root->right != NULL && i.overlaps(root->right->min, root->right->max)) r_search(root->right, i, vec, mode); }
bool true_extended_division(const interval& x, const interval& y, interval& z, interval& gap) { ASSERT(!x.contains(0) && y.contains(0)); bool ret_val = false; if (x.ub < 0) { if (y.ub==0) { z.prechecked_intersection(x.ub/y.lb, z.ub); } else if (y.lb==0) { z.prechecked_intersection(z.lb, x.ub/y.ub); } else { ret_val = save_gap_if_any(x.ub/y.ub, x.ub/y.lb, z, gap); } } else { if (y.ub==0) { z.prechecked_intersection(z.lb, x.lb/y.lb); } else if (y.lb==0) { z.prechecked_intersection(x.lb/y.ub, z.ub); } else { ret_val = save_gap_if_any(x.lb/y.lb, x.lb/y.ub, z, gap); } } return ret_val; }
void random_updater::shift_var(unsigned j, interval & r) { SASSERT(r.contains(m_core_solver.m_r_x[j])); SASSERT(m_core_solver.m_r_solver.column_is_feasible(j)); auto old_x = m_core_solver.m_r_x[j]; remove_value(old_x); auto new_val = m_core_solver.m_r_x[j] = get_random_from_interval(r); add_value(new_val); SASSERT(r.contains(m_core_solver.m_r_x[j])); SASSERT(m_core_solver.m_r_solver.column_is_feasible(j)); auto delta = m_core_solver.m_r_x[j] - old_x; unsigned i; m_column_j->reset(); mpq a; while(m_column_j->next(a, i)) { unsigned bj = m_core_solver.m_r_basis[i]; m_core_solver.m_r_x[bj] -= a * delta; SASSERT(m_core_solver.m_r_solver.column_is_feasible(bj)); } SASSERT(m_core_solver.m_r_solver.A_mult_x_is_off() == false); }
const interval operator/(const interval& x, const interval& y) { ASSERT2(x.lb<=x.ub && y.lb<=y.ub, "x: "<<x<<", y: "<<y); ASSERT2(!y.contains(0), "y: "<<y); double z[] = { x.lb/y.lb, x.lb/y.ub, x.ub/y.lb, x.ub/y.ub }; double zL = *std::min_element(z, z+4); double zU = *std::max_element(z, z+4); return interval(zL, zU); }
inline bool intersects (const interval & ot, cood eps = 0) const { return contains(ot.a, eps) || contains(ot.b, eps) || ot.contains(*this, eps); }