Программа трапециевидной интеграции не возвращает разумного значения

Почему этот код для интегрирования области под кривой sin не возвращает разумное значение? (отредактировано, чтобы включить кучу предложений)

// Я хочу написать программу, которая берет область под кривой путем вывода суммы площадей из n прямоугольников

#include <vector>
#include <iostream>
#include <cmath>
#include <numeric>

double interval(double d, double n)
{
return d / n;
}

using namespace std;

int main()
{
double xmax = 20;                   //upper bound
double xmin = 2;                    //lower bound
double line_length = xmax - xmin;   //range of curve
double n = 1000;                    //number of rectangles
vector<double> areas;
double interval_length = interval(line_length, n);
for (double i = 0; i < n; ++i)
{
double fvalue = xmin + i;
areas.push_back((interval_length * sin(fvalue)) + (0.5 * interval_length * (sin(fvalue + 1) - sin(fvalue))));
//idea is to use A = b*h1 + 1/2 b*h2 to approximate the area under a curve using trapezoid area
}

Я добавил fvalue, interval_length и немного исправил логику

 double sum_areas = accumulate(areas.begin(), areas.end(), 0.0);
//accumulate takes each element in areas and adds them together, beginning with double 0.0
cout << "The approximate area under the curve is " << '\n';
cout << sum_areas << '\n';
//this program outputs the value 0.353875, the actual value is -.82423
return 0;
}

0

Решение

Код ниже не смешивается с использованием переменной цикла и х. Недостаток (такой же, как у вашего кода) заключается в том, что при суммировании ошибок накапливается dx, т.е. dx * n! = Xmax-xmin. Чтобы учесть эту конкретную ошибку, необходимо вычислить ток x как функцию i (переменная цикла) на каждой итерации как x = xmin + (xmax — xmin) * i / n.

#include <iostream>
#include <cmath>

double sum(double xmin, double xmax, double dx)
{
double rv = 0;

for (double x = xmin + dx; x <= xmax; x += dx)
rv += (sin(x) + sin(x-dx)) * dx / 2;

return rv;
}

int main()
{
int n = 1000;
double xmin = 0;
double xmax = 3.1415926;
std::cout << sum(xmin, xmax, (xmax - xmin)/n) << std::endl;

return 0;
}
0

Другие решения

Вы забыли длину интервала в аргументе функции

double fvalue = xmin + i;
areas.push_back((interval_length * sin(fvalue)) + (0.5 * interval_length * (sin(fvalue + 1) - sin(fvalue))));

Должно быть вместо

double fvalue = xmin + i*interval_length;
areas.push_back((interval_length * sin(fvalue)) + (0.5 * interval_length * (sin(fvalue + interval_length) - sin(fvalue))));

Вторая строка может быть лучше написана как

areas.push_back(interval_length * 0.5 * (sin(fvalue + interval_length) + sin(fvalue));
0