14 #ifndef INCLUDED_numeric_kinematic_closure_sturm_hh
15 #define INCLUDED_numeric_kinematic_closure_sturm_hh
35 #define SMALL_ENOUGH 1.0e-18 // a coefficient smaller than SMALL_ENOUGH is considered to be zero (0.0)
36 #define MAX_SOLN 16 // maximum number of roots
39 namespace kinematic_closure {
57 MAXIT = *max_iter_sturm;
64 double exp_x1, exp_x2, ax;
69 }
else if ( ax < -100.0 ) {
74 return (exp_x1 - exp_x2)/(exp_x1 + exp_x2);
91 double *nr, *
end, *uc;
102 for ( k = u->
ord - v->
ord - 1; k >= 0; k -= 2 ) {
105 for ( k = u->
ord - v->
ord; k >= 0; k-- ) {
106 for ( j = v->
ord + k - 1; j >= k; j-- ) {
111 for ( k = u->
ord - v->
ord; k >= 0; k-- ) {
112 for ( j = v->
ord + k - 1; j >= k; j-- ) {
124 r->
ord = (k < 0) ? 0 : k;
143 sseq[1].
ord = ord - 1;
149 f = fabs(sseq[0].coef[ord]*ord);
152 fc = sseq[0].
coef + 1;
154 for ( i = 1; i <= ord; i++ ) {
155 *fp++ = *fc++ * i /
f;
162 for ( sp = sseq + 2;
modp(sp - 2, sp - 1, sp); sp++ ) {
169 for ( fp = &sp->
coef[sp->
ord]; fp >= sp->
coef; fp-- ) {
189 int atposinf, atneginf;
193 atposinf = atneginf = 0;
199 lf = sseq[0].
coef[sseq[0].
ord];
201 for ( s = sseq + 1; s <= sseq + np; s++ ) {
203 if ( lf == 0.0 || lf * f < 0 ) {
214 if ( sseq[0].ord & 1 ) {
215 lf = -sseq[0].
coef[sseq[0].
ord];
217 lf = sseq[0].
coef[sseq[0].
ord];
220 for ( s = sseq + 1; s <= sseq + np; s++ ) {
226 if ( lf == 0.0 || lf * f < 0 ) {
237 return(atneginf - atposinf);
254 for ( fp--; fp >= coef; fp-- ) {
277 lf =
evalpoly(sseq[0].ord, sseq[0].coef, a);
279 for ( s = sseq + 1; s <= sseq + np; s++ ) {
281 if ( lf == 0.0 || lf * f < 0 ) {
300 int modrf(
int ord,
double *coef,
double a,
double b,
double *val)
303 double fa, fb,
x, fx, lfx;
304 double *fp, *scoef, *ecoef;
311 for ( fp = ecoef - 1; fp >= scoef; fp-- ) {
319 if ( fa * fb > 0.0 ) {
340 x = (fb * a - fa *
b) / (fb - fa);
343 if ( x < a || x > b ) {
347 for ( fp = ecoef - 1; fp >= scoef; fp-- ) {
361 if ( (fa * fx) < 0 ) {
364 if ( (lfx * fx) > 0 ) {
370 if ( (lfx * fx) > 0 ) {
398 int n1 = 0, n2 = 0, its, atmid, nroot;
400 if ( (nroot = atmin - atmax) == 1 ) {
406 if (
modrf(sseq->
ord, sseq->
coef, min, max, &roots[0]) ) {
414 for ( its = 0; its <
MAXIT; its++ ) {
415 mid = (min +
max) / 2;
419 if ( fabs((max - min) / mid) <
RELERROR ) {
425 }
else if ( fabs(max - min) <
RELERROR ) {
432 if ( (atmin - atmid) == 0 ) {
438 if ( its == MAXIT ) {
449 for ( its = 0; its <
MAXIT; its++ ) {
450 mid = (min +
max) / 2;
466 if ( n1 != 0 && n2 != 0 ) {
469 sbisect(np, sseq, min, mid, atmin, atmid, roots);
470 sbisect(np, sseq, mid, max, atmid, atmax, &roots[n1]);
481 if ( its == MAXIT ) {
483 for ( n1 = atmax; n1 < atmin; n1++ ) {
485 roots[n1 - atmax] = mid;
498 int order, i, nroots, nchanges, np, atmin, atmax;
502 for ( i = order; i >= 0; i-- ) {
503 sseq[0].
coef[i] = poly_coeffs[i+1];
531 nroots =
numroots(np, sseq, &atmin, &atmax);
533 if ( (nroots == 0) || !( (0 <= nroots) && (nroots <=
MAX_ORDER)) ) {
538 roots.resize(nroots);
548 for ( i = 0; nchanges != atmin && i !=
MAXPOW; i++ ) {
553 if ( nchanges != atmin ) {
560 for ( i = 0; nchanges != atmax && i !=
MAXPOW; i++ ) {
565 if ( nchanges != atmax ) {
569 nroots = atmin - atmax;
580 sbisect(np, sseq, min, max, atmin, atmax, roots_array);
584 roots[i]=roots_array[i-1];
614 #endif //INCLUDED_numeric_kinematic_closure_sturm_hh
void initialize_sturm(double *tol_secant, int *max_iter_sturm, int *max_iter_secant)
double hyper_tan(double a, double x)
vector1: std::vector with 1-based indexing: bool specialization
void sbisect(int np, poly *sseq, double min, double max, int atmin, int atmax, double *roots)
void solve_sturm(const int &p_order, int &n_root, const utility::vector1< double > &poly_coeffs, utility::vector1< double > &roots)
utility::keys::lookup::end< KeyType > const end
double evalpoly(int ord, double *coef, double x)
short int min(short int const a, short int const b)
min( short int, short int )
short int max(short int const a, short int const b)
max( short int, short int )
rosetta project type declarations. Should be kept updated with core/types.hh. This exists because num...
int modrf(int ord, double *coef, double a, double b, double *val)
int buildsturm(int ord, poly *sseq)
int modp(poly *u, poly *v, poly *r)
struct numeric::kinematic_closure::p poly
int numchanges(int np, poly *sseq, double a)
int numroots(int np, poly *sseq, int *atneg, int *atpos)