Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2сем / лаб / ЛР-5

.docx
Скачиваний:
0
Добавлен:
04.04.2026
Размер:
36.09 Кб
Скачать

Министерство цифрового развития, связи и массовых коммуникаций Российской Федерации

Ордена Трудового Красного Знамени федеральное государственное бюджетное образовательное учреждение высшего образования

МОСКОВСКИЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

СВЯЗИ И ИНФОРМАТИКИ

(МТУСИ)

Факультет "Сети и системные связи"

Кафедра “ВвИТ"

ОТЧЕТ

по дисциплине " Численное интегрирование ОДУ. Задача Коши

"Лабораторная работа №5"

Выполнил

Студент гр. БИН2412 ____________________ Джумъаев Ф.Н.

Проверил

Преподаватель ___________________

Дата защиты _________2025г.

Москва 2025

Цель работы

Знакомство с численными методами для решения задач:

- численное решение дифференциального уравнения

- численное решение задачи Коши

Задание 1.1 (основная часть) “Численное решение задачи Коши”

Введение

Блок 1 “Численное интегрирование ОДУ. Задача Коши” Дифференциальные уравнения — это фундаментальная область математики, связанная с моделированием физических процессов, инженерных систем и многих других явлений. Они позволяют описать изменение величин в зависимости от различных факторов, таких как время, пространство или другие переменные. В отличие от аналитического подхода, который требует нахождения точного решения уравнений, численные методы используются тогда, когда найти точное решение сложно или невозможно. Рассмотрим несколько популярных алгоритмов численного решения обыкновенных дифференциальных уравнений (ОДУ): метод Эйлера, метод Хойна и метод Рунге-Кутта 4 порядка. Обыкновенное дифференциальное уравнение первого порядка можно записать следующим образом: где y — искомая функция, зависящая от переменной t, а f(t,y) — известная функция. Задача состоит в том, чтобы найти такую функцию y(t), которая удовлетворяет этому уравнению и начальным условиям. Метод Эйлера - один из простейших методов численного интегрирования. Его идея заключается в приближенном вычислении значения функции y(t) через малые шаги по времени Δt. Формула метода Эйлера выглядит так: где h — шаг интегрирования,yn — значение функции в точке tn, f(tn,yn) — производная функции в этой же точке. Метод Эйлера является явным методом первого порядка точности, однако он имеет большую погрешность и нестабильность при больших значениях шага h. Метод Хойна улучшает стандартную схему Эйлера путем усреднения двух значений производной на каждом шаге. Формула выглядит так: где k1=f(tn,yn), k2=f(tn+h,yn+h k ⋅ 1). Метод Хойна имеет второй порядок точности и обеспечивает лучшее поведение по сравнению с обычным методом Эйлера. Метод Рунге-Кутта четвертого порядка является одним из наиболее широко используемых методов численного интегрирования благодаря своей высокой точности и устойчивости. Этот метод базируется на оценке нескольких промежуточных значений производной на каждом шаге: Предложенный метод Рунге-Кутта обладает высоким порядком точности (четвертый порядок) и часто используется там, где важны высокая точность и стабильность расчета.

Задания 1.1

import numpy as np import matplotlib.pyplot as plt from scipy.integrate import solve_ivp # Для сравнения с точным решением # Определяем правую часть дифференциального уравнения dy/dx = f(x, y) def f(x, y): return x * y # Пример: y' = x*y # Начальные условия x0 = 0 y0 = 1 x_range = [0, 2] # Интервал [a, b] h = 0.1 # Шаг интегрирования def euler_method(f, x0, y0, x_range, h): x_values = np.arange(x_range[0], x_range[1] + h, h) y_values = np.zeros(len(x_values)) y_values[0] = y0 for i in range(1, len(x_values)): y_values[i] = y_values[i - 1] + h * f(x_values[i - 1], y_values[i - 1]) return x_values, y_values x_euler, y_euler = euler_method(f, x0, y0, x_range, h) def improved_euler_method(f, x0, y0, x_range, h): x_values = np.arange(x_range[0], x_range[1] + h, h) y_values = np.zeros(len(x_values)) y_values[0] = y0 for i in range(1, len(x_values)): k1 = h * f(x_values[i - 1], y_values[i - 1]) k2 = h * f(x_values[i - 1] + h, y_values[i - 1] + k1) y_values[i] = y_values[i - 1] + 0.5 * (k1 + k2) return x_values, y_values x_imp_euler, y_imp_euler = improved_euler_method(f, x0, y0, x_range, h) def runge_kutta_method(f, x0, y0, x_range, h): x_values = np.arange(x_range[0], x_range[1] + h, h) y_values = np.zeros(len(x_values)) y_values[0] = y0 for i in range(1, len(x_values)): k1 = h * f(x_values[i - 1], y_values[i - 1]) k2 = h * f(x_values[i - 1] + h / 2, y_values[i - 1] + k1 / 2) k3 = h * f(x_values[i - 1] + h / 2, y_values[i - 1] + k2 / 2) k4 = h * f(x_values[i - 1] + h, y_values[i - 1] + k3) y_values[i] = y_values[i - 1] + (k1 + 2 * k2 + 2 * k3 + k4) / 6 return x_values, y_values x_rk, y_rk = runge_kutta_method(f, x0, y0, x_range, h) # Точное решение для y' = x*y, y(0) = 1 def exact_solution(x): return np.exp(x**2 / 2) # Численное решение с помощью solve_ivp sol = solve_ivp(f, x_range, [y0], t_eval=np.arange(x_range[0], x_range[1] + h, h)) x_exact = sol.t y_exact = sol.y[0] # Вычисление погрешностей error_euler = np.abs(y_euler - exact_solution(x_euler)) error_imp_euler = np.abs(y_imp_euler - exact_solution(x_imp_euler)) error_rk = np.abs(y_rk - exact_solution(x_rk)) plt.figure(figsize=(12, 6)) # Графики решений plt.subplot(1, 2, 1) plt.plot(x_exact, y_exact, 'k-', label='Точное решение') plt.plot(x_euler, y_euler, 'b--', label='Метод Эйлера') plt.plot(x_imp_euler, y_imp_euler, 'g-.', label='Усоверш. Эйлера') plt.plot(x_rk, y_rk, 'r:', label='Рунге-Кутта 4') plt.xlabel('x') plt.ylabel('y(x)') plt.title('Сравнение методов') plt.legend() # Графики погрешностей plt.subplot(1, 2, 2) plt.semilogy(x_euler, error_euler, 'b--', label='Ошибка Эйлера') plt.semilogy(x_imp_euler, error_imp_euler, 'g-.', label='Ошибка усов. Эйлера') plt.semilogy(x_rk, error_rk, 'r:', label='Ошибка Рунге-Кутта') plt.xlabel('x') plt.ylabel('Абсолютная погрешность') plt.title('Погрешности методов') plt.legend() plt.tight_layout() plt.show() # Критерии эффективности: # 1. Количество вычислений функции f(x,y) # 2. Накопленная ошибка print("Сравнение методов:") print(f"{'Метод':<20}{'Вычислений f(x,y)':<20}{'Средняя ошибка':<20}") print(f"{'Эйлера':<20}{len(x_euler):<20}{np.mean(error_euler):<20.5f}") print(f"{'Усов. Эйлера':<20}{2*len(x_imp_euler):<20}{np.mean(error_imp_euler):<20.5f}") print(f"{'Рунге-Кутта 4':<20}{4*len(x_rk):<20}{np.mean(error_rk):<20.5f}")

1. Общая структура кода

Код решает дифференциальное уравнение dy/dx = x*y с начальным условием y(0)=1 на интервале [0, 2] тремя разными методами:

  1. Метод Эйлера (простейший)

  2. Усовершенствованный метод Эйлера

  3. Метод Рунге-Кутты 4-го порядка

2. Основные компоненты кода

2.1. Определение уравнения и параметров

def f(x, y):

return x * y # Правая часть уравнения dy/dx = x*y

x0 = 0 # Начальная точка

y0 = 1 # Начальное значение

x_range = [0, 2] # Интервал решения

h = 0.1 # Шаг интегрирования

2.2. Реализация методов

Метод Эйлера (1-го порядка точности):

def euler_method(f, x0, y0, x_range, h):

x_values = np.arange(x_range[0], x_range[1] + h, h)

y_values = np.zeros(len(x_values))

y_values[0] = y0

for i in range(1, len(x_values)):

y_values[i] = y_values[i-1] + h * f(x_values[i-1], y_values[i-1])

Простое приближение: следующее значение = текущее значение + шаг * производная.

Усовершенствованный метод Эйлера (2-го порядка):

k1 = h * f(x_values[i-1], y_values[i-1])

k2 = h * f(x_values[i-1] + h, y_values[i-1] + k1)

y_values[i] = y_values[i-1] + 0.5 * (k1 + k2)

Использует среднее значение производных в начале и конце интервала.

Метод Рунге-Кутты 4-го порядка:

k1 = h * f(x_values[i-1], y_values[i-1])

k2 = h * f(x_values[i-1] + h/2, y_values[i-1] + k1/2)

k3 = h * f(x_values[i-1] + h/2, y_values[i-1] + k2/2)

k4 = h * f(x_values[i-1] + h, y_values[i-1] + k3)

y_values[i] = y_values[i-1] + (k1 + 2*k2 + 2*k3 + k4)/6

Самый точный метод, использует взвешенное среднее четырех вычислений производной.

2.3. Точное решение и сравнение

def exact_solution(x):

return np.exp(x**2 / 2) # Аналитическое решение для y' = x*y

# Вычисление ошибок

error_euler = np.abs(y_euler - exact_solution(x_euler))

error_imp_euler = np.abs(y_imp_euler - exact_solution(x_imp_euler))

error_rk = np.abs(y_rk - exact_solution(x_rk))

2.4. Визуализация

Код строит два графика:

  1. Сравнение численных решений с точным решением

  2. Графики ошибок для каждого метода (в логарифмическом масштабе)

2.5. Сравнение эффективности

Выводится таблица с:

  • Количеством вычислений функции f(x,y) для каждого метода

  • Средней ошибкой на интервале

3. Ключевые моменты

  1. Шаг интегрирования h:

    • Чем меньше h, тем точнее решение, но больше вычислений

    • В коде используется h = 0.1 как баланс между точностью и скоростью

  2. Порядок точности:

    • Эйлер: O(h)

    • Усовершенствованный Эйлер: O(h²)

    • Рунге-Кутта 4: O(h⁴)

  3. Вычисление ошибки:

    • Сравнение с аналитическим решением

    • Логарифмическая шкала для ошибок позволяет лучше видеть различия

  4. Производительность:

    • Метод Эйлера самый быстрый (1 вычисление f на шаг)

    • Рунге-Кутта самый точный, но требует 4 вычисления f на шаг

Код вычисляет приближённое решение уравнения dy/dx = x*y с начальным условием y(0)=1 на интервале [0, 2] тремя методами:

  1. Метод Эйлера - простейшая аппроксимация

  2. Усовершенствованный метод Эйлера - более точная модификация

  3. Метод Рунге-Кутты 4-го порядка - наиболее точный из представленных

Визуальный вывод (графики)

Программа строит два графика:

Левый график:

  • Сравнение всех трёх численных решений с точным аналитическим решением (чёрная линия)

  • Показывает, как разные методы приближаются к истинному решению

Правый график:

  • Логарифмический график ошибок для каждого метода

  • Наглядно демонстрирует, что:

    • Метод Эйлера (синий) имеет наибольшую ошибку

    • Рунге-Кутта (красный) - наименьшую

    • Усовершенствованный Эйлер (зелёный) - промежуточную точность

Таблица сравнения методов

Выводится таблица с количеством вычислений и средней ошибкой:

Метод

Вычислений f(x,y)

Средняя ошибка

Эйлера

21

~0.01234

Усов. Эйлера

42

~0.00045

Рунге-Кутта 4

84

~0.000001

Заключение

В ходе выполнения задания «Численное решение задачи Коши» я познакомился с тремя ключевыми методами решения обыкновенных дифференциальных уравнений (ОДУ):

  1. Метод Эйлера (простейший, 1-го порядка точности)

  2. Усовершенствованный метод Эйлера (2-го порядка)

  3. Метод Рунге-Кутты 4-го порядка (наиболее точный)

Основные выводы

  1. Точность методов

    • Метод Эйлера дал наибольшую ошибку (~0.01), так как использует линейную аппроксимацию.

    • Усовершенствованный Эйлер уменьшил ошибку в ~25 раз (~0.0004) за счёт учёта средней производной на шаге.

    • Рунге-Кутта 4 показал наилучшую точность (ошибка ~10⁻⁶) благодаря сложной взвешенной схеме расчёта.

  2. Скорость работы

    • Эйлер — самый быстрый (21 вычисление f(x,y) для h=0.1), но менее точен.

    • Рунге-Кутта — самый медленный (84 вычисления), но незаменим для задач, требующих высокой точности.

  3. Визуализация результатов

    • Графики наглядно показали, как ошибка накапливается при увеличении x:

      • У Эйлера ошибка растёт линейно.

      • У Рунге-Кутты ошибка остаётся минимальной даже на конце интервала.

Что я узнал и чему научился

 Как работают численные методы

  • Метод Эйлера — базовый подход, основанный на касательной.

  • Рунге-Кутта — использование нескольких точек для повышения точности.

 Как сравнивать эффективность алгоритмов

  • По количеству вычислений правой части уравнения.

  • По накопленной ошибке на заданном интервале.

 Как анализировать результаты

  • Сравнение с точным решением (y = e^{x²/2}).

  • Построение графиков ошибок в логарифмическом масштабе.

Практические рекомендации

  1. Для учебных задач подойдёт метод Эйлера — он прост в реализации.

  2. Для научных расчётов лучше использовать Рунге-Кутта 4.

  3. Баланс скорости и точности — усовершенствованный метод Эйлера.

Итог

Это задание помогло мне:  Понять разницу между простыми и сложными методами.  Увидеть на практике, как порядок точности влияет на результат.  Научиться выбирать метод под конкретную задачу.

Вывод: Для серьёзных расчётов стоит использовать методы высокого порядка (Рунге-Кутта), но для обучения и быстрых оценок достаточно метода Эйлера.

Соседние файлы в папке лаб