Interpolation over an array (or two)

后端 未结 8 619
闹比i
闹比i 2020-12-10 15:27

I\'m looking for a java library or some help to write my own interpolation function. That is I have two arrays of doubles which are potentially different sizes, but are ord

相关标签:
8条回答
  • 2020-12-10 16:14

    Designed for ONE Dimension data array

    import java.util.ArrayList;
    
    public class Interpolator {
    
    public static Float CosineInterpolate(Float y1,Float y2,Float mu)
    {
        double mu2;
    
        mu2 = (1.0f-Math.cos(mu*Math.PI))/2.0f;
        Float f_mu2 = new Float(mu2);
        return(y1*(1.0f-f_mu2)+y2*f_mu2);
    }
    
    public static Float LinearInterpolate(Float y1,Float y2,Float mu)
    {
        return(y1*(1-mu)+y2*mu);
    }
    
    
    public static Float[] Interpolate(Float[] a, String mode) {
    
        // Check that have at least the very first and very last values non-null
        if (!(a[0] != null && a[a.length-1] != null)) return null;
    
        ArrayList<Integer> non_null_idx = new ArrayList<Integer>();
        ArrayList<Integer> steps = new ArrayList<Integer>();
    
        int step_cnt = 0;
        for (int i=0; i<a.length; i++)
        {
            if (a[i] != null)
            {
                non_null_idx.add(i);
                if (step_cnt != 0) {
                    steps.add(step_cnt);
                    System.err.println("aDDed step >> " + step_cnt);
                }
                step_cnt = 0;
            }
            else
            {
                step_cnt++;
            }
        }
    
        Float f_start = null;
        Float f_end = null;
        Float f_step = null;
        Float f_mu = null;
    
        int i = 0;
        while (i < a.length - 1) // Don't do anything for the very last element (which should never be null)
        {
            if (a[i] != null && non_null_idx.size() > 1 && steps.size() > 0)
            {
                f_start = a[non_null_idx.get(0)];
                f_end = a[non_null_idx.get(1)];
                f_step = new Float(1.0) / new Float(steps.get(0) + 1);
                f_mu = f_step;
                non_null_idx.remove(0);
                steps.remove(0);
            }
            else if (a[i] == null)
            {
                if (mode.equalsIgnoreCase("cosine"))
                    a[i] = CosineInterpolate(f_start, f_end, f_mu);
                else
                    a[i] = LinearInterpolate(f_start, f_end, f_mu);
                f_mu += f_step;
            }
            i++;
        }
    
        return a;
    }
    }
    

    Don't know if it helps... It is very fast coded, so if anyone has a nicer / more performing way to do the same, thank for contributing.

    USAGE:

    input : Float[] a = {1.0f, null, null, 2.0f, null, null, null, 15.0f};
    
    call : Interpolator.Interpolate(a, "Linear");
    
    output : 1.0|1.3333333|1.6666667|2.0|5.25|8.5|11.75|15.0
    
    0 讨论(0)
  • 2020-12-10 16:21

    You need to get the x-values corresponding to the y-values. Otherwise no algorithm will be able to determine whether [1, 16, 81] is x^2 for [1, 4, 9] or x^4 for [1, 2, 3]. Would you interpolate six values or none?

    And then, when you're given the x-values, you can use some sort of interpolation (linear, kubic spline, you name it) to approximate the missing values.

    0 讨论(0)
提交回复
热议问题