//////////////////////////////////////////////////////////////////////////////// // File: bisection_method_setup.c // // Routines: // // int Bisection_Method_Setup // //////////////////////////////////////////////////////////////////////////////// #include // required for fabs() //////////////////////////////////////////////////////////////////////////////// // int Bisection_Method_Setup(double *rel_tolerance, double *abs_tolerance, // // double *test_region_lower_bound, double *test_region_upper_bound, // // void *data[]) // // // // Description: // // The bisection method is an iterative procedure to locate a zero of a // // function. Each iteration requires logic to decide whether or not to // // continue or to halt the iteration. This logic requires both state // // variables, those variables describing the state of the process as well // // as variables not relevant to the evolution of the process itself but // // only in terminating the process together with possible data to inform // // the user the reason for terminating the process. // // // // The 4 variables chosen here are the relative tolerance, rel_tolerance, // // the absolute tolerance, abs_tolerance, the lower bound on the region // // which determines which test to perform, and the upper bound on that // // region. Of the four variables all, but the lower bound on the test // // region, must be strictly positive. The lower bound on the test region // // must be strictly negative. Given an interval [x0, x1] with x0 < x1 // // and let mu < 0 be the lower bound of the test region and eta > 0 the // // upper bound, then if [x0, x1] does not intersect the interval // // [mu, eta] then the relative tolerance controls whether or not to // // continue or terminate the iterative process. If [x0,x1] does intersect// // the interval [mu, eta] then the absolute tolerance governs whether or // // not to continue or terminate the iterative process. // // // // This routine is used to populate the array data[] in the order that // // the example verify_setup() routine, Bisection_Method_Verify_Setup(), // // and the example terminate() routine, Bisection_Method_Terminate(), // // expect. // // // // The tolerances as well as the upper and lower bounds are declared and // // set in the routine which ultimately calls this routine. The array // // data[] is passed to Bisection_Method which in turn passes it on to its // // verify_setup() and terminate() procedures. // // // // The Bisection_Method itself does not directly modify or use the array // // but only forwards it. // // // // Arguments: // // double *rel_tolerance // // The pointer to the user specified relative tolerance. If [x0, x1]// // is the interval containing a zero of f(x), with x0 < x1, and // // [mu, eta] is the test region, with mu < 0 < eta, then the // // relative tolerance is used to halt the iteration process if either// // x0 > eta or x1 < mu // // in which cases the iteration is halted if // // fabs(x0 - x1) < rel_tolerance * min(fabs(x0), fabs(x1)). // // The relative tolerance must be a strictly positive number. // // double *abs_tolerance // // The pointer to the user specified absolute tolerance. If [x0, x1]// // is the interval containing a zero of f(x), with x0 < x1, and // // [mu, eta] is the test region, with mu < 0 < eta, then the // // absolute tolerance is used to halt the iteration process if both // // x0 <= eta and x1 >= mu // // in which case the iteration is halted if // // fabs(x0 - x1) < abs_tolerance. // // The absolute tolerance must be a strictly positive number. // // double *test_region_lower_bound // // The pointer to the lower bound of the test region for deciding // // on whether to use the absolute or relative tolerance to halt or // // to continue the iteration. The test_region_lower_bound must be // // a strictly negative number. // // double *test_region_upper_bound // // The pointer to the upper bound of the test region for deciding // // on whether to use the absolute or relative tolerance to halt or // // to continue the iteration. The test_region_upper_bound must be // // a strictly positive number. // // void* data[] // // For this routine the array data is defined as follows: // // data[0] is a pointer to the relative tolerance. // // data[1] is a pointer to the absolute tolerance. // // data[2] is a pointer to the test_region_lower_bound. // // data[3] is a pointer to the test_region_upper_bound. // // The array data should be dimensioned at least 4 in the calling // // routine. // // // // Return Values: // // The function returns 0 (ERR) if at least one of the argument pointers // // is NULL, otherwise the function returns 1 (OK). // // // // Example: // // // // double rel_tolerance = 1.e-6, abs_tolerance = 1.e-16; // // double test_region_lower_bound = - DBL_MIN / DBL_EPSILON; // // double test_region_upper_bound = DBL_EPSILON; // // void *data[4]; // // // // if (!Bisection_Method_Setup(&rel_tolerance, &abs_tolerance, // // &test_region_lower_bound, &test_region_upper_bound, data); // // printf("At least one of the pointers is NULL\n") { // // } else { ... } // //////////////////////////////////////////////////////////////////////////////// // // enum {ERR, OK}; int Bisection_Method_Setup( double *rel_tolerance, double *abs_tolerance, double *test_region_lower_bound, double *test_region_upper_bound, void *data[]) { if ( ( rel_tolerance == 0 ) || ( abs_tolerance == 0 ) || ( test_region_lower_bound == 0 ) || ( test_region_upper_bound == 0 ) || ( data == 0 ) ) return ERR; data[0] = (void *) rel_tolerance; data[1] = (void *) abs_tolerance; data[2] = (void *) test_region_lower_bound; data[3] = (void *) test_region_upper_bound; return OK; }