33 double b,
double c,
double d,
int root,
bool& valid,
int& numroots )
37 double infnorm = fabs(a);
38 if ( infnorm < fabs(b) ) infnorm = fabs(b);
39 if ( infnorm < fabs(c) ) infnorm = fabs(c);
40 if ( infnorm < fabs(d) ) infnorm = fabs(d);
41 if ( a < 0 ) infnorm = -infnorm;
47 const double small = 1e-7;
49 if ( fabs(a) < small )
51 if ( fabs(b) < small )
53 if ( fabs(c) < small )
59 double rootval = -d/c;
61 if ( rootval < xmin || xmax < rootval ) numroots--;
62 if ( root > numroots )
return 0.0;
67 if ( b < 0 ) { b = -b; c = -c; d = -d; }
68 double discrim = c*c - 4*b*d;
75 discrim = std::sqrt(discrim)/(2*fabs(b));
76 double rootmiddle = -c/(2*b);
77 if ( rootmiddle - discrim < xmin ) numroots--;
78 if ( rootmiddle + discrim > xmax ) numroots--;
79 if ( rootmiddle + discrim < xmin ) numroots--;
80 if ( rootmiddle - discrim > xmax ) numroots--;
81 if ( root > numroots )
return 0.0;
83 if ( root == 2 || rootmiddle - discrim < xmin )
return rootmiddle + discrim;
84 return rootmiddle - discrim;
87 if ( xmin < -1e8 || xmax > 1e8 )
93 if ( fabs(c/a) + 1 > xmax ) xmax = fabs(c/a) + 1;
94 if ( fabs(b/a) + 1 > xmax ) xmax = fabs(b/a) + 1;
99 double p1a = 2*b*b - 6*a*c;
100 double p1b = b*c - 9*a*d;
101 double p0a = c*p1a*p1a + p1b*(3*a*p1b - 2*b*p1a);
105 numroots = vartop - varbottom;
107 if (root <= varbottom || root > vartop )
return 0.0;
112 double dx = (xmax - xmin)/2;
113 while ( vartop - varbottom > 1 )
115 if ( fabs( dx ) < 1e-8 )
return (xmin + xmax)/2;
116 double xmiddle = xmin + dx;
118 if ( varmiddle < root )
121 varbottom = varmiddle;
132 if ( vartop - varbottom == 1 )
136 fval1 = b + xmin*fval1;
137 fval2 = b + xmax*fval2;
138 fval1 = c + xmin*fval1;
139 fval2 = c + xmax*fval2;
140 fval1 = d + xmin*fval1;
141 fval2 = d + xmax*fval2;
142 assert ( fval1 * fval2 <= 0 );
146 return ( xmin + xmax )/2;
165 double d,
double p1a,
double p1b,
double p0a)
170 fpval = fval + x*fpval;
172 fpval = fval + x*fpval;
175 double f1val = p1a*x + p1b;
177 bool f3pos = fval >= 0;
178 bool f2pos = fpval <= 0;
179 bool f1pos = f1val >= 0;
180 bool f0pos = p0a >= 0;
183 if ( f3pos != f2pos ) variations++;
184 if ( f2pos != f1pos ) variations++;
185 if ( f1pos != f0pos ) variations++;
195 double d,
double& fval,
double& fpval,
double& fppval )
197 fval = fpval = fppval = a;
199 fpval = fval + x*fpval;
200 fppval = fpval + x*fppval;
202 fpval = fval + x*fpval;
207 double b,
double c,
double d,
double tol )
209 double fval, fpval, fppval;
211 double fval1, fval2, fpval1, fpval2, fppval1, fppval2;
214 assert ( fval1 * fval2 <= 0 );
216 assert ( xmax > xmin );
217 while ( xmax - xmin > tol )
220 assert ( fval1 * fval2 <= 0 );
221 if ( fppval1 * fppval2 < 0 || fpval1 * fpval2 < 0 )
223 double xmiddle = (xmin + xmax)/2;
225 if ( fval1*fval <= 0 )
242 if ( fval2*fppval2 > 0 ) x = xmax;
245 while ( fabs(p) > tol && iterations++ < 100 )
251 if( iterations >= 100 )
263 return (xmin + xmax)/2;
272 int numcols,
int exchange[] )
275 for (
int k = 0; k < numrows; ++k )
281 for(
int i = k; i < numrows; ++i )
283 for(
int j = k; j < numcols; ++j )
285 if (fabs(matrix[i][j]) > maxval)
287 maxval = fabs(matrix[i][j]);
296 for(
int j = k; j < numcols; ++j )
298 double t = matrix[k][j];
299 matrix[k][j] = matrix[imax][j];
305 for(
int i = 0; i < numrows; ++i )
307 double t = matrix[i][k];
308 matrix[i][k] = matrix[i][jmax];
316 if ( maxval == 0. )
return false;
319 for(
int i = k+1; i < numrows; ++i)
321 double mik = matrix[i][k]/matrix[k][k];
324 for(
int j = k+1; j < numcols; ++j )
326 matrix[i][j] -= mik*matrix[k][j];
341 int exchange[],
double solution[] )
345 for (
int j = numrows; j < numcols; ++j )
350 for(
int k = numrows - 1; k >= 0; --k )
354 for (
int j = k+1; j < numcols; ++j)
356 solution[k] -= matrix[k][j]*solution[j];
358 solution[k] /= matrix[k][k];
363 for(
int k = numrows - 1; k >= 0; --k )
365 int jmax = exchange[k];
366 double t = solution[k];
367 solution[k] = solution[jmax];
374 double det = m[0][0]*(m[1][1]*m[2][2] - m[1][2]*m[2][1]) -
375 m[0][1]*(m[1][0]*m[2][2] - m[1][2]*m[2][0]) +
376 m[0][2]*(m[1][0]*m[2][1] - m[1][1]*m[2][0]);
377 if (det == 0)
return false;
379 for (
int i=0; i < 3; i++)
381 for (
int j=0; j < 3; j++)
387 inv[j][i] = (m[i1][j1]*m[i2][j2] - m[i1][j2]*m[i2][j1])/det;
double calcCubicRoot(double xmin, double xmax, double a, double b, double c, double d, int root, bool &valid, int &numroots)
This file is part of Kig, a KDE program for Interactive Geometry...
void calcCubicDerivatives(double x, double a, double b, double c, double d, double &fval, double &fpval, double &fppval)
bool Invert3by3matrix(const double m[3][3], double inv[3][3])
bool GaussianElimination(double *matrix[], int numrows, int numcols, int exchange[])
Gaussian Elimination.
double calcCubicRootwithNewton(double xmin, double xmax, double a, double b, double c, double d, double tol)
void BackwardSubstitution(double *matrix[], int numrows, int numcols, int exchange[], double solution[])
int calcCubicVariations(double x, double a, double b, double c, double d, double p1a, double p1b, double p0a)