У меня есть две функции. Я даю здесь только базовую структуру, поскольку у каждого из них достаточно параметров для точной настройки.
Например, y = sin(.1*pi*x)^2
а также y = e^-(x-5)^2
,
Вопрос в том, сколько площади синуса захвачено e
функция:
Я пытался быть умным и рекурсивно находить точки пересечения, но это оказалось намного больше работы, чем было необходимо.
Как n.m.
указал, Вы хотите, чтобы интеграл от a
в b
из min(f, g)
, Поскольку вы интегрируете с помощью аппроксимации, вы уже проходите интервал, то есть на каждом шаге вы можете проверить, какая функция больше, и вычислить площадь текущей трапеции.
Простая реализация на C:
#define SLICES 10000
/*
* Computes the integral of min(f, g) on [a, b].
*
* Intended use is for when f and g are both non-negative, real-valued
* functions of one variable.
*
* That is, f: R -> R and g: R -> R.
*
* Assumes b ≥ a.
*
* @param a left boundary of interval to integrate over
* @param b right boundary of interval to integrate over
* @param f function accepting one double argument which returns a double
* @param g function accepting one double argument which returns a double
* @return integral of min(f, g) on [a, b]
*/
double minIntegrate (double a, double b, double (*f)(double), double (*g)(double)) {
double area = 0.0;
// the height of each trapezoid
double deltaX = (b - a) / SLICES;
/*
* We are integrating by partitioning the interval into SLICES pieces, then
* adding the areas of the trapezoids formed to our running total.
* To save a computation, we can cache the last side encountered.
* That is, let lastSide be the minimum of f(x) and g(x), where x was the
* previous "fence post" (side of the trapezoid) encountered.
* Initialize lastSide with the minimum of f and g at the left boundary.
*/
double lastSide = min(f(a), g(a));
// The loop starts at 1 since we already have the last (trapezoid) side
// for the 0th fencepost.
for (int i = 1; i <= SLICES; i++) {
double fencePost = a + (i * deltaX);
double currentSide = min(f(fencePost), g(fencePost));
area += trapezoid(lastSide, currentSide, deltaX);
lastSide = currentSide;
}
return area;
}
/*
* Computes the area of a trapezoid with bases `a` and `b` and height `height`.
*/
double trapezoid (double a, double b, double height) {
return h * (a + b) / 2.0;
}
Если вы ищете что-то действительно очень простое, почему бы вам не Интеграция Монте-Карло?
Используйте тот факт, что функции легко рассчитать, чтобы выбрать большое количество точек. Для каждой точки проверьте, находится ли она ниже 0, 1 или 2 кривых.
Возможно, вам придется немного потрудиться, чтобы найти границы для выборки, но этот метод будет работать для различных кривых.
Я предполагаю, что ваша экспонента на самом деле имеет форму е ^ — (х-5) ^ 2, так что экспонента затухает до нуля в плюс / минус бесконечности.
Учитывая это, ваш интеграл будет наиболее быстро и точно вычислен чем-то Гауссовская квадратура. Существует несколько типов общих интегралов, которые имеют очень простые решения с использованием различных полиномов (Эрмита, Лежандра и т. Д.). Ваш конкретно выглядит так, как будто это можно решить с помощью Квадратура Гаусса-Эрмита.
Надеюсь это поможет.