C# 使用Math.Net Numerics使用大x值进行不正确的线性插值
我正在尝试使用Math.NET Numerics对日期时间值序列进行插值。我从线性插值开始,但是我得到了一些非常不好看的结果 运行此测试:C# 使用Math.Net Numerics使用大x值进行不正确的线性插值,c#,linear-interpolation,math.net,numerics,C#,Linear Interpolation,Math.net,Numerics,我正在尝试使用Math.NET Numerics对日期时间值序列进行插值。我从线性插值开始,但是我得到了一些非常不好看的结果 运行此测试: public class script{ public void check_numerics() { var ticks = DateTime.Now.Ticks; Console.WriteLine("Ticks: " + ticks); var xValues = new double[] { ticks, ticks +
public class script{
public void check_numerics()
{
var ticks = DateTime.Now.Ticks;
Console.WriteLine("Ticks: " + ticks);
var xValues = new double[] { ticks, ticks + 1000, ticks + 2000, ticks + 3000, ticks + 4000, ticks + 5000 };
var yValues = new double[] {0, 1, 2, 3, 4, 5};
var spline = Interpolate.LinearBetweenPoints(xValues, yValues);
var ticks2 = ticks;
for (int i = 0; i < 10; i++)
{
ticks2 += 500;
Console.WriteLine(spline.Interpolate(ticks2));
}
}
}
请注意,2.4285是相当错误的。在不同的时间(不同的刻度值),不同的值将是“错误的”。Math.NET中是否存在x值较大的“bug”,或者我是否期望过高 作为Math.NET Numerics的维护者,仅确认上述评论: 可以双精度表示的该量级最接近数字之间的距离(ε)为128:
Precision.EpsilonOf(ticks); // 128
这意味着,如果您从该数字中添加或减去128/2-1=63
,您将得到完全相同的数字:
long ticks = DateTime.Now.Ticks // 635385606515570758
((long)(double)ticks) // 635385606515570816
((long)(63+(double)ticks)) // 635385606515570816
((long)(-63+(double)ticks)) // 635385606515570816
((long)(65+(double)ticks)) // 635385606515570944
((long)(-65+(double)ticks)) // 635385606515570688
500的增量步骤非常接近这128个步骤,并且有效地四舍五入到128的倍数(例如512),因此出现类似这样的工件也就不足为奇了
如果按照James的建议,通过将滴答数除以10000将时间精度降低到毫秒,则得到的ε为0.0078125,即使步长为1而不是500,也会得到准确的结果
Precision.EpsilonOf(ticks/10000); // 0.0078125
考虑到double只有15-17 s.f.,它不会完全准确,而且你超过了它,所以double不能准确地表示你给出的值,但我认为它会更接近这个值谢谢@jamesbarras,所以你不能用double表示当前时间——很高兴知道!不是那么精确,毫秒,也许10微秒。不会小很多。IIRC滴答声约为100纳秒
Precision.EpsilonOf(ticks/10000); // 0.0078125