Hi, I noticed that a LinearInterpolator1D will always return a value of 0 for the derivative at/outside the right boundary of the model you give it, and I don’t think this is correct. It looks to me like it is assumed that the model is a right-open interval and so assumes that the point cannot be interpolated, but this isn’t true/explicitly known.

I think it should either use the previous bounded values (this is continous), or better allow subclassing to define boundary behaviour (this can have all sorts of crazy numerical scheming applied, e.g. blending), or at least throw an UnsupportedOperationException (instead of happily returning a duff value).

One can reproduce the above simply by creaing a InterpolatedDoublesCurve for the line y=x and calculating dy/dx - note that its value is 1 everywhere, except at the right boundary.

In general interpolators are only valid within the bounds they are given, outside of that region you want an extrapolator (they actually have the same interface but work differently).

You can create a combined interpolator and extrapolator combination by using com.opengamma.analytics.math.interpolation.CombinedInterpolatorExtrapolatorFactory, here you can specify different extrapolators for the left and right side of your region if needed.

Sure, I understand the difference between an interpolator and an extrapolator (I have done a lot of work in the past on numerical boundary conditions for wave-like equations). But it still remains that there are problems with the OpenGamma implementations:

The provided interpolators quite happily interpolate the point on the left boundary - it’s just the point on the right boundary where many of them (note just the linear ones) have problems - hence my original comment about an (unwritten?) assumption that we are always interpolating a left-closed, right-open interval.

An interpolator that tries to inappropriately interpolate something outside of its domain shouldn’t return 0; it should arguably throw an exception instead.

If given the point on the right boundary, the CombinedInterpolatorExtrapolatorFactory will use the interpolator, since it is not strictly greater than the last key in the data bundle. Hence it will return an incorrect value for dy/dx.

Here is some example code to illustrate - add the following as a new test to CombinedInterpolatorExtrapolatorTest. Note that it will fail on the right boundary (x=9) because it erroneously returns zero, although everywhere else (e.g. at x=8.9,9.1) it evaluates to 3.

@Test
public void testBoundary() {
for (final double value : X) {
assertEquals("dy/dx at " + value, 3d, COMBINED3.firstDerivative(DATA, value), 1e-4);
}
}