PFASST++
polynomial_impl.hpp
Go to the documentation of this file.
2 
3 #include <algorithm>
4 #include <cassert>
5 #include <cmath>
6 #include <complex>
7 using namespace std;
8 
9 
10 namespace pfasst
11 {
12  namespace quadrature
13  {
17  template<typename CoeffT>
19  : c(n, CoeffT(0.0))
20  {}
21 
22  template<typename CoeffT>
24  {
25  return c.size() - 1;
26  }
27 
28  template<typename CoeffT>
29  CoeffT& Polynomial<CoeffT>::operator[](const size_t i)
30  {
31  return c.at(i);
32  }
33 
34  template<typename CoeffT>
36  {
37  Polynomial<CoeffT> p(c.size() - 1);
38  for (size_t j = 1; j < c.size(); j++) {
39  p[j - 1] = j * c[j];
40  }
41  return p;
42  }
43 
44  template<typename CoeffT>
46  {
47  Polynomial<CoeffT> p(c.size() + 1);
48  for (size_t j = 0; j < c.size(); j++) {
49  p[j + 1] = c[j] / (j + 1);
50  }
51  return p;
52  }
53 
54  template<typename CoeffT>
56  {
57  Polynomial<CoeffT> p(c.size());
58  for (size_t j = 0; j < c.size(); j++) {
59  p[j] = c[j] / c.back();
60  }
61  return p;
62  }
63 
69  template<typename CoeffT>
70  vector<CoeffT> Polynomial<CoeffT>::roots(size_t num_iterations, CoeffT ztol) const
71  {
72  assert(c.size() >= 1);
73  size_t n = c.size() - 1;
74 
75  // initial guess
76  vector<complex<CoeffT>> z0(n);
77  for (size_t j = 0; j < n; j++) {
78  z0[j] = pow(complex<double>(0.4, 0.9), j);
79  }
80 
81  // durand-kerner-weierstrass iterations
82  Polynomial<CoeffT> p = this->normalize();
83  for (size_t k = 0; k < num_iterations; k++) {
84  complex<CoeffT> num, den;
85  for (size_t i = 0; i < n; i++) {
86  num = p.evaluate(z0[i]);
87  den = 1.0;
88  for (size_t j = 0; j < n; j++) {
89  if (j == i) { continue; }
90  den = den * (z0[i] - z0[j]);
91  }
92  z0[i] = z0[i] - num / den;
93  }
94  }
95 
96  vector<CoeffT> roots(n);
97  for (size_t j = 0; j < n; j++) {
98  roots[j] = abs(z0[j]) < ztol ? 0.0 : real(z0[j]);
99  }
100 
101  sort(roots.begin(), roots.end());
102  return roots;
103  }
104 
105  template<typename CoeffT>
107  {
108  if (order == 0) {
109  Polynomial<CoeffT> p(1);
110  p[0] = 1.0;
111  return p;
112  }
113 
114  if (order == 1) {
115  Polynomial<CoeffT> p(2);
116  p[0] = 0.0;
117  p[1] = 1.0;
118  return p;
119  }
120 
121  Polynomial<CoeffT> p0(order + 1), p1(order + 1), p2(order + 1);
122  p0[0] = 1.0; p1[1] = 1.0;
123 
124  // (n + 1) P_{n+1} = (2n + 1) x P_{n} - n P_{n-1}
125  for (size_t m = 1; m < order; m++) {
126  for (size_t j = 1; j < order + 1; j++) {
127  p2[j] = ((2 * m + 1) * p1[j - 1] - m * p0[j]) / (m + 1);
128  }
129  p2[0] = - int(m) * p0[0] / (m + 1);
130 
131  for (size_t j = 0; j < order + 1; j++) {
132  p0[j] = p1[j];
133  p1[j] = p2[j];
134  }
135  }
136 
137  return p2;
138  }
139  } // ::pfasst::quadrature
140 } // ::pfasst
Representation of a polynomial including differentiation, integration and root finding.
Definition: polynomial.hpp:28
Polynomial< CoeffT > normalize() const
Normalizes this polynomial with respect to \( c_0 \).
Polynomial< CoeffT > integrate() const
Integrates this polynomial.
STL namespace.
Polynomial< CoeffT > differentiate() const
Differentiate this polynomial.
vector< CoeffT > roots(size_t num_iterations=100, CoeffT ztol=1.0e-20) const
Computes the roots of this polynomial.
static Polynomial< CoeffT > legendre(const size_t order)
Computes the Legendre polynomial of given order.
size_t order() const
Order of this polynomial.
CoeffT & operator[](const size_t i)
Access coefficient i.
xtype evaluate(const xtype x) const
Evaluate polynomial for given value.
Definition: polynomial.hpp:95