diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/GeneralizedPolynomial-Uniform/InterpLocalUniform.c | 53 | ||||
-rw-r--r-- | src/GeneralizedPolynomial-Uniform/InterpLocalUniform.h | 3 | ||||
-rw-r--r-- | src/GeneralizedPolynomial-Uniform/interpolate.maple | 43 | ||||
-rw-r--r-- | src/GeneralizedPolynomial-Uniform/molecule_posn.c | 58 | ||||
-rw-r--r-- | src/GeneralizedPolynomial-Uniform/template.c | 20 | ||||
-rw-r--r-- | src/GeneralizedPolynomial-Uniform/test_molecule_posn.c | 388 |
6 files changed, 342 insertions, 223 deletions
diff --git a/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.c b/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.c index f6982ac..b4eef31 100644 --- a/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.c +++ b/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.c @@ -348,23 +348,26 @@ return LocalInterp_InterpLocalUniform(interp_operator_Hermite, @vtype CCTK_INT order @endvar - @var out_of_range_tolerance + @var out_of_range_tolerance, @vdesc Specifies how out-of-range interpolation points should - be handled: - If out_of_range_tolerance[axis] >= 0.0, + be handled. The array elements are matched up with + the axes and minimum/maximum ends of the grid in the + order [x_min, x_max, y_min, y_max, z_min, z_max, ...]. + An array value TOL is interpreted as follows: + If TOL >= 0.0, then an interpolation point is considered to be "out of range" if and only if the interpolation - point is > out_of_range_tolerance[axis] - * coord_delta[axis] - outside the grid in any coordinate. - If out_of_range_tolerance[axis] == -1.0, + point is > TOL * coord_delta[axis] + outside the grid in this coordinate direction. + If TOL == -1.0, then an interpolation point is considered to be "out of range" if and only if a centered molecule (or more generally, a molecule whose centering is chosen pretending that the grid is of infinite - extent), would require data from outside the grid. - Other values of out_of_range_tolerance[axis] are illegal. - @vtype const CCTK_REAL out_of_range_tolerance[N_dims] + extent), would require data from outside the grid + in this direction. + Other values of TOL are illegal. + @vtype const CCTK_REAL out_of_range_tolerance[2*N_dims] @endvar @var input_array_offsets @@ -710,34 +713,38 @@ if ((order < 1) || (order > MAX_ORDER)) * out-of-range interpolation-point handling */ { -CCTK_REAL out_of_range_tolerance[MAX_N_DIMS]; +CCTK_REAL out_of_range_tolerance[2*MAX_N_DIMS]; +const int N_tolerances = 2*N_dims; status = Util_TableGetRealArray(param_table_handle, - N_dims, out_of_range_tolerance, + N_tolerances, out_of_range_tolerance, "out_of_range_tolerance"); if (status == UTIL_ERROR_TABLE_NO_SUCH_KEY) then { /* default */ - int axis; - for (axis = 0 ; axis < N_dims ; ++axis) + int tol_index; + for (tol_index = 0 ; tol_index < N_tolerances ; ++tol_index) { - out_of_range_tolerance[axis] = OUT_OF_RANGE_TOLERANCE_DEFAULT; + out_of_range_tolerance[tol_index] + = OUT_OF_RANGE_TOLERANCE_DEFAULT; } } -else if (status == N_dims) +else if (status == N_tolerances) then { /* check that all values are valid */ - int axis; - for (axis = 0 ; axis < N_dims ; ++axis) + int tol_index; + for (tol_index = 0 ; tol_index < N_tolerances ; ++tol_index) { - if (! ( (out_of_range_tolerance[axis] >= 0.0) - || (out_of_range_tolerance[axis] == -1.0) ) ) + if (! ( (out_of_range_tolerance[tol_index] >= 0.0) + || (out_of_range_tolerance[tol_index] == -1.0) ) ) then { CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL, __LINE__, __FILE__, CCTK_THORNSTRING, "\n" -" CCTK_InterpLocalUniform(): invalid out_of_range_tolerance[axis=%d] = %g!\n" -" (valid values are -1.0 or >= 0.0)", - axis, out_of_range_tolerance[axis]); +" CCTK_InterpLocalUniform():\n" +" invalid out_of_range_tolerance[tol_index=%d] = %g!\n" +" (valid values are -1.0 or >= 0.0)", + tol_index, + out_of_range_tolerance[tol_index]); return UTIL_ERROR_BAD_INPUT; /*** ERROR RETURN ***/ } } diff --git a/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.h b/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.h index 1486794..9559393 100644 --- a/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.h +++ b/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.h @@ -193,8 +193,9 @@ int LocalInterp_ILU_Hermite(int N_dims, /* functions in molecule_posn.c */ int LocalInterp_molecule_posn(fp grid_origin, fp grid_delta, int grid_i_min, int grid_i_max, - fp out_of_range_tolerance, int molecule_size, + fp out_of_range_tolerance_min, + fp out_of_range_tolerance_max, fp x, fp *x_rel, int *molecule_m_min, int *molecule_m_max); diff --git a/src/GeneralizedPolynomial-Uniform/interpolate.maple b/src/GeneralizedPolynomial-Uniform/interpolate.maple index 54979ba..23ca9e0 100644 --- a/src/GeneralizedPolynomial-Uniform/interpolate.maple +++ b/src/GeneralizedPolynomial-Uniform/interpolate.maple @@ -4,6 +4,7 @@ # # <<<representation of numbers, data values, etc>>> # Lagrange_polynomial_interpolant - compute Lagrange polynomial interpolant +# Hermite_polynomial_interpolant - compute Hermite polynomial interpolant # coeff_as_lc_of_data - coefficients of ... (linear combination of data) # # print_coeff__lc_of_data - print C code to compute coefficients @@ -83,6 +84,48 @@ end proc; ################################################################################ # +# This function computes a Hermite polynomial interpolant in any +# number of dimensions. +# +# Arguments: +# fn = The interpolation function. This should be a procedure in the +# coordinates, having the coefficients as global variables. For +# example, +# proc(x,y) c00 + c10*x + c01*y end proc +# coeff_list = A set of the interpolation coefficients (coefficients in +# the interpolation function), for example [c00, c10, c01]. +# coord_list = A list of the coordinates (independent variables in the +# interpolation function), for example [x,y]. +# posn_list = A list of positions (each a list of numeric values) where the +# interpolant is to use data, for example hypercube([0,0], [1,1]). +# Any positions may be used; if they're redundant (as in the +# example) the least-squares interpolant is computed. +# +# Results: +# This function returns the interpolating polynomial, in the form of +# an algebraic expression in the coordinates and the data values. +# +Hermite_polynomial_interpolant := +proc( + fn::procedure, coeff_list::list(name), + coord_list::list(name), posn_list::list(list(numeric)) + ) +local posn, data_eqns, coeff_eqns; + +# coefficients of interpolating polynomial +data_eqns := { seq( fn(op(posn))='DATA'(op(posn)) , posn=posn_list ) }; +coeff_eqns := linalg[leastsqrs](data_eqns, {op(coeff_list)}); +if (has(coeff_eqns, '_t')) + then error "interpolation coefficients aren't uniquely determined!"; +end if; + +# interpolant as a polynomial in the coordinates +return subs(coeff_eqns, eval(fn))(op(coord_list)); +end proc; + +################################################################################ + +# # This function takes as input an interpolating polynomial, expresses # it as a linear combination of the data values, and returns the coefficeints # of that form. diff --git a/src/GeneralizedPolynomial-Uniform/molecule_posn.c b/src/GeneralizedPolynomial-Uniform/molecule_posn.c index f67922e..44e78fc 100644 --- a/src/GeneralizedPolynomial-Uniform/molecule_posn.c +++ b/src/GeneralizedPolynomial-Uniform/molecule_posn.c @@ -93,9 +93,15 @@ static const char *rcsid = "$Header$"; @vtype int grid_i_max @endvar - @var out_of_range_tolerance + @var molecule_size + @vdesc The size (number of points) of the molecule. + @vtype int molecule_size + @endvar + + @var out_of_range_tolerance_min, out_of_range_tolerance_max @vdesc Specifies how out-of-range interpolation points should - be handled: + be handled for the {minimum,maximum} ends of the grid + respectively. If out_of_range_tolerance >= 0.0, then an interpolation point is considered to be "out of range" if and only if the interpolation @@ -106,12 +112,7 @@ static const char *rcsid = "$Header$"; "out of range" if and only if a centered molecule would require data from outside the grid. Other values of out_of_range_tolerance are illegal. - @vtype fp - @endvar - - @var molecule_size - @vdesc The size (number of points) of the molecule. - @vtype int molecule_size + @vtype fp out_of_range_tolerance_min, out_of_range_tolerance_max @endvar @var x @@ -128,17 +129,11 @@ static const char *rcsid = "$Header$"; @vio pointer to out @endvar - @var molecule_m_min - @vdesc A pointer to an int where this function should store the minimum - molecule coordinate m of the molecule; or NULL to skip storing this. - @vtype int *molecule_m_min - @vio pointer to out - @endvar - - @var p_molecule_m_max - @vdesc A pointer to an int where this function should store the maximum - molecule coordinate m of the molecule; or NULL to skip storing this. - @vtype int *molecle_m_max + @var molecule_m_min, molecule_m_max + @vdesc A pointer to an int where this function should store the + {minimum,maximum} molecule coordinate m of the molecule; + or NULL to skip storing this. + @vtype int *molecule_m_min, *molecule_m_max @vio pointer to out @endvar @@ -155,8 +150,9 @@ static const char *rcsid = "$Header$"; @@*/ int LocalInterp_molecule_posn(fp grid_origin, fp grid_delta, int grid_i_min, int grid_i_max, - fp out_of_range_tolerance, int molecule_size, + fp out_of_range_tolerance_min, + fp out_of_range_tolerance_max, fp x, fp *x_rel, int *molecule_m_min, int *molecule_m_max) @@ -169,14 +165,17 @@ const int m_min = m_max - molecule_size + 1; /* a negative number */ const fp fp_i = (x - grid_origin) / grid_delta; /* is point x out-of-range? */ -if (out_of_range_tolerance >= 0.0) +if (out_of_range_tolerance_min >= 0.0) then { const fp fp_effective_grid_i_min - = ((fp) grid_i_min) - out_of_range_tolerance; - const fp fp_effective_grid_i_max - = ((fp) grid_i_max) + out_of_range_tolerance; + = ((fp) grid_i_min) - out_of_range_tolerance_min; if (fp_i < fp_effective_grid_i_min) then return INT_MIN; /*** ERROR RETURN ***/ + } +if (out_of_range_tolerance_max >= 0.0) + then { + const fp fp_effective_grid_i_max + = ((fp) grid_i_max) + out_of_range_tolerance_max; if (fp_i > fp_effective_grid_i_max) then return INT_MAX; /*** ERROR RETURN ***/ } @@ -194,13 +193,10 @@ const int centered_i_min = i_center + m_min; const int centered_i_max = i_center + m_max; /* check if off-centered molecules are forbidden? */ -if (out_of_range_tolerance == -1.0) - then { - if (centered_i_min < grid_i_min) - then return INT_MIN; /*** ERROR RETURN ***/ - if (centered_i_max > grid_i_max) - then return INT_MAX; /*** ERROR RETURN ***/ - } +if ((out_of_range_tolerance_min == -1.0) && (centered_i_min < grid_i_min)) + then return INT_MIN; /*** ERROR RETURN ***/ +if ((out_of_range_tolerance_max == -1.0) && (centered_i_max > grid_i_max)) + then return INT_MAX; /*** ERROR RETURN ***/ /* off-center as needed if we're close to the edge of the grid */ { diff --git a/src/GeneralizedPolynomial-Uniform/template.c b/src/GeneralizedPolynomial-Uniform/template.c index 3cb2c38..5cb934b 100644 --- a/src/GeneralizedPolynomial-Uniform/template.c +++ b/src/GeneralizedPolynomial-Uniform/template.c @@ -421,6 +421,17 @@ int FUNCTION_NAME(/***** coordinate system *****/ #error "N_DIMS may not be > 3!" #endif +/* layout of axes and min/max ends in out_of_range_tolerance[] array */ +#define X_AXIS_MIN 0 +#define X_AXIS_MAX 1 +#define Y_AXIS_MIN 2 +#define Y_AXIS_MAX 3 +#define Z_AXIS_MIN 4 +#define Z_AXIS_MAX 5 +#if (N_DIMS > 3) + #error "N_DIMS may not be > 3!" +#endif + /* basic sanity check on molecule size */ #define MOLECULE_M_COUNT (MOLECULE_MAX_M - MOLECULE_MIN_M + 1) #if (MOLECULE_SIZE != MOLECULE_M_COUNT) @@ -740,8 +751,9 @@ int pt; = LocalInterp_molecule_posn(origin_x, delta_x, input_array_min_subscripts[X_AXIS], input_array_max_subscripts[X_AXIS], - out_of_range_tolerance[X_AXIS], MOLECULE_SIZE, + out_of_range_tolerance[X_AXIS_MIN], + out_of_range_tolerance[X_AXIS_MAX], interp_coords_fp[X_AXIS], &x_temp, (int *) NULL, (int *) NULL); @@ -753,8 +765,9 @@ int pt; = LocalInterp_molecule_posn(origin_y, delta_y, input_array_min_subscripts[Y_AXIS], input_array_max_subscripts[Y_AXIS], - out_of_range_tolerance[Y_AXIS], MOLECULE_SIZE, + out_of_range_tolerance[Y_AXIS_MIN], + out_of_range_tolerance[Y_AXIS_MAX], interp_coords_fp[Y_AXIS], &y_temp, (int *) NULL, (int *) NULL); @@ -766,8 +779,9 @@ int pt; = LocalInterp_molecule_posn(origin_z, delta_z, input_array_min_subscripts[Z_AXIS], input_array_max_subscripts[Z_AXIS], - out_of_range_tolerance[Z_AXIS], MOLECULE_SIZE, + out_of_range_tolerance[Z_AXIS_MIN], + out_of_range_tolerance[Z_AXIS_MAX], interp_coords_fp[Z_AXIS], &z_temp, (int *) NULL, (int *) NULL); diff --git a/src/GeneralizedPolynomial-Uniform/test_molecule_posn.c b/src/GeneralizedPolynomial-Uniform/test_molecule_posn.c index b4c2379..bd3a1f9 100644 --- a/src/GeneralizedPolynomial-Uniform/test_molecule_posn.c +++ b/src/GeneralizedPolynomial-Uniform/test_molecule_posn.c @@ -6,10 +6,14 @@ * * Usage: * test_molecule_posn # run a preset set of tests - * test_molecule_posn molecule_size x # do a single test as specified + * test_molecule_posn molecule_size \ + * out_of_range_tolerance_min \ + * out_of_range_tolerance_max \ + * x # do a single test as specified */ #include <math.h> +#include <string.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> @@ -22,10 +26,6 @@ #define fuzzy_EQ(x,y) (fabs(x-y) <= 1.0e-10) -/* prototypes */ -void run_interactive_test(fp out_of_range_tolerance, int molecule_size, fp x); -int run_batch_tests(void); - /* hard-wired arguments for LocalInterp_molecule_posn() */ const fp grid_x0 = 3.1; const fp grid_dx = 0.1; @@ -35,6 +35,19 @@ const int grid_i_max = 105; /* x_max = 13.6 */ /******************************************************************************/ /* + * prototypes for functions local to this file +*/ +static + void run_interactive_test(int molecule_size, + fp out_of_range_tolerance_min, + fp out_of_range_tolerance_max, + fp x); +static + int run_batch_tests(void); + +/******************************************************************************/ + +/* * test data for batch tests */ @@ -42,8 +55,9 @@ const int grid_i_max = 105; /* x_max = 13.6 */ struct args_results { /* args */ - fp out_of_range_tolerance; int molecule_size; + fp out_of_range_tolerance_min; + fp out_of_range_tolerance_max; fp x; /* results */ int i_center; @@ -53,139 +67,142 @@ struct args_results /* test data */ static const struct args_results test_data[] = - { - /* molecule size 2 */ - { 1.0, 2, 7.19, INT_MIN, -1.1, 0,+1 }, - { 1.0, 2, 7.21, 42, -0.9, 0,+1 }, - { 1.0, 2, 7.24, 42, -0.6, 0,+1 }, - { 1.0, 2, 7.26, 42, -0.4, 0,+1 }, - { 1.0, 2, 7.29, 42, -0.1, 0,+1 }, - {-1.0, 2, 7.29, INT_MIN, -0.1, 0,+1 }, - { 1.0e-12, 2, 7.3, 42, 0.0, 0,+1 }, /* x == grid_x_min */ - { 1.0e-12, 2, 7.31, 42, +0.1, 0,+1 }, - {-1.0 , 2, 7.31, 42, +0.1, 0,+1 }, - { 1.0e-12, 2, 7.35, 42, +0.5, 0,+1 }, - { 1.0e-12, 2, 7.39, 42, +0.9, 0,+1 }, - { 1.0e-12, 2, 7.41, 43, 0.1, 0,+1 }, - { 1.0e-12, 2, 9.81, 67, +0.1, 0,+1 }, - { 1.0e-12, 2, 9.85, 67, +0.5, 0,+1 }, - { 1.0e-12, 2, 9.89, 67, +0.9, 0,+1 }, - { 1.0e-12, 2, 13.45, 103, +0.5, 0,+1 }, - { 1.0e-12, 2, 13.51, 104, +0.1, 0,+1 }, - { 1.0e-12, 2, 13.55, 104, +0.5, 0,+1 }, - { 1.0e-12, 2, 13.59, 104, +0.9, 0,+1 }, - {-1.0, 2, 13.59, 104, +0.9, 0,+1 }, - { 1.0e-12, 2, 13.6, 104, +1.0, 0,+1 }, /* x == grid_x_max */ - { 1.0, 2, 13.61, 104, +1.1, 0,+1 }, - {-1.0, 2, 13.61, INT_MAX, +1.1, 0,+1 }, - { 1.0, 2, 13.65, 104, +1.5, 0,+1 }, - { 1.0, 2, 13.69, 104, +1.9, 0,+1 }, - { 1.0, 2, 13.71, INT_MAX, +2.1, 0,+1 }, - /* molecule size 3 */ - { 1.0, 3, 7.19, INT_MIN, -2.1, -1,+1 }, - { 1.0, 3, 7.21, 43, -1.9, -1,+1 }, - { 1.0, 3, 7.24, 43, -1.6, -1,+1 }, - { 1.0, 3, 7.26, 43, -1.4, -1,+1 }, - { 1.0, 3, 7.29, 43, -1.1, -1,+1 }, - {-1.0, 3, 7.29, INT_MIN, -1.1, -1,+1 }, - { 1.0e-12, 3, 7.3, 43, -1.0, -1,+1 }, /* x == grid_x_min */ - { 1.0e-12, 3, 7.31, 43, -0.9, -1,+1 }, - { 1.0e-12, 3, 7.34, 43, -0.6, -1,+1 }, - {-1.0, 3, 7.34, INT_MIN, -0.6, -1,+1 }, - { 1.0e-12, 3, 7.36, 43, -0.4, -1,+1 }, - {-1.0, 3, 7.36, 43, -0.4, -1,+1 }, - { 1.0e-12, 3, 7.39, 43, -0.1, -1,+1 }, - { 1.0e-12, 3, 7.4, 43, 0.0, -1,+1 }, - { 1.0e-12, 3, 7.44, 43, +0.4, -1,+1 }, - { 1.0e-12, 3, 7.46, 44, -0.4, -1,+1 }, - { 1.0e-12, 3, 9.8, 67, 0.0, -1,+1 }, - { 1.0e-12, 3, 9.81, 67, +0.1, -1,+1 }, - { 1.0e-12, 3, 9.84, 67, +0.4, -1,+1 }, - { 1.0e-12, 3, 9.86, 68, -0.4, -1,+1 }, - { 1.0e-12, 3, 9.89, 68, -0.1, -1,+1 }, - { 1.0e-12, 3, 9.9, 68, 0.0, -1,+1 }, - { 1.0e-12, 3, 13.44, 103, +0.4, -1,+1 }, - { 1.0e-12, 3, 13.46, 104, -0.4, -1,+1 }, - { 1.0e-12, 3, 13.5, 104, 0.0, -1,+1 }, - { 1.0e-12, 3, 13.51, 104, +0.1, -1,+1 }, - { 1.0e-12, 3, 13.54, 104, +0.4, -1,+1 }, - {-1.0, 3, 13.54, 104, +0.4, -1,+1 }, - { 1.0e-12, 3, 13.56, 104, +0.6, -1,+1 }, - {-1.0, 3, 13.56, INT_MAX, +0.6, -1,+1 }, - { 1.0e-12, 3, 13.59, 104, +0.9, -1,+1 }, - { 1.0e-12, 3, 13.6, 104, +1.0, -1,+1 }, /* x == grid_x_max */ - { 1.0, 3, 13.61, 104, +1.1, -1,+1 }, - { 1.0, 3, 13.65, 104, +1.5, -1,+1 }, - { 1.0, 3, 13.69, 104, +1.9, -1,+1 }, - { 1.0, 3, 13.71, INT_MAX, +2.1, -1,+1 }, - /* molecule size 4 */ - { 0.2, 4, 7.27, INT_MIN, -1.3, -1,+2 }, - { 0.2, 4, 7.29, 43, -1.1, -1,+2 }, - { 1.0e-12, 4, 7.3, 43, -1.0, -1,+2 }, /* x == grid_x_min */ - { 1.0e-12, 4, 7.33, 43, -0.7, -1,+2 }, - { 1.0e-12, 4, 7.39, 43, -0.1, -1,+2 }, - {-1.0, 4, 7.39, INT_MIN, -0.1, -1,+2 }, - { 1.0e-12, 4, 7.4, 43, 0.0, -1,+2 }, - {-1.0, 4, 7.41, 43, +0.1, -1,+2 }, - { 1.0e-12, 4, 7.42, 43, +0.2, -1,+2 }, - { 1.0e-12, 4, 7.48, 43, +0.8, -1,+2 }, - { 1.0e-12, 4, 7.51, 44, +0.1, -1,+2 }, - { 1.0e-12, 4, 9.81, 67, +0.1, -1,+2 }, - { 1.0e-12, 4, 9.85, 67, +0.5, -1,+2 }, - { 1.0e-12, 4, 9.89, 67, +0.9, -1,+2 }, - { 1.0e-12, 4, 13.39, 102, +0.9, -1,+2 }, - { 1.0e-12, 4, 13.41, 103, +0.1, -1,+2 }, - { 1.0e-12, 4, 13.48, 103, +0.8, -1,+2 }, - {-1.0, 4, 13.48, 103, +0.8, -1,+2 }, - { 1.0e-12, 4, 13.5, 103, +1.0, -1,+2 }, - { 1.0e-12, 4, 13.51, 103, +1.1, -1,+2 }, - {-1.0, 4, 13.51, INT_MAX, +1.1, -1,+2 }, - { 1.0e-12, 4, 13.55, 103, +1.5, -1,+2 }, - { 1.0e-12, 4, 13.59, 103, +1.9, -1,+2 }, - { 1.0e-12, 4, 13.6, 103, +2.0, -1,+2 }, /* x == grid_x_max */ - { 2.0, 4, 13.79, 103, +3.9, -1,+2 }, - { 2.0, 4, 13.81, INT_MAX, +4.1, -1,+2 }, - /* molecule size 5 */ - { 3.0, 5, 6.99, INT_MIN, -5.1, -2,+2 }, - { 3.0, 5, 7.01, 44, -4.9, -2,+2 }, - { 1.0e-12, 5, 7.3, 44, -2.0, -2,+2 }, /* x == grid_x_min */ - { 1.0e-12, 5, 7.4, 44, -1.0, -2,+2 }, - { 1.0e-12, 5, 7.44, 44, -0.6, -2,+2 }, - {-1.0, 5, 7.44, INT_MIN, -0.6, -2,+2 }, - { 1.0e-12, 5, 7.46, 44, -0.4, -2,+2 }, - {-1.0, 5, 7.46, 44, -0.4, -2,+2 }, - { 1.0e-12, 5, 7.49, 44, -0.1, -2,+2 }, - { 1.0e-12, 5, 7.5, 44, 0.0, -2,+2 }, - { 1.0e-12, 5, 7.54, 44, +0.4, -2,+2 }, - { 1.0e-12, 5, 7.56, 45, -0.4, -2,+2 }, - { 1.0e-12, 5, 7.6, 45, 0.0, -2,+2 }, - { 1.0e-12, 5, 7.64, 45, +0.4, -2,+2 }, - { 1.0e-12, 5, 9.8, 67, 0.0, -2,+2 }, - { 1.0e-12, 5, 9.81, 67, +0.1, -2,+2 }, - { 1.0e-12, 5, 9.84, 67, +0.4, -2,+2 }, - { 1.0e-12, 5, 9.86, 68, -0.4, -2,+2 }, - { 1.0e-12, 5, 9.89, 68, -0.1, -2,+2 }, - { 1.0e-12, 5, 9.9, 68, 0.0, -2,+2 }, - { 1.0e-12, 5, 13.34, 102, +0.4, -2,+2 }, - { 1.0e-12, 5, 13.36, 103, -0.4, -2,+2 }, - { 1.0e-12, 5, 13.39, 103, -0.1, -2,+2 }, - { 1.0e-12, 5, 13.41, 103, +0.1, -2,+2 }, - { 1.0e-12, 5, 13.44, 103, +0.4, -2,+2 }, - {-1.0, 5, 13.44, 103, +0.4, -2,+2 }, - { 1.0e-12, 5, 13.46, 103, +0.6, -2,+2 }, - {-1.0, 5, 13.46, INT_MAX, +0.6, -2,+2 }, - { 1.0e-12, 5, 13.48, 103, +0.8, -2,+2 }, - { 1.0e-12, 5, 13.5, 103, +1.0, -2,+2 }, - { 1.0e-12, 5, 13.51, 103, +1.1, -2,+2 }, - { 1.0e-12, 5, 13.54, 103, +1.4, -2,+2 }, - {-1.0, 5, 13.54, INT_MAX, +1.4, -2,+2 }, - { 1.0e-12, 5, 13.56, 103, +1.6, -2,+2 }, - {-1.0, 5, 13.56, INT_MAX, +1.6, -2,+2 }, - { 1.0e-12, 5, 13.59, 103, +1.9, -2,+2 }, - { 1.0e-12, 5, 13.6, 103, +2.0, -2,+2 }, /* x == grid_x_max */ - { 1.5, 5, 13.74, 103, +3.4, -2,+2 }, - { 1.5, 5, 13.76, INT_MAX, +3.6, -2,+2 }, - }; + { + /* molecule size 2 */ + { 2, 1.0, 1.0e-12, 7.19, INT_MIN, -1.1, 0,+1 }, + { 2, 1.0, 1.0e-12, 7.21, 42, -0.9, 0,+1 }, + { 2, 1.0, 1.0e-12, 7.24, 42, -0.6, 0,+1 }, + { 2, 1.0, 1.0e-12, 7.26, 42, -0.4, 0,+1 }, + { 2, 1.0, 1.0e-12, 7.29, 42, -0.1, 0,+1 }, + { 2, -1.0, 1.0e-12, 7.29, INT_MIN, -0.1, 0,+1 }, + { 2, 1.0e-12, 1.0e-12, 7.3, 42, 0.0, 0,+1 },/* grid_x_min */ + { 2, 1.0e-12, 1.0e-12, 7.31, 42, +0.1, 0,+1 }, + { 2, -1.0 , 1.0e-12, 7.31, 42, +0.1, 0,+1 }, + { 2, 1.0e-12, 1.0e-12, 7.35, 42, +0.5, 0,+1 }, + { 2, 1.0e-12, 1.0e-12, 7.39, 42, +0.9, 0,+1 }, + { 2, 1.0e-12, 1.0e-12, 7.41, 43, 0.1, 0,+1 }, + { 2, 1.0e-12, 1.0e-12, 9.81, 67, +0.1, 0,+1 }, + { 2, 1.0e-12, 1.0e-12, 9.85, 67, +0.5, 0,+1 }, + { 2, 1.0e-12, 1.0e-12, 9.89, 67, +0.9, 0,+1 }, + { 2, 1.0e-12, 1.0e-12, 13.45, 103, +0.5, 0,+1 }, + { 2, 1.0e-12, 1.0e-12, 13.51, 104, +0.1, 0,+1 }, + { 2, 1.0e-12, 1.0e-12, 13.55, 104, +0.5, 0,+1 }, + { 2, 1.0e-12, 1.0e-12, 13.59, 104, +0.9, 0,+1 }, + { 2, 1.0e-12, -1.0, 13.59, 104, +0.9, 0,+1 }, + { 2, 1.0e-12, 1.0e-12, 13.6, 104, +1.0, 0,+1 },/* grid_x_max */ + { 2, 1.0e-12, 1.0, 13.61, 104, +1.1, 0,+1 }, + { 2, 1.0e-12, -1.0, 13.61, INT_MAX, +1.1, 0,+1 }, + { 2, 1.0e-12, 1.0, 13.65, 104, +1.5, 0,+1 }, + { 2, 1.0e-12, 1.0, 13.69, 104, +1.9, 0,+1 }, + { 2, 1.0e-12, 1.0, 13.71, INT_MAX, +2.1, 0,+1 }, + + /* molecule size 3 */ + { 3, 1.0, 1.0e-12, 7.19, INT_MIN, -2.1, -1,+1 }, + { 3, 1.0, 1.0e-12, 7.21, 43, -1.9, -1,+1 }, + { 3, 1.0, 1.0e-12, 7.24, 43, -1.6, -1,+1 }, + { 3, 1.0, 1.0e-12, 7.26, 43, -1.4, -1,+1 }, + { 3, 1.0, 1.0e-12, 7.29, 43, -1.1, -1,+1 }, + { 3, -1.0, 1.0e-12, 7.29, INT_MIN, -1.1, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 7.3, 43, -1.0, -1,+1 },/* grid_x_min */ + { 3, 1.0e-12, 1.0e-12, 7.31, 43, -0.9, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 7.34, 43, -0.6, -1,+1 }, + { 3, -1.0, 1.0e-12, 7.34, INT_MIN, -0.6, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 7.36, 43, -0.4, -1,+1 }, + { 3, -1.0, 1.0e-12, 7.36, 43, -0.4, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 7.39, 43, -0.1, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 7.4, 43, 0.0, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 7.44, 43, +0.4, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 7.46, 44, -0.4, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 9.8, 67, 0.0, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 9.81, 67, +0.1, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 9.84, 67, +0.4, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 9.86, 68, -0.4, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 9.89, 68, -0.1, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 9.9, 68, 0.0, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 13.44, 103, +0.4, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 13.46, 104, -0.4, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 13.5, 104, 0.0, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 13.51, 104, +0.1, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 13.54, 104, +0.4, -1,+1 }, + { 3, 1.0e-12, -1.0, 13.54, 104, +0.4, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 13.56, 104, +0.6, -1,+1 }, + { 3, 1.0e-12, -1.0, 13.56, INT_MAX, +0.6, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 13.59, 104, +0.9, -1,+1 }, + { 3, 1.0e-12, 1.0e-12, 13.6, 104, +1.0, -1,+1 },/* grid_x_max */ + { 3, 1.0e-12, 1.0, 13.61, 104, +1.1, -1,+1 }, + { 3, 1.0e-12, 1.0, 13.65, 104, +1.5, -1,+1 }, + { 3, 1.0e-12, 1.0, 13.69, 104, +1.9, -1,+1 }, + { 3, 1.0e-12, 1.0, 13.71, INT_MAX, +2.1, -1,+1 }, + + /* molecule size 4 */ + { 4, 0.2, 1.0e-12, 7.27, INT_MIN, -1.3, -1,+2 }, + { 4, 0.2, 1.0e-12, 7.29, 43, -1.1, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 7.3, 43, -1.0, -1,+2 },/* grid_x_min */ + { 4, 1.0e-12, 1.0e-12, 7.33, 43, -0.7, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 7.39, 43, -0.1, -1,+2 }, + { 4, -1.0, 1.0e-12, 7.39, INT_MIN, -0.1, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 7.4, 43, 0.0, -1,+2 }, + { 4, -1.0, 1.0e-12, 7.41, 43, +0.1, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 7.42, 43, +0.2, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 7.48, 43, +0.8, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 7.51, 44, +0.1, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 9.81, 67, +0.1, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 9.85, 67, +0.5, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 9.89, 67, +0.9, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 13.39, 102, +0.9, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 13.41, 103, +0.1, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 13.48, 103, +0.8, -1,+2 }, + { 4, 1.0e-12, -1.0, 13.48, 103, +0.8, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 13.5, 103, +1.0, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 13.51, 103, +1.1, -1,+2 }, + { 4, 1.0e-12, -1.0, 13.51, INT_MAX, +1.1, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 13.55, 103, +1.5, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 13.59, 103, +1.9, -1,+2 }, + { 4, 1.0e-12, 1.0e-12, 13.6, 103, +2.0, -1,+2 },/* grid_x_max */ + { 4, 1.0e-12, 2.0, 13.79, 103, +3.9, -1,+2 }, + { 4, 1.0e-12, 2.0, 13.81, INT_MAX, +4.1, -1,+2 }, + + /* molecule size 5 */ + { 5, 3.0, 1.0e-12, 6.99, INT_MIN, -5.1, -2,+2 }, + { 5, 3.0, 1.0e-12, 7.01, 44, -4.9, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 7.3, 44, -2.0, -2,+2 },/* grid_x_min */ + { 5, 1.0e-12, 1.0e-12, 7.4, 44, -1.0, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 7.44, 44, -0.6, -2,+2 }, + { 5, -1.0, 1.0e-12, 7.44, INT_MIN, -0.6, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 7.46, 44, -0.4, -2,+2 }, + { 5, -1.0, 1.0e-12, 7.46, 44, -0.4, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 7.49, 44, -0.1, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 7.5, 44, 0.0, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 7.54, 44, +0.4, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 7.56, 45, -0.4, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 7.6, 45, 0.0, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 7.64, 45, +0.4, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 9.8, 67, 0.0, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 9.81, 67, +0.1, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 9.84, 67, +0.4, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 9.86, 68, -0.4, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 9.89, 68, -0.1, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 9.9, 68, 0.0, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.34, 102, +0.4, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.36, 103, -0.4, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.39, 103, -0.1, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.41, 103, +0.1, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.44, 103, +0.4, -2,+2 }, + { 5, 1.0e-12, -1.0, 13.44, 103, +0.4, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.46, 103, +0.6, -2,+2 }, + { 5, 1.0e-12, -1.0, 13.46, INT_MAX, +0.6, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.48, 103, +0.8, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.5, 103, +1.0, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.51, 103, +1.1, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.54, 103, +1.4, -2,+2 }, + { 5, 1.0e-12, -1.0, 13.54, INT_MAX, +1.4, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.56, 103, +1.6, -2,+2 }, + { 5, 1.0e-12, -1.0, 13.56, INT_MAX, +1.6, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.59, 103, +1.9, -2,+2 }, + { 5, 1.0e-12, 1.0e-12, 13.6, 103, +2.0, -2,+2 },/* grid_x_max */ + { 5, 1.0e-12, 1.5, 13.74, 103, +3.4, -2,+2 }, + { 5, 1.0e-12, 1.5, 13.76, INT_MAX, +3.6, -2,+2 }, + }; #define N_TESTS ((int) (sizeof(test_data)/sizeof(test_data[0]))) @@ -194,9 +211,9 @@ static const struct args_results test_data[] = int main(int argc, const char *const argv[]) { bool N_fail; -fp out_of_range_tolerance; int molecule_size; -fp x; +double out_of_range_tolerance_min, out_of_range_tolerance_max; +double x; switch (argc) { @@ -213,54 +230,88 @@ case 1: return 1; } -case 4: - if ( (sscanf(argv[1], "%lf", &out_of_range_tolerance) == 1) - && (sscanf(argv[2], "%d", &molecule_size) == 1) - && (sscanf(argv[3], "%lf", &x) == 1) ) +case 5: + if ( (sscanf(argv[1], "%d", &molecule_size) == 1) + && (sscanf(argv[2], "%lf", &out_of_range_tolerance_min) == 1) + && (sscanf(argv[3], "%lf", &out_of_range_tolerance_max) == 1) + && (sscanf(argv[4], "%lf", &x) == 1) ) then { - run_interactive_test(out_of_range_tolerance, molecule_size, x); + run_interactive_test(molecule_size, + out_of_range_tolerance_min, + out_of_range_tolerance_max, + x); return 0; } /* fall through */ + default: fprintf(stderr, "usage:\n" "# run a single test as specified:\n" - " %s out_of_range_tolerance molecule_size x\n" + " %s molecule_size \\\n" + " %*s out_of_range_tolerance_min \\\n" + " %*s out_of_range_tolerance_max \\\n" + " %*s x\n" "# run a preset set of tests:\n" " %s\n" , - argv[0], argv[0]); + argv[0], + (int) strlen(argv[0]), "", + (int) strlen(argv[0]), "", + (int) strlen(argv[0]), "", + argv[0]); return 1; } } /******************************************************************************/ -/* run a single test as specified */ -void run_interactive_test(fp out_of_range_tolerance, int molecule_size, fp x) +/* + * This function runs a single test as specified. + */ +static + void run_interactive_test(int molecule_size, + fp out_of_range_tolerance_min, + fp out_of_range_tolerance_max, + fp x) { fp x_rel; int m_min, m_max; -int i_center = LocalInterp_molecule_posn(grid_x0, grid_dx, - grid_i_min, grid_i_max, - out_of_range_tolerance, - molecule_size, - x, - &x_rel, - &m_min, &m_max); +printf("testing with molecule_size=%d\n", molecule_size); +printf(" out_of_range_tolerance_[min,max]=[%g,%g]\n", + (double) out_of_range_tolerance_min, + (double) out_of_range_tolerance_max); +printf(" x=%g\n", (double) x); + + { +const int i_center = LocalInterp_molecule_posn(grid_x0, grid_dx, + grid_i_min, grid_i_max, + molecule_size, + out_of_range_tolerance_min, + out_of_range_tolerance_max, + x, + &x_rel, + &m_min, &m_max); if ((i_center == INT_MIN) || (i_center == INT_MAX)) then printf("i_center=%d\n", i_center); else printf("i_center=%d x_rel=%g m_[min,max]=[%d,%d] i_[min,max]=[%d,%d]\n", i_center, x_rel, m_min, m_max, i_center+m_min, i_center+m_max); + } } /******************************************************************************/ -/* run a preset set of tests, return number of failures */ -int run_batch_tests(void) +/* + * This function run the preset set of tests specified by the + * test_data array + * + * Results: + * This function returns the number of test failures. + */ +static + int run_batch_tests(void) { int i; int failure_count = 0; @@ -272,8 +323,9 @@ int failure_count = 0; int m_min = 0, m_max = 0; int i_center = LocalInterp_molecule_posn(grid_x0, grid_dx, grid_i_min, grid_i_max, - p->out_of_range_tolerance, p->molecule_size, + p->out_of_range_tolerance_min, + p->out_of_range_tolerance_max, p->x, &x_rel, &m_min, &m_max); @@ -283,10 +335,16 @@ int failure_count = 0; && fuzzy_EQ(x_rel, p->x_rel) && (m_min == p->m_min) && (m_max == p->m_max) ); - int msglen = printf("tol=%g size=%d x=%g ==> ", - p->out_of_range_tolerance, p->molecule_size, p->x); - printf("i_center=%d x_rel=%g m_[min,max]=[%d,%d]\n", - i_center, x_rel, m_min, m_max); + + int msglen = + printf("size=%d tol=[%g,%g] x=%g ==> ", + p->molecule_size, + (double) p->out_of_range_tolerance_min, + (double) p->out_of_range_tolerance_max, + (double) p->x); + printf("i_center=%d x_rel=%g m=[%d,%d]\n", + i_center, (double) x_rel, m_min, m_max); + if (! ok) then { ++failure_count; @@ -294,7 +352,7 @@ int failure_count = 0; int error_msglen = printf("***** FAIL: "); printf("%-*s", msglen-error_msglen, "expected"); printf("i_center=%d x_rel=%g m_[min,max]=[%d,%d]\n", - p->i_center, p->x_rel, p->m_min, p->m_max); + p->i_center, (double) p->x_rel, p->m_min, p->m_max); } } } |