carl  24.04
Computer ARithmetic Library
SignVariations.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <carl-arith/core/Sign.h>
4 #include "../UnivariatePolynomial.h"
6 
7 namespace carl {
8 
9 namespace detail_sign_variations {
10 
11 /**
12  * Reverses the order of the coefficients of this polynomial.
13  * This method is meant to be called by signVariations only.
14  * @complexity O(n)
15  */
16 template<typename Coefficient>
18  std::vector<Coefficient> coeffs(std::move(p.coefficients()));
19  std::reverse(coeffs.begin(), coeffs.end());
20  return UnivariatePolynomial<Coefficient>(p.main_var(), std::move(coeffs));
21 }
22 
23 /**
24  * Scale the variable, i.e. apply \f$ x \rightarrow factor * x \f$
25  * This method is meant to be called by signVariations only.
26  * @param factor Factor to scale x.
27  * @complexity O(n)
28  */
29 template<typename Coefficient>
31  std::vector<Coefficient> coeffs(std::move(p.coefficients()));
32  Coefficient f = factor;
33  for (auto& c: coeffs) {
34  c *= f;
35  f *= factor;
36  }
37  return UnivariatePolynomial<Coefficient>(p.main_var(), std::move(coeffs));
38 }
39 
40 /**
41  * Shift the variable by a, i.e. apply \f$ x \rightarrow x + a \f$
42  * This method is meant to be called by signVariations only.
43  * @param a Offset to shift x.
44  * @complexity O(n^2)
45  */
46 template<typename Coefficient>
48  std::vector<Coefficient> next;
49  next.reserve(p.coefficients().size());
50  next.push_back(p.coefficients().back());
51 
52  for (std::size_t i = 0; i < p.coefficients().size()-1; i++) {
53  next.push_back(next.back());
54  for (std::size_t j = i; j > 0; j--) {
55  next[j] = a * next[j] + next[j-1];
56  }
57  next[0] = a * next[0] + p.coefficients()[p.coefficients().size()-2-i];
58  }
59  return UnivariatePolynomial<Coefficient>(p.main_var(), std::move(next));
60 }
61 
62 }
63 
64 /**
65  * Counts the sign variations (i.e. an upper bound for the number of real roots) via Descarte's rule of signs.
66  * This is an upper bound for countRealRoots().
67  * @param polynomial A polynomial.
68  * @param interval Count roots within this interval.
69  * @return Upper bound for number of real roots within the interval.
70  */
71 template<typename Coefficient>
73  if (interval.is_empty()) return 0;
74  if (interval.is_point_interval()) {
75  std::vector<Coefficient> vals;
76  Coefficient factor = carl::constant_one<Coefficient>::get();
77  for (const auto& c: polynomial.coefficients()) {
78  vals.push_back(c * factor);
79  factor *= interval.lower();
80  }
81  auto res = carl::sign_variations(vals.begin(), vals.end(), [](const auto& c){ return carl::sgn(c); });
82  CARL_LOG_TRACE("carl.core", polynomial << " has " << res << " sign variations at " << interval.lower());
83  return res;
84  }
86  p = detail_sign_variations::shift(p, interval.lower());
87  p = detail_sign_variations::scale(std::move(p), interval.diameter());
88  p = detail_sign_variations::reverse(std::move(p));
91  assert(p.is_consistent());
92  auto res = carl::sign_variations(p.coefficients().begin(), p.coefficients().end(), [](const auto& c){ return carl::sgn(c); });
93  CARL_LOG_TRACE("carl.core", polynomial << " has " << res << " sign variations within " << interval);
94  return res;
95 }
96 
97 }
#define CARL_LOG_TRACE(channel, msg)
Definition: carl-logging.h:44
carl is the main namespace for the library.
std::uint64_t uint
Definition: numbers.h:16
std::size_t sign_variations(InputIterator begin, InputIterator end)
Counts the number of sign variations in the given object range.
Definition: Sign.h:69
UnivariatePolynomial< Coefficient > reverse(UnivariatePolynomial< Coefficient > &&p)
Reverses the order of the coefficients of this polynomial.
UnivariatePolynomial< Coefficient > shift(const UnivariatePolynomial< Coefficient > &p, const Coefficient &a)
Shift the variable by a, i.e.
UnivariatePolynomial< Coefficient > scale(UnivariatePolynomial< Coefficient > &&p, const Coefficient &factor)
Scale the variable, i.e.
The class which contains the interval arithmetic including trigonometric functions.
Definition: Interval.h:134
bool is_empty() const
Function which determines, if the interval is empty.
Definition: Interval.h:1056
const Number & lower() const
The getter for the lower boundary of the interval.
Definition: Interval.h:840
bool is_point_interval() const
Function which determines, if the interval is a pointinterval.
Definition: Interval.h:1071
Number diameter() const
Returns the diameter of the interval.
static const T & get()
Definition: constants.h:51
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.
bool is_consistent() const
Asserts that this polynomial over numeric coefficients complies with the requirements and assumptions...