xref: /aosp_15_r20/external/eigen/unsupported/Eigen/Polynomials (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Li// This file is part of Eigen, a lightweight C++ template library
2*bf2c3715SXin Li// for linear algebra.
3*bf2c3715SXin Li//
4*bf2c3715SXin Li//
5*bf2c3715SXin Li// This Source Code Form is subject to the terms of the Mozilla
6*bf2c3715SXin Li// Public License v. 2.0. If a copy of the MPL was not distributed
7*bf2c3715SXin Li// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
8*bf2c3715SXin Li
9*bf2c3715SXin Li#ifndef EIGEN_POLYNOMIALS_MODULE_H
10*bf2c3715SXin Li#define EIGEN_POLYNOMIALS_MODULE_H
11*bf2c3715SXin Li
12*bf2c3715SXin Li#include "../../Eigen/Core"
13*bf2c3715SXin Li
14*bf2c3715SXin Li#include "../../Eigen/Eigenvalues"
15*bf2c3715SXin Li
16*bf2c3715SXin Li#include "../../Eigen/src/Core/util/DisableStupidWarnings.h"
17*bf2c3715SXin Li
18*bf2c3715SXin Li// Note that EIGEN_HIDE_HEAVY_CODE has to be defined per module
19*bf2c3715SXin Li#if (defined EIGEN_EXTERN_INSTANTIATIONS) && (EIGEN_EXTERN_INSTANTIATIONS>=2)
20*bf2c3715SXin Li  #ifndef EIGEN_HIDE_HEAVY_CODE
21*bf2c3715SXin Li  #define EIGEN_HIDE_HEAVY_CODE
22*bf2c3715SXin Li  #endif
23*bf2c3715SXin Li#elif defined EIGEN_HIDE_HEAVY_CODE
24*bf2c3715SXin Li  #undef EIGEN_HIDE_HEAVY_CODE
25*bf2c3715SXin Li#endif
26*bf2c3715SXin Li
27*bf2c3715SXin Li/**
28*bf2c3715SXin Li  * \defgroup Polynomials_Module Polynomials module
29*bf2c3715SXin Li  * \brief This module provides a QR based polynomial solver.
30*bf2c3715SXin Li	*
31*bf2c3715SXin Li  * To use this module, add
32*bf2c3715SXin Li  * \code
33*bf2c3715SXin Li  * #include <unsupported/Eigen/Polynomials>
34*bf2c3715SXin Li  * \endcode
35*bf2c3715SXin Li	* at the start of your source file.
36*bf2c3715SXin Li  */
37*bf2c3715SXin Li
38*bf2c3715SXin Li#include "src/Polynomials/PolynomialUtils.h"
39*bf2c3715SXin Li#include "src/Polynomials/Companion.h"
40*bf2c3715SXin Li#include "src/Polynomials/PolynomialSolver.h"
41*bf2c3715SXin Li
42*bf2c3715SXin Li/**
43*bf2c3715SXin Li	\page polynomials Polynomials defines functions for dealing with polynomials
44*bf2c3715SXin Li	and a QR based polynomial solver.
45*bf2c3715SXin Li	\ingroup Polynomials_Module
46*bf2c3715SXin Li
47*bf2c3715SXin Li	The remainder of the page documents first the functions for evaluating, computing
48*bf2c3715SXin Li	polynomials, computing estimates about polynomials and next the QR based polynomial
49*bf2c3715SXin Li	solver.
50*bf2c3715SXin Li
51*bf2c3715SXin Li	\section polynomialUtils convenient functions to deal with polynomials
52*bf2c3715SXin Li	\subsection roots_to_monicPolynomial
53*bf2c3715SXin Li	The function
54*bf2c3715SXin Li	\code
55*bf2c3715SXin Li	void roots_to_monicPolynomial( const RootVector& rv, Polynomial& poly )
56*bf2c3715SXin Li	\endcode
57*bf2c3715SXin Li	computes the coefficients \f$ a_i \f$ of
58*bf2c3715SXin Li
59*bf2c3715SXin Li	\f$ p(x) = a_0 + a_{1}x + ... + a_{n-1}x^{n-1} + x^n \f$
60*bf2c3715SXin Li
61*bf2c3715SXin Li	where \f$ p \f$ is known through its roots i.e. \f$ p(x) = (x-r_1)(x-r_2)...(x-r_n) \f$.
62*bf2c3715SXin Li
63*bf2c3715SXin Li	\subsection poly_eval
64*bf2c3715SXin Li	The function
65*bf2c3715SXin Li	\code
66*bf2c3715SXin Li	T poly_eval( const Polynomials& poly, const T& x )
67*bf2c3715SXin Li	\endcode
68*bf2c3715SXin Li	evaluates a polynomial at a given point using stabilized H&ouml;rner method.
69*bf2c3715SXin Li
70*bf2c3715SXin Li	The following code: first computes the coefficients in the monomial basis of the monic polynomial that has the provided roots;
71*bf2c3715SXin Li	then, it evaluates the computed polynomial, using a stabilized H&ouml;rner method.
72*bf2c3715SXin Li
73*bf2c3715SXin Li	\include PolynomialUtils1.cpp
74*bf2c3715SXin Li  Output: \verbinclude PolynomialUtils1.out
75*bf2c3715SXin Li
76*bf2c3715SXin Li	\subsection Cauchy bounds
77*bf2c3715SXin Li	The function
78*bf2c3715SXin Li	\code
79*bf2c3715SXin Li	Real cauchy_max_bound( const Polynomial& poly )
80*bf2c3715SXin Li	\endcode
81*bf2c3715SXin Li	provides a maximum bound (the Cauchy one: \f$C(p)\f$) for the absolute value of a root of the given polynomial i.e.
82*bf2c3715SXin Li	\f$ \forall r_i \f$ root of \f$ p(x) = \sum_{k=0}^d a_k x^k \f$,
83*bf2c3715SXin Li	\f$ |r_i| \le C(p) = \sum_{k=0}^{d} \left | \frac{a_k}{a_d} \right | \f$
84*bf2c3715SXin Li	The leading coefficient \f$ p \f$: should be non zero \f$a_d \neq 0\f$.
85*bf2c3715SXin Li
86*bf2c3715SXin Li
87*bf2c3715SXin Li	The function
88*bf2c3715SXin Li	\code
89*bf2c3715SXin Li	Real cauchy_min_bound( const Polynomial& poly )
90*bf2c3715SXin Li	\endcode
91*bf2c3715SXin Li	provides a minimum bound (the Cauchy one: \f$c(p)\f$) for the absolute value of a non zero root of the given polynomial i.e.
92*bf2c3715SXin Li	\f$ \forall r_i \neq 0 \f$ root of \f$ p(x) = \sum_{k=0}^d a_k x^k \f$,
93*bf2c3715SXin Li	\f$ |r_i| \ge c(p) = \left( \sum_{k=0}^{d} \left | \frac{a_k}{a_0} \right | \right)^{-1} \f$
94*bf2c3715SXin Li
95*bf2c3715SXin Li
96*bf2c3715SXin Li
97*bf2c3715SXin Li
98*bf2c3715SXin Li	\section QR polynomial solver class
99*bf2c3715SXin Li	Computes the complex roots of a polynomial by computing the eigenvalues of the associated companion matrix with the QR algorithm.
100*bf2c3715SXin Li
101*bf2c3715SXin Li	The roots of \f$ p(x) = a_0 + a_1 x + a_2 x^2 + a_{3} x^3 + x^4 \f$ are the eigenvalues of
102*bf2c3715SXin Li	\f$
103*bf2c3715SXin Li	\left [
104*bf2c3715SXin Li	\begin{array}{cccc}
105*bf2c3715SXin Li	0 & 0 &  0 & a_0 \\
106*bf2c3715SXin Li	1 & 0 &  0 & a_1 \\
107*bf2c3715SXin Li	0 & 1 &  0 & a_2 \\
108*bf2c3715SXin Li	0 & 0 &  1 & a_3
109*bf2c3715SXin Li	\end{array} \right ]
110*bf2c3715SXin Li	\f$
111*bf2c3715SXin Li
112*bf2c3715SXin Li	However, the QR algorithm is not guaranteed to converge when there are several eigenvalues with same modulus.
113*bf2c3715SXin Li
114*bf2c3715SXin Li	Therefore the current polynomial solver is guaranteed to provide a correct result only when the complex roots \f$r_1,r_2,...,r_d\f$ have distinct moduli i.e.
115*bf2c3715SXin Li
116*bf2c3715SXin Li	\f$ \forall i,j \in [1;d],~ \| r_i \| \neq \| r_j \| \f$.
117*bf2c3715SXin Li
118*bf2c3715SXin Li	With 32bit (float) floating types this problem shows up frequently.
119*bf2c3715SXin Li  However, almost always, correct accuracy is reached even in these cases for 64bit
120*bf2c3715SXin Li  (double) floating types and small polynomial degree (<20).
121*bf2c3715SXin Li
122*bf2c3715SXin Li	\include PolynomialSolver1.cpp
123*bf2c3715SXin Li
124*bf2c3715SXin Li	In the above example:
125*bf2c3715SXin Li
126*bf2c3715SXin Li	-# a simple use of the polynomial solver is shown;
127*bf2c3715SXin Li	-# the accuracy problem with the QR algorithm is presented: a polynomial with almost conjugate roots is provided to the solver.
128*bf2c3715SXin Li	Those roots have almost same module therefore the QR algorithm failed to converge: the accuracy
129*bf2c3715SXin Li	of the last root is bad;
130*bf2c3715SXin Li	-# a simple way to circumvent the problem is shown: use doubles instead of floats.
131*bf2c3715SXin Li
132*bf2c3715SXin Li  Output: \verbinclude PolynomialSolver1.out
133*bf2c3715SXin Li*/
134*bf2c3715SXin Li
135*bf2c3715SXin Li#include "../../Eigen/src/Core/util/ReenableStupidWarnings.h"
136*bf2c3715SXin Li
137*bf2c3715SXin Li#endif // EIGEN_POLYNOMIALS_MODULE_H
138