set_user_fcn_return_flag
Indicates a condition has occurred in a user-supplied function necessitating a return to the calling function.
Synopsis
#include <imsl.h>
void imsl_set_user_fcn_return_flag (int code)
Required Arguments
int code (Input)
A user-defined number that indicates the reason for the return from the user-supplied function.
Description
Given a certain condition in a user-supplied function, imsl_set_user_fcn_return_flag stops executing any IMSL algorithm that has called the function and then returns to the calling function or main program. Upon invocation of imsl_set_user_fcn_return_flag, a flag is set in the IMSL error handler. Upon returning from the user-supplied function, the error IMSL_STOP_USER_FCN is issued with severity IMSL_FATAL. Typically, if you use this function, you would disable stopping on IMSL C MATH errors, thus gaining greater control in situations where you need to prematurely return from an algorithm. (See Programming Notes.)
Programming Notes
Since the default behavior of IMSL error handling is to stop execution on
IMSL_TERMINAL and
IMSL_FATAL errors, execution of the main program stops when the
IMSL_STOP_USER_FCN error message is issued unless you alter this behavior by turning stopping off using
imsl_error_options.
In a user-supplied function, the user is responsible for checking error conditions such as memory allocation, return status for any function calls, valid return values, etc.
Use of this function is valid only if called from within a user-supplied function.
Examples
Example 1
This example is based on
imsl_f_int_fcn. In this example, the user, for any hypothetical reason, wants to stop the evaluation of the user-supplied function,
fcn, when
x is less than 0.5.
#include <math.h>
#include <imsl.h>
#include <stdio.h>
float fcn(float x);
float q;
float exact;
int main()
{
/* Turn off stopping on IMSL_FATAL errors. */
imsl_error_options(IMSL_SET_STOP, IMSL_FATAL, 0, 0);
imsl_omp_options(IMSL_SET_FUNCTIONS_THREAD_SAFE, 1, 0);
/* evaluate the integral */
q = imsl_f_int_fcn (fcn, 0.0, 2.0, 0);
/* The following lines will be executed because
stopping is turned off. */
if (q != q) {
printf("integral = NaN\n");
} else {
exact = exp(2.0) + 1.0;
printf("integral = %10.3f\nexact = %10.3f\n", q, exact);
}
}
float fcn(float x)
{
float y;
/* For a hypothetical reason, stop execution when x < 0.5. */
if (x < 0.5) {
imsl_set_user_fcn_return_flag(1);
return 0;
}
y = x * (exp(x));
return y;
}
Output
*** FATAL Error IMSL_STOP_USER_FCN from imsl_f_int_fcn. Request
*** from user supplied function to stop algorithm. User flag = "1".
integral = NaN
Example 2
This example is based on
imsl_f_chi_squared_test,
Example 3. This example demonstrates how to handle the error condition if the user-supplied function calls a C Math Library function. In this example,
THETA is set to 0 to force an error condition in calling the
imsl_f_poisson_cdf function in the user-supplied function.
#include <imsl.h>
#include <stdio.h>
#define SEED 123457
#define N_CATEGORIES 10
#define N_PARAMETERS_ESTIMATED 0
#define N_NUMBERS 1000
#define THETA 0.0
float user_proc_cdf(float);
int main()
{
int i, *poisson;
float cell_statistics[3][N_CATEGORIES];
float chi_squared_statistics[3], x[N_NUMBERS];
float cutpoints[] = {1.5, 2.5, 3.5, 4.5, 5.5, 6.5,
7.5, 8.5, 9.5};
char *cell_row_labels[] = {"count", "expected count",
"cell chi-squared"};
char *cell_col_labels[] = {"Poisson value", "0", "1", "2",
"3", "4", "5", "6", "7",
"8", "9"};
char *stat_row_labels[] = {"chi-squared",
"degrees of freedom","p-value"};
/* Turn off stopping on IMSL_FATAL errors. */
imsl_error_options(IMSL_SET_STOP, IMSL_FATAL, 0, 0);
imsl_random_seed_set(SEED);
/* Generate the data */
poisson = imsl_random_poisson(N_NUMBERS, 5.0, 0);
/* Copy data to a floating point vector*/
for (i = 0; i < N_NUMBERS; i++)
x[i] = poisson[i];
chi_squared_statistics[2] =
imsl_f_chi_squared_test(user_proc_cdf, N_NUMBERS,
N_CATEGORIES, x,
IMSL_CUTPOINTS_USER, cutpoints,
IMSL_CELL_COUNTS_USER, &cell_statistics[0][0],
IMSL_CELL_EXPECTED_USER, &cell_statistics[1][0],
IMSL_CELL_CHI_SQUARED_USER, &cell_statistics[2][0],
IMSL_CHI_SQUARED, &chi_squared_statistics[0],
IMSL_DEGREES_OF_FREEDOM, &chi_squared_statistics[1],
0);
/* The following lines will be executed because
stopping is turned off. */
if (chi_squared_statistics[2] != chi_squared_statistics[2]) {
printf("p-value = NaN\n");
} else {
imsl_f_write_matrix("\nChi-squared Statistics\n", 3, 1,
&chi_squared_statistics[0],
IMSL_ROW_LABELS, stat_row_labels,
0);
imsl_f_write_matrix("\nCell Statistics\n", 3, N_CATEGORIES,
&cell_statistics[0][0],
IMSL_ROW_LABELS, cell_row_labels,
IMSL_COL_LABELS, cell_col_labels,
IMSL_WRITE_FORMAT, "%9.1f",
0);
}
}
float user_proc_cdf(float k)
{
float cdf_v;
int setting;
/* The user is responsible for checking error conditions in the
user-supplied function, even if the user-supplied function
is calling an IMSL function.
For theta = 0.0 (an invalid input), imsl_f_poisson_cdf issues
an IMSL_TERMINAL error. Thus, stopping is turned off on
IMSL_TERMINAL errors. */
/* Get the current terminal error stopping setting which will be
used for restoring the setting later. */
imsl_error_options(IMSL_GET_STOP, IMSL_TERMINAL, &setting, 0);
/* Disable stopping on terminal errors. */
imsl_error_options(IMSL_SET_STOP, IMSL_TERMINAL, 0, 0);
cdf_v = imsl_f_poisson_cdf ((int) k, THETA);
/* If there is a terminal error, stop and return to main. */
if (imsl_error_type() == IMSL_TERMINAL) {
imsl_set_user_fcn_return_flag(1);
return 0;
}
/* Restore stopping setting */
imsl_error_options(IMSL_SET_STOP, IMSL_TERMINAL, setting, 0);
return cdf_v;
}
Output
*** TERMINAL Error from imsl_f_poisson_cdf. The mean of the Poisson
*** distribution, "theta" = 0.000000e+000, must be positive.
*** FATAL Error IMSL_STOP_USER_FCN from imsl_f_chi_squared_test.
*** Request from user supplied function to stop algorithm. User
*** flag = "1".
p-value = NaN