18 template<
typename Number>
20 template<
typename Number>
24 template<
typename Number>
35 template<
typename Number>
43 "\n---------------------------------------------\n"
44 <<
"Thom Root Finder called:\n"
45 <<
"---------------------------------------------\n"
46 <<
"p = " << p <<
" in " << mainVar <<
"\n"
47 <<
"m = " << m <<
"\n"
48 <<
"interval = " << interval <<
"\n"
49 <<
"---------------------------------------------");
54 return std::list<ThomEncoding<Number>>();
57 for(
const auto& entry : m) {
58 CARL_LOG_ASSERT(
"carl.thom.rootfinder", entry.first == entry.second.main_var(),
"invalid map Variable -> Thom encoding");
62 CARL_LOG_ASSERT(
"carl.thom.rootfinder", m.find(v) != m.end(),
"there is a variable which is in p but not in m");
67 return realRootsThom<Number>(p, mainVar,
nullptr, interval);
73 std::shared_ptr<ThomEncoding<Number>> point_ptr = std::make_shared<ThomEncoding<Number>>(point);
116 template<
typename Number>
124 std::list<ThomEncoding<Number>> result;
128 if(point_ptr ==
nullptr) {
129 std::list<Polynomial> derivatives =
der(p, mainVar, 1, p.
degree(mainVar));
131 std::vector<Polynomial> zeroSet = {p};
135 if(numOfRoots == 0)
return {};
137 std::list<SignCondition> signs = {};
138 auto it = derivatives.rbegin();
139 while(signs.size() < numOfRoots) {
143 std::shared_ptr<SignDetermination<Number>> sd_ptr = std::make_shared<SignDetermination<Number>>(sd);
144 for(
const auto& sigma : signs) {
152 result.push_back(newEncoding);
158 if(point_ptr->makesPolynomialZero(p, mainVar)) {
163 zeroSet.push_front(p);
167 if(numOfRoots == 0)
return {};
169 std::list<Polynomial> pointDerivatives = point_ptr->sd().processedPolynomials();
172 std::list<Polynomial> pDerivatives =
der(p, mainVar, 1, p.
degree(mainVar));
174 std::list<SignCondition> signs = {};
176 auto it = pDerivatives.rbegin();
177 while(signs.size() < numOfRoots) {
183 std::shared_ptr<SignDetermination<Number>> sd_ptr = std::make_shared<SignDetermination<Number>>(sd);
184 SignCondition pointSigns = point_ptr->accumulateRelevantSigns();
185 for(
const auto& sigma : signs) {
186 CARL_LOG_ASSERT(
"carl.thom.rootfinder", sigma.size() == pointSigns.size() + relevant,
"");
187 if(pointSigns.isSuffixOf(sigma)) {
189 newSigma.resize(relevant);
198 result.push_back(newEncoding);
204 std::vector<ThomEncoding<Number>> result_vec(result.begin(), result.end());
205 std::sort(result_vec.begin(), result_vec.end());
206 result = std::list<ThomEncoding<Number>>(result_vec.begin(), result_vec.end());
211 auto it = result.begin();
212 while(it != result.end() && *it <= interval.
lower()) {
213 it = result.erase(it);
217 auto it = result.begin();
218 while(it != result.end() && *it < interval.
lower()) {
219 it = result.erase(it);
225 auto it = result.begin();
226 while(it != result.end() && *it >= interval.
upper()) {
227 it = result.erase(it);;
233 auto it = result.begin();
234 while(it != result.end() && *it > interval.
upper()) {
235 it = result.erase(it);
240 CARL_LOG_INFO(
"carl.thom.rootfinder",
"found the following roots: " << result);
268 template<
typename Coeff,
typename Number>
278 std::list<ThomEncoding<Number>> roots;
281 std::map<Variable, ThomEncoding<Number>> TEmap;
285 assert(m.count(v) > 0);
286 if (m.at(v).is_numeric()) {
289 TEmap.emplace(v, m.at(v).getThomEncoding());
294 std::list<RealAlgebraicNumber<Number>> roots_triv;
302 tmp_univ.eliminateZeroRoots();
304 CARL_LOG_TRACE(
"carl.thom.rootfinder",
"tmp_univ = " << tmp_univ);
305 switch (tmp_univ.
degree()) {
307 CARL_LOG_TRACE(
"carl.thom.rootfinder",
"roots_triv = " << roots_triv);
312 assert(a != Number(0));
314 CARL_LOG_TRACE(
"carl.thom.rootfinder",
"roots_triv = " << roots_triv);
319 assert(a != Number(0));
320 CARL_LOG_TRACE(
"carl.thom.rootfinder",
"a = " << a <<
", b = " << b <<
", c = " << c);
324 Number rad = b*b - 4*a*c;
327 CARL_LOG_TRACE(
"carl.thom.rootfinder",
"roots_triv = " << roots_triv);
361 std::list<RealAlgebraicNumber<Number>> res;
363 for(
const auto& number : roots_triv) res.push_back(number);
365 CARL_LOG_TRACE(
"carl.thom.rootfinder",
"found the following roots: " << res);
#define CARL_LOG_TRACE(channel, msg)
#define CARL_LOG_ASSERT(channel, condition, msg)
#define CARL_LOG_INFO(channel, msg)
carl is the main namespace for the library.
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)
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())
typename UnderlyingNumberType< P >::type Coeff
@ WEAK
the given bound is compared by a weak ordering relation
@ STRICT
the given bound is compared by a strict ordering relation
void variables(const BasicConstraint< Pol > &c, carlVariables &vars)
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.
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.
static Interval< Number > unbounded_interval()
Method which returns the unbounded interval rooted at 0.
This class represents a univariate polynomial with coefficients of an arbitrary type.
const std::vector< Coefficient > & coefficients() const &
Retrieves the coefficients defining this polynomial.
Variable main_var() const
Retrieves the main variable of this polynomial.
UnivariatePolynomial< NewCoeff > convert() const
uint degree() const
Get the maximal exponent of the main variable.
bool zero_is_root() const
Checks if zero is a real root of 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.
bool has(Variable v) const
uint sizeOfZeroSet() const
std::list< SignCondition > getSignsAndAddAll(InputIt first, InputIt last)
std::list< SignCondition > getSignsAndAdd(const Polynomial &p)
std::list< Polynomial > accumulatePolynomials() const
static ThomEncoding< Number > analyzeTEMap(const std::map< Variable, ThomEncoding< Number >> &m)