Riemann Midpoint Sum得到了疯狂的数字

时间:2016-04-20 22:35:14

标签: c# algorithm

我正在研究Midpoint Riemann Sum计划,它找到了一个名为function的随机生成f的积分。

这里写的是:

 public static double FindIntegral (double start, double end, function f)
    {
        double sum = 0;
        double stepsize = 1E-2;
        int numSteps = (int)((end - start) / stepsize);
        for (int i = 0; i < numSteps; i++)
        {
            sum += f(start +  (stepsize * (i + 0.5)));
        }
        return sum * stepsize;
    }

该函数返回的数字太低(我有一个可靠的检查机制)。 我输入x ^ 3表示f,我得到了正确的答案。我尝试了几个可集成的函数并得到了一个很好的答案。但不知怎的,一旦我放入f,它就无法运作。

1 个答案:

答案 0 :(得分:0)

我得到了#34; Riemann Midpoint Sum&#34;的数学公式。来自here

我的下面的实现似乎得到了正确的答案(使用页面上的示例函数)。我使用了一个类,因为1)我可以使算法工作指定步长或矩形数(我更喜欢后者)和2)我没有看到任何理由硬编码到算法中。

事实证明你的代码似乎工作得很好(见下文);确保您在问题中的代码是您正在执行的代码,并确保您的预期结果是准确的,并且您提供了良好的输入(即您没有startend向后或错误的function f或其他东西)。换句话说,您在问题中提供的内容看起来很好。注意double是C#中的近似值(通常是浮点算术),因此为了比较相等性,您不能使用==,除非您想要使用单位测试或其他内容。

public class Program
{
    public static void Main()
    {           
        function f = x => 50 / (10 + x * x);    

        // 9.41404285216233
        Console.Out.WriteLine(new RiemannMidpointSum(6).FindIntegral(1, 4, f)); 

        // 9.41654853716462
        Console.Out.WriteLine(new RiemannMidpointSum(1E-2).FindIntegral(1, 4, f));

        // 9.41654853716462
        Console.Out.WriteLine(Program.FindIntegral(1, 4, f));   
    }

    // This is your function.
    public static double FindIntegral (double start, double end, function f)
    {
        double sum = 0;
        double stepsize = 1E-2;
        int numSteps = (int)((end - start) / stepsize);
        for (int i = 0; i < numSteps; i++)
        {
            sum += f(start +  (stepsize * (i + 0.5)));
        }
        return sum * stepsize;
    }   
}

public delegate double function(double d);

public class RiemannMidpointSum
{
    private int? _numberOfRectangles;
    private double? _widthPerRectangle;

    public RiemannMidpointSum(int numberOfRectangles)
    {
        // TODO: Handle non-positive input.
        this._numberOfRectangles = numberOfRectangles;
    }

    public RiemannMidpointSum(double widthPerRectangle)
    {
        // TODO: Handle non-positive input.
        this._widthPerRectangle = widthPerRectangle;
    }

    public double FindIntegral(double a, double b, function f)
    {       
        var totalWidth = b - a;
        var widthPerRectangle = this._widthPerRectangle ?? (totalWidth / this._numberOfRectangles.Value);
        var numberOfRectangles = this._numberOfRectangles ?? ((int)Math.Round(totalWidth / this._widthPerRectangle.Value, 0));

        double sum = 0;     
        foreach (var i in Enumerable.Range(0, numberOfRectangles))
        {
            var rectangleMidpointX = a + widthPerRectangle * i + widthPerRectangle / 2;         
            var rectangleHeightY = f(rectangleMidpointX);
            var rectangleArea = widthPerRectangle * rectangleHeightY;

            sum += rectangleArea;
        }       

        return sum;
    }
}