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