Function 如何在Dart中的数字数据表值之间进行插值(实际上是在任何语言中)

Function 如何在Dart中的数字数据表值之间进行插值(实际上是在任何语言中),function,dart,interpolation,Function,Dart,Interpolation,我有一个简单的数据表,其中包含x和y值,如下所示: x y -10 -0.505 -9 -0.422 -8 -0.335 -7 -0.243 -6 -0.148 -5 -0.051 -4 0.046 -3 0.144 -2 0.242 -1 0.34 0 0.539 1 0.658 2 0.773 3 0.716 4 0.8 5 0.88 6 0.952 7 1.016 8

我有一个简单的数据表,其中包含x和y值,如下所示:

x     y
-10  -0.505
-9   -0.422
-8   -0.335
-7   -0.243
-6   -0.148
-5   -0.051
-4    0.046
-3    0.144
-2    0.242
-1    0.34
0     0.539
1     0.658
2     0.773
3     0.716
4     0.8
5     0.88
6     0.952
7     1.016
8     1.071
9     1.116
10    1.15
x步长以及最小值和最大值可能不同

我正在寻找一个内置的功能来插值这些值。 所以我需要一个函数,它取x值并返回相应的y值。当没有精确匹配时,我需要函数在两个最接近的值之间进行线性插值

当然,我可以编写自己的函数,但我觉得可能有一个简单的解决方案,甚至可能是内置的Dart

谢谢你的帮助

谢谢,干杯


Tobi

pub.dev上可能有一些软件包已经这样做了,但我会使用a及其方法来查找周围的点,然后在它们之间进行插值。例如:

导入“dart:collection”显示SplayTreeMap;
导入“省道:数学”显示点;
///返回定义行上指定x坐标的y坐标
///通过两个给定点。
双插值(点p0、点p1、双x){
//y-y0=m*(x-x0)
var m=(p1.y-p0.y)/(p1.x-p0.x);
返回m*(x-p0.x)+p0.y;
}
类插值映射{
最终SplayTreeMap_数据;
插值地图(地图数据)
:_data=SplayTreeMap.of(数据);
双运算符[](双x){
var值=_数据[x];
if(值!=null){
返回值;
}
if(_data.isEmpty){
抛出状态错误('InterpolingMap为空');
}
double?lower=_data.lastKeyBefore(x);
double?upper=_data.firstKeyAfter(x);
断言(下!=null | |上!=null);
双x0;
双x1;
如果(下限==null){
//'x'位于最左侧数据点的左侧。从
//前两项。
x0=上!;
x1=_数据。第一个键之后(上)??x0;
}else if(上限==null){
//'x'位于最右侧数据点的右侧。从
//最后两项。
x1=更低;
x0=_数据。lastKeyBefore(下)??x1;
}否则{
x0=更低;
x1=上限;
}
返回插值(
点(x0,_数据[x0]!),
点(x1,_数据[x1]!),
x,,
);
}
}
void main(){
var插值映射=插值映射({
0: 1,
1: 2,
2: 1,
});
打印(插值映射[-1]);//打印:0
打印(插值映射[0]);//打印:1
打印(插值贴图[0.25]);//打印:1.25
打印(插值贴图[0.5]);//打印:1.5
打印(插值贴图[0.75]);//打印:1.75
打印(插值映射[1]);//打印:2
打印(插值映射[1.5]);//打印:1.5
打印(插值映射[3]);//打印:0
}

请注意,上述实现中的
interpolingmap
有点用词不当,因为它还将外推数据范围之外的值。(如果你想禁用外推,让它抛出一个异常应该很简单。)它也没有实现
Map
接口(这留给关心这个的读者作为练习)。

我可能会使用二进制搜索来找到匹配范围,然后从中进行插值。 您可以使用
package:collection
中的方法查找小于或等于您搜索的元素的最大元素

比如:

import“package:collection/collection.dart”;
双插值(列出关键点、列表值、num x){
如果(关键点长度<2){
抛出ArgumentError.value(关键点,“关键点”,
“至少需要插入两个点”);
}
if(keyPoints.length!=values.length){
抛出ArgumentError.value(值,“值”,
“必须具有与关键点相同数量的元素”);
}
var p=关键点。下限(x);
如果(p>keyPoints.length-2)p=keyPoints.length-2;
var起始位置=关键点[p];
var endPosition=关键点[p+1];
var startValue=数值[p];
var endValue=数值[p+1];
返回(x-起始位置)/(结束位置-起始位置)*(结束值-起始值);
}
x
位于两个关键点之间时,这将对值进行插值,如果
x
值超出关键点范围,则将对第一个或最后一个范围进行外推