Еngee как альтернатива PascalABC
Методы численного интегрирования. Нахождение определённого интеграла. ЛР №14
Подгрузка нужных библиотек:
Pkg.add("PrettyTables");
Pkg.add("NumericalIntegration");
using Printf
using NumericalIntegration
using PrettyTables
В данной лабораторной работе мы рассмотрим различные методы интегрирования, на примере функции .
Определим нижний и верхний предел функции, а также количество шагов интегрирования, от которого будет зависеть точность полученных результатов:
println("Нахождение определенного интеграла")
println("Введите нижний предел a: ")
a = parse(Float64, readline())
println("Введите верхний предел b: ")
b = parse(Float64, readline())
println("Введите количество шагов n: ")
n = parse(Int, readline())
h = (b - a) / n;
Определим нашу функцию и найдём её значения на заданном интервале:
# Определяем функцию
fun(x1) = x1^2 * sqrt(4 - x1^2)
# Вычисляем значения функции на интервале
x = collect(a:h:b)
y = fun.(x);
В качестве референтного значения - возьмём точное значение интеграла при помощи функции integrate() из библиотеки NumericalIntegration:
# Вычисляем точное значение интеграла
Точное_значение = NumericalIntegration.integrate(x, y)
println("Точное значение интеграла = ", Точное_значение)
Метод трапеций
Первый рассматриваемый метод - метод трапеций. И реализуется он следующим образом:
# Метод трапеций
x_trap = collect((a+h):h:(b-h))
y_trap = fun.(x_trap) # Используем точечное применение функции
трапеций = h * ((fun(a) + fun(b)) / 2 + sum(y_trap))
s1 = abs(Точное_значение - трапеций) / abs(Точное_значение);
Выведем полученный результат и погрешность, округлив полученные значения до 4 знаков после запятой:
print("Значение интеграла МТ = ", round(трапеций, digits = 4), "\nПогрешность = ", round(s1, digits = 4))
Метод правых прямоугольников
Второй рассматриваемый метод - метод правых прямоугольников. Его реализация выглядит так:
# Метод правых прямоугольников
x_right = collect((a+h):h:b)
y_right = fun.(x_right) # Используем точечное применение функции
правых = h * sum(y_right)
s2 = abs(Точное_значение - правых) / abs(Точное_значение);
Выведем полученный результат и погрешность, округлив полученные значения до 4 знаков после запятой:
print("Значение интеграла МПП = ", round(правых, digits = 4), "\nПогрешность = ", round(s2, digits = 4))
Метод левых прямоугольников
Следующим, третьим методом мы рассмотрим - метод левых прямоугольников. Его реализация похожа на предыдущий метод, но имеет некоторые ключевые отличия:
# Метод левых прямоугольников
x_left = collect(a:h:(b-h))
y_left = fun.(x_left) # Используем точечное применение функции
левых = h * sum(y_left)
s3 = abs(Точное_значение - левых) / abs(Точное_значение);
Выведем полученный результат и погрешность, округлив полученные значения до 4 знаков после запятой:
print("Значение интеграла МЛП = ", round(левых, digits = 4), "\nПогрешность = ", round(s3, digits = 4))
Метод Симпсона
Последним, четвёртым методом из рассматриваемых является Метод Симпсона. Для его реализации используем функцию integrate() с указанием метода SimpsonEven() в качестве аргумента:
# Метод Симпсона
Симпсона = NumericalIntegration.integrate(x, y, SimpsonEven())
s4 = abs(Точное_значение - Симпсона) / abs(Точное_значение);
Выведем полученный результат и погрешность, округлив полученные значения до 4 знаков после запятой:
print("Значение интеграла МС = ", round(Симпсона, digits = 4), "\nПогрешность = ", round(s4, digits = 4))
Сравнение методов интегрирования
Для сравнения рассмотренных методов, соберём их в одну программу и выведем результаты интегрирования и погрешности в таблицу. Благодаря использованию масок ячеек, можем менять пределы интегрирования и количество шагов, чтобы в динамике пронаблюдать за тем, как они влияют на полученные результаты:
Введите_нижний_предел_a = "0" # @param{type: "string"}
a = parse(Float64, Введите_нижний_предел_a)
Введите_верхний_предел_b = "2" # @param{type: "string"}
b = parse(Float64, Введите_верхний_предел_b)
Введите_количество_шагов_n = "4" # @param{type: "string"}
n = parse(Int64, Введите_количество_шагов_n)
h = (b - a) / n;
# Определяем функцию
fun(x1) = x1^2 * sqrt(4 - x1^2)
# Вычисляем значения функции на интервале
x = collect(a:h:b)
y = fun.(x);
# Вычисляем точное значение интеграла
Точное_значение = NumericalIntegration.integrate(x, y)
println("Точное значение интеграла = ", Точное_значение)
# Метод трапеций
x_trap = collect((a+h):h:(b-h))
y_trap = fun.(x_trap) # Используем точечное применение функции
трапеций = h * ((fun(a) + fun(b)) / 2 + sum(y_trap))
s1 = abs(Точное_значение - трапеций) / abs(Точное_значение)
# Метод правых прямоугольников
x_right = collect((a+h):h:b)
y_right = fun.(x_right) # Используем точечное применение функции
правых = h * sum(y_right)
s2 = abs(Точное_значение - правых) / abs(Точное_значение)
# Метод левых прямоугольников
x_left = collect(a:h:(b-h))
y_left = fun.(x_left) # Используем точечное применение функции
левых = h * sum(y_left)
s3 = abs(Точное_значение - левых) / abs(Точное_значение)
# Метод Симпсона
Симпсона = NumericalIntegration.integrate(x, y, SimpsonEven())
s4 = abs(Точное_значение - Симпсона) / abs(Точное_значение)
# Подготовка данных для таблицы
методы = ["Трапеций", "Правых прямоугольников", "Левых прямоугольников", "Симпсона"]
результаты = round.([трапеций, правых, левых, Симпсона], digits=5)
погрешности = round.([s1, s2, s3, s4], digits=5)
# Вывод таблицы
pretty_table([методы результаты погрешности], header = ["Метод", "Результат", "Относительная погрешность"])