/** * Tests that a given interpolation type reproduces the data points it is given, * and then tests that it correctly reproduces additional values. * * @param xarr the x values of the points that define the function * @param yarr the y values of the points that define the function * @param zarr the values of the function at the points specified by xarr and yarr * @param xsize the length of xarr * @param ysize the length of yarr * @param xval the x values of additional points at which to calculate interpolated values * @param yval the y values of additional points at which to calculate interpolated values * @param zval the expected results of the additional interpolations * @param zxval the expected results of the x derivative calculations * @param zyval the expected results of the y derivative calculations * @param zxxval the expected results of the xx derivative calculations * @param zyyval the expected results of the yy derivative calculations * @param zxyval the expected results of the xy derivative calculations * @param test_size the length of xval, yval, zval, etc. * @param T the interpolation type */ int test_interp2d(const double xarr[], const double yarr[], const double zarr[], // interpolation data size_t xsize, size_t ysize, // sizes of xarr and yarr const double xval[], const double yval[], // test points const double zval[], // expected results const double zxval[], const double zyval[], const double zxxval[], const double zyyval[], const double zxyval[], size_t test_size, // number of test points const interp2d_type* T) { gsl_interp_accel *xa, *ya; int status = 0; size_t xi, yi, zi, i; xa = gsl_interp_accel_alloc(); ya = gsl_interp_accel_alloc(); interp2d* interp = interp2d_alloc(T, xsize, ysize); interp2d_spline* interp_s = interp2d_spline_alloc(T, xsize, ysize); unsigned int min_size = interp2d_type_min_size(T); gsl_test_int(min_size, T->min_size, "interp2d_type_min_size on %s", interp2d_name(interp)); interp2d_init(interp, xarr, yarr, zarr, xsize, ysize); interp2d_spline_init(interp_s, xarr, yarr, zarr, xsize, ysize); // First check that the interpolation reproduces the given points for (xi = 0; xi < xsize; xi++) { double x = xarr[xi]; for (yi = 0; yi < ysize; yi++) { double y = yarr[yi]; zi = INDEX_2D(xi, yi, xsize, ysize); test_single_low_level(&interp2d_eval, &interp2d_eval_e, interp, xarr, yarr, zarr, x, y, xa, ya, zarr, zi); test_single_low_level(&interp2d_eval_no_boundary_check, &interp2d_eval_e_no_boundary_check, interp, xarr, yarr, zarr, x, y, xa, ya, zarr, zi); test_single_high_level(&interp2d_spline_eval, &interp2d_spline_eval_e, interp_s, x, y, xa, ya, zarr, zi); } } // Then check additional points provided for (i = 0; i < test_size; i++) { double x = xval[i]; double y = yval[i]; test_single_low_level(&interp2d_eval, &interp2d_eval_e, interp, xarr, yarr, zarr, x, y, xa, ya, zval, i); test_single_low_level(&interp2d_eval_deriv_x, &interp2d_eval_deriv_x_e, interp, xarr, yarr, zarr, x, y, xa, ya, zxval, i); test_single_low_level(&interp2d_eval_deriv_y, &interp2d_eval_deriv_y_e, interp, xarr, yarr, zarr, x, y, xa, ya, zyval, i); test_single_low_level(&interp2d_eval_deriv_xx,&interp2d_eval_deriv_xx_e, interp, xarr, yarr, zarr, x, y, xa, ya, zxxval, i); test_single_low_level(&interp2d_eval_deriv_yy,&interp2d_eval_deriv_yy_e, interp, xarr, yarr, zarr, x, y, xa, ya, zyyval, i); test_single_low_level(&interp2d_eval_deriv_xy,&interp2d_eval_deriv_xy_e, interp, xarr, yarr, zarr, x, y, xa, ya, zxyval, i); test_single_high_level(&interp2d_spline_eval, &interp2d_spline_eval_e, interp_s, x, y, xa, ya, zval, i); test_single_high_level(&interp2d_spline_eval_deriv_x, &interp2d_spline_eval_deriv_x_e, interp_s, x, y, xa, ya, zxval, i); test_single_high_level(&interp2d_spline_eval_deriv_y, &interp2d_spline_eval_deriv_y_e, interp_s, x, y, xa, ya, zyval, i); test_single_high_level(&interp2d_spline_eval_deriv_xx,&interp2d_spline_eval_deriv_xx_e, interp_s, x, y, xa, ya, zxxval, i); test_single_high_level(&interp2d_spline_eval_deriv_yy,&interp2d_spline_eval_deriv_yy_e, interp_s, x, y, xa, ya, zyyval, i); test_single_high_level(&interp2d_spline_eval_deriv_xy,&interp2d_spline_eval_deriv_xy_e, interp_s, x, y, xa, ya, zxyval, i); test_single_low_level(&interp2d_eval_no_boundary_check, &interp2d_eval_e_no_boundary_check, interp, xarr, yarr, zarr, x, y, xa, ya, zval, i); } gsl_interp_accel_free(xa); gsl_interp_accel_free(ya); interp2d_free(interp); return status; }
void velinterp (struct drifter *ptdrifter, int ndr, int xdim, int ydim, const double *u, const double *v){ int i, j; double *xarr, *yarr; xarr = new double[xdim]; yarr = new double[ydim]; for (i = 0; i < xdim; i++) xarr[i] = i * 1.0; for (j = 0; j < ydim; j++) yarr[j] = j * 1.0; gsl_interp_accel *xa, *ya; const interp2d_type* T = interp2d_bicubic; xa = gsl_interp_accel_alloc(); ya = gsl_interp_accel_alloc(); interp2d_spline* interp_u = interp2d_spline_alloc(T, xdim, ydim); interp2d_spline* interp_v = interp2d_spline_alloc(T, xdim, ydim); interp2d_spline_init(interp_u, xarr, yarr, u, xdim, ydim); interp2d_spline_init(interp_v, xarr, yarr, v, xdim, ydim); double xdr, ydr; for (i = 0; i < ndr; i++) { xdr = ptdrifter[i].x; ydr = ptdrifter[i].y; ptdrifter[i].u = interp2d_spline_eval(interp_u, xdr, ydr, xa, ya); ptdrifter[i].v = interp2d_spline_eval(interp_v, xdr, ydr, xa, ya); } delete[]xarr; delete[]yarr; gsl_interp_accel_free(xa); gsl_interp_accel_free(ya); interp2d_spline_free(interp_u); interp2d_spline_free(interp_v); }