Commons Math
  1. Commons Math
  2. MATH-985

BicubicSpline interpolation returns unexpected values (BicubicSplineInterpolator/BicubicSplineInterpolationFunction)

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.1.1
    • Fix Version/s: 3.3
    • Labels:
      None
    • Environment:

      Windows 7 64 bit, 64 bit JVM

      Description

      I've been testing out the Tricubic spline functions, and have been getting some strange values. I dug down a bit, and it seems like they start at the Bicubic level. SplineInterpolator/PolynomialSplineFunction seem to be returning correct values. I set up a block of data that increases linearly, so you'd expect the interpolated values to follow the same trend, except the values tend to overshoot to half the distance between knot points, and then undershoot for the remaining half. Probably the easiest thing would be to show some tests. First - 1D which works fine:

      SplineTest.java
      import org.apache.commons.math3.analysis.interpolation.SplineInterpolator;
      import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction;
      
      public class SplineTest {
      
      	double[] x = new double[]{.52,.54,.56,.58,.6};
      	double[] y = new double[]{76,77,78,79,80};
      	
      	public static void main(String[] args){
      		SplineTest st = new SplineTest();
      		st.go();
      	}
      	
      	public void go(){
      		SplineInterpolator si = new SplineInterpolator();
      		PolynomialSplineFunction sf = si.interpolate(x, y);
      		
      		System.out.println(sf.value(0.52));
      		System.out.println(sf.value(0.5225));
      		System.out.println(sf.value(0.525));
      		System.out.println(sf.value(0.5275));
      		System.out.println(sf.value(0.53));
      		System.out.println(sf.value(0.5325));
      		System.out.println(sf.value(0.535));
      		System.out.println(sf.value(0.5375));
      		System.out.println(sf.value(0.54));
      		System.out.println(sf.value(0.5425));
      		System.out.println(sf.value(0.545));
      		System.out.println(sf.value(0.5475));
      		System.out.println(sf.value(0.55));
      		System.out.println(sf.value(0.5525));
      		System.out.println(sf.value(0.555));
      		System.out.println(sf.value(0.5575));
      		System.out.println(sf.value(0.56));
      	}
      }
      

      and next, 2D which doesn't:

      BicubicSplineTest.java
      import org.apache.commons.math3.analysis.interpolation.BicubicSplineInterpolatingFunction;
      import org.apache.commons.math3.analysis.interpolation.BicubicSplineInterpolator;
      
      public class BicubicSplineTest {
      
      	double[] x = new double[]{0,1,2};
      	double[] y = new double[]{.52,.54,.56,.58,.6};
      	double[] v1 = new double[]{76,77,78,79,80};
      	double[][] v2 = new double[][]{v1,v1,v1};
      	
      	public static void main(String[] args){
      		BicubicSplineTest bt = new BicubicSplineTest();
      		bt.go();
      	}
      	
      	public void go(){
      		BicubicSplineInterpolator bi = new BicubicSplineInterpolator();
      		BicubicSplineInterpolatingFunction bf = bi.interpolate(x, y, v2);
      		
      		System.out.println(bf.value(1, 0.52));
      		System.out.println(bf.value(1, 0.5225));
      		System.out.println(bf.value(1, 0.525));
      		System.out.println(bf.value(1, 0.5275));
      		System.out.println(bf.value(1, 0.53));
      		System.out.println(bf.value(1, 0.5325));
      		System.out.println(bf.value(1, 0.535));
      		System.out.println(bf.value(1, 0.5375));
      		System.out.println(bf.value(1, 0.54));
      		System.out.println(bf.value(1, 0.5425));
      		System.out.println(bf.value(1, 0.545));
      		System.out.println(bf.value(1, 0.5475));
      		System.out.println(bf.value(1, 0.55));
      		System.out.println(bf.value(1, 0.5525));
      		System.out.println(bf.value(1, 0.555));
      		System.out.println(bf.value(1, 0.5575));
      		System.out.println(bf.value(1, 0.56));
      	}
      }
      

      The data points increase from 76 to 80 in a linear way. Incrementing by 1/8 the distance to the next point, the 1D spline returns:

      76.0
      76.125
      76.25
      76.375
      76.5
      76.625
      76.75
      76.875
      77.0
      77.125
      77.25
      77.375
      77.5
      77.625
      77.75
      77.875
      78.0

      The 2D spline returns:

      76.0
      80.14453124999996
      80.84375000000003
      79.24609375000007
      76.50000000000003
      73.75390625000007
      72.15625000000001
      72.85546874999996
      76.99999999999997
      81.14453124999993
      81.84374999999997
      80.24609375000006
      77.50000000000003
      74.75390625000009
      73.15625000000004
      73.85546874999997
      78.0

      Even though it's still effectively a 1D problem. I'm not sure exactly what's causing it - maybe something when multiplying the coefficients, but thought I should flag it.

        Issue Links

          Activity

          Hide
          Gilles added a comment -

          [...] thought I should flag it.

          Thanks a lot!

          There was an indexing bug (I'm sorry for that) which is now fixed (revision 1488145).

          Show
          Gilles added a comment - [...] thought I should flag it. Thanks a lot! There was an indexing bug (I'm sorry for that) which is now fixed (revision 1488145).
          Hide
          Gilles added a comment -

          I've attached a plot of your example, comparing the old and new code.

          There are still discrepancies with the original data, but this happens "only" on the border of the interpolation range. I don't know whether this is expected or not.

          I'm going to replace the unit tests that now fail; that they succeeded with a buggy code proves their uselessness . You are warmly welcome to suggest some tests that properly demonstrate expectations from this algorithm.

          Show
          Gilles added a comment - I've attached a plot of your example, comparing the old and new code. There are still discrepancies with the original data, but this happens "only" on the border of the interpolation range. I don't know whether this is expected or not. I'm going to replace the unit tests that now fail; that they succeeded with a buggy code proves their uselessness . You are warmly welcome to suggest some tests that properly demonstrate expectations from this algorithm.
          Hide
          Gilles added a comment -

          Unit test classes that currently contain "@Ignore"d tests (which should be replaced):

          • BicubicSplineInterpolatingFunctionTest
          • TricubicSplineInterpolatorTest
          • BicubicSplineInterpolatorTest
          Show
          Gilles added a comment - Unit test classes that currently contain "@Ignore"d tests (which should be replaced): BicubicSplineInterpolatingFunctionTest TricubicSplineInterpolatorTest BicubicSplineInterpolatorTest
          Hide
          Gilles added a comment -

          New unit tests in "BicubicSplineInterpolatingFunctionTest" (r1488256).

          TBD is whether the tolerances for the tests to pass (i.e. the error on the interpolated values) are correct for this kind of interpolation.

          Show
          Gilles added a comment - New unit tests in "BicubicSplineInterpolatingFunctionTest" (r1488256). TBD is whether the tolerances for the tests to pass (i.e. the error on the interpolated values) are correct for this kind of interpolation.
          Hide
          Gilles added a comment -

          New unit tests in "BicubicSplineInterpolatorTest" (r1488417).

          Show
          Gilles added a comment - New unit tests in "BicubicSplineInterpolatorTest" (r1488417).
          Hide
          Thomas Neidhart added a comment -

          Can this issue be closed?

          Show
          Thomas Neidhart added a comment - Can this issue be closed?
          Hide
          Johnathan Kool added a comment -

          I believe so - it's been a while since I checked it. I'd say go ahead and close it. If anything else crops up, I'll generate a new ticket.

          Thanks!

          Dr. Johnathan Kool
          Marine Ecologist | Coastal, Marine and Climate Change
          Environmental Geoscience Division | GEOSCIENCE AUSTRALIA

          Show
          Johnathan Kool added a comment - I believe so - it's been a while since I checked it. I'd say go ahead and close it. If anything else crops up, I'll generate a new ticket. Thanks! Dr. Johnathan Kool Marine Ecologist | Coastal, Marine and Climate Change Environmental Geoscience Division | GEOSCIENCE AUSTRALIA
          Hide
          Thomas Neidhart added a comment -

          Added changelog entry in r1561510.

          For the remaining tests which are ignored atm I would suggest to create a separate ticket.

          Show
          Thomas Neidhart added a comment - Added changelog entry in r1561510. For the remaining tests which are ignored atm I would suggest to create a separate ticket.
          Hide
          Luc Maisonobe added a comment -

          Closing all resolved issue now available in released 3.3 version.

          Show
          Luc Maisonobe added a comment - Closing all resolved issue now available in released 3.3 version.

            People

            • Assignee:
              Unassigned
              Reporter:
              Johnathan Kool
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development