计算方法

实例1 分段线性插值--基础版
实例2 分段线性插值--求平方

实例1 分段线性插值--基础版

核心就是两点间的线性插值公式。你需要先确定x所在的区间,然后调用该方法计算

  public static void MathAlgorithm_PiecewiseLinearInterpolation1(){

  System.out.println("----------分段线性插值1--基础版--------");
       /**
        * @param x1 第一点的x坐标
        * @param y1 第一点的y坐标
        * @param x2 第二点的x坐标
        * @param y2 第二点的y坐标
        * @param x  待插值的x值
        * @return   插值计算出的y值*/


       // 假设已知两个点 (1.0, 2.0) 和 (3.0, 4.0)
       double x1 = 1.0, x2 = 3.0;     //x坐标
       double y1 = 2.0, y2 = 4.0;     //y坐标
       
       
       double x = 2.0; // 需要估算 x=2.0 时,对应Y的值
       double y = y1 + (y2 - y1) * (x - x1) / (x2 - x1);
       System.out.println(" x = " + x + " 是 " + y);   
      // 输出结果:Interpolated value at x=2.0 is 3.0  
   }

2. 实例2 分段线性插值--求平方

调用1

PiecewiseLinearInterpolation p = new PiecewiseLinearInterpolation();
System.out.println("\n分段线性插值2-------------------单点插值");
double xi = 2.5;
double yi = p.interpolate(xi);
System.out.printf("f(%.1f) = %.4f (实际值: %.4f)%n", xi, yi, Math.pow(xi, 2));

输出结果:f(2.5) = 6.5000 (实际值: 6.2500)


调用1
System.out.println("\n分段线性插值2-------------------批量插值");
double[] xiArray = {0.5, 1.5, 2.5, 3.5, 4.5};
double[] yiArray = p.interpolate(xiArray);
System.out.println("\n批量插值结果:");
for (int i = 0; i < xiArray.length; i++) {
    System.out.printf("f(%.1f) = %.4f%n", xiArray[i], yiArray[i]);
}

输出结果:批量插值结果:
f(0.5) = 0.5000
f(1.5) = 2.5000
f(2.5) = 6.5000
f(3.5) = 12.5000
f(4.5) = 20.5000



调用3
System.out.println("\n分段线性插值2-------------------边界测试");
System.out.printf("\n左边界外推: f(-1) = %.4f%n", p.interpolate(-1));
System.out.printf("右边界外推: f(6) = %.4f%n", p.interpolate(6));

输出结果:

边界处理:小于最小值用第一个区间外推

左边界外推: f(-1) = -1.0000
边界处理:大于最大值用最后一个区间外推
右边界外推: f(6) = 34.0000

实现类

class PiecewiseLinearInterpolation{

    double[] x = {0, 1, 2, 3, 4, 5};
    double[] y = {0, 1, 4, 9, 16, 25};  // y = x²

    // 插值计算
    public double interpolate(double xi) {
        //
        if (xi <= x[0]) {

            System.out.println("边界处理:小于最小值用第一个区间外推");
            return linearInterpolate(x[0], y[0], x[1], y[1], xi);
        }
        if (xi >= x[x.length - 1]) {

            System.out.println("边界处理:大于最大值用最后一个区间外推");
            return linearInterpolate(x[x.length-2], y[x.length-2], x[x.length-1], y[x.length-1], xi);
        }

        // 找到xi所在的区间
        int index = findInterval(xi);
        return linearInterpolate(x[index], y[index], x[index+1], y[index+1], xi);
    }

    // 二分查找找到xi所在的区间索引
    private int findInterval(double xi) {
        int left = 0;
        int right = x.length - 1;

        while (left < right - 1) {
            int mid = (left + right) / 2;
            if (xi < x[mid]) {
                right = mid;
            } else {
                left = mid;
            }
        }
        return left;
    }

    // 线性插值公式
    private double linearInterpolate(double x0, double y0, double x1, double y1, double x) {

        double slope = (y1 - y0) / (x1 - x0);
        return y0 + slope * (x - x0);

    }

    // 批量插值
    public double[] interpolate(double[] xi) {
        double[] yi = new double[xi.length];
        for (int i = 0; i < xi.length; i++) {
            yi[i] = interpolate(xi[i]);
        }
        return yi;
    }
}

持续更新中

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐