polynomialsolver.cpp
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2010 Manuel Yguel <manuel.yguel@gmail.com>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #include "main.h"
11 #include <unsupported/Eigen/Polynomials>
12 #include <iostream>
13 #include <algorithm>
14 
15 using namespace std;
16 
17 namespace Eigen {
18 namespace internal {
19 template<int Size>
21 {
22  enum {
23  ret = (Size == Dynamic) ? Dynamic : Size+1
24  };
25 };
26 }
27 }
28 
29 
30 template<int Deg, typename POLYNOMIAL, typename SOLVER>
31 bool aux_evalSolver( const POLYNOMIAL& pols, SOLVER& psolve )
32 {
33  typedef typename POLYNOMIAL::Scalar Scalar;
34 
35  typedef typename SOLVER::RootsType RootsType;
36  typedef Matrix<Scalar,Deg,1> EvalRootsType;
37 
38  const Index deg = pols.size()-1;
39 
40  // Test template constructor from coefficient vector
41  SOLVER solve_constr (pols);
42 
43  psolve.compute( pols );
44  const RootsType& roots( psolve.roots() );
45  EvalRootsType evr( deg );
46  for( int i=0; i<roots.size(); ++i ){
47  evr[i] = std::abs( poly_eval( pols, roots[i] ) ); }
48 
49  bool evalToZero = evr.isZero( test_precision<Scalar>() );
50  if( !evalToZero )
51  {
52  cerr << "WRONG root: " << endl;
53  cerr << "Polynomial: " << pols.transpose() << endl;
54  cerr << "Roots found: " << roots.transpose() << endl;
55  cerr << "Abs value of the polynomial at the roots: " << evr.transpose() << endl;
56  cerr << endl;
57  }
58 
59  std::vector<Scalar> rootModuli( roots.size() );
60  Map< EvalRootsType > aux( &rootModuli[0], roots.size() );
61  aux = roots.array().abs();
62  std::sort( rootModuli.begin(), rootModuli.end() );
63  bool distinctModuli=true;
64  for( size_t i=1; i<rootModuli.size() && distinctModuli; ++i )
65  {
66  if( internal::isApprox( rootModuli[i], rootModuli[i-1] ) ){
67  distinctModuli = false; }
68  }
69  VERIFY( evalToZero || !distinctModuli );
70 
71  return distinctModuli;
72 }
73 
74 
75 
76 
77 
78 
79 
80 template<int Deg, typename POLYNOMIAL>
81 void evalSolver( const POLYNOMIAL& pols )
82 {
83  typedef typename POLYNOMIAL::Scalar Scalar;
84 
85  typedef PolynomialSolver<Scalar, Deg > PolynomialSolverType;
86 
87  PolynomialSolverType psolve;
88  aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve );
89 }
90 
91 
92 
93 
94 template< int Deg, typename POLYNOMIAL, typename ROOTS, typename REAL_ROOTS >
95 void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const REAL_ROOTS& real_roots )
96 {
97  using std::sqrt;
98  typedef typename POLYNOMIAL::Scalar Scalar;
99 
100  typedef PolynomialSolver<Scalar, Deg > PolynomialSolverType;
101 
102  PolynomialSolverType psolve;
103  if( aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve ) )
104  {
105  //It is supposed that
106  // 1) the roots found are correct
107  // 2) the roots have distinct moduli
108 
109  typedef typename REAL_ROOTS::Scalar Real;
110 
111  //Test realRoots
112  std::vector< Real > calc_realRoots;
113  psolve.realRoots( calc_realRoots );
114  VERIFY( calc_realRoots.size() == (size_t)real_roots.size() );
115 
116  const Scalar psPrec = sqrt( test_precision<Scalar>() );
117 
118  for( size_t i=0; i<calc_realRoots.size(); ++i )
119  {
120  bool found = false;
121  for( size_t j=0; j<calc_realRoots.size()&& !found; ++j )
122  {
123  if( internal::isApprox( calc_realRoots[i], real_roots[j], psPrec ) ){
124  found = true; }
125  }
126  VERIFY( found );
127  }
128 
129  //Test greatestRoot
130  VERIFY( internal::isApprox( roots.array().abs().maxCoeff(),
131  abs( psolve.greatestRoot() ), psPrec ) );
132 
133  //Test smallestRoot
134  VERIFY( internal::isApprox( roots.array().abs().minCoeff(),
135  abs( psolve.smallestRoot() ), psPrec ) );
136 
137  bool hasRealRoot;
138  //Test absGreatestRealRoot
139  Real r = psolve.absGreatestRealRoot( hasRealRoot );
140  VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
141  if( hasRealRoot ){
142  VERIFY( internal::isApprox( real_roots.array().abs().maxCoeff(), abs(r), psPrec ) ); }
143 
144  //Test absSmallestRealRoot
145  r = psolve.absSmallestRealRoot( hasRealRoot );
146  VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
147  if( hasRealRoot ){
148  VERIFY( internal::isApprox( real_roots.array().abs().minCoeff(), abs( r ), psPrec ) ); }
149 
150  //Test greatestRealRoot
151  r = psolve.greatestRealRoot( hasRealRoot );
152  VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
153  if( hasRealRoot ){
154  VERIFY( internal::isApprox( real_roots.array().maxCoeff(), r, psPrec ) ); }
155 
156  //Test smallestRealRoot
157  r = psolve.smallestRealRoot( hasRealRoot );
158  VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
159  if( hasRealRoot ){
160  VERIFY( internal::isApprox( real_roots.array().minCoeff(), r, psPrec ) ); }
161  }
162 }
163 
164 
165 template<typename _Scalar, int _Deg>
166 void polynomialsolver(int deg)
167 {
168  typedef internal::increment_if_fixed_size<_Deg> Dim;
169  typedef Matrix<_Scalar,Dim::ret,1> PolynomialType;
170  typedef Matrix<_Scalar,_Deg,1> EvalRootsType;
171 
172  cout << "Standard cases" << endl;
173  PolynomialType pols = PolynomialType::Random(deg+1);
174  evalSolver<_Deg,PolynomialType>( pols );
175 
176  cout << "Hard cases" << endl;
177  _Scalar multipleRoot = internal::random<_Scalar>();
178  EvalRootsType allRoots = EvalRootsType::Constant(deg,multipleRoot);
179  roots_to_monicPolynomial( allRoots, pols );
180  evalSolver<_Deg,PolynomialType>( pols );
181 
182  cout << "Test sugar" << endl;
183  EvalRootsType realRoots = EvalRootsType::Random(deg);
184  roots_to_monicPolynomial( realRoots, pols );
185  evalSolverSugarFunction<_Deg>(
186  pols,
187  realRoots.template cast <
188  std::complex<
189  typename NumTraits<_Scalar>::Real
190  >
191  >(),
192  realRoots );
193 }
194 
196 {
197  for(int i = 0; i < g_repeat; i++)
198  {
199  CALL_SUBTEST_1( (polynomialsolver<float,1>(1)) );
200  CALL_SUBTEST_2( (polynomialsolver<double,2>(2)) );
201  CALL_SUBTEST_3( (polynomialsolver<double,3>(3)) );
202  CALL_SUBTEST_4( (polynomialsolver<float,4>(4)) );
203  CALL_SUBTEST_5( (polynomialsolver<double,5>(5)) );
204  CALL_SUBTEST_6( (polynomialsolver<float,6>(6)) );
205  CALL_SUBTEST_7( (polynomialsolver<float,7>(7)) );
206  CALL_SUBTEST_8( (polynomialsolver<double,8>(8)) );
207 
208  CALL_SUBTEST_9( (polynomialsolver<float,Dynamic>(
209  internal::random<int>(9,13)
210  )) );
211  CALL_SUBTEST_10((polynomialsolver<double,Dynamic>(
212  internal::random<int>(9,13)
213  )) );
214  CALL_SUBTEST_11((polynomialsolver<float,Dynamic>(1)) );
215  }
216 }
void evalSolver(const POLYNOMIAL &pols)
SCALAR Scalar
Definition: bench_gemm.cpp:33
void test_polynomialsolver()
T poly_eval(const Polynomials &poly, const T &x)
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:94
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Namespace containing all symbols from the Eigen library.
Definition: jet.h:637
Definition: Half.h:150
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:150
void roots_to_monicPolynomial(const RootVector &rv, Polynomial &poly)
void evalSolverSugarFunction(const POLYNOMIAL &pols, const ROOTS &roots, const REAL_ROOTS &real_roots)
static int g_repeat
Definition: main.h:144
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:33
EIGEN_DEVICE_FUNC NewType cast(const OldType &x)
bool aux_evalSolver(const POLYNOMIAL &pols, SOLVER &psolve)
mp::number< mp::cpp_dec_float< 100 >, mp::et_on > Real
#define VERIFY(a)
Definition: main.h:325
DenseIndex ret
Definition: level1_impl.h:59
const int Dynamic
Definition: Constants.h:21
void polynomialsolver(int deg)
EIGEN_DEVICE_FUNC bool isApprox(const Scalar &x, const Scalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
#define abs(x)
Definition: datatypes.h:17
A polynomial solver.
std::ptrdiff_t j


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:43:27