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>
41 template <
typename Vector, enable_vector<Vector> = true>
44 coeff.resize(c.size());
46 for (
size_t i = 0; i < c.size(); ++i)
55 inline const Type&
at(
unsigned int i)
const {
60 inline Type&
at(
unsigned int i) {
78 template<
typename EvalType = Type>
79 inline EvalType
eval(EvalType x)
const {
81 EvalType
sum = EvalType(0.0);
84 for (
unsigned int i = 0; i <
coeff.size(); ++i)
92 template<
typename EvalType = Type>
102 for (
int i =
coeff.size() - 1; i >= 0; --i) {
114 for (
unsigned int i =
coeff.size() - 1; i >= 0; --i) {
137 for (; i <
min(
coeff.size(), p.size()); ++i)
138 r[i] =
coeff[i] + p[i];
140 if (
coeff.size() > p.size())
141 for (; i <
coeff.size(); ++i)
144 for (; i < p.size(); ++i)
159 for (; i <
min(r.size(), p.size()); ++i)
160 r[i] =
coeff[i] - p[i];
162 if (
coeff.size() > p.size())
163 for (; i <
coeff.size(); ++i)
166 for (; i < p.size(); ++i)
177 r.coeff.resize(this->
size() + p.
size() - 1);
179 for (
unsigned int i = 0; i <
size(); ++i) {
180 for (
unsigned int j = 0; j < p.size(); ++j) {
181 r[i + j] +=
coeff[i] * p[j];
195 if(d_order == 0 && d[0] == 0) {
207 while(i < this_order) {
210 const unsigned int r_order = r.find_order();
219 r[r_order] / d[d_order],
232 if(i == this_order) {
246 for (
unsigned int i = 0; i <
size(); ++i)
262 for (
unsigned int i = 0; i <
size(); ++i)
273 if(
coeff.size() < p.size())
274 coeff.resize(p.size(), Type(0));
276 for (
unsigned int i = 0; i <
min(
size(), p.size()); ++i)
287 if(
coeff.size() < p.size())
288 coeff.resize(p.size(), Type(0));
290 for (
unsigned int i = 0; i <
min(
coeff.size(), p.size()); ++i)
301 r.coeff.resize(this->
size() + p.
size() - 1, Type(0));
303 for (
unsigned int i = 0; i <
coeff.size(); ++i)
304 for (
unsigned int j = 0; j < p.size(); ++j)
305 r[i + j] +=
coeff[i] * p[j];
315 for (
unsigned int i = 0; i <
coeff.size(); ++i)
324 return (*
this = (*
this / a));
336 for (
unsigned int i = 0; i <
coeff.size(); ++i)
346 const unsigned int n =
min(other.size(), this->size());
347 for (
unsigned int i = 0; i < n; ++i) {
352 if(
size() > other.size()) {
353 for (
unsigned int i = 0; i <
size(); ++i) {
358 for (
unsigned int i = 0; i < other.size(); ++i) {
371 return coeff.begin();
385 return coeff.cbegin();
404 return vec<complex<>, 2>({
nan(),
nan()});
412 return {complex<>(-p), complex<>(0)};
419 z1 = -
sgn(p) * (
abs(p) / 2.0
420 +
abs(p) *
sqrt(complex<>(0.25 - (q / p) / p)));
425 const complex<> s =
sqrt(complex<>(0.25 *
square(p) - q));
436 const std::vector<Type>&
roots) {
438 polynomial<Type> P = {1};
441 for (
unsigned int i = 0; i <
roots.size(); ++i)
442 P *= polynomial<Type>({
roots[i] * -1, 1});
449 inline static polynomial<Type>
monomial(Type c,
unsigned int order) {
452 m.
coeff = std::vector<Type>(order + 1, Type(0));
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) {
473 inline friend polynomial<Type>
operator*(
474 Type r,
const polynomial<Type>& z) {
480#ifndef THEORETICA_NO_PRINT
484 const std::string& unknown =
"x",
485 const std::string& exponentiation =
"^")
const {
487 std::stringstream res;
488 const int sz =
coeff.size();
495 res <<
coeff[sz - 1];
498 res <<
"*" << unknown << exponentiation << (sz - 1) <<
" ";
500 for (
int i = sz - 2; i >= 0; --i) {
505 res << (
coeff[i] >= 0 ?
"+ " :
"- ");
509 res <<
"*" << unknown << exponentiation << i;
519 inline operator std::string() {
527 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:323
polynomial()=default
Default constructor.
polynomial & operator+=(const polynomial &p)
Sum a polynomial to this one.
Definition polynomial.h:270
auto begin()
Get an iterator for the first coefficient of the polynomial.
Definition polynomial.h:370
polynomial(std::initializer_list< Type > l)
Initialize from an std::initializer_list.
Definition polynomial.h:51
auto cbegin()
Get a const iterator for the first coefficient of the polynomial.
Definition polynomial.h:384
polynomial(const Vector &c)
Initialize from a vector of coefficients where the n-th order coefficient is given by the n-th elemen...
Definition polynomial.h:42
EvalType eval(EvalType x) const
Evaluate the polynomial using x as variable.
Definition polynomial.h:79
polynomial operator/(const polynomial &d) const
Polynomial division.
Definition polynomial.h:190
void trim()
Remove trailing zero coefficients.
Definition polynomial.h:112
EvalType operator()(EvalType x) const
Evaluate the polynomial using x as variable.
Definition polynomial.h:93
polynomial & operator*=(const polynomial &p)
Multiply two polynomials.
Definition polynomial.h:298
Type & at(unsigned int i)
Access i-th coefficient by reference, with bound checking.
Definition polynomial.h:60
polynomial(Type a)
Initialize as a constant.
Definition polynomial.h:35
auto end()
Get an iterator for the one plus last coefficient of the polynomial.
Definition polynomial.h:377
vec< complex<>, 2 > quadratic_roots() const
Compute the roots of a quadratic polynomial.
Definition polynomial.h:397
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:526
polynomial & operator-=(const polynomial &p)
Subtract a polynomial from this one.
Definition polynomial.h:284
const Type & operator[](unsigned int i) const
Get the n-th order coefficient by constant reference.
Definition polynomial.h:66
static polynomial< Type > monomial(Type c, unsigned int order)
Returns a monomial of the given degree and coefficient.
Definition polynomial.h:449
bool operator==(const polynomial &other) const
Check whether two polynomials are equal.
Definition polynomial.h:344
polynomial operator*(const polynomial &p) const
Multiply two polynomials.
Definition polynomial.h:174
polynomial & operator/=(Type a)
Divide a polynomial by a scalar value.
Definition polynomial.h:329
const Type & at(unsigned int i) const
Get i-th coefficient by constant reference, with bound checking.
Definition polynomial.h:55
Type & operator[](unsigned int i)
Get the n-th order coefficient by reference.
Definition polynomial.h:72
unsigned int find_order() const
Find the true order of the polynomial (ignoring trailing null coefficients)
Definition polynomial.h:100
auto cend()
Get a const iterator for the one plus last coefficient of the polynomial.
Definition polynomial.h:391
size_t size() const
Get the number of coefficients.
Definition polynomial.h:124
polynomial operator+(const polynomial &p) const
Sum two polynomials.
Definition polynomial.h:130
polynomial operator-(const polynomial &p) const
Subtract a polynomial from another.
Definition polynomial.h:152
polynomial operator/(Type a) const
Divide a polynomial by a scalar.
Definition polynomial.h:254
std::string to_string(const std::string &unknown="x", const std::string &exponentiation="^") const
Convert the polynomial to string representation.
Definition polynomial.h:483
polynomial & operator*=(Type a)
Multiply a polynomial by a scalar value.
Definition polynomial.h:313
std::vector< Type > coeff
Coefficients of the polynomial, coeff[n] is the n-th order coefficient.
Definition polynomial.h:29
polynomial operator*(Type a) const
Multiply a polynomial by a scalar.
Definition polynomial.h:242
static polynomial< Type > from_roots(const std::vector< Type > &roots)
Construct a polynomial from its roots.
Definition polynomial.h:435
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compilation op...
Definition error.h:238
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:78
@ ImpossibleOperation
Mathematically impossible operation.
@ NoConvergence
Algorithm did not converge.
@ DivByZero
Division by zero.
constexpr real MACH_EPSILON
Machine epsilon for the real type.
Definition constants.h:216
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