You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

均值保持二次插值的不稳定实现问题问询

均值保持二次插值的数值稳定性问题

我一直在寻找高效的均值保持二次插值计算方法,但始终没有找到合适的方案。于是我用Python构建了一个线性方程组系统,可即便输入完全平坦的数组,该系统仍存在数值不稳定的问题。

模型设定

每个数据分箱宽度为1,分箱值等于二次多项式在该分箱上的积分,即:

Int(a_i+b_ix+c_ix^2,{dx,x-1/2,x+1/2})=data[x,i, x=i]=a_i+b_ix+c_i*(x^2+1/12)

同时设置了相邻分箱间的两个匹配条件:

  • 数值匹配:
a_i+b_i*(x+1/2)+c_i*(x+1/2)^2=a_{i+1}+b_{i+1}*(x+1/2)+c_{i+1}*(x+1/2)^2
  • 斜率匹配条件(对应多项式导数在分箱边界相等)

样条节点绑定在±1/2处,第一个分箱的负端自由,最后一个分箱定义边界条件。对于长度为n的数据集,我构建了3n个方程和3n个变量,np.linalg.solve()可以处理该系统,但所有输入数据集的结果均不稳定,输入[1,2,3]时直接失效,方程组根本无法正确求解。

我期望integro_quadratic_spline_orig函数在输入integro_quadratic_spline(I)的输出后能返回原数组I,但实际结果偏差极大。

实现代码

import numpy as np
import scipy as sp

def integro_quadratic_spline(I):
    # 区间数量
    n = len(I)

    # 初始化系数数组
    a = np.zeros(n)
    b = np.zeros(n)
    c = np.zeros(n)

    # 构建方程组矩阵与结果向量
    A = sp.sparse.csr_array((3*n, 3*n))
    B = np.zeros(3*n)

    # 填充方程组:积分条件、斜率连续、数值连续
    for i in range(0,n-1):
        # 积分匹配条件:分箱积分等于原数据值
        A[3*(i),3*(i):3*(i)+6]=[1,(i),(i)**2+1/12,0,0,0]
        # 斜率连续条件:当前分箱右边界斜率等于下一分箱左边界斜率
        A[3*(i)+1,3*(i):3*(i)+6]=[0,1,2*(i+1/2),0,-1,-2*(i+1/2)]
        # 数值连续条件:当前分箱右边界值等于下一分箱左边界值
        A[3*(i)+2,3*(i):3*(i)+6]=[1,i+1/2,(i+1/2)**2,-1,-(i+1/2),-(i+1/2)**2]
        B[3*(i)]=I[i]
        B[3*(i)+1]=0
        B[3*(i)+2]=0
    # 处理最后一个分箱的边界条件
    i=i+1    
    A[3*(i),3*(i):3*(i)+3]=[1,(i),(i)**2+1/12]
    A[3*(i)+1,3*(i):3*(i)+3]=[0,1,2*(i+1/2)]
    A[3*(i)+2,3*(i):3*(i)+3]=[1,i+1/2,(i+1/2)**2]
    B[3*(i)]=I[i]
    B[3*(i)+1]=0
    B[3*(i)+2]=I[i]

    # 求解方程组
    coeffs = sp.sparse.linalg.spsolve(A, B)
    print(np.allclose(np.dot(A.toarray(), coeffs), B))

    # 提取各分箱的多项式系数
    for i in range(n):
        a[i] = coeffs[3*i]
        b[i] = coeffs[3*i+1]
        c[i] = coeffs[3*i+2]

    return a, b, c


def integro_quadratic_spline_return(coeffs, mag):
    original_length = len(coeffs[0])
    new_length=original_length*mag
    newplot=np.empty(new_length)
    # 根据系数生成高分辨率插值结果
    for i in range(original_length):
        for j in range(int(mag)):
            newplot[mag*i+j]=coeffs[0][i]+coeffs[1][i]*(i+j/mag-1/2)+coeffs[2][i]*(i+j/mag-1/2)**2

    return newplot

def integro_quadratic_spline_orig(coeffs):
    original_length = len(coeffs[0])
    newplot=np.empty(original_length)
    # 尝试从系数还原原分箱值
    for i in range(original_length):
        newplot[i]=coeffs[0][i]+coeffs[1][i]*(i)+coeffs[2][i]*((i)**2-12)

    return newplot

内容的提问来源于stack exchange,提问作者Matt Reed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 14:37:18