VTK
|
polynomial solvers More...
#include <vtkPolynomialSolversUnivariate.h>
Public Types | |
typedef vtkObject | Superclass |
Public Member Functions | |
virtual int | IsA (const char *type) |
vtkPolynomialSolversUnivariate * | NewInstance () const |
void | PrintSelf (ostream &os, vtkIndent indent) |
Static Public Member Functions | |
static vtkPolynomialSolversUnivariate * | New () |
static int | IsTypeOf (const char *type) |
static vtkPolynomialSolversUnivariate * | SafeDownCast (vtkObjectBase *o) |
static ostream & | PrintPolynomial (ostream &os, double *P, int degP) |
static int | LinBairstowSolve (double *c, int d, double *r, double &tolerance) |
static int | FerrariSolve (double *c, double *r, int *m, double tol) |
static int | TartagliaCardanSolve (double *c, double *r, int *m, double tol) |
static double * | SolveCubic (double c0, double c1, double c2, double c3) |
static double * | SolveQuadratic (double c0, double c1, double c2) |
static double * | SolveLinear (double c0, double c1) |
static int | SolveQuadratic (double *c, double *r, int *m) |
static int | SolveLinear (double c0, double c1, double *r1, int *num_roots) |
static int | HabichtBisectionSolve (double *P, int d, double *a, double *upperBnds, double tol) |
static int | HabichtBisectionSolve (double *P, int d, double *a, double *upperBnds, double tol, int intervalType) |
static int | HabichtBisectionSolve (double *P, int d, double *a, double *upperBnds, double tol, int intervalType, bool divideGCD) |
static int | SturmBisectionSolve (double *P, int d, double *a, double *upperBnds, double tol) |
static int | SturmBisectionSolve (double *P, int d, double *a, double *upperBnds, double tol, int intervalType) |
static int | SturmBisectionSolve (double *P, int d, double *a, double *upperBnds, double tol, int intervalType, bool divideGCD) |
static int | FilterRoots (double *P, int d, double *upperBnds, int rootcount, double diameter) |
static int | SolveCubic (double c0, double c1, double c2, double c3, double *r1, double *r2, double *r3, int *num_roots) |
static int | SolveQuadratic (double c0, double c1, double c2, double *r1, double *r2, int *num_roots) |
static void | SetDivisionTolerance (double tol) |
static double | GetDivisionTolerance () |
Protected Member Functions | |
virtual vtkObjectBase * | NewInstanceInternal () const |
vtkPolynomialSolversUnivariate () | |
~vtkPolynomialSolversUnivariate () | |
Static Protected Attributes | |
static double | DivisionTolerance |
polynomial solvers
vtkPolynomialSolversUnivariate provides solvers for univariate polynomial equations with real coefficients. The Tartaglia-Cardan and Ferrari solvers work on polynomials of fixed degree 3 and 4, respectively. The Lin-Bairstow and Sturm solvers work on polynomials of arbitrary degree. The Sturm solver is the most robust solver but only reports roots within an interval and does not report multiplicities. The Lin-Bairstow solver reports multiplicities.
For difficult polynomials, you may wish to use FilterRoots to eliminate some of the roots reported by the Sturm solver. FilterRoots evaluates the derivatives near each root to eliminate cases where a local minimum or maximum is close to zero.
Definition at line 57 of file vtkPolynomialSolversUnivariate.h.
Reimplemented from vtkObject.
Definition at line 61 of file vtkPolynomialSolversUnivariate.h.
vtkPolynomialSolversUnivariate::vtkPolynomialSolversUnivariate | ( | ) | [inline, protected] |
Definition at line 248 of file vtkPolynomialSolversUnivariate.h.
vtkPolynomialSolversUnivariate::~vtkPolynomialSolversUnivariate | ( | ) | [inline, protected] |
Definition at line 249 of file vtkPolynomialSolversUnivariate.h.
static vtkPolynomialSolversUnivariate* vtkPolynomialSolversUnivariate::New | ( | ) | [static] |
Create an object with Debug turned off, modified time initialized to zero, and reference counting on.
Reimplemented from vtkObject.
static int vtkPolynomialSolversUnivariate::IsTypeOf | ( | const char * | name | ) | [static] |
Return 1 if this class type is the same type of (or a subclass of) the named class. Returns 0 otherwise. This method works in combination with vtkTypeMacro found in vtkSetGet.h.
Reimplemented from vtkObject.
virtual int vtkPolynomialSolversUnivariate::IsA | ( | const char * | name | ) | [virtual] |
Return 1 if this class is the same type of (or a subclass of) the named class. Returns 0 otherwise. This method works in combination with vtkTypeMacro found in vtkSetGet.h.
Reimplemented from vtkObject.
static vtkPolynomialSolversUnivariate* vtkPolynomialSolversUnivariate::SafeDownCast | ( | vtkObjectBase * | o | ) | [static] |
Reimplemented from vtkObject.
virtual vtkObjectBase* vtkPolynomialSolversUnivariate::NewInstanceInternal | ( | ) | const [protected, virtual] |
Reimplemented from vtkObject.
Reimplemented from vtkObject.
void vtkPolynomialSolversUnivariate::PrintSelf | ( | ostream & | os, |
vtkIndent | indent | ||
) | [virtual] |
static ostream& vtkPolynomialSolversUnivariate::PrintPolynomial | ( | ostream & | os, |
double * | P, | ||
int | degP | ||
) | [static] |
static int vtkPolynomialSolversUnivariate::HabichtBisectionSolve | ( | double * | P, |
int | d, | ||
double * | a, | ||
double * | upperBnds, | ||
double | tol | ||
) | [static] |
Finds all REAL roots (within tolerance tol) of the d -th degree polynomial
in ]a[0] ; a[1]] using the Habicht sequence (polynomial coefficients are REAL) and returns the count nr. All roots are bracketed in the first ]upperBnds[i] - tol ; upperBnds[i]] intervals. Returns -1 if anything went wrong (such as: polynomial does not have degree d, the interval provided by the other is absurd, etc.). intervalType specifies the search interval as follows: 0 = 00 = ]a,b[ 1 = 10 = [a,b[ 2 = 01 = ]a,b] 3 = 11 = [a,b] This defaults to 0. The last non-zero item in the Habicht sequence is the gcd of P and P'. The parameter divideGCD specifies whether the program should attempt to divide by the gcd and run again. It works better with polynomials known to have high multiplicities. When divideGCD != 0 then it attempts to divide by the GCD, if applicable. This defaults to 0. Compared to the Sturm solver the Habicht solver is slower, although both are O(d^2). The Habicht solver has the added benefit that it has a built in mechanism to keep the leading coefficients of the result from polynomial division bounded above and below in absolute value. This will tend to keep the coefficients of the polynomials in the sequence from zeroing out prematurely or becoming infinite. Constructing the Habicht sequence is O(d^2) in both time and space. Warning: it is the user's responsibility to make sure the upperBnds array is large enough to contain the maximal number of expected roots. Note that nr is smaller or equal to the actual number of roots in ]a[0] ; a[1]] since roots within are lumped in the same bracket. array is large enough to contain the maximal number of expected upper bounds.
static int vtkPolynomialSolversUnivariate::HabichtBisectionSolve | ( | double * | P, |
int | d, | ||
double * | a, | ||
double * | upperBnds, | ||
double | tol, | ||
int | intervalType | ||
) | [static] |
Finds all REAL roots (within tolerance tol) of the d -th degree polynomial
in ]a[0] ; a[1]] using the Habicht sequence (polynomial coefficients are REAL) and returns the count nr. All roots are bracketed in the first ]upperBnds[i] - tol ; upperBnds[i]] intervals. Returns -1 if anything went wrong (such as: polynomial does not have degree d, the interval provided by the other is absurd, etc.). intervalType specifies the search interval as follows: 0 = 00 = ]a,b[ 1 = 10 = [a,b[ 2 = 01 = ]a,b] 3 = 11 = [a,b] This defaults to 0. The last non-zero item in the Habicht sequence is the gcd of P and P'. The parameter divideGCD specifies whether the program should attempt to divide by the gcd and run again. It works better with polynomials known to have high multiplicities. When divideGCD != 0 then it attempts to divide by the GCD, if applicable. This defaults to 0. Compared to the Sturm solver the Habicht solver is slower, although both are O(d^2). The Habicht solver has the added benefit that it has a built in mechanism to keep the leading coefficients of the result from polynomial division bounded above and below in absolute value. This will tend to keep the coefficients of the polynomials in the sequence from zeroing out prematurely or becoming infinite. Constructing the Habicht sequence is O(d^2) in both time and space. Warning: it is the user's responsibility to make sure the upperBnds array is large enough to contain the maximal number of expected roots. Note that nr is smaller or equal to the actual number of roots in ]a[0] ; a[1]] since roots within are lumped in the same bracket. array is large enough to contain the maximal number of expected upper bounds.
static int vtkPolynomialSolversUnivariate::HabichtBisectionSolve | ( | double * | P, |
int | d, | ||
double * | a, | ||
double * | upperBnds, | ||
double | tol, | ||
int | intervalType, | ||
bool | divideGCD | ||
) | [static] |
Finds all REAL roots (within tolerance tol) of the d -th degree polynomial
in ]a[0] ; a[1]] using the Habicht sequence (polynomial coefficients are REAL) and returns the count nr. All roots are bracketed in the first ]upperBnds[i] - tol ; upperBnds[i]] intervals. Returns -1 if anything went wrong (such as: polynomial does not have degree d, the interval provided by the other is absurd, etc.). intervalType specifies the search interval as follows: 0 = 00 = ]a,b[ 1 = 10 = [a,b[ 2 = 01 = ]a,b] 3 = 11 = [a,b] This defaults to 0. The last non-zero item in the Habicht sequence is the gcd of P and P'. The parameter divideGCD specifies whether the program should attempt to divide by the gcd and run again. It works better with polynomials known to have high multiplicities. When divideGCD != 0 then it attempts to divide by the GCD, if applicable. This defaults to 0. Compared to the Sturm solver the Habicht solver is slower, although both are O(d^2). The Habicht solver has the added benefit that it has a built in mechanism to keep the leading coefficients of the result from polynomial division bounded above and below in absolute value. This will tend to keep the coefficients of the polynomials in the sequence from zeroing out prematurely or becoming infinite. Constructing the Habicht sequence is O(d^2) in both time and space. Warning: it is the user's responsibility to make sure the upperBnds array is large enough to contain the maximal number of expected roots. Note that nr is smaller or equal to the actual number of roots in ]a[0] ; a[1]] since roots within are lumped in the same bracket. array is large enough to contain the maximal number of expected upper bounds.
static int vtkPolynomialSolversUnivariate::SturmBisectionSolve | ( | double * | P, |
int | d, | ||
double * | a, | ||
double * | upperBnds, | ||
double | tol | ||
) | [static] |
Finds all REAL roots (within tolerance tol) of the d -th degree polynomial P[0] X^d + ... + P[d-1] X + P[d] in ]a[0] ; a[1]] using Sturm's theorem ( polynomial coefficients are REAL ) and returns the count nr. All roots are bracketed in the first ]upperBnds[i] - tol ; upperBnds[i]] intervals. Returns -1 if anything went wrong (such as: polynomial does not have degree d, the interval provided by the other is absurd, etc.). intervalType specifies the search interval as follows: 0 = 00 = ]a,b[ 1 = 10 = [a,b[ 2 = 01 = ]a,b] 3 = 11 = [a,b] This defaults to 0. The last non-zero item in the Sturm sequence is the gcd of P and P'. The parameter divideGCD specifies whether the program should attempt to divide by the gcd and run again. It works better with polynomials known to have high multiplicities. When divideGCD != 0 then it attempts to divide by the GCD, if applicable. This defaults to 0. Constructing the Sturm sequence is O(d^2) in both time and space. Warning: it is the user's responsibility to make sure the upperBnds array is large enough to contain the maximal number of expected roots. Note that nr is smaller or equal to the actual number of roots in ]a[0] ; a[1]] since roots within are lumped in the same bracket. array is large enough to contain the maximal number of expected upper bounds.
static int vtkPolynomialSolversUnivariate::SturmBisectionSolve | ( | double * | P, |
int | d, | ||
double * | a, | ||
double * | upperBnds, | ||
double | tol, | ||
int | intervalType | ||
) | [static] |
Finds all REAL roots (within tolerance tol) of the d -th degree polynomial P[0] X^d + ... + P[d-1] X + P[d] in ]a[0] ; a[1]] using Sturm's theorem ( polynomial coefficients are REAL ) and returns the count nr. All roots are bracketed in the first ]upperBnds[i] - tol ; upperBnds[i]] intervals. Returns -1 if anything went wrong (such as: polynomial does not have degree d, the interval provided by the other is absurd, etc.). intervalType specifies the search interval as follows: 0 = 00 = ]a,b[ 1 = 10 = [a,b[ 2 = 01 = ]a,b] 3 = 11 = [a,b] This defaults to 0. The last non-zero item in the Sturm sequence is the gcd of P and P'. The parameter divideGCD specifies whether the program should attempt to divide by the gcd and run again. It works better with polynomials known to have high multiplicities. When divideGCD != 0 then it attempts to divide by the GCD, if applicable. This defaults to 0. Constructing the Sturm sequence is O(d^2) in both time and space. Warning: it is the user's responsibility to make sure the upperBnds array is large enough to contain the maximal number of expected roots. Note that nr is smaller or equal to the actual number of roots in ]a[0] ; a[1]] since roots within are lumped in the same bracket. array is large enough to contain the maximal number of expected upper bounds.
static int vtkPolynomialSolversUnivariate::SturmBisectionSolve | ( | double * | P, |
int | d, | ||
double * | a, | ||
double * | upperBnds, | ||
double | tol, | ||
int | intervalType, | ||
bool | divideGCD | ||
) | [static] |
Finds all REAL roots (within tolerance tol) of the d -th degree polynomial P[0] X^d + ... + P[d-1] X + P[d] in ]a[0] ; a[1]] using Sturm's theorem ( polynomial coefficients are REAL ) and returns the count nr. All roots are bracketed in the first ]upperBnds[i] - tol ; upperBnds[i]] intervals. Returns -1 if anything went wrong (such as: polynomial does not have degree d, the interval provided by the other is absurd, etc.). intervalType specifies the search interval as follows: 0 = 00 = ]a,b[ 1 = 10 = [a,b[ 2 = 01 = ]a,b] 3 = 11 = [a,b] This defaults to 0. The last non-zero item in the Sturm sequence is the gcd of P and P'. The parameter divideGCD specifies whether the program should attempt to divide by the gcd and run again. It works better with polynomials known to have high multiplicities. When divideGCD != 0 then it attempts to divide by the GCD, if applicable. This defaults to 0. Constructing the Sturm sequence is O(d^2) in both time and space. Warning: it is the user's responsibility to make sure the upperBnds array is large enough to contain the maximal number of expected roots. Note that nr is smaller or equal to the actual number of roots in ]a[0] ; a[1]] since roots within are lumped in the same bracket. array is large enough to contain the maximal number of expected upper bounds.
static int vtkPolynomialSolversUnivariate::FilterRoots | ( | double * | P, |
int | d, | ||
double * | upperBnds, | ||
int | rootcount, | ||
double | diameter | ||
) | [static] |
This uses the derivative sequence to filter possible roots of a polynomial. First it sorts the roots and removes any duplicates. If the number of sign changes of the derivative sequence at a root at upperBnds[i] == that at upperBnds[i] - diameter then the i^th value is removed from upperBnds. It returns the new number of roots.
static int vtkPolynomialSolversUnivariate::LinBairstowSolve | ( | double * | c, |
int | d, | ||
double * | r, | ||
double & | tolerance | ||
) | [static] |
Seeks all REAL roots of the d -th degree polynomial c[0] X^d + ...
static int vtkPolynomialSolversUnivariate::FerrariSolve | ( | double * | c, |
double * | r, | ||
int * | m, | ||
double | tol | ||
) | [static] |
Algebraically extracts REAL roots of the quartic polynomial with REAL coefficients X^4 + c[0] X^3 + c[1] X^2 + c[2] X + c[3] and stores them (when they exist) and their respective multiplicities in the r and m arrays, based on Ferrari's method. Some numerical noise can be filtered by the use of a tolerance tol instead of equality with 0 (one can use, e.g., VTK_DBL_EPSILON). Returns the number of roots. Warning: it is the user's responsibility to pass a non-negative tol.
static int vtkPolynomialSolversUnivariate::TartagliaCardanSolve | ( | double * | c, |
double * | r, | ||
int * | m, | ||
double | tol | ||
) | [static] |
Algebraically extracts REAL roots of the cubic polynomial with REAL coefficients X^3 + c[0] X^2 + c[1] X + c[2] and stores them (when they exist) and their respective multiplicities in the r and m arrays. Some numerical noise can be filtered by the use of a tolerance tol instead of equality with 0 (one can use, e.g., VTK_DBL_EPSILON). The main differences with SolveCubic are that (1) the polynomial must have unit leading coefficient, (2) complex roots are discarded upfront, (3) non-simple roots are stored only once, along with their respective multiplicities, and (4) some numerical noise is filtered by the use of relative tolerance instead of equality with 0. Returns the number of roots. In memoriam Niccolo Tartaglia (1500 - 1559), unfairly forgotten.
static double* vtkPolynomialSolversUnivariate::SolveCubic | ( | double | c0, |
double | c1, | ||
double | c2, | ||
double | c3 | ||
) | [static] |
Solves a cubic equation c0*t^3 + c1*t^2 + c2*t + c3 = 0 when c0, c1, c2, and c3 are REAL. Solution is motivated by Numerical Recipes In C 2nd Ed. Return array contains number of (real) roots (counting multiple roots as one) followed by roots themselves. The value in roots[4] is a integer giving further information about the roots (see return codes for int SolveCubic() ).
static double* vtkPolynomialSolversUnivariate::SolveQuadratic | ( | double | c0, |
double | c1, | ||
double | c2 | ||
) | [static] |
Solves a quadratic equation c1*t^2 + c2*t + c3 = 0 when c1, c2, and c3 are REAL. Solution is motivated by Numerical Recipes In C 2nd Ed. Return array contains number of (real) roots (counting multiple roots as one) followed by roots themselves. Note that roots[3] contains a return code further describing solution - see documentation for SolveCubic() for meaning of return codes.
static double* vtkPolynomialSolversUnivariate::SolveLinear | ( | double | c0, |
double | c1 | ||
) | [static] |
Solves a linear equation c2*t + c3 = 0 when c2 and c3 are REAL. Solution is motivated by Numerical Recipes In C 2nd Ed. Return array contains number of roots followed by roots themselves.
static int vtkPolynomialSolversUnivariate::SolveCubic | ( | double | c0, |
double | c1, | ||
double | c2, | ||
double | c3, | ||
double * | r1, | ||
double * | r2, | ||
double * | r3, | ||
int * | num_roots | ||
) | [static] |
Solves a cubic equation when c0, c1, c2, And c3 Are REAL. Solution is motivated by Numerical Recipes In C 2nd Ed. Roots and number of real roots are stored in user provided variables r1, r2, r3, and num_roots. Note that the function can return the following integer values describing the roots: (0)-no solution; (-1)-infinite number of solutions; (1)-one distinct real root of multiplicity 3 (stored in r1); (2)-two distinct real roots, one of multiplicity 2 (stored in r1 & r2); (3)-three distinct real roots; (-2)-quadratic equation with complex conjugate solution (real part of root returned in r1, imaginary in r2); (-3)-one real root and a complex conjugate pair (real root in r1 and real part of pair in r2 and imaginary in r3).
static int vtkPolynomialSolversUnivariate::SolveQuadratic | ( | double | c0, |
double | c1, | ||
double | c2, | ||
double * | r1, | ||
double * | r2, | ||
int * | num_roots | ||
) | [static] |
Solves a quadratic equation c1*t^2 + c2*t + c3 = 0 when c1, c2, and c3 are REAL. Solution is motivated by Numerical Recipes In C 2nd Ed. Roots and number of roots are stored in user provided variables r1, r2, num_roots
static int vtkPolynomialSolversUnivariate::SolveQuadratic | ( | double * | c, |
double * | r, | ||
int * | m | ||
) | [static] |
Algebraically extracts REAL roots of the quadratic polynomial with REAL coefficients c[0] X^2 + c[1] X + c[2] and stores them (when they exist) and their respective multiplicities in the r and m arrays. Returns either the number of roots, or -1 if ininite number of roots.
static int vtkPolynomialSolversUnivariate::SolveLinear | ( | double | c0, |
double | c1, | ||
double * | r1, | ||
int * | num_roots | ||
) | [static] |
Solves a linear equation c2*t + c3 = 0 when c2 and c3 are REAL. Solution is motivated by Numerical Recipes In C 2nd Ed. Root and number of (real) roots are stored in user provided variables r2 and num_roots.
static void vtkPolynomialSolversUnivariate::SetDivisionTolerance | ( | double | tol | ) | [static] |
Set/get the tolerance used when performing polynomial Euclidean division to find polynomial roots. This tolerance is used to decide whether the coefficient(s) of a polynomial remainder are close enough to zero to be neglected.
static double vtkPolynomialSolversUnivariate::GetDivisionTolerance | ( | ) | [static] |
Set/get the tolerance used when performing polynomial Euclidean division to find polynomial roots. This tolerance is used to decide whether the coefficient(s) of a polynomial remainder are close enough to zero to be neglected.
double vtkPolynomialSolversUnivariate::DivisionTolerance [static, protected] |
Definition at line 249 of file vtkPolynomialSolversUnivariate.h.