In [48]:
# Import modules
import sys
import math
import numpy as np
from matplotlib import pyplot as plt
from scipy import linalg
In [71]:
def newton_divided_diff(X, Y, n):
V = {}
for j in range(n):
V[j, 0] = Y[j]
for i in range(1,n):
for j in range(n-i):
V[j, i] = (V[j+1, i-1] - V[j, i-1]) / (X[j+i] - X[j])
C = np.zeros(n)
for i in range(n):
C[i] = V[0,i]
return C
In [72]:
X = [0, 1, 2, 3]
Y = [2, 1, 0, -1]
C = newton_divided_diff(X, Y, 4)
print(C)
In [73]:
def chebyshev_interpolation_nodes(a, b, n):
X = np.zeros(n)
for i in range(1,n + 1):
X[i - 1] = (b + a) / 2 + (b - a) / 2 * math.cos( (2 * i - 1) * math.pi / (2 * n) )
return X
In [145]:
def interpolating_polynomial(X, Y, x):
while x >= math.pi * 2:
x -= (2 * math.pi)
C = newton_divided_diff(X, Y, X.size)
poly = 0
for i in range(C.size):
mul = 1
for j in range(0, i):
mul *= (x - X[j])
poly += (C[i] * mul)
return poly
In [292]:
X = chebyshev_interpolation_nodes(0, 2 * math.pi, 8)
Y = np.sin(X)
In [293]:
x = 1
poly = interpolating_polynomial(X, Y, x)
print('chebyshev : %.15f' %poly)
print('real sin : %.15f' %math.sin(x))
print('error : %.15f' %abs(math.sin(x) - poly))
In [294]:
pX = np.linspace(0, 2 * math.pi, 1024)
pY = np.zeros(1024)
for i in range(pX.size):
pY[i] = interpolating_polynomial(X, Y, pX[i])
real_sin_y = np.sin(pX)
error_y = real_sin_y - pY
plt.subplot(211)
plt.title('real vs chebyshev interpolation $\sin{(x)}$')
plt.plot(pX, pY, color='b',linewidth=2)
plt.plot(pX, real_sin_y, color='r', linestyle='--',linewidth=2)
plt.grid(True)
plt.subplot(212)
plt.plot(pX, error_y, color='g', linewidth=2)
plt.grid(True)
plt.show()
In [3]:
def natural_cubic_spline(X, Y):
A = np.zeros(X.size - 1, dtype=float)
for i in range(X.size - 1):
A[i] = Y[i]
delta = np.zeros(X.size - 1, dtype=float)
Delta = np.zeros(X.size - 1, dtype=float)
for i in range(1, X.size):
delta[i - 1] = X[i] - X[i - 1]
Delta[i - 1] = Y[i] - Y[i - 1]
Mat = np.zeros(X.size * X.size, dtype=float).reshape(X.size, X.size)
Mat[0][0] = Mat[X.size - 1][X.size - 1] = 1.0
for i in range(1, X.size - 1):
Mat[i][i] = 2 * (delta[i - 1] + delta[i]) #diagonal
Mat[i][i - 1] = delta[i - 1]
Mat[i][i + 1] = delta[i]
b = np.zeros(X.size, dtype=float)
for i in range(1,X.size - 1):
b[i] = 3 * (Delta[i]/delta[i] - Delta[i - 1]/delta[i - 1])
# Solve the equations systems
lu, piv = linalg.lu_factor(Mat)
C = linalg.lu_solve([lu, piv], b)
D = np.zeros(X.size - 1, dtype=float)
B = np.zeros(X.size - 1, dtype=float)
for i in range(1, X.size):
D[i - 1] = (C[i] - C[i - 1]) / (3 * delta[i - 1])
B[i - 1] = Delta[i - 1] / delta[i - 1] - delta[i - 1] * (2 * C[i - 1] + C[i]) / 3
return A, B, C, D
In [126]:
X = np.array([0, 1, 2])
Y = np.array([3, -2, 1])
A, B, C, D = natural_cubic_spline(X, Y)
S = lambda x, i : A[i] + B[i] * (x - X[i]) + C[i] * pow(x - X[i], 2) + D[i] * pow(x - X[i], 3)
total = 200
pX = np.linspace(0,2,total)
pY = np.zeros(total)
for i in range(pX.size):
x = pX[i]
for j in range(X.size - 1):
if x <= X[j + 1]:
pY[i] = S(x, j)
break
else:
continue
plt.plot(pX,pY,color='b')
plt.plot(X,Y,'ro')
plt.show()
In [4]:
X = np.array([0, 1, 2, 3, 4, 5])
Y = np.array([3, 1, 4, 1, 2, 0])
A, B, C, D = natural_cubic_spline(X, Y)
S = lambda x, i : A[i] + B[i] * (x - X[i]) + C[i] * pow(x - X[i], 2) + D[i] * pow(x - X[i], 3)
total = 1000
pX = np.linspace(0,5,total)
pY = np.zeros(total)
for i in range(pX.size):
x = pX[i]
for j in range(X.size - 1):
if x <= X[j + 1]:
pY[i] = S(x, j)
break
else:
continue
plt.plot(pX,pY,color='b')
plt.plot(X,Y,'ro')
plt.grid(True)
plt.show()
In [38]:
def bezier_curve(X, Y):
"""
Make the function handle of the bezier curve formula
Args:
X - x-axis points (include endpoints and control points)
Y - y-axis points (include endpoints and control points)
Returns:
fx - bezier curve for x-axis points
fy - bezier curve for y-axis points
"""
x1 = X[0]
x2 = X[1]
x3 = X[2]
x4 = X[3]
y1 = Y[0]
y2 = Y[1]
y3 = Y[2]
y4 = Y[3]
bx = 3 * (x2 - x1)
cx = 3 * (x3 - x2) - bx
dx = x4 - x1 - bx - cx
by = 3 * (y2 - y1)
cy = 3 * (y3 - y2) - by
dy = y4 - y1 - by - cy
fx = lambda t : x1 + bx * t + cx * pow(t, 2) + dx * pow(t, 3)
fy = lambda t : y1 + by * t + cy * pow(t, 2) + dy * pow(t, 3)
return fx, fy
In [47]:
X = np.array([1, 1, 3, 2])
Y = np.array([1, 3, 3, 2])
fx, fy = bezier_curve(X, Y)
t = np.linspace(0, 1, 100)
px = fx(t)
py = fy(t)
plt.plot(px, py, color='b')
plt.plot(X[0:2], Y[0:2], color='r', marker='o', linestyle='--')
plt.plot(X[2:4], Y[2:4], color='r', marker='o', linestyle='--')
plt.grid(True)
plt.show()