File indexing completed on 2025-01-18 09:57:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef EIGEN_POLYNOMIAL_UTILS_H
0011 #define EIGEN_POLYNOMIAL_UTILS_H
0012
0013 namespace Eigen {
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 template <typename Polynomials, typename T>
0027 inline
0028 T poly_eval_horner( const Polynomials& poly, const T& x )
0029 {
0030 T val=poly[poly.size()-1];
0031 for(DenseIndex i=poly.size()-2; i>=0; --i ){
0032 val = val*x + poly[i]; }
0033 return val;
0034 }
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 template <typename Polynomials, typename T>
0045 inline
0046 T poly_eval( const Polynomials& poly, const T& x )
0047 {
0048 typedef typename NumTraits<T>::Real Real;
0049
0050 if( numext::abs2( x ) <= Real(1) ){
0051 return poly_eval_horner( poly, x ); }
0052 else
0053 {
0054 T val=poly[0];
0055 T inv_x = T(1)/x;
0056 for( DenseIndex i=1; i<poly.size(); ++i ){
0057 val = val*inv_x + poly[i]; }
0058
0059 return numext::pow(x,(T)(poly.size()-1)) * val;
0060 }
0061 }
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 template <typename Polynomial>
0074 inline
0075 typename NumTraits<typename Polynomial::Scalar>::Real cauchy_max_bound( const Polynomial& poly )
0076 {
0077 using std::abs;
0078 typedef typename Polynomial::Scalar Scalar;
0079 typedef typename NumTraits<Scalar>::Real Real;
0080
0081 eigen_assert( Scalar(0) != poly[poly.size()-1] );
0082 const Scalar inv_leading_coeff = Scalar(1)/poly[poly.size()-1];
0083 Real cb(0);
0084
0085 for( DenseIndex i=0; i<poly.size()-1; ++i ){
0086 cb += abs(poly[i]*inv_leading_coeff); }
0087 return cb + Real(1);
0088 }
0089
0090
0091
0092
0093
0094
0095
0096 template <typename Polynomial>
0097 inline
0098 typename NumTraits<typename Polynomial::Scalar>::Real cauchy_min_bound( const Polynomial& poly )
0099 {
0100 using std::abs;
0101 typedef typename Polynomial::Scalar Scalar;
0102 typedef typename NumTraits<Scalar>::Real Real;
0103
0104 DenseIndex i=0;
0105 while( i<poly.size()-1 && Scalar(0) == poly(i) ){ ++i; }
0106 if( poly.size()-1 == i ){
0107 return Real(1); }
0108
0109 const Scalar inv_min_coeff = Scalar(1)/poly[i];
0110 Real cb(1);
0111 for( DenseIndex j=i+1; j<poly.size(); ++j ){
0112 cb += abs(poly[j]*inv_min_coeff); }
0113 return Real(1)/cb;
0114 }
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126 template <typename RootVector, typename Polynomial>
0127 void roots_to_monicPolynomial( const RootVector& rv, Polynomial& poly )
0128 {
0129
0130 typedef typename Polynomial::Scalar Scalar;
0131
0132 poly.setZero( rv.size()+1 );
0133 poly[0] = -rv[0]; poly[1] = Scalar(1);
0134 for( DenseIndex i=1; i< rv.size(); ++i )
0135 {
0136 for( DenseIndex j=i+1; j>0; --j ){ poly[j] = poly[j-1] - rv[i]*poly[j]; }
0137 poly[0] = -rv[i]*poly[0];
0138 }
0139 }
0140
0141 }
0142
0143 #endif