7namespace PolynomialTools{
 
   12typedef std::complex<double> ComplexDouble;
 
   34    void Evaluate(ComplexDouble x, ComplexDouble& fx, ComplexDouble& dfx, ComplexDouble& ddfx, 
double& err){
 
   40        for(
int i = N-1; i >= 0; i--){
 
   44            err  =  err*abx + fabs(fx);
 
   47        err*=2.0*std::numeric_limits<double>::epsilon();
 
   57        for(
int i = N-2; i >= 0 ; i--){
 
   58            Factor.C[i] = C[i+1] + Factor.C[i+1]*root;
 
   65    ComplexDouble 
LaguerreIteration(
const ComplexDouble& FX, 
const ComplexDouble& DFX, 
const ComplexDouble& DDFX){
 
   66        ComplexDouble G = DFX/FX;
 
   67        ComplexDouble H = G*G-DDFX/FX;
 
   68        ComplexDouble SQ = sqrt(ComplexDouble(N-1)*(ComplexDouble(N)*H - G*G));
 
   69        ComplexDouble GP = G + SQ;
 
   70        ComplexDouble GM = G - SQ;
 
   71        if(GM.real()*GM.real() + GM.imag()*GM.imag() > GP.real()*GP.real() + GP.imag()*GP.imag()){
 
   74        return ComplexDouble(N)/GP;
 
   81    int FindRoots(ComplexDouble X0, ComplexDouble* roots){
 
   82        ComplexDouble C_X, FX, DFX, DDFX;
 
   87        while(fabs(FX) > ERR){
 
   95        return it + factorize.FindRoots(X0,roots+1);
 
  104        ComplexDouble C_X, FX, DFX, DDFX;
 
  109        while(fabs(FX) > ERR){
 
  117        int iterations = it + factorize.FindRootsHQ(X0,roots+1);
 
  118        for(
int i = 1; i < N; i++){
 
  120            while(fabs(FX) > ERR){
 
  128    ComplexDouble C[N+1];
 
  138        ComplexDouble squareRoot = sqrt(C[1]*C[1]-4.0*C[2]*C[0]);
 
  139        roots[0] = (( squareRoot - C[1])/(2.0*C[2]));
 
  140        roots[1] = ((-squareRoot - C[1])/(2.0*C[2]));
 
  143    int FindRootsHQ(ComplexDouble , ComplexDouble* roots){
 
  144        ComplexDouble squareRoot = sqrt(C[1]*C[1]-4.0*C[2]*C[0]);
 
  145        roots[0] = (( squareRoot - C[1])/(2.0*C[2]));
 
  146        roots[1] = ((-squareRoot - C[1])/(2.0*C[2]));
 
  155    template <
class Number> 
void Evaluate(Number x, Number& fx, Number& dfx, Number& ddfx, 
double& err){
 
  156        double abx = fabs(x);
 
  161        for(
int i = N-1; i >= 0; i--){
 
  165            err  =  err*abx + fabs(fx);
 
  168        err*=2.0*std::numeric_limits<double>::epsilon();
 
  172        Factor.C[N-1] = C[N];
 
  173        for(
int i = N-2; i >= 0 ; i--){
 
  174            Factor.C[i] = C[i+1] + Factor.C[i+1]*root;
 
  179        Factor.C[N-2] = C[N];
 
  180        Factor.C[N-3] = C[N-1] + 2.0*root.real()*C[N];
 
  181        for(
int i = N-4; i >= 0 ; i--){
 
  182            Factor.C[i] = C[i+2] + 2.0*Factor.C[i+1]*root.real() - (root.real()*root.real() + root.imag()*root.imag())*Factor.C[i+2];
 
  186    int FindRoots(
double X0, 
double* roots){
 
  187        double FX, DFX, DDFX, ERR;
 
  189        Evaluate(X0,FX,DFX,DDFX,ERR);
 
  190        while(fabs(FX) > ERR){
 
  192            double H = G*G-DDFX/FX;
 
  193            double discriminant = (N-1)*(N*H-G*G);
 
  194            if(discriminant < 0){
 
  195                ComplexDouble C_FX, C_DFX, C_DDFX;
 
  196                ComplexDouble C_N = ComplexDouble(N);
 
  197                ComplexDouble C_X = ComplexDouble(roots[0]) - (C_N/ComplexDouble(G,sqrt(fabs(discriminant))));
 
  199                Evaluate(C_X,C_FX,C_DFX,C_DDFX,ERR);
 
  200                while(fabs(C_FX) > ERR){
 
  201                    ComplexDouble C_G = C_DFX/C_FX;
 
  202                    ComplexDouble C_H = C_G*C_G-C_DDFX/C_FX;
 
  203                    ComplexDouble SQ = sqrt(ComplexDouble(N-1.0)*(C_N*C_H - C_G*C_G));
 
  205                    ComplexDouble GP = C_G + SQ;
 
  206                    ComplexDouble GM = C_G - SQ;
 
  207                    if(GM.real()*GM.real() + GM.imag()*GM.imag() > GP.real()*GP.real() + GP.imag()*GP.imag()){
 
  211                    Evaluate(C_X,C_FX,C_DFX,C_DDFX,ERR);
 
  214                ExtractComplexConjugateRootPair(C_X,factorize);
 
  215                roots[0] = C_X.real();
 
  216                roots[N-2] = std::numeric_limits<double>::quiet_NaN();
 
  217                return 1+factorize.FindRoots(X0,roots+1);
 
  219                roots[0] -= N/(G+(1-2*(G < 0))*sqrt(discriminant));
 
  220                Evaluate(roots[0],FX,DFX,DDFX,ERR);
 
  224        ExtractRealRoot(roots[0],factorize);
 
  225        return 1+factorize.FindRoots(roots[0],roots+1);
 
  241    int FindRoots(
double,
double* roots){
 
  243            roots[0] = -C[0]/C[1];
 
  246            roots[0] = std::numeric_limits<double>::quiet_NaN();
 
  256    int FindRoots(
double, 
double* roots){
 
  257        double discriminant = C[1]*C[1]-4.0*C[2]*C[0];
 
  258        if(discriminant >= 0){
 
  259            double squareRoot = sqrt(discriminant);
 
  260            roots[0] = ( squareRoot - C[1])/(2.0*C[2]);
 
  261            roots[1] = (-squareRoot - C[1])/(2.0*C[2]);
 
  264            roots[0] = -0.5*C[1]/C[2];
 
  265            roots[1] = std::numeric_limits<double>::quiet_NaN();
 
int FindRoots(ComplexDouble, ComplexDouble *roots)
Definition: PolynomialTools.h:137
Class representing a general polynomial with complex coefficients.
Definition: PolynomialTools.h:28
ComplexDouble LaguerreIteration(const ComplexDouble &FX, const ComplexDouble &DFX, const ComplexDouble &DDFX)
Definition: PolynomialTools.h:65
void ExtractRoot(ComplexDouble root, ComplexPolynomial< N-1 > &Factor)
Definition: PolynomialTools.h:55
int FindRootsHQ(ComplexDouble X0, ComplexDouble *roots)
Definition: PolynomialTools.h:103
void Evaluate(ComplexDouble x, ComplexDouble &fx, ComplexDouble &dfx, ComplexDouble &ddfx, double &err)
Definition: PolynomialTools.h:34
int FindRoots(ComplexDouble X0, ComplexDouble *roots)
Definition: PolynomialTools.h:81
Definition: PolynomialTools.h:153
Definition: CollisionManager.h:6