edit: Je ne cherche pas à déboguer ce code. Si vous connaissez cet algorithme bien connu, vous pourrez peut-être aider. Veuillez noter que l'algorithme produit correctement les coefficients.Cubic Spline Python code produisant des splines linéaires
Ce code pour l'interpolation spline cubique produit des splines linéaires et je n'arrive pas à comprendre pourquoi (pour l'instant). L'algorithme provient de Burden's Numerical Analysis, qui est à peu près identique au pseudo code here, ou vous pouvez trouver ce livre à partir d'un lien dans les commentaires (voir le chapitre 3, ça vaut le coup de le faire quand même). Le code produit les coefficients corrects; Je crois que je me méprends sur la mise en œuvre. Tout commentaire est grandement apprécié. De plus, je suis novice en programmation, donc tout commentaire sur la qualité de mon codage est également le bienvenu. J'ai essayé de télécharger des photos du système linéaire en termes de h, a et c, mais en tant que nouvel utilisateur, je ne peux pas. Si vous voulez un visuel du système linéaire tridiagonal que l'algorithme résout, et qui est mis en place par la var alpha, voir le lien dans les commentaires pour le livre, voir le chapitre 3. Le système est strictement diagonalement dominant, nous savons donc existe une solution unique c0, ..., cn. Une fois que nous connaissons les valeurs ci, les autres coefficients suivent.
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))
Pour l'ennuyer ou overachieving ...
Voici le code pour le test, l'intervalle est x: [1, 9], y: [0, 19,7750212]. La fonction de test est XLN (x), donc nous commençons 1 et augmenter de 0,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
... et pour le traçage:
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()
Avez-vous essayé de déboguer le programme? Passer à travers avec un débogueur? Insérer des instructions d'impression de débogage? Si vous ne montrez aucun effort, personne ne va lire tout ce code et le déboguer pour vous. –
Aucun effort? Cela a été des heures et des heures de travail. J'ai essayé de rendre le message simple et précis. J'ai fait des tonnes de débogage. Im cherchant l'aide de quelqu'un avec l'expérience avec l'interpolation cubique de spline, b/c n'importe qui qui l'a fait connaît déjà ce code. C'est le même algorithme que tout le monde utilise. Je ne cherche pas quelqu'un pour franchir ligne par ligne, comme je l'ai dit, les coefficients sont calculés correctement. – daniel
Il me semble que vous interpolez entre deux points seulement: 'X = [1., 9.]'. Si c'est le cas, pourquoi attendriez-vous autre chose qu'une ligne droite? –