1
#include <2geom/poly.h>
5
#include <gsl/gsl_poly.h>
10
Poly Poly::operator*(const Poly& p) const {
12
result.resize(degree() + p.degree()+1);
14
for(unsigned i = 0; i < size(); i++) {
15
for(unsigned j = 0; j < p.size(); j++) {
16
result[i+j] += (*this)[i] * p[j];
22
/*double Poly::eval(double x) const {
23
return gsl_poly_eval(&coeff[0], size(), x);
26
void Poly::normalize() {
31
void Poly::monicify() {
34
double scale = 1./back(); // unitize
36
for(unsigned i = 0; i < size(); i++) {
43
std::vector<std::complex<double> > solve(Poly const & pp) {
46
gsl_poly_complex_workspace * w
47
= gsl_poly_complex_workspace_alloc (p.size());
49
gsl_complex_packed_ptr z = new double[p.degree()*2];
50
double* a = new double[p.size()];
51
for(unsigned int i = 0; i < p.size(); i++)
53
std::vector<std::complex<double> > roots;
54
//roots.resize(p.degree());
56
gsl_poly_complex_solve (a, p.size(), w, z);
59
gsl_poly_complex_workspace_free (w);
61
for (unsigned int i = 0; i < p.degree(); i++) {
62
roots.push_back(std::complex<double> (z[2*i] ,z[2*i+1]));
63
//printf ("z%d = %+.18f %+.18f\n", i, z[2*i], z[2*i+1]);
69
std::vector<double > solve_reals(Poly const & p) {
70
std::vector<std::complex<double> > roots = solve(p);
71
std::vector<double> real_roots;
73
for(unsigned int i = 0; i < roots.size(); i++) {
74
if(roots[i].imag() == 0) // should be more lenient perhaps
75
real_roots.push_back(roots[i].real());
81
double polish_root(Poly const & p, double guess, double tol) {
82
Poly dp = derivative(p);
85
while(fabs(fn) > tol) {
86
guess -= fn/dp(guess);
92
Poly integral(Poly const & p) {
95
result.reserve(p.size()+1);
96
result.push_back(0); // arbitrary const
97
for(unsigned i = 0; i < p.size(); i++) {
98
result.push_back(p[i]/(i+1));
104
Poly derivative(Poly const & p) {
109
result.reserve(p.size()-1);
110
for(unsigned i = 1; i < p.size(); i++) {
111
result.push_back(i*p[i]);
116
Poly compose(Poly const & a, Poly const & b) {
119
for(unsigned i = a.size(); i > 0; i--) {
120
result = Poly(a[i-1]) + result * b;
126
/* This version is backwards - dividing taylor terms
127
Poly divide(Poly const &a, Poly const &b, Poly &r) {
131
const unsigned k = a.size();
135
for(unsigned i = 0; i < k; i++) {
136
double ci = r[i]/b[0];
139
std::cout << ci <<"*" << b << ", r= " << r << std::endl;
147
Poly divide(Poly const &a, Poly const &b, Poly &r) {
150
assert(b.size() > 0);
152
const unsigned k = a.degree();
153
const unsigned l = b.degree();
156
for(unsigned i = k; i >= l; i--) {
158
double ci = r.back()/b.back();
161
//std::cout << ci <<"*(" << b.shifted(i-l) << ") = "
162
// << bb.shifted(i-l) << " r= " << r << std::endl;
163
r -= bb.shifted(i-l);
166
//std::cout << "r= " << r << std::endl;
173
Poly gcd(Poly const &a, Poly const &b, const double /*tol*/) {
174
if(a.size() < b.size())
187
/*Poly divide_out_root(Poly const & p, double x) {
196
c-file-style:"stroustrup"
197
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
202
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :