//////////////////////////////////////////////////////////////////////////////// // File: illinois_algorithm_verify_setup.c // // Routines: // // int Illinois_Algorithm_Verify_Setup // //////////////////////////////////////////////////////////////////////////////// #include // required for fabs() //////////////////////////////////////////////////////////////////////////////// // int Illinois_Algorithm_Verify_Setup( double a, double fa, double b, // // double fb, void *data[], int *err) // // // // Description: // // This routine is an example of a Illinois_Algorithm verify_setup() // // routine used to verify the input data to Illinois_Algorithm. // // This routine checks: // // (1) That the endpoints of the initial interval are different. // // (2) That fa and fb have different signs. // // (3) That the address of the data array is non-zero. // // (4) That each element of the data array are non-zero. // // (5) That the relative tolerance is strictly positive. // // (6) That the absolute tolerance is strictly positive. // // (7) That the test region lower bound is strictly negative. // // (8) That the test region upper bound is strictly positive. // // // // Arguments: // // double a // // Either the upper or lower bound which brackets a zero of f(x), // // f(a) * f(b) < 0. // // double fa // // The value of f(x) at a. // // double b // // The other bound which brackets a zero of f(x), f(a) * f(b) < 0. // // double fb // // The value of f(x) at b. // // 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. // // data[4] is a pointer to the maximum number of iterations. // // int *err // // Pointer to an error number, see the section Return Values (below) // // for the list of error numbers. // // // // Return Values: // // The return value is either 0 if there is no err or 1 if there is an // // err in which case the *err contains a number indicating the error. // // The possible error numbers are: // // 0 - No error. // // 1 - The two endpoints a and b agree. // // 2 - The two initial function values have the same sign. // // 3 - The address of the data array is 0. // // 4 - At least one of the pointers in the data array is 0. // // 5 - The specified relative tolerance <= 0.0. // // 6 - The specified absolute tolerance <= 0.0. // // 7 - The lower bound of the test region is non-negative. // // 8 - The upper bound of the test region is non-postive. // // // // Example: // // // // double a,fa,b,fb; // // void *data[]; // // int err; // // . // // . // // if (!Illinois_Algorithm_Verify_Setup(a,fa,b,fb,data,&err)) // // switch (err) { // // case 0: printf("No error.\n"); break; // // case 1: printf("The endpoints a,b agree.\n"); break; // // case 2: printf("The initial function values have the same \ // // sign.\n"); break; // // case 3: printf("The address of the data array is zero. \n"); // // break; // // case 4: printf("At least one of the elements in data is // // zero.\n"); break; // // case 5: printf("The relative tolerance is non positive.\n"); // // break; // // case 6: printf("The absolute tolerance is non positive.\n"); // // break; // // case 7: printf("The lower bound of the test region is not // // negative.\n"); // // break; // // case 8: printf("The upper bound of the test region is not // // positive.\n"); break; // // default: printf("Unknown error number\n"); // // } // // ... // //////////////////////////////////////////////////////////////////////////////// // // enum {NO_ERR, ENDPOINTS_AGREE, NO_BRACKET, INVALID_DATA_ADDRESS, INVALID_DATA_ELEMENT_ADDRESS, REL_TOL_NON_POS, ABS_TOL_NON_POS, TEST_REG_LOWER_BOUND_NON_NEG, TEST_REG_UPPER_BOUND_NON_POS}; enum {ERR, OK}; int Illinois_Algorithm_Verify_Setup( double a, double fa, double b, double fb, void *data[], int *err) { double rel_tolerance; double abs_tolerance; double test_region_lower_bound; double test_region_upper_bound; unsigned int max_number_of_iterations; // If the endpoints of the initial interval are the // // same, there is no need to iterate. Return ERR // // with err set to ENDPOINTS_AGREE. // if ( a == b ) { *err = ENDPOINTS_AGREE; return ERR; } // If the function evaluated at both endpoints of the // // interval have the same sign and are nonzero, then // // return ERR with err set to NO_BRACKET. // if ( ( (fa > 0.0) && (fb > 0.0) ) || ( (fa < 0.0) && (fb < 0.0) ) ) { *err = NO_BRACKET; return ERR; } // Check that the address of the data array is non-zero. // if ( data == 0 ) {*err = INVALID_DATA_ADDRESS; return ERR; } // Check that each element of the data array are non-zero. // // For this version there are 4 data elements in the data // // array. If any element is zero, return ERR with err set // // to INVALID_DATA_ADDRESS. // if ( data[0] == 0 ) { *err = INVALID_DATA_ELEMENT_ADDRESS; return ERR; } if ( data[1] == 0 ) { *err = INVALID_DATA_ELEMENT_ADDRESS; return ERR; } if ( data[2] == 0 ) { *err = INVALID_DATA_ELEMENT_ADDRESS; return ERR; } if ( data[3] == 0 ) { *err = INVALID_DATA_ELEMENT_ADDRESS; return ERR; } if ( data[4] == 0 ) { *err = INVALID_DATA_ELEMENT_ADDRESS; return ERR; } // If the rel_tolerance <= 0.0, then return // // ERR with err set to REL_TOL_NON_POS. // rel_tolerance = *((double*) (data[0])); if ( rel_tolerance <= 0.0 ) { *err = REL_TOL_NON_POS; return ERR;} // If the abs_tolerance <= 0.0, then return // // ERR with err set to ABS_TOL_NON_POS. // abs_tolerance = *((double*) (data[1])); if ( abs_tolerance <= 0.0 ) { *err = ABS_TOL_NON_POS; return ERR;} // If the test_region_lower_bound >= 0.0, then return // // ERR with err set to TEST_REG_LOWER_BOUND_NON_NEG. // test_region_lower_bound = *((double*) (data[2])); if ( test_region_lower_bound >= 0.0 ) { *err = TEST_REG_LOWER_BOUND_NON_NEG; return ERR; } // If the test_region_upper_bound >= 0.0, then return // // ERR with err set to TEST_REG_UPPER_BOUND_NON_POS. // test_region_upper_bound = *((double*) (data[3])); if ( test_region_upper_bound <= 0.0 ) { *err = TEST_REG_UPPER_BOUND_NON_POS; return ERR; } *err = NO_ERR; return OK; }