/* ---------------------------------------------------------------------- ** Use the secant method to find a root of a function named f(). ** Figure 23.12: The secant algorithm. ** Figure 23.13: The verbose_print() function. ** ---------------------------------------------------------------------- */ #include "tools.h" #include "root.h" /* Interface between roots module and main. */ #include "ffam.h" /* Prototype for function to solve. */ extern bool verbose; /* Imported from main. */ static void verbose_print( int k, double x1, double y1, double x2, double y2, double x3, double y3); /* ---------------------------------------------------------------------- ** Secant root finder function. ** Returns 0 on success, -1 on failure. */ er_type secant( double x1, double x2, double *rootp ) { int k; /* the actual iteration starting from 0 */ double x3; /* estimates of root value */ double y1, y2, y3; /* f( x) at points x1, x2, x3, resp. */ double slope, delta; /* line coefficients */ if (fabs( x2 - x1 ) < EPS) /* initial points too close together */ return BAD_INITIAL_POINTS; y1 = f( x1 ); y2 = f( x2 ); for (k = 0; k < MAX_ITER; k++) { slope = (y2 - y1) / (x2 - x1); if (fabs( slope ) < LIMIT) return HORIZONTAL; delta = -y2 / slope; x3 = x2 + delta; /* compute new estimate */ y3 = f( x3 ); if (verbose) verbose_print( k, x1, y1, x2, y2, x3, y3 ); /* see if root has been found */ if ( fabs( delta ) < EPS || fabs( y3 ) < LIMIT) { *rootp = x3; /* Store root in caller's variable */ return ROOT_OK; /* and return the success code. */ } /* Get ready for the next iteration -------------------------- */ x1 = x2; y1 = y2; /* Move old root estimate to older slot */ x2 = x3; y2 = y3; /* Move new root estimate to old slot */ } return TOO_MANY_ITERATIONS; } /* ---------------------------------------------------------------------- ** Verbose feedback. ** Print intermediate output if user selects verbose mode. */ void verbose_print( int k, double x1, double y1, double x2, double y2, double x3, double y3 ) { printf( " During iteration %i:\n", k ); printf( " x1 = %15g, y1 = %15g\n", x1, y1 ); printf( " x2 = %15g, y2 = %15g\n", x2, y2 ); printf( " x3 = %15g, y3 = %15g\n", x3, y3 ); }