梯形积分程序没有返回合理的值

时间:2017-01-21 18:45:07

标签: c++ visual-c++ calculus

为什么这段代码没有整合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;
    }

2 个答案:

答案 0 :(得分:0)

以下代码不使用循环变量和x进行混合。它有一个缺点(与你的代码相同),累加误差求和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;
}

答案 1 :(得分: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));