Exemple #1
0
void testMonotonic(const Spline &sp,
                   const double *x,
                   const double *y)
{
    // test the common properties of splines
    testCommon(sp, x, y);

    size_t n = sp.numSamples();

    for (size_t i = 0; i < n - 1; ++ i) {
        // make sure that the spline is monotonic for each interval
        // between sampling points
        if (!sp.monotonic(x[i], x[i + 1]))
            OPM_THROW(std::runtime_error,
                      "Spline says it is not monotonic in interval "
                      << i << " where it should be");

        // test the intersection methods
        double d = (y[i] + y[i+1])/2;
        double interX = sp.template intersectInterval<double>(x[i], x[i+1],
                                                              /*a=*/0, /*b=*/0, /*c=*/0, d);
        double interY = sp.eval(interX);
        if (std::abs(interY - d) > 1e-5)
            OPM_THROW(std::runtime_error,
                      "Spline::intersectInterval() seems to be broken: "
                      << sp.eval(interX) << " - " << d << " = " << sp.eval(interX) - d << "!");
    }

    // make sure the spline says to be monotonic on the (extrapolated)
    // left and right sides
    if (!sp.monotonic(x[0] - 1.0, (x[0] + x[1])/2, /*extrapolate=*/true))
        OPM_THROW(std::runtime_error,
                  "Spline says it is not monotonic on left side where it should be");
    if (!sp.monotonic((x[n - 2]+ x[n - 1])/2, x[n-1] + 1.0, /*extrapolate=*/true))
        OPM_THROW(std::runtime_error,
                  "Spline says it is not monotonic on right side where it should be");

    for (size_t i = 0; i < n - 2; ++ i) {
        // make sure that the spline says that it is non-monotonic for
        // if extrema are within the queried interval
        if (sp.monotonic((x[i] + x[i + 1])/2, (x[i + 1] + x[i + 2])/2))
            OPM_THROW(std::runtime_error,
                      "Spline says it is monotonic in interval "
                      << i << " where it should not be");
    }
}