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