E128. Интегрирование по формуле Симпсона
emaxx algorithm
Task
Источник: e-maxx.ru/algo, страница PDF 419.
Требуется посчитать значение определённого интеграла: Решение, описываемое здесь, было опубликовано в одной из диссертаций Томаса Симпсона (Thomas Simpson) в 1743 г.
Формула Симпсона
Пусть
— некоторое натуральное число. Разобьём отрезок интегрирования
на
равных частей:
Теперь посчитаем интеграл отдельно на каждом из отрезков
, а затем сложим все значения.
Итак, пусть мы рассматриваем очередной отрезок
. Заменим функцию
на
нём параболой, проходящей через 3 точки
. Такая парабола всегда существует и единственна. Её можно найти аналитически, затем останется только проинтегрировать выражение для неё, и окончательно получаем: Складывая эти значения по всем отрезкам, получаем окончательную формулу Симпсона:
Погрешность
Погрешность, даваемая формулой Симпсона, не превосходит по модулю величины:
Таким образом, погрешность имеет порядок уменьшения как
.
Реализация
Здесь
— некоторая пользовательская функция.
double a, b; // входные данные
const int N = 1000*1000; // количество шагов (уже умноженное на 2)
double s = 0;
double h = (b - a) / N;
for (int i=0; i<=N; ++i) {
double x = a + h * i;
s += f(x) * ((i==0 || i==N) ? 1 : ((i&1)==0) ? 2 : 4);
}
s *= h / 3;
C# solution
auto-draft, review before submitusing System;
using System.Collections.Generic;
using System.Linq;
public static class AlgorithmDraft
{
// Auto-generated C# draft from the original e-maxx C/C++ listing. Review before production use.
double a, b; // входные данные
const int N = 1000*1000; // количество шагов (уже умноженное на 2)
double s = 0;
double h = (b - a) / N;
for (int i=0; i<=N; ++i) {
double x = a + h * i;
s += f(x) * ((i==0 || i==N) ? 1 : ((i&1)==0) ? 2 : 4);
}
s *= h / 3;
}C++ solution
matched/originaldouble a, b; // входные данные
const int N = 1000*1000; // количество шагов (уже умноженное на 2)
double s = 0;
double h = (b - a) / N;
for (int i=0; i<=N; ++i) {
double x = a + h * i;
s += f(x) * ((i==0 || i==N) ? 1 : ((i&1)==0) ? 2 : 4);
}
s *= h / 3;Java solution
auto-draft, review before submitimport java.util.*;
import java.math.*;
public class AlgorithmDraft {
// Auto-generated Java draft from the original e-maxx C/C++ listing. Review before production use.
double a, b; // входные данные
const int N = 1000*1000; // количество шагов (уже умноженное на 2)
double s = 0;
double h = (b - a) / N;
for (int i=0; i<=N; ++i) {
double x = a + h * i;
s += f(x) * ((i==0 || i==N) ? 1 : ((i&1)==0) ? 2 : 4);
}
s *= h / 3;
}Explanation
Материал разбит как алгоритмическая задача: изучить постановку, понять асимптотику и реализовать алгоритм на выбранном языке.