12 #include <boost/logic/tribool_io.hpp> 
   29 template<
typename Number>
 
   31     CARL_LOG_DEBUG(
"carl.ran.interval", 
"Evaluating " << p << 
" on " << m);
 
   34     for (
const auto& [var, ran] : m) {
 
   35         if (!p.
has(var)) 
continue;
 
   37             CARL_LOG_TRACE(
"carl.ran.interval", 
"Refine " << var << 
" = " << ran);
 
   38             static Number min_width = Number(1) / (Number(1048576)); 
 
   39             while (!ran.is_numeric() && ran.interval().diameter() > min_width) {
 
   43         if (ran.is_numeric()) {
 
   44             CARL_LOG_TRACE(
"carl.ran.interval", 
"Substitute " << var << 
" = " << ran);
 
   56     std::map<Variable, Interval<Number>> var_to_interval;
 
   57     for (
const auto& [var, ran] : m) {
 
   59             assert(!ran.is_numeric());
 
   60             var_to_interval.emplace(var, ran.interval());
 
   63     CARL_LOG_TRACE(
"carl.ran.interval", 
"Interval map: " << var_to_interval);
 
   65     assert(!var_to_interval.empty());
 
   66     if (var_to_interval.size() == 1) {
 
   69         assert(poly.main_var() == var_to_interval.begin()->first);
 
   70         CARL_LOG_TRACE(
"carl.ran.interval", 
"Consider univariate poly " << poly);
 
   71         if (
sgn(m.at(var_to_interval.begin()->first), poly) == 
Sign::ZERO) {
 
   81         CARL_LOG_DEBUG(
"carl.ran.interval", 
"Interval is point interval " << interval);
 
   87     std::vector<UnivariatePolynomial<MultivariatePolynomial<Number>>> algebraic_information;
 
   88     for (
const auto& [var, ran] : m) {
 
   89         if (var_to_interval.find(var) == var_to_interval.end()) 
continue;
 
   90         assert(!ran.is_numeric());
 
   94     std::sort(algebraic_information.begin(), algebraic_information.end(), [](
const auto& a, 
const auto& b){ 
 
   95         return a.degree() > b.degree();
 
  105     CARL_LOG_TRACE(
"carl.ran.interval", 
"var_to_interval = " << var_to_interval);
 
  118         for (
const auto& [var, ran] : m) {
 
  119             if (var_to_interval.find(var) == var_to_interval.end()) 
continue;
 
  121             if (ran.is_numeric()) {
 
  123                 for (
const auto& entry : m) {
 
  124                     if (!p.
has(entry.first)) var_to_interval.erase(entry.first);
 
  127                 var_to_interval[var] = ran.interval();
 
  133     CARL_LOG_DEBUG(
"carl.ran.interval", 
"Result is " << *res << 
" " << interval);
 
  141 template<
typename Number>
 
  143     CARL_LOG_DEBUG(
"carl.ran.interval", 
"Evaluating " << c << 
" on " << m);
 
  145     if (!use_root_bounds) {
 
  146         CARL_LOG_DEBUG(
"carl.ran.interval", 
"Evaluate constraint by evaluating poly");
 
  148         if (!res) 
return boost::indeterminate;
 
  155         for (
const auto& [var, ran] : m) {
 
  156             if (!p.
has(var)) 
continue;
 
  158                 static Number min_width = Number(1) / (Number(1048576)); 
 
  159                 while (!ran.is_numeric() && ran.interval().diameter() > min_width) {
 
  163             if (ran.is_numeric()) {
 
  165                 CARL_LOG_TRACE(
"carl.ran.interval", 
"Substituting numeric value p["<<ran.value()<<
"/"<<var<<
"] = " << p);
 
  170             CARL_LOG_DEBUG(
"carl.ran.interval", 
"Left hand side is constant");
 
  175             CARL_LOG_DEBUG(
"carl.ran.interval", 
"Constraint already evaluates to value");
 
  179         CARL_LOG_TRACE(
"carl.ran.interval", 
"p = " << p << 
" (after simplification)");
 
  181         std::map<Variable, Interval<Number>> var_to_interval;
 
  182         for (
const auto& [var, ran] : m) {
 
  184                 assert(!ran.is_numeric());
 
  185                 var_to_interval.emplace(var, ran.interval());
 
  191             CARL_LOG_TRACE(
"carl.ran.interval", 
"Interval evaluation of " << p << 
" under " << var_to_interval << 
" results in " << interval);
 
  193             CARL_LOG_TRACE(
"carl.ran.interval", 
"Obtained " << interval << 
" " << constr.
relation() << 
" 0 -> " << (indeterminate(int_res) ? -1 : (
bool)int_res));
 
  194             if (!indeterminate(int_res)) {
 
  195                 CARL_LOG_DEBUG(
"carl.ran.interval", 
"Result obtained by interval evaluation");
 
  196                 return (
bool)int_res;
 
  200         CARL_LOG_DEBUG(
"carl.ran.interval", 
"Evaluate constraint using resultants and root bounds");
 
  201         assert(var_to_interval.size() > 0);
 
  202         if (var_to_interval.size() == 1) {
 
  205             assert(poly.main_var() == var_to_interval.begin()->first);
 
  206             CARL_LOG_TRACE(
"carl.ran.interval", 
"Consider univariate poly " << poly);
 
  207             if (
sgn(m.at(var_to_interval.begin()->first), poly) == 
Sign::ZERO) {
 
  215         std::vector<UnivariatePolynomial<MultivariatePolynomial<Number>>> algebraic_information;
 
  216         for (
const auto& [var, ran] : m) {
 
  217             if (var_to_interval.find(var) == var_to_interval.end()) 
continue;
 
  218             assert(!ran.is_numeric());
 
  222         std::sort(algebraic_information.begin(), algebraic_information.end(), [](
const auto& a, 
const auto& b){ 
 
  223             return a.degree() > b.degree();
 
  228             return boost::indeterminate;
 
  232         CARL_LOG_DEBUG(
"carl.ran.interval", 
"var_to_interval = " << var_to_interval);
 
  241         CARL_LOG_TRACE(
"carl.ran.interval", 
"positive root lower bound: " << pos_lb);
 
  252         CARL_LOG_TRACE(
"carl.ran.interval", 
"negative root upper bound: " << neg_ub);
 
  263         if (pos_lb == 0 && neg_ub == 0) {
 
  272         CARL_LOG_DEBUG(
"carl.ran.interval", 
"Refine until interval is in (" << neg_ub << 
"," << pos_lb << 
") or interval is positive or negative");
 
  273         while (!((neg_ub < interval.
lower() || neg_ub == 0) && (interval.
upper() < pos_lb || pos_lb == 0))) {
 
  274             for (
const auto& [var, ran] : m) {
 
  275                 if (var_to_interval.find(var) == var_to_interval.end()) 
continue;
 
  277                 if (ran.is_numeric()) {
 
  279                     for (
const auto& entry : m) {
 
  280                         if (!p.
has(entry.first)) var_to_interval.erase(entry.first);
 
  283                     var_to_interval[var] = ran.interval();
 
  288             if (!indeterminate(int_res)) {
 
  290                 return (
bool)int_res;
 
  300 template<
typename Coeff, 
typename Ordering, 
typename Policies>
 
  305 template<
typename Coeff, 
typename Ordering, 
typename Policies>
 
This file contains carl::algebraic_substitution which performs what we call an algebraic substitution...
#define CARL_LOG_TRACE(channel, msg)
#define CARL_LOG_DEBUG(channel, msg)
carl is the main namespace for the library.
MultivariatePolynomial< C, O, P > squareFreePart(const MultivariatePolynomial< C, O, P > &polynomial)
UnivariatePolynomial< C > to_univariate_polynomial(const MultivariatePolynomial< C, O, P > &p)
Convert a univariate polynomial that is currently (mis)represented by a 'MultivariatePolynomial' into...
std::vector< UnivariatePolynomial< Coeff > > sturm_sequence(const UnivariatePolynomial< Coeff > &p, const UnivariatePolynomial< Coeff > &q)
Computes the sturm sequence of two polynomials.
int count_real_roots(const std::vector< UnivariatePolynomial< Coefficient >> &seq, const Interval< Coefficient > &i)
Calculate the number of real roots of a polynomial within a given interval based on a sturm sequence ...
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
bool evaluate(const BasicConstraint< Poly > &c, const Assignment< Number > &m)
bool is_root_of(const UnivariatePolynomial< Coeff > &p, const Coeff &value)
UnivariatePolynomial< Coeff > replace_main_variable(const UnivariatePolynomial< Coeff > &p, Variable newVar)
Replaces the main variable in a polynomial.
Sign sgn(const Number &n)
Obtain the sign of the given number.
BasicConstraint< ToPoly > convert(const typename ToPoly::ContextType &context, const BasicConstraint< FromPoly > &c)
Variable fresh_real_variable() noexcept
Coeff lagrangePositiveLowerBound(const UnivariatePolynomial< Coeff > &p)
Computes a lower bound on the value of the positive real roots of the given univariate polynomial.
std::map< Variable, T > Assignment
Coeff lagrangeNegativeUpperBound(const UnivariatePolynomial< Coeff > &p)
Computes an upper bound on the value of the negative real roots of the given univariate polynomial.
void substitute_inplace(MultivariateRoot< Poly > &mr, Variable var, const Poly &poly)
Create a copy of the underlying polynomial with the given variable replaced by the given polynomial.
BasicConstraint< Pol > create_normalized_constraint(const Pol &lhs, Relation rel)
std::optional< UnivariatePolynomial< Number > > algebraic_substitution(const UnivariatePolynomial< MultivariatePolynomial< Number >> &p, const std::vector< UnivariatePolynomial< MultivariatePolynomial< Number >>> &polynomials, AlgebraicSubstitutionStrategy strategy=AlgebraicSubstitutionStrategy::RESULTANT)
Computes the algebraic substitution of the given defining polynomials into a multivariate polynomial ...
Represent a polynomial (in)equality against zero.
unsigned is_consistent() const
Relation relation() const
A Variable represents an algebraic variable that can be used throughout carl.
The class which contains the interval arithmetic including trigonometric functions.
const Number & upper() const
The getter for the upper boundary of the interval.
const Number & lower() const
The getter for the lower boundary of the interval.
bool is_point_interval() const
Function which determines, if the interval is a pointinterval.
This class represents a univariate polynomial with coefficients of an arbitrary type.
const Coeff & constant_part() const
Retrieve the constant term of this polynomial or zero, if there is no constant term.
bool is_number() const
Check if the polynomial is a number, i.e., a constant.
bool has(Variable v) const
const UnivariatePolynomial< MultivariatePolynomial< Coeff, Ordering, Policies > > & content() const
typename UnivariatePolynomial< NumberType >::RootType RootType