6#ifndef THEORETICA_POLYNOMIAL_H
7#define THEORETICA_POLYNOMIAL_H
9#ifndef THEORETICA_NO_PRINT
14#include "../core/real_analysis.h"
15#include "../algebra/vec.h"
16#include "../complex/complex.h"
17#include "../complex/complex_analysis.h"
24 template<
typename Type = real>
27 std::vector<Type> coeff;
46 inline const Type&
at(
unsigned int i)
const {
51 inline Type&
at(
unsigned int i) {
69 template<
typename EvalType = Type>
70 inline EvalType
eval(EvalType x)
const {
78 for (
unsigned int i = 0; i < coeff.size(); ++i)
79 sum = coeff[coeff.size() - i - 1] + x *
sum;
86 template<
typename EvalType = Type>
96 for (
int i = coeff.size() - 1; i >= 0; --i) {
108 for (
unsigned int i = coeff.size() - 1; i >= 0; --i) {
127 r.coeff.resize(
max(coeff.size(), p.size()));
131 for (; i <
min(coeff.size(), p.size()); ++i)
132 r[i] = coeff[i] + p[i];
134 if (coeff.size() > p.size())
135 for (; i < coeff.size(); ++i)
138 for (; i < p.size(); ++i)
149 r.coeff.resize(
max(coeff.size(), p.size()));
153 for (; i <
min(r.size(), p.size()); ++i)
154 r[i] = coeff[i] - p[i];
156 if (coeff.size() > p.size())
157 for (; i < coeff.size(); ++i)
160 for (; i < p.size(); ++i)
171 r.coeff.resize(this->
size() + p.
size() - 1);
173 for (
unsigned int i = 0; i <
size(); ++i) {
174 for (
unsigned int j = 0; j < p.size(); ++j) {
175 r[i + j] += coeff[i] * p[j];
189 if(d_order == 0 && d[0] == 0) {
201 while(i < this_order) {
204 const unsigned int r_order = r.find_order();
213 r[r_order] / d[d_order],
226 if(i == this_order) {
227 TH_MATH_ERROR(
"polynomial::operator/", i, NO_ALGO_CONVERGENCE);
240 for (
unsigned int i = 0; i <
size(); ++i)
256 for (
unsigned int i = 0; i <
size(); ++i)
267 if(coeff.size() < p.size())
268 coeff.resize(p.size(), Type(0));
270 for (
unsigned int i = 0; i <
min(
size(), p.size()); ++i)
281 if(coeff.size() < p.size())
282 coeff.resize(p.size(), Type(0));
284 for (
unsigned int i = 0; i <
min(coeff.size(), p.size()); ++i)
295 r.coeff.resize(this->
size() + p.
size() - 1, Type(0));
297 for (
unsigned int i = 0; i < coeff.size(); ++i)
298 for (
unsigned int j = 0; j < p.size(); ++j)
299 r[i + j] += coeff[i] * p[j];
309 for (
unsigned int i = 0; i < coeff.size(); ++i)
318 return (*
this = (*
this / a));
330 for (
unsigned int i = 0; i < coeff.size(); ++i)
340 const unsigned int n =
min(other.size(), this->size());
341 for (
unsigned int i = 0; i < n; ++i) {
346 if(
size() > other.size()) {
347 for (
unsigned int i = 0; i <
size(); ++i) {
352 for (
unsigned int i = 0; i < other.size(); ++i) {
365 return coeff.begin();
379 return coeff.cbegin();
397 TH_MATH_ERROR(
"quadratic_roots", order, IMPOSSIBLE_OPERATION);
398 return vec<complex<>, 2>({
nan(),
nan()});
401 const Type p = coeff[1] / coeff[2];
402 const Type q = coeff[0] / coeff[2];
406 return {complex<>(-p), complex<>(0)};
413 z1 = -
sgn(p) * (
abs(p) / 2.0
414 +
abs(p) *
sqrt(complex<>(0.25 - (q / p) / p)));
419 const complex<> s =
sqrt(complex<>(0.25 *
square(p) - q));
430 const std::vector<Type>&
roots) {
432 polynomial<Type> P = {1};
435 for (
unsigned int i = 0; i <
roots.size(); ++i)
436 P *= polynomial<Type>({
roots[i] * -1, 1});
443 inline static polynomial<Type>
monomial(Type c,
unsigned int order) {
446 m.coeff = std::vector<Type>(order + 1, Type(0));
455 inline friend polynomial<Type> operator+(
456 Type r,
const polynomial<Type>& z) {
461 inline friend polynomial<Type> operator-(
462 Type r,
const polynomial<Type>& z) {
467 inline friend polynomial<Type>
operator*(
468 Type r,
const polynomial<Type>& z) {
474#ifndef THEORETICA_NO_PRINT
478 const std::string& unknown =
"x",
479 const std::string& exponentiation =
"^")
const {
481 std::stringstream res;
483 const int sz = coeff.size();
485 for (
int i = sz - 1; i >= 0; --i) {
490 res << (coeff[i] >= 0 ?
"+ " :
"- ");
491 res <<
abs(coeff[i]);
494 res <<
"*" << unknown << exponentiation << i;
509 inline operator std::string() {
517 return out << obj.to_string();
A polynomial of arbitrary order.
Definition polynomial.h:25
polynomial & operator/=(const polynomial &a)
Multiply a polynomial by a scalar value.
Definition polynomial.h:317
polynomial & operator+=(const polynomial &p)
Sum a polynomial to this one.
Definition polynomial.h:264
~polynomial()
Default destructor.
Definition polynomial.h:42
auto begin()
Get an iterator for the first coefficient of the polynomial.
Definition polynomial.h:364
polynomial(std::initializer_list< Type > l)
Initialize from an std::initializer_list.
Definition polynomial.h:39
polynomial(const std::vector< Type > &c)
Initialize from an std::vector.
Definition polynomial.h:36
auto cbegin()
Get a const iterator for the first coefficient of the polynomial.
Definition polynomial.h:378
EvalType eval(EvalType x) const
Evaluate the polynomial using x as variable.
Definition polynomial.h:70
polynomial operator/(const polynomial &d) const
Polynomial division.
Definition polynomial.h:184
void trim()
Remove trailing zero coefficients.
Definition polynomial.h:106
EvalType operator()(EvalType x) const
Evaluate the polynomial using x as variable.
Definition polynomial.h:87
polynomial & operator*=(const polynomial &p)
Multiply two polynomials.
Definition polynomial.h:292
Type & at(unsigned int i)
Access i-th coefficient by reference, with bound checking.
Definition polynomial.h:51
polynomial(Type a)
Initialize as a constant.
Definition polynomial.h:33
auto end()
Get an iterator for the one plus last coefficient of the polynomial.
Definition polynomial.h:371
vec< complex<>, 2 > quadratic_roots() const
Compute the roots of a quadratic polynomial.
Definition polynomial.h:391
friend std::ostream & operator<<(std::ostream &out, const polynomial &obj)
Stream the polynomial in string representation to an output stream (std::ostream)
Definition polynomial.h:516
polynomial & operator-=(const polynomial &p)
Subtract a polynomial from this one.
Definition polynomial.h:278
const Type & operator[](unsigned int i) const
Get the n-th order coefficient by constant reference.
Definition polynomial.h:57
static polynomial< Type > monomial(Type c, unsigned int order)
Returns a monomial of the given degree and coefficient.
Definition polynomial.h:443
bool operator==(const polynomial &other) const
Check whether two polynomials are equal.
Definition polynomial.h:338
polynomial operator*(const polynomial &p) const
Multiply two polynomials.
Definition polynomial.h:168
polynomial & operator/=(Type a)
Divide a polynomial by a scalar value.
Definition polynomial.h:323
const Type & at(unsigned int i) const
Get i-th coefficient by constant reference, with bound checking.
Definition polynomial.h:46
Type & operator[](unsigned int i)
Get the n-th order coefficient by reference.
Definition polynomial.h:63
polynomial()
Initialize as an empty polynomial.
Definition polynomial.h:30
unsigned int find_order() const
Find the true order of the polynomial (ignoring trailing null coefficients)
Definition polynomial.h:94
auto cend()
Get a const iterator for the one plus last coefficient of the polynomial.
Definition polynomial.h:385
size_t size() const
Get the number of coefficients.
Definition polynomial.h:118
polynomial operator+(const polynomial &p) const
Sum two polynomials.
Definition polynomial.h:124
polynomial operator-(const polynomial &p) const
Subtract a polynomial from another.
Definition polynomial.h:146
polynomial operator/(Type a) const
Divide a polynomial by a scalar.
Definition polynomial.h:248
std::string to_string(const std::string &unknown="x", const std::string &exponentiation="^") const
Convert the polynomial to string representation.
Definition polynomial.h:477
polynomial & operator*=(Type a)
Multiply a polynomial by a scalar value.
Definition polynomial.h:307
polynomial operator*(Type a) const
Multiply a polynomial by a scalar.
Definition polynomial.h:236
static polynomial< Type > from_roots(const std::vector< Type > &roots)
Construct a polynomial from its roots.
Definition polynomial.h:429
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compiling opti...
Definition error.h:225
Main namespace of the library which contains all functions and objects.
Definition algebra.h:27
auto min(const Vector &X)
Finds the minimum value inside a dataset.
Definition dataset.h:351
dual2 sqrt(dual2 x)
Compute the square root of a second order dual number.
Definition dual2_functions.h:54
dual2 abs(dual2 x)
Compute the absolute value of a second order dual number.
Definition dual2_functions.h:198
auto sum(const Vector &X)
Compute the sum of a vector of real values using pairwise summation to reduce round-off error.
Definition dataset.h:219
std::vector< real > roots(RealFunction f, real a, real b, real tol=OPTIMIZATION_TOL, real steps=10)
Find the roots of a univariate real function inside a given interval, by first searching for candidat...
Definition roots.h:650
auto max(const Vector &X)
Finds the maximum value inside a dataset.
Definition dataset.h:330
TH_CONSTEXPR real nan()
Return a quiet NaN number in floating point representation.
Definition error.h:54
constexpr real MACH_EPSILON
Machine epsilon for the real type.
Definition constants.h:207
int sgn(real x)
Return the sign of x (1 if positive, -1 if negative, 0 if null)
Definition real_analysis.h:259
dual2 square(dual2 x)
Return the square of a second order dual number.
Definition dual2_functions.h:23