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 << ")!"); } }