polynomialsolver.cpp File Reference
#include "main.h"
#include <unsupported/Eigen/Polynomials>
#include <iostream>
#include <algorithm>

Classes

struct  Eigen::internal::increment_if_fixed_size< Size >
 

Namespaces

 Eigen
 Namespace containing all symbols from the Eigen library.
 
 Eigen::internal
 Namespace containing low-level routines from the Eigen library.
 

Functions

template<typename PolynomialType >
PolynomialType polyder (const PolynomialType &p)
 
template<int Deg, typename POLYNOMIAL , typename SOLVER >
bool aux_evalSolver (const POLYNOMIAL &pols, SOLVER &psolve)
 
template<int Deg, typename POLYNOMIAL >
void evalSolver (const POLYNOMIAL &pols)
 
template<int Deg, typename POLYNOMIAL , typename ROOTS , typename REAL_ROOTS >
void evalSolverSugarFunction (const POLYNOMIAL &pols, const ROOTS &roots, const REAL_ROOTS &real_roots)
 
template<typename Scalar_ , int Deg_>
void polynomialsolver (int deg)
 
 EIGEN_DECLARE_TEST (polynomialsolver)
 

Function Documentation

◆ aux_evalSolver()

template<int Deg, typename POLYNOMIAL , typename SOLVER >
bool aux_evalSolver ( const POLYNOMIAL &  pols,
SOLVER &  psolve 
)
36  {
37  typedef typename POLYNOMIAL::Scalar Scalar;
38  typedef typename POLYNOMIAL::RealScalar RealScalar;
39 
40  typedef typename SOLVER::RootsType RootsType;
41  typedef Matrix<RealScalar, Deg, 1> EvalRootsType;
42 
43  const Index deg = pols.size() - 1;
44 
45  // Test template constructor from coefficient vector
46  SOLVER solve_constr(pols);
47 
48  psolve.compute(pols);
49  const RootsType& roots(psolve.roots());
50  EvalRootsType evr(deg);
51  POLYNOMIAL pols_der = polyder(pols);
52  EvalRootsType der(deg);
53  for (int i = 0; i < roots.size(); ++i) {
54  evr[i] = std::abs(poly_eval(pols, roots[i]));
55  der[i] = numext::maxi(RealScalar(1.), std::abs(poly_eval(pols_der, roots[i])));
56  }
57 
58  // we need to divide by the magnitude of the derivative because
59  // with a high derivative is very small error in the value of the root
60  // yiels a very large error in the polynomial evaluation.
61  bool evalToZero = (evr.cwiseQuotient(der)).isZero(test_precision<Scalar>());
62  if (!evalToZero) {
63  cerr << "WRONG root: " << endl;
64  cerr << "Polynomial: " << pols.transpose() << endl;
65  cerr << "Roots found: " << roots.transpose() << endl;
66  cerr << "Abs value of the polynomial at the roots: " << evr.transpose() << endl;
67  cerr << endl;
68  }
69 
70  std::vector<RealScalar> rootModuli(roots.size());
71  Map<EvalRootsType> aux(&rootModuli[0], roots.size());
72  aux = roots.array().abs();
73  std::sort(rootModuli.begin(), rootModuli.end());
74  bool distinctModuli = true;
75  for (size_t i = 1; i < rootModuli.size() && distinctModuli; ++i) {
76  if (internal::isApprox(rootModuli[i], rootModuli[i - 1])) {
77  distinctModuli = false;
78  }
79  }
80  VERIFY(evalToZero || !distinctModuli);
81 
82  return distinctModuli;
83 }
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
int i
Definition: BiCGSTAB_step_by_step.cpp:9
SCALAR Scalar
Definition: bench_gemm.cpp:45
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:96
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
#define VERIFY(a)
Definition: main.h:362
EIGEN_DEVICE_FUNC bool isApprox(const Scalar &x, const Scalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
Definition: MathFunctions.h:1923
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T maxi(const T &x, const T &y)
Definition: MathFunctions.h:926
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
T poly_eval(const Polynomials &poly, const T &x)
Definition: PolynomialUtils.h:47
PolynomialType polyder(const PolynomialType &p)
Definition: polynomialsolver.cpp:27

References abs(), i, Eigen::internal::isApprox(), Eigen::numext::maxi(), Eigen::poly_eval(), polyder(), and VERIFY.

◆ EIGEN_DECLARE_TEST()

EIGEN_DECLARE_TEST ( polynomialsolver  )
187  {
188  for (int i = 0; i < g_repeat; i++) {
189  CALL_SUBTEST_1((polynomialsolver<float, 1>(1)));
190  CALL_SUBTEST_2((polynomialsolver<double, 2>(2)));
191  CALL_SUBTEST_3((polynomialsolver<double, 3>(3)));
192  CALL_SUBTEST_4((polynomialsolver<float, 4>(4)));
193  CALL_SUBTEST_5((polynomialsolver<double, 5>(5)));
194  CALL_SUBTEST_6((polynomialsolver<float, 6>(6)));
195  CALL_SUBTEST_7((polynomialsolver<float, 7>(7)));
196  CALL_SUBTEST_8((polynomialsolver<double, 8>(8)));
197 
198  CALL_SUBTEST_9((polynomialsolver<float, Dynamic>(internal::random<int>(9, 13))));
199  CALL_SUBTEST_10((polynomialsolver<double, Dynamic>(internal::random<int>(9, 13))));
200  CALL_SUBTEST_11((polynomialsolver<float, Dynamic>(1)));
201  CALL_SUBTEST_12((polynomialsolver<std::complex<double>, Dynamic>(internal::random<int>(2, 13))));
202  }
203 }
static int g_repeat
Definition: main.h:191
const int Dynamic
Definition: Constants.h:25
void polynomialsolver(int deg)
Definition: polynomialsolver.cpp:164
#define CALL_SUBTEST_6(FUNC)
Definition: split_test_helper.h:34
#define CALL_SUBTEST_3(FUNC)
Definition: split_test_helper.h:16
#define CALL_SUBTEST_1(FUNC)
Definition: split_test_helper.h:4
#define CALL_SUBTEST_8(FUNC)
Definition: split_test_helper.h:46
#define CALL_SUBTEST_5(FUNC)
Definition: split_test_helper.h:28
#define CALL_SUBTEST_11(FUNC)
Definition: split_test_helper.h:64
#define CALL_SUBTEST_12(FUNC)
Definition: split_test_helper.h:70
#define CALL_SUBTEST_2(FUNC)
Definition: split_test_helper.h:10
#define CALL_SUBTEST_7(FUNC)
Definition: split_test_helper.h:40
#define CALL_SUBTEST_4(FUNC)
Definition: split_test_helper.h:22
#define CALL_SUBTEST_9(FUNC)
Definition: split_test_helper.h:52
#define CALL_SUBTEST_10(FUNC)
Definition: split_test_helper.h:58

References CALL_SUBTEST_1, CALL_SUBTEST_10, CALL_SUBTEST_11, CALL_SUBTEST_12, CALL_SUBTEST_2, CALL_SUBTEST_3, CALL_SUBTEST_4, CALL_SUBTEST_5, CALL_SUBTEST_6, CALL_SUBTEST_7, CALL_SUBTEST_8, CALL_SUBTEST_9, Eigen::Dynamic, Eigen::g_repeat, i, and polynomialsolver().

◆ evalSolver()

template<int Deg, typename POLYNOMIAL >
void evalSolver ( const POLYNOMIAL &  pols)
86  {
87  typedef typename POLYNOMIAL::Scalar Scalar;
88 
89  typedef PolynomialSolver<Scalar, Deg> PolynomialSolverType;
90 
91  PolynomialSolverType psolve;
92  aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>(pols, psolve);
93 }
A polynomial solver.
Definition: PolynomialSolver.h:300

◆ evalSolverSugarFunction()

template<int Deg, typename POLYNOMIAL , typename ROOTS , typename REAL_ROOTS >
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  typedef typename POLYNOMIAL::RealScalar RealScalar;
100 
101  typedef PolynomialSolver<Scalar, Deg> PolynomialSolverType;
102 
103  PolynomialSolverType psolve;
104  if (aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>(pols, psolve)) {
105  // It is supposed that
106  // 1) the roots found are correct
107  // 2) the roots have distinct moduli
108 
109  // Test realRoots
110  std::vector<RealScalar> calc_realRoots;
111  psolve.realRoots(calc_realRoots, test_precision<RealScalar>());
112  VERIFY_IS_EQUAL(calc_realRoots.size(), (size_t)real_roots.size());
113 
114  const RealScalar psPrec = sqrt(test_precision<RealScalar>());
115 
116  for (size_t i = 0; i < calc_realRoots.size(); ++i) {
117  bool found = false;
118  for (size_t j = 0; j < calc_realRoots.size() && !found; ++j) {
119  if (internal::isApprox(calc_realRoots[i], real_roots[j], psPrec)) {
120  found = true;
121  }
122  }
123  VERIFY(found);
124  }
125 
126  // Test greatestRoot
127  VERIFY(internal::isApprox(roots.array().abs().maxCoeff(), abs(psolve.greatestRoot()), psPrec));
128 
129  // Test smallestRoot
130  VERIFY(internal::isApprox(roots.array().abs().minCoeff(), abs(psolve.smallestRoot()), psPrec));
131 
132  bool hasRealRoot;
133  // Test absGreatestRealRoot
134  RealScalar r = psolve.absGreatestRealRoot(hasRealRoot);
135  VERIFY(hasRealRoot == (real_roots.size() > 0));
136  if (hasRealRoot) {
137  VERIFY(internal::isApprox(real_roots.array().abs().maxCoeff(), abs(r), psPrec));
138  }
139 
140  // Test absSmallestRealRoot
141  r = psolve.absSmallestRealRoot(hasRealRoot);
142  VERIFY(hasRealRoot == (real_roots.size() > 0));
143  if (hasRealRoot) {
144  VERIFY(internal::isApprox(real_roots.array().abs().minCoeff(), abs(r), psPrec));
145  }
146 
147  // Test greatestRealRoot
148  r = psolve.greatestRealRoot(hasRealRoot);
149  VERIFY(hasRealRoot == (real_roots.size() > 0));
150  if (hasRealRoot) {
151  VERIFY(internal::isApprox(real_roots.array().maxCoeff(), r, psPrec));
152  }
153 
154  // Test smallestRealRoot
155  r = psolve.smallestRealRoot(hasRealRoot);
156  VERIFY(hasRealRoot == (real_roots.size() > 0));
157  if (hasRealRoot) {
158  VERIFY(internal::isApprox(real_roots.array().minCoeff(), r, psPrec));
159  }
160  }
161 }
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
void realRoots(Stl_back_insertion_sequence &bi_seq, const RealScalar &absImaginaryThreshold=NumTraits< Scalar >::dummy_precision()) const
Definition: PolynomialSolver.h:73
#define VERIFY_IS_EQUAL(a, b)
Definition: main.h:367
bool found
Definition: MergeRestartFiles.py:24
r
Definition: UniformPSDSelfTest.py:20
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References abs(), MergeRestartFiles::found, i, Eigen::internal::isApprox(), j, UniformPSDSelfTest::r, Eigen::PolynomialSolverBase< Scalar_, Deg_ >::realRoots(), sqrt(), VERIFY, and VERIFY_IS_EQUAL.

◆ polyder()

template<typename PolynomialType >
PolynomialType polyder ( const PolynomialType &  p)
27  {
28  typedef typename PolynomialType::Scalar Scalar;
29  PolynomialType res(p.size());
30  for (Index i = 1; i < p.size(); ++i) res[i - 1] = p[i] * Scalar(i);
31  res[p.size() - 1] = 0.;
32  return res;
33 }
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
float * p
Definition: Tutorial_Map_using.cpp:9
PolynomialType
PolynomialType is used to define how files are opened random fixed-particle bottom.
Definition: Polynomial.h:29

References i, p, and res.

Referenced by aux_evalSolver().

◆ polynomialsolver()

template<typename Scalar_ , int Deg_>
void polynomialsolver ( int  deg)
164  {
165  typedef typename NumTraits<Scalar_>::Real RealScalar;
166  typedef internal::increment_if_fixed_size<Deg_> Dim;
168  typedef Matrix<Scalar_, Deg_, 1> EvalRootsType;
169  typedef Matrix<RealScalar, Deg_, 1> RealRootsType;
170 
171  cout << "Standard cases" << endl;
172  PolynomialType pols = PolynomialType::Random(deg + 1);
173  evalSolver<Deg_, PolynomialType>(pols);
174 
175  cout << "Hard cases" << endl;
176  Scalar_ multipleRoot = internal::random<Scalar_>();
177  EvalRootsType allRoots = EvalRootsType::Constant(deg, multipleRoot);
178  roots_to_monicPolynomial(allRoots, pols);
179  evalSolver<Deg_, PolynomialType>(pols);
180 
181  cout << "Test sugar" << endl;
182  RealRootsType realRoots = RealRootsType::Random(deg);
183  roots_to_monicPolynomial(realRoots, pols);
184  evalSolverSugarFunction<Deg_>(pols, realRoots.template cast<std::complex<RealScalar> >().eval(), realRoots);
185 }
EIGEN_DEVICE_FUNC NewType cast(const OldType &x)
Definition: MathFunctions.h:362
void roots_to_monicPolynomial(const RootVector &rv, Polynomial &poly)
Definition: PolynomialUtils.h:128
static const unsigned Dim
Problem dimension.
Definition: two_d_tilted_square.cc:62
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217

References Eigen::internal::cast(), Global_Variables::Dim, and Eigen::roots_to_monicPolynomial().

Referenced by EIGEN_DECLARE_TEST().