Загрузка данных


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)