7 template<
typename CoeffType>
9 unsigned num_roots = 0;
10 for(
size_t i = 0; i < coeffs.size(); ++i){
11 if(coeffs.at(i) == 0)
continue;
12 for(
size_t j = i + 1; j < coeffs.size(); ++j){
13 if(coeffs.at(j) == 0){
16 if((coeffs.at(i) < 0 && coeffs.at(j) > 0)
17 || (coeffs.at(i) > 0 && coeffs.at(j) < 0)) ++num_roots;
26 template<
typename CoeffType>
47 if(degree >=
coeffs_.size() && coefficient != 0){
49 coeffs_.at(degree) = coefficient;
50 }
else if(degree <
coeffs_.size()){
51 coeffs_.at(degree) = coefficient;
52 if(coefficient == 0 && degree+1 ==
coeffs_.size()){
59 if(degree >=
coeffs_.size())
return 0;
82 operator std::vector<CoeffType>()
const{
86 template<
typename ArgType>
87 auto operator()(
const ArgType &x)
const -> decltype(CoeffType(0)*x){
88 if(
coeffs_.size() == 0)
return 0;
90 for(
size_t degree =
coeffs_.size()-2; degree <
coeffs_.size(); --degree){
91 value = value * x +
coeffs_.at(degree);
100 for(
size_t i = 0; i < p.
coeffs_.size(); ++i){
111 for(
size_t i = 0; i < p.
coeffs_.size(); ++i){
119 std::vector<CoeffType> output(
Degree()+p.
Degree()+1, 0);
120 for(
size_t deg_a = 0; deg_a <
coeffs_.size(); ++deg_a){
121 for(
size_t deg_b = 0; deg_b < p.
coeffs_.size(); ++deg_b){
134 size_t before_deg = rem.
Degree();
153 size_t before_deg = rem.
Degree();
194 if(coeffs_.size() == 0)
return;
198 for(
size_t i = coeffs_.size()-1; i < coeffs_.size() && is_zero; --i){
199 if(coeffs_.at(i) != 0){
205 coeffs_.resize(is_zero ? 0 : degree + 1, 0);
209 template<
typename CoeffType>
214 template<
typename CoeffType>
219 template<
typename CoeffType>
224 template<
typename CoeffType>
229 template<
typename CoeffType>
234 template<
typename CoeffType>
235 std::ostream & operator<<(std::ostream &stream, const Polynomial<CoeffType> &p){
236 stream <<
"Poly[" << p.
Degree() <<
"](";
237 for(
size_t deg = 0; deg < p.Degree(); ++deg){
238 stream << p.GetCoefficient(deg) <<
',';
240 stream << p.GetCoefficient(p.Degree()) <<
')';
244 template<
typename CoeffType>
246 auto coeffs =
static_cast<std::vector<CoeffType>
>(poly);
248 for(
size_t from_degree = 1; from_degree < coeffs.size(); ++from_degree){
249 coeffs.at(from_degree-1) = from_degree * coeffs.at(from_degree);
256 template<
typename CoeffType>
258 std::vector<Polynomial<CoeffType> > out(1, poly);
259 if(poly.
Degree() == 0)
return out;
262 auto negrem = -(out.at(i) % out.at(i+1));
263 while(!negrem.IsZero()){
265 out.push_back(negrem);
267 negrem = -(out.at(i) % out.at(i+1));
272 template<
typename CoeffType>
275 std::vector<CoeffType> pos_seq, neg_seq;
276 for(
const auto &p: sturm){
277 pos_seq.push_back(p.LeadingCoefficient());
278 neg_seq.push_back(p.Degree()%2 == 0 ? p.LeadingCoefficient() : -p.LeadingCoefficient());
284 return changes_neg - changes_pos;
287 template<
typename CoeffType,
typename ArgType =
double>
290 std::vector<CoeffType> pos_seq, neg_seq;
291 for(
const auto &p: sturm){
292 pos_seq.push_back(p(high));
293 neg_seq.push_back(p(low));
298 return changes_neg - changes_pos;
CoeffType LeadingCoefficient() const
unsigned NumRoots(const Polynomial< CoeffType > &poly)
Polynomial operator+() const
auto operator()(const ArgType &x) const -> decltype(CoeffType(0)*x)
std::vector< CoeffType > coeffs_
Polynomial & operator=(const Polynomial &)=default
Polynomial< CoeffType > operator*(Polynomial< CoeffType > a, Polynomial< CoeffType > b)
Polynomial & operator-=(const Polynomial &p)
Polynomial & operator*=(const Polynomial &p)
unsigned GetSignChanges(const std::vector< CoeffType > &coeffs)
Polynomial(const std::vector< CoeffType > &coeffs)
std::size_t Degree() const
Polynomial operator-() const
Polynomial & operator/=(const Polynomial &p)
Polynomial & operator%=(const Polynomial &p)
Polynomial & operator+=(const Polynomial &p)
Polynomial< CoeffType > Derivative(const Polynomial< CoeffType > &poly, size_t n=1)
Polynomial(const CoeffType &coeff)
void TruncateToDegree(std::size_t degree)
Polynomial< CoeffType > operator%(Polynomial< CoeffType > a, Polynomial< CoeffType > b)
Polynomial< CoeffType > operator/(Polynomial< CoeffType > a, Polynomial< CoeffType > b)
bool operator!=(const Polynomial &p)
bool operator==(const Polynomial &p)
void SetCoefficient(std::size_t degree, CoeffType coefficient)
CoeffType GetCoefficient(std::size_t degree) const
std::vector< Polynomial< CoeffType > > SturmSequence(const Polynomial< CoeffType > &poly)