-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterpolator.py
122 lines (100 loc) · 3.92 KB
/
interpolator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def get_table(a, b, m, func):
step = (b - a) / m
table = {}
for j in range(0, m + 1):
z = a + j * step
table[z] = func(z)
return table
def sort_table(table):
table_sorted = {k: v for k, v in sorted(table.items(), key=lambda item: abs(item[0] - x))}
table_sorted_keys = list(table_sorted.keys())
table_new = {}
i = 0
while i <= n:
table_new[table_sorted_keys[i]] = table_sorted[table_sorted_keys[i]]
i += 1
return table_new
def print_table(table):
print(" x | f(x)")
for key in table.keys():
if key >= 0:
print(" " + "{:.6f}".format(key), end=" | ")
else:
print("{:.6f}".format(key), end=" | ")
if table[key] >= 0:
print(" " + "{:.6f}".format(table[key]))
else:
print("{:.6f}".format(table[key]))
# table: dict {x0 : f(x0)}
def LagrangeInterpolation(table, x, n):
args = list(table.keys())
res = 0
for k in range(0, n + 1):
x_k = args[k]
x_k_value = table[x_k]
local_res = 1
for i in range(0, n + 1):
if k != i:
local_res *= (x - args[i]) / (args[k] - args[i])
res += x_k_value * local_res
return res
# get divided differences
def GetDiv(table, arguments):
if len(arguments) == 2:
return (table[arguments[1]] - table[arguments[0]]) / (arguments[1] - arguments[0])
else:
numOfArguments = len(arguments)
return (GetDiv(table, arguments[1: numOfArguments]) - GetDiv(table, arguments[0: numOfArguments - 1])) / (
arguments[numOfArguments - 1] - arguments[0])
# table: dict {x0 : f(x0)}
def NewtonInterpolation(table, x, n):
arguments = list(table.keys())
result = 0
rightMultiplicant = 1
pairIndex = 0
result += table[arguments[0]]
for arguementValuePair in table:
if pairIndex == 0:
pairIndex += 1
continue
rightMultiplicant *= (x - arguments[pairIndex - 1])
leftMultiplicant = GetDiv(table, arguments[0: pairIndex + 1])
result += leftMultiplicant * rightMultiplicant
pairIndex += 1
return result
if __name__ == "__main__":
print("Задача алгебраического интерполирования\n"
"Интерполяционный многочлен в форме Ньютона и в форме Лагранжа\n")
print("Вариант №6")
print("f(x): x^2 / (1 + x^2)\n"
"A = -0.5, B = 1\n"
"m+1 = 31, n = 8")
func = lambda y: y ** 2 / (1 + y ** 2)
exit_program = False
while not exit_program:
args_count = int(input("Введите число значений в таблице (m+1): "))
m = args_count - 1
a = float(input("Введите A (начало отрезка): "))
b = float(input("Введите B (конец отрезка): "))
table = get_table(a, b, m, func)
print()
print_table(table)
print()
x = float(input("Введите X (точка интерполирования): "))
n = int(input("Введите N (степень интерполяционного многочлена, не превышающая m): "))
while n > m:
n = int(input("Получено недопустимое значение n, введите другое: "))
sorted_table = sort_table(table)
print()
print_table(sorted_table)
print()
lagrange = LagrangeInterpolation(sorted_table, x, n)
print(f"L({x}) = {lagrange}")
print(f"|f(x)-L(x)|: {abs(func(x) - lagrange)}")
print()
newton = NewtonInterpolation(sorted_table, x, n)
print(f"N({x}) = {newton}")
print(f"|f(x)-N(x)|: {abs(func(x) - newton)}")
print()
exit_program = input('Завершить программу? (y/n): ').lower().strip() == 'y'
print()