CNLMath : Utilities : set_user_fcn_return_flag
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