Honeycomb  0.1
Component-Model Framework
Polynomial.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Math/Alge/Alge.h"
5 #include "Honey/Math/Alge/Trig.h"
7 
8 namespace honey
9 {
10 
12 
16 template<class Real>
18 {
19  typedef typename Numeral<Real>::Real_ Real_;
20  typedef Alge_<Real> Alge;
21  typedef Trig_<Real> Trig;
22 
23 public:
24  typedef Vec<2, Real> Vec2;
25  typedef Vec<3, Real> Vec3;
26  typedef Vec<4, Real> Vec4;
27  typedef Vec<5, Real> Vec5;
29 
31  template<class T>
32  static Real eval(const VecBase<T>& c, Real x)
33  {
34  int degree = size(c)-1;
35  Real res = degree >= 0 ? c[degree] : 0;
36  for (auto i : range(degree-1, -1, -1))
37  {
38  res *= x;
39  res += c[i];
40  }
41  return res;
42  }
43 
45 
51  template<class T>
52  static tuple<T, int> compress(const VecBase<T>& c, Real epsilon = Real_::epsilon)
53  {
54  T poly = c;
55  int degree = size(poly)-1;
56 
57  for (auto i : range(degree, -1, -1))
58  if (Alge::isNearZero(poly[i], epsilon)) --degree;
59  else break;
60 
61  if (degree >= 0)
62  {
63  Real leadingInv = 1 / poly[degree];
64  poly[degree] = 1;
65  for (auto i : range(degree)) poly[i] *= leadingInv;
66  }
67 
68  return make_tuple(poly, degree);
69  }
70 
72  template<class T>
73  static auto derivative(const VecBase<T>& c) ->
74  honey::Vec<(T::s_size == matrix::dynamic ? matrix::dynamic : T::s_size - 1), Real>
75  {
76  int degree = size(c)-1;
77  honey::Vec<(T::s_size == matrix::dynamic ? matrix::dynamic : T::s_size - 1), Real> poly;
78  poly.resize(degree);
79 
80  int i1 = 1;
81  for (auto i0 : range(degree))
82  {
83  poly[i0] = i1*c[i1];
84  ++i1;
85  }
86  return poly;
87  }
88 
90 
94  static tuple<Real, int> roots(const Vec2& c, Real epsilon = Real_::epsilon);
96  static tuple<Vec2, int> roots(const Vec3& c, Real epsilon = Real_::epsilon);
98  static tuple<Vec3, int> roots(const Vec4& c, Real epsilon = Real_::epsilon);
100  static tuple<Vec4, int> roots(const Vec5& c, Real epsilon = Real_::epsilon);
101 
103 
107  static tuple<Vec, int> roots(const Vec& c, Real epsilon = Real_::epsilon, int iterMax = 30);
109  static tuple<Vec, int> rootsInRange(const Vec& c, Real min, Real max, Real epsilon = Real_::epsilon, int iterMax = 30);
110 
112  template<class T>
113  static tuple<Real,Real> rootBounds(const VecBase<T>& c, Real epsilon = Real_::epsilon)
114  {
115  T poly;
116  int degree;
117  tie(poly, degree) = compress(c, epsilon);
118 
119  if (degree <= 0) return make_tuple((Real)0,(Real)0); //Polynomial is constant
120 
121  Real upperMax = 0, lowerMax = 0;
122  for (auto i : range(degree))
123  {
124  Real tmp = Alge::abs(poly[i]);
125  if (tmp > upperMax) upperMax = tmp;
126  tmp = Alge::abs(poly[i+1]);
127  if (tmp > lowerMax) lowerMax = tmp;
128  }
129 
130  //Leading is 1 because of compress
131  Real constant = Alge::abs(poly[0]);
132  return make_tuple(!Alge::isNearZero(constant) ? constant / (constant + lowerMax) : 0, 1 + upperMax);
133  }
134 };
135 
136 extern template class Polynomial<Float>;
137 extern template class Polynomial<Double>;
138 extern template class Polynomial<Quad>;
139 
140 }
static const sdt dynamic
Definition: Traits.h:23
Algebra.
Definition: Alge.h:13
Vec< 3, Real > Vec3
Definition: Polynomial.h:25
static Real eval(const VecBase< T > &c, Real x)
Evaluate a polynomial at x.
Definition: Polynomial.h:32
Vec< matrix::dynamic, Real > Vec
Definition: Polynomial.h:28
static tuple< T, int > compress(const VecBase< T > &c, Real epsilon=Real_::epsilon)
Reduce the degree by eliminating all near-zero leading coefficients and by making the leading coeffic...
Definition: Polynomial.h:52
static auto derivative(const VecBase< T > &c) -> honey::Vec<(T::s_size==matrix::dynamic?matrix::dynamic:T::s_size-1), Real >
Get the derivative of a polynomial. Returns a polynomial with 1 degree less.
Definition: Polynomial.h:73
std::enable_if< mt::isIterator< Iter1 >::value, Range_< Iter1, Iter2 > >::type range(Iter1 &&first, Iter2 &&last)
Range from iterators [first, last)
Definition: Range.h:116
Vec< 2, Real > Vec2
Definition: Polynomial.h:24
static Int abs(Int x)
Get absolute value of signed integer.
Definition: Alge.h:21
float Real
Real number type. See Real_ for real number operations and constants.
Definition: Real.h:21
Numeric type information, use numeral() to get instance safely from a static context.
Definition: Numeral.h:17
static bool isNearZero(Real val, Real tol=Real_::zeroTol)
Check whether a number is close to zero.
Definition: Alge.h:108
static tuple< Vec, int > rootsInRange(const Vec &c, Real min, Real max, Real epsilon=Real_::epsilon, int iterMax=30)
Find roots of generic polynomial within range using bisection.
Definition: Polynomial.cpp:220
Vector base class.
Definition: Base.h:11
static tuple< Real, int > roots(const Vec2 &c, Real epsilon=Real_::epsilon)
Find roots using an algebraic closed form expression. Solves the linear equation: ...
Definition: Polynomial.cpp:10
int size(const StdContainer &cont)
Safely get the size of a std container as a signed integer.
Definition: StdUtil.h:19
Vec< 4, Real > Vec4
Definition: Polynomial.h:26
Polynomial algorithms.
Definition: Polynomial.h:17
Vec< 5, Real > Vec5
Definition: Polynomial.h:27
Global Honeycomb namespace.
static tuple< Real, Real > rootBounds(const VecBase< T > &c, Real epsilon=Real_::epsilon)
Get lower and upper bounds of root magnitudes. Returns positive range or 0 if polynomial is constant ...
Definition: Polynomial.h:113
Trigonometry.
Definition: Trig.h:52
VecS & resize(sdt dim)
Sets number of dimensions and reallocates only if different. All previous data is lost on reallocatio...
Definition: Base.h:69