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

    static double eps = 1e-5;
    size_t n = sp.numSamples();

    // make sure the second derivatives at both end points are 0
    double d0 = sp.evalDerivative(x[0]);
    double d1 = sp.evalDerivative(x[0] + eps);

    double d2 = sp.evalDerivative(x[n-1] - eps);
    double d3 = sp.evalDerivative(x[n-1]);

    if (std::abs(d1 - d0)/eps > 1000*eps)
        OPM_THROW(std::runtime_error,
                   "Invalid second derivative at beginning of interval: is "
                   << (d1 - d0)/eps << " ought to be 0");

    if (std::abs(d3 - d2)/eps > 1000*eps)
        OPM_THROW(std::runtime_error,
                   "Invalid second derivative at end of interval: is "
                   << (d3 - d2)/eps << " ought to be 0");
}
Beispiel #2
0
void testFull(const Spline &sp,
              const double *x,
              const double *y,
              double m0,
              double m1)
{
    // test the common properties of splines
    testCommon(sp, x, y);
    static double eps = 1e-5;
    size_t n = sp.numSamples();
    // make sure the derivative at both end points is correct
    double d0 = sp.evalDerivative(x[0]);
    double d1 = sp.evalDerivative(x[n-1]);
    if (std::abs(d0 - m0) > eps)
        OPM_THROW(std::runtime_error,
                   "Invalid derivative at beginning of interval: is "
                   << d0 << " ought to be " << m0);
    if (std::abs(d1 - m1) > eps)
        OPM_THROW(std::runtime_error,
                   "Invalid derivative at end of interval: is "
                   << d1 << " ought to be " << m1);
}
Beispiel #3
0
void testCommon(const Spline &sp,
                const double *x,
                const double *y)
{
    static double eps = 1e-10;
    static double epsFD = 1e-7;

    size_t n = sp.numSamples();
    for (size_t i = 0; i < n; ++i) {
        // sure that we hit all sampling points
        double y0 = (i>0)?sp.eval(x[i]-eps):y[0];
        double y1 = sp.eval(x[i]);
        double y2 = (i<n-1)?sp.eval(x[i]+eps):y[n-1];

        if (std::abs(y0 - y[i]) > 100*eps || std::abs(y2 - y[i]) > 100*eps)
            OPM_THROW(std::runtime_error,
                       "Spline seems to be discontinuous at sampling point " << i << "!");
        if (std::abs(y1 - y[i]) > eps)
            OPM_THROW(std::runtime_error,
                       "Spline does not capture sampling point " << i << "!");

        // make sure the derivative is continuous (assuming that the
        // second derivative is smaller than 1000)
        double d1 = sp.evalDerivative(x[i]);
        double d0 = (i>0)?sp.evalDerivative(x[i]-eps):d1;
        double d2 = (i<n-1)?sp.evalDerivative(x[i]+eps):d1;

        if (std::abs(d1 - d0) > 1000*eps || std::abs(d2 - d0) > 1000*eps)
            OPM_THROW(std::runtime_error,
                      "Spline seems to exhibit a discontinuous derivative at sampling point " << i << "!");
    }

    // make sure the derivatives are consistent with the curve
    size_t np = 3*n;
    for (size_t i = 0; i < np; ++i) {
        double xMin = sp.xAt(0);
        double xMax = sp.xAt(sp.numSamples() - 1);
        double xval = xMin + (xMax - xMin)*i/np;

        // first derivative
        double y1 = sp.eval(xval+epsFD);
        double y0 = sp.eval(xval);

        double mFD = (y1 - y0)/epsFD;
        double m = sp.evalDerivative(xval);

        if (std::abs( mFD - m ) > 1000*epsFD)
            OPM_THROW(std::runtime_error,
                      "Derivative of spline seems to be inconsistent with cuve"
                      " (" << mFD << " - " << m << " = " << mFD - m << ")!");

        // second derivative
        y1 = sp.evalDerivative(xval+epsFD);
        y0 = sp.evalDerivative(xval);

        mFD = (y1 - y0)/epsFD;
        m = sp.evalSecondDerivative(xval);

        if (std::abs( mFD - m ) > 1000*epsFD)
            OPM_THROW(std::runtime_error,
                      "Second derivative of spline seems to be inconsistent with cuve"
                      " (" << mFD << " - " << m << " = " << mFD - m << ")!");

        // Third derivative
        y1 = sp.evalSecondDerivative(xval+epsFD);
        y0 = sp.evalSecondDerivative(xval);

        mFD = (y1 - y0)/epsFD;
        m = sp.evalThirdDerivative(xval);

        if (std::abs( mFD - m ) > 1000*epsFD)
            OPM_THROW(std::runtime_error,
                      "Third derivative of spline seems to be inconsistent with cuve"
                      " (" << mFD << " - " << m << " = " << mFD - m << ")!");
    }
}