этот код объединяет 2-мерное [(1/2 * pi) * exp (-xr ^ 2/2) * exp (-xa ^ 2/2)].
интеграл для этого уравнения равен 1 в бесконечности, поэтому в c ++ мы должны увеличить пределы и n, чтобы получить результат, равный 1 в теории.
Если мы применим квадратуру Ньютона – Котса к бесконечному интегралу
, нам нужно обрезать нижнюю и верхнюю границу этогоинтеграл.Интегральное выражение должно быть пренебрежимо малым в точках отсечения.Какое значение вы выбрали?
Интегралом вашей задачи является гауссовское значение, которое быстро уменьшается следующим образом:
exp(-10*10/2) ~ 1.93 * 10^(-22)
, что было бы незначительным в текущей интеграции.Таким образом, если мы обрежем нижнюю и верхнюю границу на -10 и +10, соответственно, и установим достаточное количество точек в этом диапазоне, мы должны получить точный результат.
Я действительно получил точный результат с точками 100x100, используяследующая трапециевидная квадратура.Эта квадратура самая простая.Мой тестовый код здесь .
1-мерная интеграция:
template<typename F>
double integrate_trapezoidal(F func, std::size_t n, double lowerBnd, double upperBnd)
{
if(lowerBnd == upperBnd){
return 0.0;
}
auto integral = 0.0;
auto x = lowerBnd;
const auto dx = (upperBnd - lowerBnd)/n;
auto left = func(x);
for(std::size_t i = 0; i<n; ++i)
{
x += dx;
const auto right = func(x);
integral += (left + right);
left = right;
}
integral *= (0.5*dx);
return integral;
}
2-мерная интеграция:
template<typename F>
double integrate_trapezoidal_2dim(
F func_2dim,
std::size_t n,
double x_lowerBnd, double x_upperBnd,
double y_lowerBnd, double y_upperBnd)
{
auto func = [&](double x)
{
return integrate_trapezoidal(
std::bind(func_2dim, x, std::placeholders::_1),
n, y_lowerBnd, y_upperBnd);
};
return integrate_trapezoidal(func, n, x_lowerBnd, x_upperBnd);
}
Я беспокоюсь, что вы установили конечную, но очень большую верхнюю и нижнюю границу.В этом случае вам нужно установить много точек, чтобы увеличить количество точек в диапазоне -10
Наконец, существуют различные квадратуры для числовых интегрирований.Если вы вставляете какую-то функцию в эту гауссову подынтегральную функцию, то рекомендуется использовать квадратуру Эрмита или быстрое преобразование Гаусса.