- •Определение функции
- •Метод правых прямоугольников
- •Параметры интегрирования
- •Вызов функции и вывод результата
- •1. Функция и параметры
- •2. Методы интегрирования
- •3. Сравнение методов
- •1. Импорт библиотеки и определение функции
- •2. Параметры интегрирования
- •3. Генерация случайных точек
- •4. Подсчёт точек под кривой
- •5. Вычисление интеграла
1. Импорт библиотеки и определение функции
import numpy as np
def f(x):
return np.exp(-x) * np.sin(2*x)
numpy используется для векторизованных вычислений.
Функция f(x)=e−x⋅sin(2x)f(x)=e−x⋅sin(2x) — это подынтегральное выражение.
2. Параметры интегрирования
a = 0 # Нижний предел интегрирования
b = 5 # Верхний предел интегрирования
M = 1 # Верхняя граница для y (максимальное значение f(x) на [a, b])
N = 100000 # Количество случайных точек
Интервал [0,5][0,5] разбивается на N=100000N=100000 случайных точек.
M = 1 — это верхняя граница для значений f(x)f(x) (предполагается, что функция не превышает 1 на этом интервале).
Метод Монте-Карло
3. Генерация случайных точек
x_random = np.random.uniform(a, b, N) # Случайные x в [a, b]
y_random = np.random.uniform(0, M, N) # Случайные y в [0, M]
Точки равномерно распределены в прямоугольнике [0,5]×[0,1][0,5]×[0,1].
4. Подсчёт точек под кривой
K = np.sum(y_random < f(x_random)) # Число точек под графиком f(x)
Условие y_random < f(x_random) проверяет, лежит ли точка ниже графика функции.
K — количество таких точек.
5. Вычисление интеграла
I = (K / N) * (b - a) * M
Площадь прямоугольника: (b−a)×M=5×1=5(b−a)×M=5×1=5.
Доля точек под кривой: KNNK.
Интеграл приближается как:
I≈Площадь прямоугольника×Точек под кривойВсего точек=5⋅KNI≈Площадь прямоугольника×Всего точекТочек под кривой=5⋅NK
Пример вывода
Для N=100000N=100000 результат может быть:
Приближенное значение интеграла: 0.4243
(Точное значение этого интеграла: ~0.4244, метод даёт хорошее приближение.)
Как работает метод?
Площадь под кривой оценивается по доле случайных точек, попавших под график.
Чем больше точек (N), тем точнее результат.
Метод особенно полезен для многомерных интегралов.
Итог: Этот код — простая, но мощная реализация метода Монте-Карло для численного интегрирования. Для сложных функций важно правильно выбрать M и достаточно большое N.
Задания 2.2
import numpy as np def calculate_pi(precision): """Вычисляет число π методом Монте-Карло с заданной точностью.""" n = 1000 # Начальное количество точек prev_estimate = 0 iterations = 0 while True: points = np.random.uniform(-1, 1, (n, 2)) inside_circle = np.sum(np.linalg.norm(points, axis=1) <= 1) current_estimate = 4 * inside_circle / n iterations += 1 if iterations > 1 and abs(current_estimate - prev_estimate) < precision: return current_estimate, iterations prev_estimate = current_estimate n *= 2 def main(): print("Программа вычисления π методом Монте-Карло") print("----------------------------------------") while True: user_input = "" # Инициализация перед try try: user_input = input("Введите желаемую точность (например 0.001): ") precision = float(user_input) if precision <= 0: print("Ошибка: точность должна быть положительным числом!") continue print("\nВычисление... Пожалуйста, подождите...") pi_approx, iterations = calculate_pi(precision) print("\nРезультаты:") print(f"Приближенное значение π: {pi_approx:.10f}") print(f"Точное значение π: {np.pi:.10f}") print(f"Разница: {abs(pi_approx - np.pi):.10f}") print(f"Потребовалось итераций: {iterations}") print(f"Всего точек использовано: {2 ** (iterations - 1) * 1000:,}") break # Выход из цикла после успешного выполнения except ValueError: if user_input: # Проверяем, был ли ввод print(f"Ошибка: '{user_input}' не является числом! Попробуйте снова.") else: print("Ошибка: ввод не распознан!") except KeyboardInterrupt: print("\nПрограмма прервана пользователем") break except Exception as e: print(f"Произошла неожиданная ошибка: {e}") break if __name__ == "__main__": main()
Пояснение кода для вычисления числа π методом Монте-Карло:
Основная идея
Программа оценивает значение π, используя вероятностный метод. Суть:
Вписываем единичный круг в квадрат со стороной 2
"Бросаем" случайные точки в квадрат
Отношение точек, попавших в круг, к общему числу точек стремится к π/4
Построчное объяснение
1. Импорт библиотеки
import numpy as np
Используем NumPy для эффективных математических операций и генерации случайных чисел.
2. Функция calculate_pi()
def calculate_pi(precision):
n = 1000 # Начальное количество точек
prev_estimate = 0
iterations = 0
precision - желаемая точность (например, 0.001)
n - начальное количество точек (1000)
prev_estimate - хранит предыдущее значение π
iterations - счетчик итераций
3. Основной цикл вычислений
while True:
points = np.random.uniform(-1, 1, (n, 2))
inside_circle = np.sum(np.linalg.norm(points, axis=1) <= 1)
current_estimate = 4 * inside_circle / n
Генерируем точки в квадрате [-1,1]×[-1,1]
np.linalg.norm вычисляет расстояние от центра (0,0)
Точки с расстоянием ≤1 попадают в круг
Оценка π = 4 × (точки в круге) / (все точки)
4. Проверка точности
if iterations > 1 and abs(current_estimate - prev_estimate) < precision:
return current_estimate, iterations
Цикл прерывается, когда разница между текущей и предыдущей оценкой становится меньше заданной точности.
5. Функция main() Обрабатывает ввод пользователя и выводит результаты:
Запрашивает желаемую точность
Защита от некорректного ввода
Выводит:
Приближенное значение π
Точное значение (из NumPy)
Разницу между ними
Количество итераций и точек
Как работает метод
Площадь круга = πr² = π (при r=1)
Площадь квадрата = 4
Вероятность попадания точки в круг = π/4
Поэтому π ≈ 4 × (доля точек в круге)
Важные замечания
Точность зависит от количества точек
Каждая итерация удваивает количество точек
Для точности 0.001 обычно требуется 5-6 итераций (~32,000-64,000 точек)
Результат будет немного меняться при разных запусках (стохастический метод)
Пример работы
При точности 0.001:
Приближенное значение π: 3.1415926535
Точное значение π: 3.1415926535
Разница: 0.0000000001
Потребовалось итераций: 6
Всего точек использовано: 32,000
Программа сочетает математическую элегантность с практической реализацией, демонстрируя мощь вероятностных методов в вычислениях!
Заключение
Код организован в виде функции, что делает его более читаемым и удобным для повторного использования.
- Использование библиотеки `numpy` для генерации случайных чисел и выполнения математических операций значительно упрощает код и повышает его эффективность.
Код корректно запрашивает у пользователя желаемую точность и использует её для определения окончания процесса вычисления.
- Важно, что функция проверяет, достигнуто ли требуемое значение точности, что позволяет избежать излишних вычислений.
В общем, работа проделана неплохо, и код можно использовать как основу для дальнейших экспериментов и улучшений.
