-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnonlinear_equations.py
148 lines (118 loc) · 5.88 KB
/
nonlinear_equations.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
def newton(f, df, x, epsilon=1e-6):
"""
Метод Ньютона (касательных) для нахождения корня уравнения f(x) = 0.
:param f: Функция, корень которой нужно найти.
:param df: Производная функции f.
:param x: Начальное приближение.
:param epsilon: Заданная точность (по умолчанию 1e-6).
:return: Приближённое значение корня и количество итераций.
"""
x_next = x - f(x) / df(x)
i = 0
while abs(x_next - x) > epsilon:
x = x_next
x_next = x - f(x) / df(x)
i += 1
return x_next, i
def simplified_newton(f, df, x0, epsilon=1e-6):
"""
Упрощённый метод Ньютона для нахождения корня уравнения f(x) = 0.
:param f: Функция, корень которой нужно найти.
:param df: Производная функции f.
:param x0: Начальное приближение.
:param epsilon: Заданная точность (по умолчанию 1e-6).
:return: Приближённое значение корня и количество итераций.
"""
x00 = x0
x1 = x0 - f(x0) / df(x00)
i = 0
while abs(x1 - x0) > epsilon:
x0 = x1
x1 = x0 - f(x0) / df(x00)
i += 1
return x1, i
def false_position(f, a, b, epsilon=1e-6):
"""
Метод ложного положения для нахождения корня уравнения f(x) = 0.
Работает для отрезка [a, b], на котором f(a) * f(b) < 0.
:param f: Функция, корень которой нужно найти.
:param a: Левая граница отрезка.
:param b: Правая граница отрезка.
:param epsilon: Заданная точность (по умолчанию 1e-6).
:return: Приближённое значение корня и количество итераций.
"""
i = 0
c_before = 0
c = (a * f(b) - b * f(a)) / (f(a) - f(b))
error = abs(c - c_before)
while error > epsilon:
c_after = (a * f(b) - b * f(a)) / (f(b) - f(a))
if f(a) * f(b) >= 0:
return "Указан неверный участок локализации!"
elif f(c_after) * f(a) < 0:
error = abs(c_after - b)
b = c_after
i += 1
elif f(c_after) * f(b) < 0:
error = abs(c_after - a)
a = c_after
i += 1
return c_after, i
def secant(f, x_minus_1, x_n, epsilon=1e-6):
"""
Метод секущих для нахождения корня уравнения f(x) = 0.
Не требует аналитической производной.
:param f: Функция, корень которой нужно найти.
:param x_minus_1: Предыдущее приближение.
:param x_n: Текущее приближение.
:param epsilon: Заданная точность (по умолчанию 1e-6).
:return: Приближённое значение корня и количество итераций.
"""
i = 0
x_plus_1 = x_n - (x_minus_1 - x_n) / (f(x_minus_1) - f(x_n)) * f(x_n)
while abs(x_plus_1 - x_n) > epsilon:
x_minus_1 = x_n
x_n = x_plus_1
x_plus_1 = x_n - (x_n - x_minus_1) / (f(x_n) - f(x_minus_1)) * f(x_n)
i += 1
return x_plus_1, i
def bisection(f, a, b, epsilon=1e-6):
"""
Метод бисекций для нахождения корня функции на интервале [a, b].
:param f: Функция, корень которой нужно найти. Функция должна быть продолжительной на интервале [a, b] и иметь разные знаки на концах интервала.
:param a: Левый конец интервала.
:param b: Правый конец интервала.
:param epsilon: Точность, при которой метод останавливается, когда длина интервала становится меньше epsilon. По умолчанию 1e-6.
:return: Кортеж из двух значений: корень уравнения и количество итераций, выполненных для нахождения решения.
:raises ValueError: Если на концах интервала значения функции имеют одинаковый знак (f(a) * f(b) >= 0).
"""
if f(a) * f(b) >= 0:
raise ValueError("Указан неверный участок локализации! f(a) * f(b) должно быть отрицательным.")
i = 0
c = a
while (b - a) > 2 * epsilon:
c = (a + b) / 2
if f(c) == 0:
break
elif f(c) * f(a) < 0:
b = c
else:
a = c
i += 1
return c, i
def simple_iteration_method(phi, x0, epsilon=1e-6):
"""
Метод простой итерации для решения нелинейного уравнения.
:param phi: функция, задающая итерационный процесс phi(x).
:param x0: начальное приближение.
:param epsilon: точность решения (по умолчанию 1e-6).
:return: Кортеж из двух значений: корень уравнения и количество итераций, выполненных для нахождения решения.
"""
i = 0
x_prev = x0
while True:
x_next = phi(x_prev)
if abs(x_next - x_prev) < epsilon:
return x_next, i
i += 1
x_prev = x_next