42#include <gsl/gsl_poly.h>
48# define M_PI 3.14159265358979323846
55 for(
unsigned i = 0; i <
size(); i++) {
56 for(
unsigned j = 0; j < p.size(); j++) {
57 result[i+j] += (*this)[i] * p[j];
75 double scale = 1./back();
77 for(
unsigned i = 0; i <
size(); i++) {
84std::vector<std::complex<double> >
solve(
Poly const & pp) {
87 gsl_poly_complex_workspace *
w
88 = gsl_poly_complex_workspace_alloc (p.size());
90 gsl_complex_packed_ptr z =
new double[p.
degree()*2];
91 double* a =
new double[p.size()];
92 for(
unsigned int i = 0; i < p.size(); i++)
94 std::vector<std::complex<double> >
roots;
97 gsl_poly_complex_solve (a, p.size(),
w, z);
100 gsl_poly_complex_workspace_free (
w);
102 for (
unsigned int i = 0; i < p.
degree(); i++) {
103 roots.emplace_back(z[2*i] ,z[2*i+1]);
111 std::vector<std::complex<double> >
roots =
solve(p);
112 std::vector<double> real_roots;
116 real_roots.push_back(
root.real());
125 double fn = p(guess);
126 while(fabs(fn) > tol) {
127 guess -= fn/dp(guess);
136 result.reserve(p.size()+1);
138 for(
unsigned i = 0; i < p.size(); i++) {
139 result.push_back(p[i]/(i+1));
150 result.reserve(p.size()-1);
151 for(
unsigned i = 1; i < p.size(); i++) {
160 for(
unsigned i = a.size(); i > 0; i--) {
191 assert(b.size() > 0);
193 const unsigned k = a.
degree();
194 const unsigned l = b.
degree();
197 for(
unsigned i = k; i >= l; i--) {
199 double ci = r.back()/b.back();
215 if(a.size() < b.size())
228 std::vector<Coord>
result;
232 if (b == 0)
return result;
241 result.push_back(-b / (2*a));
242 }
else if (
delta > 0) {
249 int sign = b >= 0 ? 1 : -1;
250 Coord t = -0.5 * (b +
sign * delta_sqrt);
276 std::vector<Coord>
result;
284 Coord Q = (3*
c - b*b) / 9;
285 Coord R = (-27 * d + b * (9*
c - 2*b*b)) / 54;
295 result.push_back(-b/3 + S + T);
300 result.push_back(-term1 + 2*rroot);
301 result.push_back(-term1 - rroot);
302 result.push_back(-term1 - rroot);
309 result.push_back(-term1 + rroot *
cos(theta / 3));
310 result.push_back(-term1 + rroot *
cos((theta + 2*M_PI) / 3));
311 result.push_back(-term1 + rroot *
cos((theta + 4*M_PI) / 3));
341 auto const resolvent_solutions =
solve_cubic(1, -
c, b * d - 4 * e, 4 *
c * e -
sqr(b) * e -
sqr(d));
343 auto const y = resolvent_solutions[resolvent_solutions.size() == 3];
348 if (linear_terms.size() < 2 || constant_terms.size() < 2) {
354 auto const current_cross = linear_terms[0] * constant_terms[1] + linear_terms[1] * constant_terms[0];
355 auto const reordered_cross = linear_terms[0] * constant_terms[0] + linear_terms[1] * constant_terms[1];
356 if (std::abs(d - reordered_cross) < std::abs(d - current_cross)) {
357 std::swap(constant_terms[0], constant_terms[1]);
361 std::vector<Coord>
result;
363 for (
size_t i : {0, 1}) {
364 auto const factor_roots =
solve_quadratic(1, linear_terms[i], constant_terms[i]);
365 result.insert(
result.end(), factor_roots.begin(), factor_roots.end());
Polynomial in canonical (monomial) basis.
Poly shifted(unsigned const terms) const
Poly operator*(const double p) const
double Coord
Floating point type used to store coordinates.
Low level math functions and compatibility wrappers.
Various utility functions.
SBasisN< n > cos(LinearN< n > bo, int k)
std::vector< Coord > solve_quartic(Coord a, Coord b, Coord c, Coord d, Coord e)
Analytically solve quartic equation.
SBasisN< n > divide(SBasisN< n > const &a, SBasisN< n > const &b, int k)
Poly gcd(Poly const &a, Poly const &b, const double tol=1e-10)
static float sign(double number)
Returns +1 for positive numbers, -1 for negative numbers, and 0 otherwise.
std::vector< Coord > solve_quadratic(Coord a, Coord b, Coord c)
Analytically solve quadratic equation.
SBasisN< n > sqrt(SBasisN< n > const &a, int k)
std::vector< Coord > solve_cubic(Coord a, Coord b, Coord c, Coord d)
Analytically solve cubic equation.
D2< T > compose(D2< T > const &a, T const &b)
std::vector< double > roots(SBasis const &s)
std::vector< double > solve_reals(const Poly &p)
std::vector< std::complex< double > > solve(const Poly &p)
Bezier integral(Bezier const &a)
Bezier derivative(Bezier const &a)
double polish_root(Poly const &p, double guess, double tol)
Polynomial in canonical (monomial) basis.