Загрузка данных
import math
import numpy as np
import matplotlib.pyplot as plt
# =========================
# Вариант 22
# f(x) = arcsin(x)/sqrt(1 - x^2) - 1/2
# Рабочий отрезок: [-0.5, 0.8]
# Nmax = 10^6
# eps_x = 1e-14
# eps_f = 1e-15
# =========================
a = -0.5
b = 0.8
eps_x = 1e-14
eps_f = 1e-15
Nmax = 10**6
def f(x):
return math.asin(x) / math.sqrt(1 - x**2) - 0.5
def df(x):
return (
1 + x * math.asin(x) / math.sqrt(1 - x**2)
) / (1 - x**2)
def bisection_method(a, b):
fa = f(a)
fb = f(b)
if fa * fb > 0:
print("Метод бисекции неприменим: нет смены знака на [a,b].")
return None, []
steps = []
for n in range(1, Nmax + 1):
c = (a + b) / 2
fc = f(c)
steps.append((n, a, b, c, fc, abs(b - a)))
if abs(b - a) < eps_x or abs(fc) < eps_f:
return c, steps
if fa * fc <= 0:
b = c
fb = fc
else:
a = c
fa = fc
return c, steps
def newton_method(x0):
x = x0
steps = []
for n in range(1, Nmax + 1):
fx = f(x)
dfx = df(x)
if abs(dfx) < 1e-16:
print("Производная слишком мала.")
return None, steps
x_next = x - fx / dfx
delta_x = abs(x_next - x)
delta_f = abs(f(x_next) - f(x))
steps.append((n, x, fx, dfx, x_next, delta_x, delta_f))
if delta_x < eps_x or delta_f < eps_f:
return x_next, steps
x = x_next
return x, steps
def plot_bisection(steps):
xs = np.linspace(a, b, 600)
ys = [f(x) for x in xs]
plt.figure(figsize=(10, 6))
plt.plot(xs, ys, color='blue', linewidth=2,
label='f(x)=arcsin(x)/sqrt(1-x^2)-1/2')
plt.axhline(0, color='black', linewidth=1)
first_steps = steps[:5]
for n, left, right, mid, fm, width in first_steps:
plt.axvline(mid, linestyle='--', alpha=0.5)
plt.scatter(mid, fm, color='red', s=40)
plt.text(mid, fm, f' c{n}', fontsize=10)
plt.title('Метод бисекции: первые итерации')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.grid(True, alpha=0.3)
plt.legend()
plt.show()
def plot_newton(steps):
xs = np.linspace(a, b, 600)
ys = [f(x) for x in xs]
plt.figure(figsize=(10, 6))
plt.plot(xs, ys, color='blue', linewidth=2,
label='f(x)=arcsin(x)/sqrt(1-x^2)-1/2')
plt.axhline(0, color='black', linewidth=1)
first_steps = steps[:5]
for n, x, fx, dfx, x_next, delta_x, delta_f in first_steps:
x_line = np.linspace(max(a, x - 0.3), min(b, x + 0.3), 100)
y_line = fx + dfx * (x_line - x)
plt.plot(x_line, y_line, '--', linewidth=1.5, label=f'Касательная {n}')
plt.scatter(x, fx, color='red', s=40)
plt.text(x, fx, f' x{n-1}', fontsize=10)
if a <= x_next <= b:
plt.scatter(x_next, 0, color='green', s=40)
plt.text(x_next, 0, f' x{n}', fontsize=10)
plt.title('Метод касательных: первые итерации')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.grid(True, alpha=0.3)
plt.legend()
plt.show()
print("ВАРИАНТ 22")
print("f(x) = arcsin(x)/sqrt(1 - x^2) - 1/2")
print(f"Отрезок: [{a}, {b}]")
print(f"Nmax = {Nmax}")
print(f"eps_x = {eps_x}")
print(f"eps_f = {eps_f}")
print("-" * 50)
fa = f(a)
fb = f(b)
print(f"f({a}) = {fa:.16f}")
print(f"f({b}) = {fb:.16f}")
if fa * fb < 0:
print("На отрезке есть смена знака, корень существует.\n")
else:
print("На отрезке нет смены знака.\n")
root_bis, bis_steps = bisection_method(a, b)
root_newton, newton_steps = newton_method((a + b) / 2)
if root_bis is not None:
print(f"Бисекция: x ≈ {root_bis:.16f}, итераций = {len(bis_steps)}")
print(f"f(root_bis) = {f(root_bis):.16e}")
if root_newton is not None:
print(f"Ньютон: x ≈ {root_newton:.16f}, итераций = {len(newton_steps)}")
print(f"f(root_newton) = {f(root_newton):.16e}")
plot_bisection(bis_steps)
plot_newton(newton_steps)