gpt4 book ai didi

python - 生成线性样条的三次样条 Python 代码

转载 作者:行者123 更新时间:2023-11-28 22:03:06 26 4
gpt4 key购买 nike

编辑:我不是要你调试这段代码。如果您熟悉这个著名的算法,那么您可能会有所帮助。请注意,该算法会正确生成系数。

这段用于三次样条插值的代码正在生成线性样条,我似乎无法弄清楚原因(目前)。该算法来自 Burden 的数值分析,与伪代码几乎相同 here ,或者您可以从评论中的链接找到那本书(请参阅第 3 章,无论如何都值得拥有)。该代码正在产生正确的系数;我相信我误解了实现。非常感谢任何反馈。另外,我是编程新手,所以也欢迎任何关于我的编码有多糟糕的反馈。我尝试根据 h、a 和 c 上传线性系统的图片,但作为新用户我不能。如果你想要算法解决的三对角线线性系统的视觉效果,它是由 var alpha 建立的,请参阅本书评论中的链接,请参阅第 3 章。该系统严格对角占优势,所以我们知道那里存在唯一解 c0,...,cn。一旦我们知道 ci 值,其他系数就会随之而来。

import matplotlib.pyplot as plt

# need some zero vectors...
def zeroV(m):
z = [0]*m
return(z)

#INPUT: n; x0, x1, ... ,xn; a0 = f(x0), a1 =f(x1), ... , an = f(xn).
def cubic_spline(n, xn, a, xd):
"""function cubic_spline(n,xn, a, xd) interpolates between the knots
specified by lists xn and a. The function computes the coefficients
and outputs the ranges of the piecewise cubic splines."""

h = zeroV(n-1)

# alpha will be values in a system of eq's that will allow us to solve for c
# and then from there we can find b, d through substitution.
alpha = zeroV(n-1)

# l, u, z are used in the method for solving the linear system
l = zeroV(n+1)
u = zeroV(n)
z = zeroV(n+1)

# b, c, d will be the coefficients along with a.
b = zeroV(n)
c = zeroV(n+1)
d = zeroV(n)

for i in range(n-1):
# h[i] is used to satisfy the condition that
# Si+1(xi+l) = Si(xi+l) for each i = 0,..,n-1
# i.e., the values at the knots are "doubled up"
h[i] = xn[i+1]-xn[i]

for i in range(1, n-1):
# Sets up the linear system and allows us to find c. Once we have
# c then b and d follow in terms of it.
alpha[i] = (3./h[i])*(a[i+1]-a[i])-(3./h[i-1])*(a[i] - a[i-1])

# I, II, (part of) III Sets up and solves tridiagonal linear system...
# I
l[0] = 1
u[0] = 0
z[0] = 0

# II
for i in range(1, n-1):
l[i] = 2*(xn[i+1] - xn[i-1]) - h[i-1]*u[i-1]
u[i] = h[i]/l[i]
z[i] = (alpha[i] - h[i-1]*z[i-1])/l[i]

l[n] = 1
z[n] = 0
c[n] = 0

# III... also find b, d in terms of c.
for j in range(n-2, -1, -1):
c[j] = z[j] - u[j]*c[j+1]
b[j] = (a[j+1] - a[j])/h[j] - h[j]*(c[j+1] + 2*c[j])/3.
d[j] = (c[j+1] - c[j])/(3*h[j])

# This is my only addition, which is returning values for Sj(x). The issue I'm having
# is related to this implemention, i suspect.
for j in range(n-1):
#OUTPUT:S(x)=Sj(x)= aj + bj(x - xj) + cj(x - xj)^2 + dj(x - xj)^3; xj <= x <= xj+1)
return(a[j] + b[j]*(xd - xn[j]) + c[j]*((xd - xn[j])**2) + d[j]*((xd - xn[j])**3))

对于无聊的人,或者成就超群的人......

这里是测试代码,区间为x: [1, 9], y:[0, 19.7750212]。测试函数是 xln(x),所以我们从 1 开始,然后增加 .1,直到 9。

ln = [] 
ln_dom = []
cub = []
step = 1.
X=[1., 9.]
FX=[0, 19.7750212]
while step <= 9.:
ln.append(step*log(step))
ln_dom.append(step)
cub.append(cubic_spline(2, x, fx, step))
step += 0.1

...以及绘图:

plt.plot(ln_dom, cub, color='blue')
plt.plot(ln_dom, ln, color='red')
plt.axis([1., 9., 0, 20], 'equal')
plt.axhline(y=0, color='black')
plt.axvline(x=0, color='black')
plt.show()

最佳答案

好的,开始工作了。问题出在我的实现中。我用不同的方法让它工作,其中样条曲线是单独构造的,而不是连续构造的。这是功能完备的三次样条插值法,首先构造样条多项式的系数(占工作的 99%),然后实现它们。显然,这不是唯一的方法。如果有兴趣,我可能会采用不同的方法并发布。可以澄清代码的一件事是已解决的线性系统的图像,但在我的代表达到 10 之前我不能发布图片。如果您想更深入地了解算法,请参阅教科书链接上面的评论。

import matplotlib.pyplot as plt
from pylab import arange
from math import e
from math import pi
from math import sin
from math import cos
from numpy import poly1d

# need some zero vectors...
def zeroV(m):
z = [0]*m
return(z)

#INPUT: n; x0, x1, ... ,xn; a0 = f(x0), a1 =f(x1), ... , an = f(xn).
def cubic_spline(n, xn, a):
"""function cubic_spline(n,xn, a, xd) interpolates between the knots
specified by lists xn and a. The function computes the coefficients
and outputs the ranges of the piecewise cubic splines."""

h = zeroV(n-1)

# alpha will be values in a system of eq's that will allow us to solve for c
# and then from there we can find b, d through substitution.
alpha = zeroV(n-1)

# l, u, z are used in the method for solving the linear system
l = zeroV(n+1)
u = zeroV(n)
z = zeroV(n+1)

# b, c, d will be the coefficients along with a.
b = zeroV(n)
c = zeroV(n+1)
d = zeroV(n)

for i in range(n-1):
# h[i] is used to satisfy the condition that
# Si+1(xi+l) = Si(xi+l) for each i = 0,..,n-1
# i.e., the values at the knots are "doubled up"
h[i] = xn[i+1]-xn[i]

for i in range(1, n-1):
# Sets up the linear system and allows us to find c. Once we have
# c then b and d follow in terms of it.
alpha[i] = (3./h[i])*(a[i+1]-a[i])-(3./h[i-1])*(a[i] - a[i-1])

# I, II, (part of) III Sets up and solves tridiagonal linear system...
# I
l[0] = 1
u[0] = 0
z[0] = 0

# II
for i in range(1, n-1):
l[i] = 2*(xn[i+1] - xn[i-1]) - h[i-1]*u[i-1]
u[i] = h[i]/l[i]
z[i] = (alpha[i] - h[i-1]*z[i-1])/l[i]

l[n] = 1
z[n] = 0
c[n] = 0

# III... also find b, d in terms of c.
for j in range(n-2, -1, -1):
c[j] = z[j] - u[j]*c[j+1]
b[j] = (a[j+1] - a[j])/h[j] - h[j]*(c[j+1] + 2*c[j])/3.
d[j] = (c[j+1] - c[j])/(3*h[j])

# Now that we have the coefficients it's just a matter of constructing
# the appropriate polynomials and graphing.
for j in range(n-1):
cub_graph(a[j],b[j],c[j],d[j],xn[j],xn[j+1])

plt.show()

def cub_graph(a,b,c,d, x_i, x_i_1):
"""cub_graph takes the i'th coefficient set along with the x[i] and x[i+1]'th
data pts, and constructs the polynomial spline between the two data pts using
the poly1d python object (which simply returns a polynomial with a given root."""

# notice here that we are just building the cubic polynomial piece by piece
root = poly1d(x_i,True)
poly = 0
poly = d*(root)**3
poly = poly + c*(root)**2
poly = poly + b*root
poly = poly + a

# Set up our domain between data points, and plot the function
pts = arange(x_i,x_i_1, 0.001)
plt.plot(pts, poly(pts), '-')
return

如果你想测试它,这里有一些你可以用来开始的数据,这些数据来自函数 1.6e^(-2x)sin(3*pi*x) 在 0 和 1 之间:

# These are our data points
x_vals = [0, 1./6, 1./3, 1./2, 7./12, 2./3, 3./4, 5./6, 11./12, 1]

# Set up the domain
x_domain = arange(0,2, 1e-2)

fx = zeroV(10)

# Defines the function so we can get our fx values
def sine_func(x):
return(1.6*e**(-2*x)*sin(3*pi*x))

for i in range(len(x_vals)):
fx[i] = sine_func(x_vals[i])

# Run cubic_spline interpolant.
cubic_spline(10,x_vals,fx)

关于python - 生成线性样条的三次样条 Python 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9866724/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com