11 #include <unsupported/Eigen/Polynomials> 30 template<
int Deg,
typename POLYNOMIAL,
typename SOLVER>
34 typedef typename POLYNOMIAL::Scalar Scalar;
36 typedef typename SOLVER::RootsType RootsType;
37 typedef Matrix<Scalar,Deg,1> EvalRootsType;
39 const Index deg = pols.size()-1;
42 SOLVER solve_constr (pols);
44 psolve.compute( pols );
45 const RootsType& roots( psolve.roots() );
46 EvalRootsType evr( deg );
47 for(
int i=0; i<roots.size(); ++i ){
50 bool evalToZero = evr.isZero( test_precision<Scalar>() );
53 cerr <<
"WRONG root: " << endl;
54 cerr <<
"Polynomial: " << pols.transpose() << endl;
55 cerr <<
"Roots found: " << roots.transpose() << endl;
56 cerr <<
"Abs value of the polynomial at the roots: " << evr.transpose() << endl;
60 std::vector<Scalar> rootModuli( roots.size() );
61 Map< EvalRootsType > aux( &rootModuli[0], roots.size() );
62 aux = roots.array().abs();
63 std::sort( rootModuli.begin(), rootModuli.end() );
64 bool distinctModuli=
true;
65 for(
size_t i=1; i<rootModuli.size() && distinctModuli; ++i )
67 if( internal::isApprox( rootModuli[i], rootModuli[i-1] ) ){
68 distinctModuli =
false; }
70 VERIFY( evalToZero || !distinctModuli );
72 return distinctModuli;
81 template<
int Deg,
typename POLYNOMIAL>
84 typedef typename POLYNOMIAL::Scalar Scalar;
86 typedef PolynomialSolver<Scalar, Deg > PolynomialSolverType;
88 PolynomialSolverType psolve;
89 aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve );
95 template<
int Deg,
typename POLYNOMIAL,
typename ROOTS,
typename REAL_ROOTS >
99 typedef typename POLYNOMIAL::Scalar Scalar;
101 typedef PolynomialSolver<Scalar, Deg > PolynomialSolverType;
103 PolynomialSolverType psolve;
104 if( aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve ) )
110 typedef typename POLYNOMIAL::Scalar Scalar;
111 typedef typename REAL_ROOTS::Scalar Real;
114 std::vector< Real > calc_realRoots;
115 psolve.realRoots( calc_realRoots );
116 VERIFY( calc_realRoots.size() == (size_t)real_roots.size() );
118 const Scalar psPrec =
sqrt( test_precision<Scalar>() );
120 for(
size_t i=0; i<calc_realRoots.size(); ++i )
123 for(
size_t j=0; j<calc_realRoots.size()&& !found; ++j )
125 if( internal::isApprox( calc_realRoots[i], real_roots[j], psPrec ) ){
132 VERIFY( internal::isApprox( roots.array().abs().maxCoeff(),
133 abs( psolve.greatestRoot() ), psPrec ) );
136 VERIFY( internal::isApprox( roots.array().abs().minCoeff(),
137 abs( psolve.smallestRoot() ), psPrec ) );
141 Real r = psolve.absGreatestRealRoot( hasRealRoot );
142 VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
144 VERIFY( internal::isApprox( real_roots.array().abs().maxCoeff(),
abs(r), psPrec ) ); }
147 r = psolve.absSmallestRealRoot( hasRealRoot );
148 VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
150 VERIFY( internal::isApprox( real_roots.array().abs().minCoeff(),
abs( r ), psPrec ) ); }
153 r = psolve.greatestRealRoot( hasRealRoot );
154 VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
156 VERIFY( internal::isApprox( real_roots.array().maxCoeff(), r, psPrec ) ); }
159 r = psolve.smallestRealRoot( hasRealRoot );
160 VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
162 VERIFY( internal::isApprox( real_roots.array().minCoeff(), r, psPrec ) ); }
167 template<
typename _Scalar,
int _Deg>
170 typedef internal::increment_if_fixed_size<_Deg> Dim;
171 typedef Matrix<_Scalar,Dim::ret,1> PolynomialType;
172 typedef Matrix<_Scalar,_Deg,1> EvalRootsType;
174 cout <<
"Standard cases" << endl;
175 PolynomialType pols = PolynomialType::Random(deg+1);
176 evalSolver<_Deg,PolynomialType>( pols );
178 cout <<
"Hard cases" << endl;
179 _Scalar multipleRoot = internal::random<_Scalar>();
180 EvalRootsType allRoots = EvalRootsType::Constant(deg,multipleRoot);
182 evalSolver<_Deg,PolynomialType>( pols );
184 cout <<
"Test sugar" << endl;
185 EvalRootsType realRoots = EvalRootsType::Random(deg);
187 evalSolverSugarFunction<_Deg>(
189 realRoots.template
cast <
191 typename NumTraits<_Scalar>::Real
199 for(
int i = 0; i < g_repeat; i++)
201 CALL_SUBTEST_1( (polynomialsolver<float,1>(1)) );
202 CALL_SUBTEST_2( (polynomialsolver<double,2>(2)) );
203 CALL_SUBTEST_3( (polynomialsolver<double,3>(3)) );
204 CALL_SUBTEST_4( (polynomialsolver<float,4>(4)) );
205 CALL_SUBTEST_5( (polynomialsolver<double,5>(5)) );
206 CALL_SUBTEST_6( (polynomialsolver<float,6>(6)) );
207 CALL_SUBTEST_7( (polynomialsolver<float,7>(7)) );
208 CALL_SUBTEST_8( (polynomialsolver<double,8>(8)) );
210 CALL_SUBTEST_9( (polynomialsolver<float,Dynamic>(
211 internal::random<int>(9,13)
213 CALL_SUBTEST_10((polynomialsolver<double,Dynamic>(
214 internal::random<int>(9,13)
216 CALL_SUBTEST_11((polynomialsolver<float,Dynamic>(1)) );
void evalSolver(const POLYNOMIAL &pols)
void test_polynomialsolver()
T poly_eval(const Polynomials &poly, const T &x)
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const AbsReturnType abs() const
void roots_to_monicPolynomial(const RootVector &rv, Polynomial &poly)
void evalSolverSugarFunction(const POLYNOMIAL &pols, const ROOTS &roots, const REAL_ROOTS &real_roots)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
bool aux_evalSolver(const POLYNOMIAL &pols, SOLVER &psolve)
EIGEN_DEVICE_FUNC CastXpr< NewType >::Type cast() const
void polynomialsolver(int deg)