Skip to content

Commit df82e83

Browse files
author
pmrukot
committed
Add spline interpolation
1 parent 3eafc6f commit df82e83

File tree

6 files changed

+203
-0
lines changed

6 files changed

+203
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import numpy as np
2+
3+
4+
def calculate_cubic_value(t, y):
5+
n = len(t)
6+
h = []
7+
b = []
8+
u = [0]
9+
v = [0]
10+
11+
for i in range(0, n - 1):
12+
h.append(t[i + 1] - t[i])
13+
b.append(6 * (y[i + 1] - y[i]) / h[i])
14+
15+
u.append(2 * (h[0] + h[1]))
16+
v.append(b[1] - b[0])
17+
18+
for i in range(2, n - 1):
19+
u.append(2 * (h[i - 1] + h[i]) - (h[i - 1] * h[i - 1]) / u[i - 1])
20+
v.append((b[i] - b[i - 1]) - (h[i - 1] * v[i - 1] / u[i - 1]))
21+
22+
z = [0] * (n)
23+
24+
for i in range(n - 2, 0, -1):
25+
z[i] = ((v[i] - h[i] * z[i + 1]) / u[i])
26+
27+
z[0] = 0
28+
return z, h
29+
30+
31+
def calculate_cubic_value_not_a_knot(t, y):
32+
n = len(t)
33+
h = []
34+
b = []
35+
v = [0]
36+
A = np.zeros(shape=(n, n))
37+
38+
for i in range(0, n - 1):
39+
h.append(t[i + 1] - t[i])
40+
b.append(6 * (y[i + 1] - y[i]) / h[i])
41+
42+
A[0][0] = h[1]
43+
A[0][1] = - h[1] - h[0]
44+
A[0][2] = h[0]
45+
46+
for i in range(1, n - 1):
47+
A[i][i - 1] = h[i - 1]
48+
A[i][i] = 2 * (h[i - 1] + h[i])
49+
A[i][i + 1] = h[i]
50+
v.append(b[i] - b[i - 1])
51+
52+
v.append(0)
53+
A[n - 1][n - 3] = h[n - 2]
54+
A[n - 1][n - 2] = - h[n - 2] - h[n - 3]
55+
A[n - 1][n - 1] = h[n - 3]
56+
57+
z = np.linalg.solve(A, v)
58+
59+
return z, h
60+
61+
62+
def create_cubic_function(t, y, calc):
63+
z, h = calc(t, y)
64+
65+
def spline_function(x):
66+
i = 0
67+
while float(x) - t[i] >= 0:
68+
i += 1
69+
i -= 1
70+
A = (z[i + 1] - z[i]) / (6 * h[i])
71+
B = z[i] / 2.
72+
C = -(h[i] * (z[i + 1] + 2 * z[i])) / 6 + (y[i + 1] - y[i]) / h[i]
73+
return y[i] + ((x - t[i]) * (C + (x - t[i]) * (B + (x - t[i]) * A)))
74+
75+
return spline_function
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import numpy as np
2+
3+
4+
def calculate_mean_square_error(n, function_y, interpolated_y):
5+
error = 0
6+
for i in range(0, n):
7+
error += (function_y[i] - interpolated_y[i])**2
8+
error /= n
9+
return error
10+
11+
12+
def calculate_max_error(n, function_y, interpolated_y):
13+
max_error = 0
14+
for i in range(0, n):
15+
if np.fabs(function_y[i] - interpolated_y[i]) > max_error:
16+
max_error = np.fabs(function_y[i] - interpolated_y[i])
17+
return max_error
18+
19+
20+
def print_error(N, x_len, y_values, y_interpolated, label):
21+
print('{0},{1},{2},{3}'.format(label, N,
22+
calculate_mean_square_error(x_len, y_values, y_interpolated),
23+
calculate_max_error(x_len, y_values, y_interpolated)
24+
))
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import numpy as np
2+
3+
4+
def fun(x, k=3, m=1):
5+
return np.exp((-k) * np.sin(m * x)) + k * np.sin(m * x) - 1

SplineFunctionsInterpolation/main.py

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
4+
from cubic_splines import calculate_cubic_value, create_cubic_function, calculate_cubic_value_not_a_knot
5+
from quadratic_splines import create_quadratic_function, calculate_quadratic_value, calculate_quadratic_value_not_a_knot
6+
from function import fun
7+
from errors import print_error
8+
from points import get_points
9+
10+
11+
if __name__ == '__main__':
12+
start = -2.*np.pi
13+
end = 2.*np.pi
14+
step = 0.05
15+
N = 8
16+
function = fun
17+
18+
points = get_points(N-1, start, end, function)
19+
20+
x_points, y_points = zip(*points)
21+
22+
x = np.arange(start, end, step)
23+
y = [function(x) for x in x]
24+
x_len = len(x)
25+
26+
quadratic_spline_natural = create_quadratic_function(x_points, y_points, calculate_quadratic_value)
27+
quadratic_spline_notaknot = create_quadratic_function(x_points, y_points, calculate_quadratic_value_not_a_knot)
28+
cubic_spline_natural = create_cubic_function(x_points, y_points, calculate_cubic_value)
29+
cubic_spline_not_a_knot = create_cubic_function(x_points, y_points, calculate_cubic_value_not_a_knot)
30+
31+
quadratic_spline_natural_values = [quadratic_spline_natural(x) for x in x]
32+
quadratic_spline_notaknot_values = [quadratic_spline_notaknot(x) for x in x]
33+
cubic_spline_natural_values = [cubic_spline_natural(x) for x in x]
34+
cubic_spline_notaknot_values = [cubic_spline_not_a_knot(x) for x in x]
35+
36+
print('label,N,mean_sqaure_error,max_error')
37+
print_error(N, x_len, y, quadratic_spline_natural_values, 'quadratic_natural')
38+
print_error(N, x_len, y, quadratic_spline_notaknot_values, 'quadratic_notaknot')
39+
print_error(N, x_len, y, cubic_spline_natural_values, 'cubic_natural')
40+
print_error(N, x_len, y, cubic_spline_notaknot_values, 'cubic_notaknot')
41+
42+
plt.plot(x, function(x), 'b', linewidth=2.5, label="function")
43+
plt.plot(x, cubic_spline_natural_values, 'r--', linewidth=2.5, label='cubic natural')
44+
plt.plot(x, cubic_spline_notaknot_values, 'r--', color='#880000', linewidth=2.5, label='cubic notaknot')
45+
plt.plot(x, quadratic_spline_natural_values, 'g--', linewidth=2.5, label='quad natural')
46+
plt.plot(x, quadratic_spline_notaknot_values, 'g--', color='#808000', linewidth=2.5, label='quad notaknot')
47+
plt.plot(x_points, y_points, 'yo')
48+
plt.legend(loc='upper left')
49+
plt.show()
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import numpy as np
2+
3+
4+
def get_points(n, start, end, function):
5+
points = []
6+
r = end - start
7+
step = r / n
8+
9+
for i in np.arange(-2 * np.pi, 2 * np.pi, step):
10+
points.append((i, function(i)))
11+
points.append((end, function(end)))
12+
13+
return points
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import numpy as np
2+
3+
4+
def calculate_quadratic_value(t, y):
5+
n = len(t)
6+
z = [0]
7+
8+
for i in range(0, n - 1):
9+
z.append(-z[i] + 2 * ((y[i + 1] - y[i]) / (t[i + 1] - t[i])))
10+
return z
11+
12+
13+
def calculate_quadratic_value_not_a_knot(t, y):
14+
n = len(t)
15+
d = [(y[1] - y[0]) / (t[1] - t[0])]
16+
A = np.zeros(shape=(n, n))
17+
A[0][0] = 1
18+
19+
for i in range(1, n):
20+
A[i][i-1] = 1
21+
A[i][i] = 1
22+
d.append(2 * ((y[i] - y[i-1]) / (t[i] - t[i-1])))
23+
24+
return np.linalg.solve(A, d)
25+
26+
27+
def create_quadratic_function(t, y, calc):
28+
z = calc(t, y)
29+
30+
def spline_function(x):
31+
i = 0
32+
while x - t[i] >= 0:
33+
i += 1
34+
i -= 1
35+
return ((z[i + 1] - z[i]) * (x - t[i]) * (x - t[i])) / (2 * (t[i + 1] - t[i])) + z[i] * (x - t[i]) + y[i]
36+
37+
return spline_function

0 commit comments

Comments
 (0)