javamathapache-commonssplineapache-commons-math

1D Array resizing with Spline Functions using Apache Math - How to?


I am looking for an example on resizing an 1D array using the Spline Functions with the Apache Commons - Math.

What I need is a method to expand and/or shrink the input array (double[]).

I could not find a good example trying to search online.


Solution

  • The trick here is that you need two arrays to create a spline but you only have one. Thus you need to fabricate an array. You can assume that the input array contains your y values and that the new fabricated array contains your x values so for any given x you have a corresponding y.

    Disclaimer, I have not tested this code so make sure to adjust accordingly.

    // To expand the array
    public static double[] expand(double[] array, int newSize) {
    
        final int length = array.length;
    
        // let's calculate the new step size
        double step = (double) length / (newSize + 1);
    
        // fabricated array of x values
        double[] x = new double[length];
        for(int i = 0; i < length; ++i) {
            x[i] = i;
        }
    
        // using Linear interpolator but it can be any other interpolator
        LinearInterpolator li = new LinearInterpolator(); // or other interpolator
        PolynomialSplineFunction psf = li.interpolate(x, array);
    
        double[] expandedArray = new double[newSize];
        double xi = x[0];
        for (int i = 0; i < newSize - 1; ++i) {
           expandedArray[i] = psf.value(xi);
           xi += step;
        }
        expandedArray[newSize - 1] = array[length - 1];
        return expandedArray;
    }
    

    To shrink the array you can either decimate the input array i.e. just create a new smaller array and just take the values based on the new step size or use an interpolator as before:

    // To shrink the array
    public static double[] shrink(double[] array, int newSize) {
    
        final int length = array.length;
    
        // let's calculate the new step size
        double step = (double) length / (newSize - 1);
    
        // fabricated array of x values
        double[] x = new double[length];
        for(int i = 0; i < length; ++i) {
            x[i] = i;
        }
    
        // using Linear interpolator but it can be any other interpolator
        LinearInterpolator li = new LinearInterpolator(); // or other interpolator
        PolynomialSplineFunction psf = li.interpolate(x, array);
    
        double[] expandedArray = new double[newSize];
        double xi = x[0];
        for (int i = 0; i < newSize - 1; ++i) {
           expandedArray[i] = psf.value(xi);
           xi += step;
        }
        expandedArray[newSize - 1] = array[length - 1];
        return expandedArray;
    }