Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 阵列(或两个)上的插值_Java_Dataset_Interpolation - Fatal编程技术网

Java 阵列(或两个)上的插值

Java 阵列(或两个)上的插值,java,dataset,interpolation,Java,Dataset,Interpolation,我正在寻找一个java库或一些帮助来编写我自己的插值函数。也就是说,我有两个double数组,它们可能大小不同,但是是有序的。我需要能够估计中间值,并进行插入,以便两个数组的大小相同。事实上,插值中出现的总点数是两个数组大小之和减去1。但是,每个阵列的范围必须保持不变,因此不需要外推 a1=[1,4,9,16,25,36]和a2=[6,9,14,30] 结果可能是 a1=[1,2.25,4,6.25,9,12.25,16,25,36] 和 a2=[6,6.5625,7.25,9,10.0625,

我正在寻找一个java库或一些帮助来编写我自己的插值函数。也就是说,我有两个double数组,它们可能大小不同,但是是有序的。我需要能够估计中间值,并进行插入,以便两个数组的大小相同。事实上,插值中出现的总点数是两个数组大小之和减去1。但是,每个阵列的范围必须保持不变,因此不需要外推

a1=[1,4,9,16,25,36]和a2=[6,9,14,30]

结果可能是

a1=[1,2.25,4,6.25,9,12.25,16,25,36] 和 a2=[6,6.5625,7.25,9,10.0625,11.25,14,25.25,30]


这些例子是
f(x)=x^2和g(x)=x^2+5
,但是很可能是任何多项式-关键是能够从数据集很好地估计/近似函数,以提供足够好的插值。这里的x值只是输入数组的索引。在输出中,只有y值是重要的。

简单的线性插值可以使用以下方法计算:

Point2D interp1_lin(Point2D p1, Point2D p2, double x) {
 //Pre conditions
assert p1.x<x;
assert x<p2.x;
//Calculate slope from p1 to p2
double m = (p2.x-p1.x)/(p2.y-p1.y);
//Calculate y position of x
double y = (x-p1.x)*m+p1.y;
//create new point
return new Point2D.Double(x,y);
}
Point2D接口(Point2D p1、Point2D p2、双x){
//先决条件

断言p1.x您需要获得对应于y值的x值。否则,没有算法能够确定[1,16,81]是[1,4,9]的x^2还是[1,2,3]的x^4。您是插值六个值还是不插值


然后,当你得到x值时,你可以使用某种插值(线性,kubic样条,你可以说)来近似缺少的值。

其他答案给你线性插值——这些插值对复杂的非线性数据并不有效。我想你需要一种,(样条插值)。

样条拟合使用数据中的一组控制点来描述数据区域,然后在控制点之间应用多项式插值。控制点越多,拟合越精确。样条拟合比线性拟合精确得多,使用速度比一般回归拟合快,比高阶拟合好因为它不会在控制点之间做疯狂的事情

我一时记不起名字,但Java中有一些非常适合的库——我建议您寻找一个,而不是编写自己的函数


**编辑:可能有用的库:**

  • (希望你能读德语)
**可能有用的理论/代码:**

  • 带代码的样条线小程序:
  • 多边形线到bezier样条曲线的样条曲线拟合
  • 样条曲线,以及一些拟合的数学。如果库不这样做,更多的数学,更少的代码可能会有所帮助

专为一维数据阵列设计

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;
}
}

我知道这是一个古老的答案,但这是谷歌搜索Java插值时的第一个成功答案。公认的答案提供了一些有用的链接,但必须购买JMSL,而且JSpline+网站看起来很粗略

ApacheCommonsMath提供了线性插值和样条插值的实现,这些实现看起来简单、功能强大且值得信赖


重量轻的一维阵列线性插值器:

public static float[] interpolate(float[] data) {
    int startIdx = -1;
    float startValue = 0f;
    float element;
    for (int i = 0; i < data.length - 1; i++) {
        element = data[i];
        if (element != 0f) {
            if (startIdx != -1) {
                doInterpolate(startValue, element, startIdx + 1, i - startIdx - 1, data);
            }
            startValue = element;
            startIdx = i;
        }
    }
    return data;
}

private static void doInterpolate(float start, float end, int startIdx, int count, float[] data) {
    float delta = (end - start) / (count + 1);
    for (int i = startIdx; i < startIdx + count; i++) {
        data[i] = start + delta * (i - startIdx + 1);
    }
}
公共静态浮点[]插值(浮点[]数据){
int startIdx=-1;
浮动起始值=0f;
浮动元件;
对于(int i=0;i
使用样条拟合和多项式拟合时要非常小心。这两种拟合可能会产生荒谬的行为,可能会破坏数据的许多用途(据信是数据的表示)

任何使用数据导数(斜率)的东西都可能完全出轨

您可以做的最好的事情是绘制数据,了解它在做什么,然后拟合(线性、多项式、对数)回归;一旦这样做,您应该绘制原始数据的拟合图,并确保您看到合理的一致性。跳过此比较步骤是一个非常糟糕的主意


某些数据集不会屈服于多项式、对数等的拟合;如果数据点在数据范围内适当分布,则分段插值(线性或多项式等)没有问题。要想打败一匹死马,如果你使用分段插值,请避免使用分段插值的导数/斜率,因为它会有不连续性,并会导致事情表现不好。

你可以使用插值,例如

你的问题有点不清楚。你能给我们一个简单的具体例子吗?我已经编辑过举个例子,虽然它不一定是一个函数可以给出的输出,但我认为它展示了一个可接受的输出。好的,我没有正确地思考我的例子-假设每个数组索引都是输入的x值-然后在插值之后,我们对x值不再感兴趣。是的,这正是我想要的之后…更具体地说,这些库是什么和在哪里。我添加了一些库的链接,如果库没有,则使用code+theory来处理样条线。如果对您有帮助,请不要忘记接受答案!还有专门用于此目的的LinerarInterpolator。返回空值。
public static float[] interpolate(float[] data) {
    int startIdx = -1;
    float startValue = 0f;
    float element;
    for (int i = 0; i < data.length - 1; i++) {
        element = data[i];
        if (element != 0f) {
            if (startIdx != -1) {
                doInterpolate(startValue, element, startIdx + 1, i - startIdx - 1, data);
            }
            startValue = element;
            startIdx = i;
        }
    }
    return data;
}

private static void doInterpolate(float start, float end, int startIdx, int count, float[] data) {
    float delta = (end - start) / (count + 1);
    for (int i = startIdx; i < startIdx + count; i++) {
        data[i] = start + delta * (i - startIdx + 1);
    }
}