/*
poly.cc -- routines for manipulation of polynomials in one var
- (c) 1993--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 1993--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
#include "polynomial.hh"
+#include "warn.hh"
+
#include <cmath>
+
+using namespace std;
+
/*
Een beter milieu begint bij uzelf. Hergebruik!
*/
Real
-Polynomial::eval (Real x)const
+Polynomial::eval (Real x) const
{
Real p = 0.0;
// horner's scheme
- for (int i = coefs_.size (); i--;)
+ for (vsize i = coefs_.size (); i--;)
p = x * p + coefs_[i];
return p;
int deg = p1.degree () + p2.degree ();
for (int i = 0; i <= deg; i++)
{
- dest.coefs_.push (0);
+ dest.coefs_.push_back (0);
for (int j = 0; j <= i; j++)
if (i - j <= p2.degree () && j <= p1.degree ())
- dest.coefs_.top () += p1.coefs_[j] * p2.coefs_[i - j];
+ dest.coefs_.back () += p1.coefs_[j] * p2.coefs_[i - j];
}
return dest;
Polynomial::differentiate ()
{
for (int i = 1; i <= degree (); i++)
- {
- coefs_[i - 1] = coefs_[i] * i;
- }
- coefs_.pop ();
+ coefs_[i - 1] = coefs_[i] * i;
+ coefs_.pop_back ();
}
Polynomial
We only do relative comparisons. Absolute comparisons break down in
degenerate cases. */
while (degree () > 0
- && (fabs (coefs_.top ()) < FUDGE *fabs (coefs_.top (1))
- || !coefs_.top ()))
- coefs_.pop ();
+ && (fabs (coefs_.back ()) < FUDGE * fabs (back (coefs_, 1))
+ || !coefs_.back ()))
+ coefs_.pop_back ();
}
void
Polynomial::operator += (Polynomial const &p)
{
while (degree () < p.degree ())
- coefs_.push (0.0);
+ coefs_.push_back (0.0);
for (int i = 0; i <= p.degree (); i++)
coefs_[i] += p.coefs_[i];
Polynomial::operator -= (Polynomial const &p)
{
while (degree () < p.degree ())
- coefs_.push (0.0);
+ coefs_.push_back (0.0);
for (int i = 0; i <= p.degree (); i++)
coefs_[i] -= p.coefs_[i];
while (k >= 0 && coefs_[k] == 0.0)
k--;
- coefs_.set_size (1+ ((k < 0) ? 0 : k));
+ coefs_.resize (1+ ((k < 0) ? 0 : k));
return degree ();
}
Real d = p.eval (x);
if (abs (f) > abs (d) * FUDGE)
- ;
- /*
- warning ("x=%f is not a root of polynomial\n"
- "f (x)=%f, f' (x)=%f \n", x, f, d); */
+ programming_error ("not a root of polynomial\n");
}
void
-Polynomial::check_sols (Array<Real> roots) const
+Polynomial::check_sols (vector<Real> roots) const
{
- for (int i = 0; i < roots.size (); i++)
+ for (vsize i = 0; i < roots.size (); i++)
check_sol (roots[i]);
}
Polynomial::Polynomial (Real a, Real b)
{
- coefs_.push (a);
+ coefs_.push_back (a);
if (b)
- coefs_.push (b);
+ coefs_.push_back (b);
}
/* cubic root. */
return pow (x, 1.0 / 3.0);
else if (x < 0.0)
return -pow (-x, 1.0 / 3.0);
- else
- return 0.0;
+ return 0.0;
}
static bool
return !r;
}
-Array<Real>
+vector<Real>
Polynomial::solve_cubic ()const
{
- Array<Real> sol;
+ vector<Real> sol;
/* normal form: x^3 + Ax^2 + Bx + C = 0 */
Real A = coefs_[2] / coefs_[3];
if (iszero (D))
{
if (iszero (q)) { /* one triple solution */
- sol.push (0);
- sol.push (0);
- sol.push (0);
+ sol.push_back (0);
+ sol.push_back (0);
+ sol.push_back (0);
}
else { /* one single and one double solution */
Real u = cubic_root (-q);
- sol.push (2 * u);
- sol.push (-u);
+ sol.push_back (2 * u);
+ sol.push_back (-u);
}
}
- else if (D < 0) { /* Casus irreducibilis: three real solutions */
- Real phi = 1.0 / 3 * acos (-q / sqrt (-cb));
- Real t = 2 * sqrt (-p);
-
- sol.push (t * cos (phi));
- sol.push (-t * cos (phi + M_PI / 3));
- sol.push (-t * cos (phi - M_PI / 3));
- }
- else { /* one real solution */
- Real sqrt_D = sqrt (D);
- Real u = cubic_root (sqrt_D - q);
- Real v = -cubic_root (sqrt_D + q);
-
- sol.push (u + v);
- }
+ else if (D < 0)
+ {
+ /* Casus irreducibilis: three real solutions */
+ Real phi = 1.0 / 3 * acos (-q / sqrt (-cb));
+ Real t = 2 * sqrt (-p);
+
+ sol.push_back (t * cos (phi));
+ sol.push_back (-t * cos (phi + M_PI / 3));
+ sol.push_back (-t * cos (phi - M_PI / 3));
+ }
+ else
+ {
+ /* one real solution */
+ Real sqrt_D = sqrt (D);
+ Real u = cubic_root (sqrt_D - q);
+ Real v = -cubic_root (sqrt_D + q);
+
+ sol.push_back (u + v);
+ }
/* resubstitute */
Real sub = 1.0 / 3 * A;
- for (int i = sol.size (); i--;)
+ for (vsize i = sol.size (); i--;)
{
sol[i] -= sub;
Real
Polynomial::lc () const
{
- return coefs_.top ();
+ return coefs_.back ();
}
Real &
Polynomial::lc ()
{
- return coefs_.top ();
+ return coefs_.back ();
}
int
/*
all roots of quadratic eqn.
*/
-Array<Real>
+vector<Real>
Polynomial::solve_quadric ()const
{
- Array<Real> sol;
+ vector<Real> sol;
/* normal form: x^2 + px + q = 0 */
Real p = coefs_[1] / (2 * coefs_[2]);
Real q = coefs_[0] / coefs_[2];
{
D = sqrt (D);
- sol.push (D - p);
- sol.push (-D - p);
+ sol.push_back (D - p);
+ sol.push_back (-D - p);
}
return sol;
}
/* solve linear equation */
-Array<Real>
+vector<Real>
Polynomial::solve_linear ()const
{
- Array<Real> s;
+ vector<Real> s;
if (coefs_[1])
- s.push (-coefs_[0] / coefs_[1]);
+ s.push_back (-coefs_[0] / coefs_[1]);
return s;
}
-Array<Real>
+vector<Real>
Polynomial::solve () const
{
Polynomial *me = (Polynomial *) this;
case 3:
return solve_cubic ();
}
- Array<Real> s;
+ vector<Real> s;
return s;
}