15 #define INITIAL_OFFSET (Number(1)/10)
20 template<
typename Number>
29 std::shared_ptr<ThomEncoding<Number>>
mPoint;
30 mutable std::shared_ptr<SignDetermination<Number>>
mSd;
62 mSc = roots.front().mSc;
63 mP = roots.front().mP;
64 mSd = roots.front().mSd;
77 for(
const auto& r : roots) {
129 return mPoint->lowestInChain();
133 if(
mPoint ==
nullptr)
return 1;
134 return 1 +
point().dimension();
139 std::list<Polynomial> res =
point().accumulatePolynomials();
146 std::list<Variable> res =
point().accumulateVariables();
154 res.insert(res.begin(),
mSc.begin(),
mSc.end());
162 res.insert(res.begin(), mScRel.begin(), mScRel.end());
170 std::list<SignCondition> signs =
mSd->getSigns(p);
172 for(
const auto& sigma : signs) {
173 if(relevant.
isSuffixOf(sigma))
return sigma.front();
230 CARL_LOG_TRACE(
"carl.thom",
"concating: \n" << *
this <<
"\nwith\n" << other);
233 std::list<ThomEncoding<Number>> thisEncodings;
235 std::shared_ptr<ThomEncoding<Number>> curr =
mPoint;
236 while(curr !=
nullptr) {
238 curr = thisEncodings.back().mPoint;
240 assert(thisEncodings.size() == this->dimension());
247 for(
auto itEncoding = thisEncodings.rbegin(); itEncoding != thisEncodings.rend(); itEncoding++) {
249 if(std::find(vars.begin(), vars.end(), itEncoding->main_var()) != vars.end()) {
252 std::shared_ptr<ThomEncoding<Number>> result_ptr = std::make_shared<ThomEncoding<Number>>(result);
253 std::list<ThomEncoding<Number>> roots =
realRootsThom(itEncoding->polynomial(), itEncoding->main_var(), result_ptr);
255 for(
const auto& r : roots) {
296 CARL_LOG_ASSERT(
"carl.thom", !m.empty(),
"called analyzeTEMap with empty map");
300 std::list<Variable> vars;
301 for(
const auto& entry : m) {
302 CARL_LOG_ASSERT(
"carl.thom", std::find(vars.begin(), vars.end(), entry.first) == vars.end(),
"variable appears twice in map");
303 vars.push_back(entry.first);
305 std::list<Variable> originalVars = vars;
308 std::list<ThomEncoding<Number>> encodings;
309 for(
const auto& entry : m) {
310 encodings.push_back(entry.second);
323 for(
const auto& v : encodings.front().accumulateVariables()) {
324 auto it = std::find(vars.begin(), vars.end(), v);
325 if(it != vars.end()) vars.erase(it);
327 encodings.erase(encodings.begin());
329 while(!vars.empty()) {
332 for(
const auto& v : encodings.front().accumulateVariables()) {
333 if(std::find(originalVars.begin(), originalVars.end(), v) == originalVars.end()) {
336 auto it = std::find(vars.begin(), vars.end(), v);
337 if(it != vars.end()) {
343 result = result.
concat(encodings.front());
344 for(
const auto& v : encodings.front().accumulateVariables()) {
345 auto it = std::find(vars.begin(), vars.end(), v);
346 if(it != vars.end()) vars.erase(it);
349 encodings.erase(encodings.begin());
363 CARL_LOG_INFO(
"carl.thom.compare",
"lhs = " << lhs <<
", rhs = " << rhs);
367 CARL_LOG_TRACE(
"carl.thom.compare",
"encodings are not comparable");
375 CARL_LOG_TRACE(
"carl.thom.compare",
"comparing encodings with same underlying polynomials");
382 CARL_LOG_TRACE(
"carl.thom.compare",
"comparing encodings with different underlying polynomials, !!hopefully with same defining point!!");
389 CARL_LOG_TRACE(
"carl.thom.compare",
"one of the encodings is new on this level");
390 if(lhs.
mPoint ==
nullptr) {
393 if(rhs.
mPoint ==
nullptr) {
397 CARL_LOG_ASSERT(
"carl.thom.compare",
false,
"we should never get here ... inputs where lhs = " << lhs <<
", rhs = " << rhs);
413 CARL_LOG_TRACE(
"carl.thom.compare",
"\nlhs = " << lhs <<
"\nrhs = " << rhs <<
"\nlhs.mPoint = " << lhs.
mPoint <<
"\nrhs.mPoint = " << rhs.
mPoint);
415 CARL_LOG_TRACE(
"carl.thom.compare",
"underlying points are unequal");
418 CARL_LOG_TRACE(
"carl.thom.compare",
"underlying points are equal");
447 if(this->mPoint !=
nullptr && other.
mPoint !=
nullptr) {
462 for(
const auto& r: roots) {
465 CARL_LOG_ASSERT(
"carl.thom.samples",
false,
"we should never get here");
477 Number epsilon(INITIAL_OFFSET);
478 std::cout << "epsilon =
" << epsilon << std::endl;
479 // pick the polynomial with smaller degree here (or lhs, if equal degree)
480 if(lhs.mP.degree(lhs.mMainVar) <= rhs.mP.degree(rhs.mMainVar)) {
481 ThomEncoding<Number> res = lhs + epsilon;
486 CARL_LOG_TRACE("carl.thom.samples
", "result:
" << res);
491 ThomEncoding<Number> res = rhs + epsilon;
492 std::cout << "res =
" << res << std::endl;
497 CARL_LOG_TRACE("carl.thom.samples
", "result:
" << res);
504 * finds an intermediate point between the thom encoding and the rational
505 * always returns a rational
507 static Number intermediatePoint(const ThomEncoding<Number>& lhs, const Number& rhs) {
508 CARL_LOG_INFO("carl.thom.samples
", lhs << ",
" << rhs);
509 CARL_LOG_ASSERT("carl.thom.samples
", lhs < rhs, "intermediatePoint with wrong order or equal arguments called
");
511 Number epsilon(INITIAL_OFFSET);
517 CARL_LOG_TRACE("carl.thom.samples
", "result:
" << res);
521 static Number intermediatePoint(const Number& lhs, const ThomEncoding<Number>& rhs) {
522 CARL_LOG_INFO("carl.thom.samples
", lhs << ",
" << rhs);
523 CARL_LOG_ASSERT("carl.thom.samples
", lhs < rhs, "intermediatePoint with wrong order order in arguments called
");
525 Number epsilon(INITIAL_OFFSET);
531 CARL_LOG_TRACE("carl.thom.samples
", "result:
" << res);
538 void print(std::ostream& os) const {
539 os << "\n---------------------------------------------------
" << std::endl;
540 os << "Thom encoding
" << std::endl;
541 os << "---------------------------------------------------
" << std::endl;
542 os << "sign condition:\t\t\t
" << mSc << std::endl;
543 os << "relevant:\t\t\t
" << mRelevant << std::endl;
545 os << "main variable: \t\t\t
" << mMainVar << std::endl;
546 os << "point below:\t\t\t
" << mPoint << std::endl;
547 os << "sign determination obejct:\t
" << mSd << std::endl;
548 os << "dimension:\t\t\t
" << dimension() << std::endl;
549 os << "---------------------------------------------------
" << std::endl;
552 }; // class ThomEncoding
557 // compare thom encodings with thom encodings
559 bool operator<(const ThomEncoding<N>& lhs, const ThomEncoding<N>& rhs) { return ThomEncoding<N>::compare(lhs, rhs) == LESS; }
561 bool operator<=(const ThomEncoding<N>& lhs, const ThomEncoding<N>& rhs) { return ThomEncoding<N>::compare(lhs, rhs) != GREATER; }
563 bool operator>(const ThomEncoding<N>& lhs, const ThomEncoding<N>& rhs) { return ThomEncoding<N>::compare(lhs, rhs) == GREATER; }
565 bool operator>=(const ThomEncoding<N>& lhs, const ThomEncoding<N>& rhs) { return ThomEncoding<N>::compare(lhs, rhs) != LESS; }
567 bool operator==(const ThomEncoding<N>& lhs, const ThomEncoding<N>& rhs) { return ThomEncoding<N>::compare(lhs, rhs) == EQUAL; }
569 bool operator!=(const ThomEncoding<N>& lhs, const ThomEncoding<N>& rhs) { return ThomEncoding<N>::compare(lhs, rhs) != EQUAL; }
571 // comparing with rational numbers
573 bool operator<(const ThomEncoding<N>& lhs, const N& rhs) { return ThomEncoding<N>::compareRational(lhs, rhs) == LESS; }
575 bool operator<=(const ThomEncoding<N>& lhs, const N& rhs) { return ThomEncoding<N>::compareRational(lhs, rhs) != GREATER; }
577 bool operator>(const ThomEncoding<N>& lhs, const N& rhs) { return ThomEncoding<N>::compareRational(lhs, rhs) == GREATER; }
579 bool operator>=(const ThomEncoding<N>& lhs, const N& rhs) { return ThomEncoding<N>::compareRational(lhs, rhs) != LESS; }
581 bool operator==(const ThomEncoding<N>& lhs, const N& rhs) { return ThomEncoding<N>::compareRational(lhs, rhs) == EQUAL; }
583 bool operator!=(const ThomEncoding<N>& lhs, const N& rhs) { return ThomEncoding<N>::compareRational(lhs, rhs) != EQUAL; }
586 bool operator<(const N& lhs, const ThomEncoding<N>& rhs) { return rhs > lhs; }
588 bool operator<=(const N& lhs, const ThomEncoding<N>& rhs) { return rhs >= lhs; }
590 bool operator>(const N& lhs, const ThomEncoding<N>& rhs) { return rhs < lhs; }
592 bool operator>=(const N& lhs, const ThomEncoding<N>& rhs) { return rhs <= lhs; }
594 bool operator==(const N& lhs, const ThomEncoding<N>& rhs) { return rhs == lhs; }
596 bool operator!=(const N& lhs, const ThomEncoding<N>& rhs) { return rhs != lhs; }
599 ThomEncoding<N> operator+(const N& lhs, const ThomEncoding<N>& rhs) { return rhs + lhs; }
602 std::ostream& operator<<(std::ostream& os, const ThomEncoding<N>& rhs) {
603 os << "TE
" << rhs.polynomial() << " in
" << rhs.main_var() << ",
" << rhs.signCondition();
604 if(rhs.dimension() > 1) {
605 os << " OVER
" << rhs.point();
#define CARL_LOG_TRACE(channel, msg)
#define CARL_LOG_ASSERT(channel, condition, msg)
#define CARL_LOG_INFO(channel, msg)
int main(int argc, char **argv)
carl is the main namespace for the library.
UnivariatePolynomial< C > to_univariate_polynomial(const MultivariatePolynomial< C, O, P > &p)
Convert a univariate polynomial that is currently (mis)represented by a 'MultivariatePolynomial' into...
const T & derivative(const T &t, Variable, std::size_t n=1)
Computes the n'th derivative of a number, which is either the number itself (for n = 0) or zero.
Sign
This class represents the sign of a number .
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
std::list< MultivariatePolynomial< Number > > der(const MultivariatePolynomial< Number > &p, Variable::Arg var, uint from, uint upto)
Sign sgn(const Number &n)
Obtain the sign of the given number.
std::list< ThomEncoding< Number > > realRootsThom(const MultivariatePolynomial< Number > &p, Variable::Arg mainVar, std::shared_ptr< ThomEncoding< Number >> point_ptr, const Interval< Number > &interval=Interval< Number >::unbounded_interval())
Coeff substitute(const Monomial &m, const std::map< Variable, Coeff > &substitutions)
Applies the given substitutions to a monomial.
@ WEAK
the given bound is compared by a weak ordering relation
@ STRICT
the given bound is compared by a strict ordering relation
@ INFTY
the given bound is interpreted as minus or plus infinity depending on whether it is the left or the r...
void variables(const BasicConstraint< Pol > &c, carlVariables &vars)
UnivariatePolynomial< Coefficient > reverse(UnivariatePolynomial< Coefficient > &&p)
Reverses the order of the coefficients of this polynomial.
A Variable represents an algebraic variable that can be used throughout carl.
The class which contains the interval arithmetic including trigonometric functions.
BoundType lower_bound_type() const
The getter for the lower bound type of the interval.
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.
BoundType upper_bound_type() const
The getter for the upper bound type of the interval.
This class represents a univariate polynomial with coefficients of an arbitrary type.
const std::vector< Coefficient > & coefficients() const &
Retrieves the coefficients defining this polynomial.
bool is_constant() const
Check if the polynomial is constant.
std::size_t degree(Variable::Arg var) const
Calculates the degree of this polynomial with respect to the given variable.
bool is_univariate() const
Checks whether only one variable occurs.
const Coeff & lcoeff() const
Returns the coefficient of the leading term.
bool isSuffixOf(const SignCondition &other) const
static ThomComparisonResult compare(const SignCondition &lhs, const SignCondition &rhs)
SignCondition trailingPart(uint count) const
Sign sgn(const Polynomial &p) const
ThomEncoding< Number > operator+(const Number &rhs) const
bool containedIn(const Interval< Number > &i) const
std::list< Polynomial > relevantDerivatives() const
std::list< Polynomial > accumulatePolynomials() const
std::list< Variable > accumulateVariables() const
ThomEncoding< Number > concat(const ThomEncoding< Number > &other) const
static ThomComparisonResult compareDifferentPoly(const ThomEncoding< Number > &lhs, const ThomEncoding< Number > &rhs)
static ThomComparisonResult compareRational(const ThomEncoding< Number > &lhs, const Number &rhs)
Sign signOnPolynomial(const Polynomial &p) const
ThomEncoding< Number > lowestInChain() const
SignCondition accumulateRelevantSigns() const
SignCondition accumulateSigns() const
std::shared_ptr< SignDetermination< Number > > mSd
SignDetermination< Number > sd() const
SignCondition relevantSignCondition() const
std::shared_ptr< ThomEncoding< Number > > mPoint
const Polynomial & polynomial() const
MultivariatePolynomial< Number > Polynomial
static ThomComparisonResult compare(const ThomEncoding< Number > &lhs, const ThomEncoding< Number > &rhs)
bool makesPolynomialZero(const Polynomial &pol, Variable::Arg pol_mainVar) const
SignCondition signCondition() const
ThomEncoding(SignCondition sc, const Polynomial &p, Variable mainVar, std::shared_ptr< ThomEncoding< Number >> point, std::shared_ptr< SignDetermination< Number >> sd, uint mRelevant)
Sign sgn(const UnivariatePolynomial< Number > &p) const
Number integer_below() const
static ThomEncoding< Number > intermediatePoint(const ThomEncoding< Number > &lhs, const ThomEncoding< Number > &rhs)
static bool areComparable(const ThomEncoding< Number > &lhs, const ThomEncoding< Number > &rhs)
static ThomComparisonResult compareDifferentLevels(const ThomEncoding< Number > &lhs, const ThomEncoding< Number > &rhs)
const ThomEncoding< Number > & point() const
ThomEncoding(const ThomEncoding< Number > &te, std::shared_ptr< ThomEncoding< Number >> point)
static ThomEncoding< Number > analyzeTEMap(const std::map< Variable, ThomEncoding< Number >> &m)
const auto & get_number() const
void extendSignCondition() const
bool equals(const ThomEncoding< Number > &other) const
ThomEncoding(const Number &n, Variable mainVar, std::shared_ptr< ThomEncoding< Number >> point=nullptr)
Variable::Arg main_var() const