10 #ifndef EIGEN_POLYNOMIAL_SOLVER_H
11 #define EIGEN_POLYNOMIAL_SOLVER_H
13 #include "./InternalHeaderCheck.h"
30 template<
typename Scalar_,
int Deg_ >
34 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar_,Deg_==
Dynamic ?
Dynamic : Deg_)
36 typedef Scalar_ Scalar;
38 typedef std::complex<RealScalar> RootType;
41 typedef DenseIndex Index;
44 template<
typename OtherPolynomial >
45 inline void setPolynomial(
const OtherPolynomial& poly ){
46 m_roots.
resize(poly.size()-1); }
49 template<
typename OtherPolynomial >
51 setPolynomial( poly() ); }
70 template<
typename Stl_back_insertion_sequence>
71 inline void realRoots( Stl_back_insertion_sequence& bi_seq,
76 for(Index i=0; i<m_roots.size(); ++i )
78 if(
abs( m_roots[i].
imag() ) < absImaginaryThreshold ){
79 bi_seq.push_back( m_roots[i].
real() ); }
84 template<
typename squaredNormBinaryPredicate>
85 inline const RootType& selectComplexRoot_withRespectToNorm( squaredNormBinaryPredicate& pred )
const
88 RealScalar norm2 = numext::abs2( m_roots[0] );
89 for(
Index i=1; i<m_roots.size(); ++i )
91 const RealScalar currNorm2 = numext::abs2( m_roots[i] );
92 if( pred( currNorm2, norm2 ) ){
93 res=i; norm2=currNorm2; }
104 std::greater<RealScalar> greater;
105 return selectComplexRoot_withRespectToNorm( greater );
113 std::less<RealScalar> less;
114 return selectComplexRoot_withRespectToNorm( less );
118 template<
typename squaredRealPartBinaryPredicate>
119 inline const RealScalar& selectRealRoot_withRespectToAbsRealPart(
120 squaredRealPartBinaryPredicate& pred,
125 hasArealRoot =
false;
129 for(
Index i=0; i<m_roots.size(); ++i )
131 if(
abs( m_roots[i].
imag() ) <= absImaginaryThreshold )
137 abs2 = m_roots[i].real() * m_roots[i].real();
141 const RealScalar currAbs2 = m_roots[i].real() * m_roots[i].real();
142 if( pred( currAbs2,
abs2 ) )
149 else if(!hasArealRoot)
155 return numext::real_ref(m_roots[res]);
159 template<
typename RealPartBinaryPredicate>
160 inline const RealScalar& selectRealRoot_withRespectToRealPart(
161 RealPartBinaryPredicate& pred,
163 const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() )
const
166 hasArealRoot =
false;
170 for( Index i=0; i<m_roots.size(); ++i )
172 if(
abs( m_roots[i].
imag() ) <= absImaginaryThreshold )
178 val = m_roots[i].real();
182 const RealScalar curr = m_roots[i].real();
183 if( pred( curr, val ) )
196 return numext::real_ref(m_roots[res]);
218 std::greater<RealScalar> greater;
219 return selectRealRoot_withRespectToAbsRealPart( greater, hasArealRoot, absImaginaryThreshold );
241 std::less<RealScalar> less;
242 return selectRealRoot_withRespectToAbsRealPart( less, hasArealRoot, absImaginaryThreshold );
264 std::greater<RealScalar> greater;
265 return selectRealRoot_withRespectToRealPart( greater, hasArealRoot, absImaginaryThreshold );
287 std::less<RealScalar> less;
288 return selectRealRoot_withRespectToRealPart( less, hasArealRoot, absImaginaryThreshold );
295 #define EIGEN_POLYNOMIAL_SOLVER_BASE_INHERITED_TYPES( BASE ) \
296 typedef typename BASE::Scalar Scalar; \
297 typedef typename BASE::RealScalar RealScalar; \
298 typedef typename BASE::RootType RootType; \
299 typedef typename BASE::RootsType RootsType;
332 template<
typename Scalar_,
int Deg_>
336 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar_,Deg_==
Dynamic ?
Dynamic : Deg_)
339 EIGEN_POLYNOMIAL_SOLVER_BASE_INHERITED_TYPES(
PS_Base )
342 typedef std::conditional_t<NumTraits<Scalar>::IsComplex,
345 typedef std::conditional_t<NumTraits<Scalar>::IsComplex, Scalar, std::complex<Scalar> > ComplexScalar;
349 template<
typename OtherPolynomial >
352 eigen_assert( Scalar(0) != poly[poly.size()-1] );
353 eigen_assert( poly.size() > 1 );
356 internal::companion<Scalar,Deg_> companion( poly );
358 m_eigenSolver.compute( companion.denseMatrix() );
359 m_roots = m_eigenSolver.eigenvalues();
365 for(Index i = 0; i<m_roots.size(); ++i)
367 if( internal::isMuchSmallerThan(numext::abs(numext::imag(m_roots[i])),
368 numext::abs(numext::real(m_roots[i])),
371 ComplexScalar as_real_root = ComplexScalar(numext::real(m_roots[i]));
372 if( numext::abs(
poly_eval(poly, as_real_root))
373 <= numext::abs(
poly_eval(poly, m_roots[i])))
375 m_roots[i] = as_real_root;
380 else if(poly.size () == 2)
383 m_roots[0] = -poly[0]/poly[1];
388 template<
typename OtherPolynomial >
392 inline PolynomialSolver(){}
395 using PS_Base::m_roots;
396 EigenSolverType m_eigenSolver;
400 template<
typename Scalar_ >
401 class PolynomialSolver<Scalar_,1> :
public PolynomialSolverBase<Scalar_,1>
404 typedef PolynomialSolverBase<Scalar_,1> PS_Base;
405 EIGEN_POLYNOMIAL_SOLVER_BASE_INHERITED_TYPES( PS_Base )
409 template<
typename OtherPolynomial >
410 void compute(
const OtherPolynomial& poly )
412 eigen_assert( poly.size() == 2 );
413 eigen_assert( Scalar(0) != poly[1] );
414 m_roots[0] = -poly[0]/poly[1];
418 template<
typename OtherPolynomial >
419 inline PolynomialSolver(
const OtherPolynomial& poly ){
422 inline PolynomialSolver(){}
425 using PS_Base::m_roots;
void resize(Index rows, Index cols)
Defined to be inherited by polynomial solvers: it provides convenient methods such as.
Definition: PolynomialSolver.h:32
const RootType & greatestRoot() const
Definition: PolynomialSolver.h:102
const RootType & smallestRoot() const
Definition: PolynomialSolver.h:111
const RealScalar & greatestRealRoot(bool &hasArealRoot, const RealScalar &absImaginaryThreshold=NumTraits< Scalar >::dummy_precision()) const
Definition: PolynomialSolver.h:260
void realRoots(Stl_back_insertion_sequence &bi_seq, const RealScalar &absImaginaryThreshold=NumTraits< Scalar >::dummy_precision()) const
Definition: PolynomialSolver.h:71
const RealScalar & smallestRealRoot(bool &hasArealRoot, const RealScalar &absImaginaryThreshold=NumTraits< Scalar >::dummy_precision()) const
Definition: PolynomialSolver.h:283
const RealScalar & absSmallestRealRoot(bool &hasArealRoot, const RealScalar &absImaginaryThreshold=NumTraits< Scalar >::dummy_precision()) const
Definition: PolynomialSolver.h:237
const RealScalar & absGreatestRealRoot(bool &hasArealRoot, const RealScalar &absImaginaryThreshold=NumTraits< Scalar >::dummy_precision()) const
Definition: PolynomialSolver.h:214
const RootsType & roots() const
Definition: PolynomialSolver.h:57
A polynomial solver.
Definition: PolynomialSolver.h:334
void compute(const OtherPolynomial &poly)
Definition: PolynomialSolver.h:350
T poly_eval(const Polynomials &poly, const T &x)
Definition: PolynomialUtils.h:48
Namespace containing all symbols from the Eigen library.
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_imag_op< typename Derived::Scalar >, const Derived > imag(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs2_op< typename Derived::Scalar >, const Derived > abs2(const Eigen::ArrayBase< Derived > &x)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_real_op< typename Derived::Scalar >, const Derived > real(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)