【问题标题】:Trapezoidal integration program doesn't return a reasonable value梯形积分程序没有返回合理的值
【发布时间】:2017-01-21 18:45:07
【问题描述】:

为什么这个对 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;
    }

【问题讨论】:

  • "#include "../../../../../Desktop/C++/stroustrupheaders/std_lib_facilities.h" " Blimey
  • 您可以将重复多次的值存储到一个变量中,以避免不必要的重新计算。
  • 你有没有尝试增加 n 的值,看看会发生什么?
  • 对不起!我只是没有太多使用标准库的东西。我确实知道,对于这个程序,它让我可以使用向量类和命名空间 std。我只是不知道要包含什么来使用这两个。
  • 先试着写下公式:根据 x 和 y = sin(x),b 和 h 是什么不清楚。 Sin(i) 和 sin(i+1) 看起来很可疑:sin 应该是 x 的函数,而不是循环变量。

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


【解决方案1】:

下面的代码没有混合使用循环变量和 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;
}

【讨论】:

    【解决方案2】:

    您忘记了函数参数中的间隔长度

    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));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-27
      • 1970-01-01
      • 2014-03-24
      • 2015-05-15
      • 2020-05-24
      • 2019-08-27
      相关资源
      最近更新 更多