Почему этот код для интегрирования области под кривой 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;
}
Код ниже не смешивается с использованием переменной цикла и х. Недостаток (такой же, как у вашего кода) заключается в том, что при суммировании ошибок накапливается 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;
}
Вы забыли длину интервала в аргументе функции
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));