Skip to content

Commit 44bdee9

Browse files
add more interpolation
1 parent a733a9a commit 44bdee9

File tree

2 files changed

+259
-0
lines changed

2 files changed

+259
-0
lines changed

lab2.1.py

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
"""Интерполяция методом полинома Ньютона"""
2+
from math import cos, pi, fabs, factorial
3+
import numpy as np
4+
from prettytable import PrettyTable
5+
6+
7+
def get_table(up, down, step):
8+
xs = []
9+
ys = []
10+
for x in np.arange(up, down, step):
11+
xs.append(x)
12+
ys.append(cos(x))
13+
return xs, ys
14+
15+
16+
def bin_search(lst, x):
17+
a = 0
18+
b = len(lst) - 1
19+
while a < b:
20+
m = int((a + b) / 2)
21+
if x > lst[m]:
22+
a = m + 1
23+
else:
24+
b = m
25+
return b
26+
27+
28+
def divided_difference(xs, ys):
29+
l = len(xs)
30+
if l == 1:
31+
return ys[0]
32+
else:
33+
return (divided_difference(xs[:-1], ys[:-1]) - divided_difference(xs[1:], ys[1:])) / (xs[0] - xs[l - 1])
34+
35+
36+
def newton_interpolation(lst_x, lst_y, x, n):
37+
i = bin_search(lst_x, x) # поиск ближайшего
38+
if len(lst_x) < i + (n + 1) / 2: # если не получается взыть выборку с нужным х посередине
39+
sample_x = lst_x[len(lst_x) - (n + 1):]
40+
sample_y = lst_y[len(lst_y) - (n + 1):]
41+
else:
42+
if n % 2 != 0:
43+
sample_x = lst_x[i - int((n + 1) / 2): i + int((n + 1) / 2)]
44+
sample_y = lst_y[i - int((n + 1) / 2): i + int((n + 1) / 2)]
45+
else:
46+
sample_x = lst_x[i - int((n + 1) / 2) - 1: i + int((n + 1) / 2)]
47+
sample_y = lst_y[i - int((n + 1) / 2) - 1: i + int((n + 1) / 2)]
48+
y_x = sample_y[0]
49+
for i in range(1, len(sample_x)):
50+
k = 1
51+
for j in range(i):
52+
k *= (x - sample_x[j])
53+
dd = divided_difference(sample_x[:i+1], sample_y[:i+1])
54+
y_x += (k * dd)
55+
return y_x
56+
57+
58+
def gen_error(x, y_inter, n, xs):
59+
y_real = cos(x)
60+
diff = abs(y_real - y_inter)
61+
omega = x - xs[n]
62+
for i in range(0, n):
63+
omega *= (x - xs[i])
64+
omega = abs(omega)
65+
d = abs(cos(x + (pi * n)/2)) / factorial(n + 1)
66+
return diff <= d * omega
67+
68+
69+
a = float(input('Введите нижнюю границу значений Х: '))
70+
b = float(input('Введите верхнюю границу значений Х: '))
71+
h = float(input('Введите шаг: '))
72+
73+
xss, yss = get_table(a, b, h)
74+
75+
table = PrettyTable()
76+
table.add_column("X", xss)
77+
table.add_column("Y", yss)
78+
79+
try:
80+
x = float(input('Введите значение х в пределах [{0}, {1}]: '.format(a, b)))
81+
if x > b or x < a:
82+
x = float(input("X должен лежать в пределах [{0}, {1}]! Повторите ввод х: ".format(a,b)))
83+
n = int(input('Введите степень полинома: '))
84+
if n < 0:
85+
n = int(input('Степень должна быть больше 0!\nПовторите ввод: '))
86+
87+
except ValueError:
88+
print("Неверный ввод! Повторите")
89+
x = float(input('Введите значение х в пределах [{0}, {1}]: '.format(a, b)))
90+
if x > b or x < a:
91+
x = float(input("X должен лежать в пределах [{0}, {1}]! Повторите ввод х: ".format(a, b)))
92+
n = int(input('Введите степень полинома: '))
93+
if n < 0:
94+
n = int(input('Степень должна быть больше 0!\nПовторите ввод: '))
95+
96+
print(table)
97+
in_res = newton_interpolation(xss, yss, x, n)
98+
r_res = cos(x)
99+
absolute_error = fabs(in_res - r_res)
100+
try:
101+
ratio_error = absolute_error / fabs(r_res)
102+
except ZeroDivisionError:
103+
ratio_error = None
104+
print('Упс')
105+
print("Результат при интерполяции: ", in_res)
106+
print("Реальный результат: ", r_res)
107+
print("Абсолютная погрешность: {0:.5e}".format(absolute_error))
108+
print("Относительная погрешность: {0:.5e}".format(ratio_error))
109+
print('Погрешность полинома Ньютона:', gen_error(x, in_res, n, xss))
110+

lab2.2.py

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
"""Обратная интерполяция"""
2+
from math import cos, sin, pi, fabs, ceil, log
3+
from prettytable import PrettyTable
4+
5+
relative_accuracy = 0.001
6+
7+
left_fist = -5
8+
right_first = 1
9+
10+
left_second = -3
11+
right_second = 3
12+
13+
14+
def f(x, y):
15+
return x ** 3 - 15 * y + 4
16+
17+
18+
def g(x, y):
19+
return cos(x) - y
20+
21+
22+
def bisection(a, b, x, eps, f):
23+
if f(x, a) == eps:
24+
return a
25+
if f(x, b) == eps:
26+
return b
27+
c = (a + b) / 2
28+
while abs(b - a) > eps * abs(c) + eps:
29+
c = (a + b) / 2
30+
if f(x, b) * f(x, c) < 0:
31+
a = c
32+
else:
33+
b = c
34+
return (a + b) / 2
35+
36+
37+
def for_first_equation(x):
38+
return bisection(left_fist, right_first, x, relative_accuracy, f)
39+
40+
41+
def for_second_equation(x):
42+
return bisection(left_fist, right_first, x, relative_accuracy, g)
43+
44+
45+
def create_table(left, right, step, function):
46+
x = []
47+
y = []
48+
49+
while left <= right:
50+
x.append(left)
51+
y.append(function(left))
52+
left += step
53+
54+
return [x, y]
55+
56+
57+
def find_beg(x, table, size, near, deg):
58+
deg += 1
59+
if near == 0 and table[near] > x:
60+
return 0
61+
62+
if near == size - 1 and table[near] < x:
63+
return size - deg - 1
64+
65+
if x <= table[near]:
66+
if near < deg / 2:
67+
return 0
68+
if (size - 1 - near) < (ceil(deg / 2) - 1):
69+
return size - deg - 1
70+
return near - deg / 2
71+
72+
if x > table[near]:
73+
if near < (ceil(deg / 2) - 1):
74+
return 0
75+
if size - 1 - deg < deg / 2:
76+
return size - 1 - deg
77+
return near - (ceil(deg / 2) - 1)
78+
79+
return 0
80+
81+
82+
def nearest_value(x, table, size):
83+
if x < table[0]:
84+
return 0
85+
86+
if x > table[size - 1]:
87+
return size - 1\
88+
89+
diff = fabs(x - table[0])
90+
first_y = 0
91+
92+
for i in range(1, size):
93+
if fabs(x - table[i]) < diff:
94+
first_y = i
95+
diff = fabs(x - table[i])
96+
97+
return first_y
98+
99+
100+
def newton_interpolation(x, degree, beginnig, table_x, table_y):
101+
result = table_y[beginnig]
102+
103+
for i in range((beginnig + 1), beginnig + degree):
104+
divided = 0
105+
for j in range(beginnig, i + 1):
106+
difference = 1
107+
for k in range(beginnig, i + 1):
108+
if (k != j):
109+
difference *= (table_x[j] - table_x[k])
110+
divided += (table_y[j] / difference)
111+
for k in range(beginnig, i):
112+
divided *= (x - table_x[k])
113+
result += divided
114+
115+
return result
116+
117+
118+
a = float(input('Введите левый предел: \n'))
119+
b = float(input('ВВедите правый предел: \n'))
120+
step = float(input("Вывдете шаг: \n"))
121+
122+
x_column_first, y_column_first = create_table(a, b, step, for_first_equation)
123+
124+
x_column_second, y_column_second = create_table(a, b, step, for_second_equation)
125+
126+
x_result, y_result = [], []
127+
128+
for index in range(len(y_column_first)):
129+
y_result.append(x_column_first[index])
130+
x_result.append(y_column_second[index] - y_column_first[index])
131+
132+
table_data = PrettyTable()
133+
table_data.add_column('X', x_result)
134+
table_data.add_column('Y(X)', y_result)
135+
print(table_data)
136+
137+
degree = int(input('Enter degree of Newton\'s polynomial: \n'))
138+
x = 0
139+
140+
for_first_y = nearest_value(x, x_result, len(x_result))
141+
beginning = find_beg(x, x_result, len(x_result), for_first_y, degree)
142+
143+
result = newton_interpolation(x, degree, int(beginning), x_result, y_result)
144+
145+
print('\n -------- Results -------- \n')
146+
print('X = ', result)
147+
y_first = for_first_equation(result)
148+
y_second = for_second_equation(result)
149+
print('Y = ', y_first + (y_second - y_first) / 2)

0 commit comments

Comments
 (0)