1 #ifndef VTESTBED_CORE_POLYNOMIAL_HH 2 #define VTESTBED_CORE_POLYNOMIAL_HH 6 #include <initializer_list> 9 #include <vtestbed/base/blitz.hh> 10 #include <vtestbed/core/math.hh> 27 typedef blitz::Array<T,1> array_type;
29 typedef value_type* pointer;
30 typedef const value_type* const_pointer;
35 >::type complex_polynomial;
39 blitz::Array<std::complex<T>,1>
40 >::type complex_array;
43 array_type _coefficients;
52 _coefficients = value;
57 _coefficients{coefs} {}
61 _coefficients(coefs.size()) {
62 std::copy(coefs.begin(), coefs.end(), this->begin());
67 _coefficients{rhs._coefficients.copy()} {}
71 this->_coefficients.reference(rhs._coefficients.copy());
77 this->_coefficients.reference(rhs._coefficients);
89 evaluate(value_type x)
const {
91 const_pointer last = this->begin()-1;
92 const_pointer first = this->end()-1;
93 while (first != last) {
94 result = fma(result, x, *first);
101 operator()(value_type x)
const {
102 return this->evaluate(x);
105 inline const value_type&
106 operator[](
int i)
const noexcept {
107 return this->_coefficients(i);
111 operator[](
int i) noexcept {
112 return this->_coefficients(i);
116 begin()
const noexcept {
117 return this->_coefficients.data();
122 return this->_coefficients.data();
126 end()
const noexcept {
127 return this->_coefficients.data() + this->size();
132 return this->_coefficients.data() + this->size();
136 size()
const noexcept {
137 return this->_coefficients.extent(0);
141 order()
const noexcept {
142 return std::max(0, this->size() - 1);
147 blitz::swap(this->_coefficients, rhs._coefficients);
150 inline const array_type&
151 coefficients()
const noexcept {
152 return this->_coefficients;
156 coefficients() noexcept {
157 return this->_coefficients;
160 inline const value_type&
161 coefficients(
int i)
const noexcept {
162 return this->_coefficients(i);
166 coefficients(
int i) noexcept {
167 return this->_coefficients(i);
170 inline complex_polynomial
172 complex_polynomial result(this->size());
173 const int n = this->size();
174 for (
int i=0; i<n; ++i) {
175 result[i] = std::conj((*
this)[n-1-i]);
181 operator*(
const Polynomial& lhs,
const T& rhs) {
186 operator*(
const T& lhs,
const Polynomial& rhs) {
191 operator/(
const Polynomial& lhs,
const T& rhs) {
199 if (lhs.size() < rhs.size()) {
201 Range r{0,lhs.size()-1};
202 result._coefficients(r) += lhs._coefficients;
205 Range r{0,rhs.size()-1};
206 result._coefficients(r) += rhs._coefficients;
215 if (lhs.size() < rhs.size()) {
217 Range r{0,lhs.size()-1};
218 result._coefficients(r) -= lhs._coefficients;
221 Range r{0,rhs.size()-1};
222 result._coefficients(r) -= rhs._coefficients;
245 const int n = p.size();
247 const T conj_a_0 = std::conj(p[0]);
248 const T a_n = p[n-1];
249 for (
int i=0; i<n-1; ++i) {
250 result[i] = conj_a_0*p[i] - a_n*std::conj(p[n-1-i]);
265 const int n = p.size();
266 Polynomial<T> result(n-1);
268 const T a_n = p[n-1];
269 for (
int i=0; i<n-1; ++i) {
270 result[i] = a_0*p[i] - a_n*p[n-1-i];
289 typedef decltype(std::real(p[0])) Real;
290 blitz::Array<Real,1> mask(n);
291 int negative_degree = 0;
292 bool negative_multiple_times =
false;
293 for (
int i=0; i<n-1; ++i) {
294 p = schur_transform<T>(p);
295 Real delta = std::real(p[0]);
297 #if defined(VTB_DEBUG_SCHUR_COHN) 298 std::clog <<
"delta=" << delta << std::endl;
301 if (negative_degree == 0) {
302 negative_degree = p.size();
304 negative_multiple_times =
true;
308 if (negative_degree == 0) {
311 if (!negative_multiple_times) {
312 return negative_degree;
321 #endif // vim:filetype=cpp
auto schur_transform(const Polynomial< T > &p) -> typename std::enable_if< is_complex< T >::value, Polynomial< T >>::type
Schur transform for polynomials with complex coefficients.
int num_roots_inside_unit_disk(Polynomial< T > p)
Finds the number of polynomial roots inside the unit disk.