固定样条曲线上的边界值?

问题描述 投票:0回答:1

我有数据 x 和 y,它们是函数 f:[0,alpha] -> [0,1] 的噪声评估。除了 f(0) = 0 和 f(alpha) = 1 之外,我对我的函数知之甚少。

在拟合样条线时有什么方法可以强制执行这些边界条件吗?

这是一张图片,可以看到样条曲线拟合得很好,但近似值在 0 左右很差,它的值约为 0.08:plot of function

我知道各种样条线的 bc_type ,但据我所知,这仅允许指定一阶和二阶导数,而不是固定边界值。

(可能这个问题暴露了我对样条线如何拟合的无知,并且我所要求的东西是不可能的。我只是想确保我没有遗漏一些明显的东西。)

这是一个玩具示例:

    import numpy as np
    from scipy.interpolate import UnivariateSpline
    import matplotlib.pyplot as plt

    ## Generate noisy evaluations of the square root function.
    ## (In my exmaple, I don't have a closed form expression for my function)

    x = np.linspace(0,1,1000)
    y = np.sqrt(x) + (np.random.random(1000)-0.5)*0.05
    
    ## Fit spline
    
    spline = UnivariateSpline(x,y)
    
    plt.figure(figsize=(7,7))
    plt.scatter(x,y,s=1,label="Monte Carlo samples")
    plt.plot(x,spline(x),color='red',label="spline")
    plt.legend()
    plt.title("Noisy evaluations of sqrt")
    plt.grid()
    plt.show()

结果图,可以很好地看到样条曲线在零附近提供了一个较差的近似值:

enter image description here

python scipy interpolation spline approximation
1个回答
0
投票

拟合此函数的一个想法是 f(0) = 0 和 f(1) = 1 只是对函数的观察。当然,它们是你比其他人更确定的观察结果,但它们仍然只是观察结果。

UnivariateSpline 接受参数

w
,以赋予特定观察更多权重。 “强制”这些边界条件的一种方法是将这些点添加为常规但权重较高的点。

import numpy as np
from scipy.interpolate import UnivariateSpline
import matplotlib.pyplot as plt
## Generate noisy evaluations of the square root function.
## (In my exmaple, I don't have a closed form expression for my function)

x = np.linspace(0,1,1000)
y = np.sqrt(x) + (np.random.random(1000)-0.5)*0.05


# Add fixpoints to function
fixpoint_weight = 1000
fixpoints = np.array([
    #X, Y
    (0, 0),
    (1, 1),
]).T
x_with_fixpoints = np.concatenate([x, fixpoints[0]])
y_with_fixpoints = np.concatenate([y, fixpoints[1]])
weights = np.ones(len(x_with_fixpoints))
weights[-fixpoints.shape[1]:] = fixpoint_weight
# x must be increasing - sort x, y, and weights by x
sort_order = x_with_fixpoints.argsort()
x_with_fixpoints = x_with_fixpoints[sort_order]
y_with_fixpoints = y_with_fixpoints[sort_order]
weights = weights[sort_order]

## Fit spline
spline = UnivariateSpline(x_with_fixpoints, y_with_fixpoints, w=weights, s=0.5)

plt.figure(figsize=(7,7))
plt.scatter(x,y,s=1,label="Monte Carlo samples")
plt.plot(x,spline(x),color='red',label="spline")
plt.legend()
plt.title("Noisy evaluations of sqrt")
plt.grid()
plt.show()
print(spline(0) - 0, spline(1) - 1)

fitted curve

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.