我正在研究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
,它就无法运作。
答案 0 :(得分:0)
我得到了#34; Riemann Midpoint Sum&#34;的数学公式。来自here。
我的下面的实现似乎得到了正确的答案(使用页面上的示例函数)。我使用了一个类,因为1)我可以使算法工作指定步长或矩形数(我更喜欢后者)和2)我没有看到任何理由硬编码到算法中。
事实证明你的代码似乎工作得很好(见下文);确保您在问题中的代码是您正在执行的代码,并确保您的预期结果是准确的,并且您提供了良好的输入(即您没有start
和end
向后或错误的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;
}
}