import numpy as np
import matplotlib.pyplot as plt
import math
from matplotlib.patches import Rectangle
# --- 1. Настройки Варианта 20 ---
def f(x):
return np.sqrt(1 - x**2)
a, b = 0, 0.5
n = 10
h = (b - a) / n
# Аналитический эталон для 16 знаков точности
TRUE_VAL = math.pi/12 + math.sqrt(3)/8
# --- 2. Отрисовка 6 графиков ---
fig, axes = plt.subplots(2, 3, figsize=(16, 11))
axes = axes.flatten()
x_curve = np.linspace(a, b, 200)
# Общие стили
LINE_WIDTH = 1.0 # Одинаковая толщина для всех линий разделения
STYLE = {'alpha': 0.5, 'edgecolor': 'black', 'lw': LINE_WIDTH}
COLOR_BLUE = '#add8e6'
COLOR_RED = '#ff4444'
methods = ["ЛПР", "ППР", "СПР", "ТР", "СИМП", "ММК"]
for idx, name in enumerate(methods):
ax = axes[idx]
ax.plot(x_curve, f(x_curve), color='#0055ff', lw=2.5, zorder=10)
if name == "ЛПР":
for i in range(n):
ax.add_patch(Rectangle((a+i*h, 0), h, f(a+i*h), facecolor=COLOR_BLUE, **STYLE))
elif name == "ППР":
for i in range(n):
ax.add_patch(Rectangle((a+i*h, 0), h, f(a+(i+1)*h), facecolor=COLOR_BLUE, **STYLE))
elif name == "СПР":
for i in range(n):
xm = a + i*h + h/2
ax.add_patch(Rectangle((a+i*h, 0), h, f(xm), facecolor=COLOR_BLUE, **STYLE))
elif name == "ТР":
for i in range(n):
xi, xj = a + i*h, a + (i+1)*h
ax.fill([xi, xi, xj, xj], [0, f(xi), f(xj), 0], color=COLOR_BLUE, **STYLE)
elif name == "СИМП":
# 1. Рисуем 5 параболических крыш
for i in range(0, n, 2):
x_pts = [a+i*h, a+(i+1)*h, a+(i+2)*h]
y_pts = f(np.array(x_pts))
poly = np.polyfit(x_pts, y_pts, 2)
xr = np.linspace(x_pts[0], x_pts[2], 50)
ax.fill_between(xr, 0, np.polyval(poly, xr), color=COLOR_BLUE, alpha=0.5, zorder=4)
# 2. Рисуем ровно 11 вертикальных линий (границы 10 столбиков) одной толщины
x_lines = np.linspace(a, b, n + 1)
ax.vlines(x_lines, 0, f(x_lines), color='black', lw=LINE_WIDTH, zorder=5)
elif name == "ММК":
# 10 случайных накладывающихся столбиков
for i in range(n):
# Случайная позиция начала столбика
rx = np.random.uniform(a, b - h)
# Высота столбика привязана к функции с небольшим отклонением
rh = f(rx) + np.random.uniform(-0.02, 0.02)
ax.add_patch(Rectangle(
(rx, 0), h, rh,
facecolor=COLOR_RED, alpha=0.35,
edgecolor='darkred', lw=LINE_WIDTH, zorder=5
))
ax.set_title(f"Метод: {name} (n={n})", fontsize=11, fontweight='bold')
ax.set_xlim(a-0.02, b+0.02)
ax.set_ylim(0, 1.1)
ax.grid(True, ls=':', alpha=0.4)
plt.tight_layout()
# --- 3. Точный расчет для таблицы ---
def calculate_simpson(n_val):
if n_val % 2 != 0: n_val += 1
h_s = (b - a) / n_val
x = np.linspace(a, b, n_val + 1)
y = f(x)
return (h_s/3) * (y[0] + y[-1] + 4*np.sum(y[1:-1:2]) + 2*np.sum(y[2:-2:2]))
s_hat = calculate_simpson(1000)
delta = abs(TRUE_VAL - s_hat)
sigma = (delta / TRUE_VAL) * 100
print(f"\nИстинное значение S = {TRUE_VAL:.18f}")
print("="*105)
# Формат вывода с буквами S-крышка, Дельта и Сигма
print(f"| n = 1000 | Метод СИМП | Ŝ = {s_hat:.18f} | Δ = {delta:.2e} | δ = {sigma:.16f}% |")
print("="*105)
plt.show()