c# - C#中PointCollection的数值积分
问题描述
我有一个 PointCollection,其中包含我生成的正弦数据。现在我必须建立这些数据的数值积分并将其与正弦数据(每折线)一起绘制。我在stackoverflow上找到了这个函数,但它并没有真正起作用:(sin(x)的积分通常应该是-cos(x),但我得到的是-sin(x),我必须缩放是的,但在类似的插值函数中,它无需缩放即可工作.有人知道我的问题在哪里吗?
红色:原始噪声数据,蓝色:插值数据绿色:综合数据
private PointCollection Numerical_Integration(PointCollection input_data)
{
PointCollection integrated_data = new();
for (int i = 1; i < input_data.Count; i++)
{
double integrated_ypos = (input_data[i].Y + input_data[i - 1].Y) / 2 * (input_data[i].X - input_data[i - 1].X);
integrated_data.Add(new Point(input_data[i].X, integrated_ypos/5+300));
}
return integrated_data;
}
解决方案
这使用标准梯形规则进行积分。
程序
static class Program
{
static void Main(string[] args)
{
// Integrate f(x) = 10*cos(x) between x=0..4π
var curve = new PointCollection();
const int n = 180;
for (int i = 0; i < n; i++)
{
float x = (float)( (4 * Math.PI * i) / n );
float y = (float)( 10 * Math.Cos(x) );
curve.Add(new PointF(x, y));
}
var integral = Integrate(curve, 0f);
// Compare results to 10*sin(x)
float max_error = 0;
for (int i = 0; i < n; i++)
{
float x = (float)((4 * Math.PI * i) / n);
float iy_expect = (float)(10 * Math.Sin(x));
float iy_actual = integral[i].Y;
float iy_error = Math.Abs(iy_actual - iy_expect);
max_error = Math.Max(max_error, iy_error);
}
Console.WriteLine($"Steps = {n}, Max Error = {max_error}.");
}
public static PointCollection Integrate(PointCollection inputData, float integrationConstant = 0)
{
float h;
var integral = new PointCollection();
integral.Add(new PointF(inputData[0].X, integrationConstant));
for (int i = 1; i < inputData.Count; i++)
{
h = inputData[i].X - inputData[i - 1].X;
float iy = integral[i - 1].Y + h * (inputData[i].Y + inputData[i - 1].Y) / 2;
integral.Add(new PointF(inputData[i].X, iy));
}
return integral;
}
}
输出
Steps = 180, Max Error = 0.004058838.
从输出中可以看出,考虑到输入曲线的分辨率,误差非常好。
错误分析
考虑到越来越多的步骤,这是我报告的最大错误:
Steps Error
16 0.5194054
32 0.1288424
64 0.03214836
128 0.008034706
256 0.002008438
512 0.0005044937
1024 0.0001296997
2048 3.71933E-05
4096 1.049042E-05
8192 1.716614E-05
16384 1.335144E-05
32768 2.288818E-05
如您所见,我float
在大约 4096 步处达到了数字的精度极限。
推荐阅读
- git - 如何使用 git commit count 找到对应的提交?
- r - 根据其他列中的值添加列
- php - 在 Laravel 的页面上应用过滤器后获取表格上的数据
- c# - VS Community 2019 中 ASP.NET 项目的默认模板不起作用
- json - 由于格式不正确,无法读取 Json 解析和数据
- python - 我在一个变量中有多个字典。如何将它们转换为熊猫数据框?
- android - 如何在firebase firestore中的数据中应用具有不同深度级别的多个where子句?
- r - unique.default(x, nmax = nmax) 中的错误:unique() 仅适用于使用 with(data_frame, table(year, country)) 的向量
- azure - 创建索引器,将数据源作为索引内 JSON 文档中的字段
- azure-active-directory - Azure Graph,通过 PrincipalId (ObjectId) 获取类型