背景
我有一个我喜欢不时想太多的宠物项目。该项目与 RC 飞机控制输入设备有关。熟悉该爱好的人可能也熟悉所谓的“摇杆博览会”,这是 RC 发射器的一个共同特征,其中控制杆在中性中心位置附近或多或少敏感,并随着摇杆靠近其最小值或最大值。
我读过一些我不完全理解的论文。我显然没有数学背景来解决这个问题,所以我希望你们中的一个人可能会。
问题
我决定通过获取预定数量的样本来近似曲线,并使用线性插值来确定样本点之间任何输入值的输出值。 我试图找到一种方法来确定最佳的样本点集。
如果您查看此应用程序的典型增长曲线示例,您会注意到有些部分更线性(更直),而另一些则不太线性(更弯曲)。
这些样本彼此之间的距离相等,但并非必须如此。在有更多变化的地方增加样本密度,从而通过从直线段借用冗余点来提高曲线段的分辨率,这将是明智的。
是否可以量化误差程度?如果是,那么是否也可以确定给定函数的最佳样本集和预定数量的样本?
参考代码
使用预先计算的一组点来近似输出值的类的片段。
/* This makes the following assumptions:
* 1. The _points[] data member contians at least 2 defined Points.
* 2. All defined Points have x and y values between MIN_VALUE and MAX_VALUE.
* 3. The Points in the array are ordered by ascending values of x.
*/
int InterpolatedCurve::value( int x ) {
if( _points[0].x >= x ) { return _points[0].y; }
for( unsigned int i = 1; i < _point_count; i++ ) {
if( _points[i].x >= x ) {
return map(x, _points[i-1].x, _points[i].x,
_points[i-1].y, _points[i].y);
}
}
// This is an error condition that is not otherwise reported.
// It won't happen as long as the points are set up correctly.
return x;
}
// Example map function (borrowed from Arduino site)
long map( long x, long x1, long x2, long y1, long y2 ) {
return (x - x1) * (y2 - y1) / (x2 - x1) + y1;
}
尽管我的项目实际上是用 C++ 编写的,但在思考这个问题时,我正在使用 Google 电子表格生成一些数字。
// x: Input value between -1 and 1
// s: Scaling factor for curve between 0 (linear) and 1 (maximum curve)
// c: Tunable constant
function expo_fn( x, s, c ) {
s = typeof s !== 'undefined' ? s : 1.0;
c = typeof c !== 'undefined' ? c : 4.0;
var k = c * ((c - 1.0) * s*s*s + s)/c + 1.0;
return ((k - 1.0) * x*x*x*x*x + x)/k;
};
下面在输入值 -1 和 1 之间创建一组等距分布(非最佳)点。对于上述示例电子表格,这些输出值已扩展为 -16383 和 16383 之间的整数。因子是一个介于 0 和 1 之间的值,它决定了“曲线”——零是平坦的线性曲线,而 1 是我想要生成的最小线性曲线。
function Point( x, y ) {
this.x = x;
this.y = y;
};
function compute_points_iso( count, factor ) {
var points = [];
for( var i = 0; i < count; ++i ) {
var x = 2.0/(count - 1.0) * i - 1.0;
var y = expo_fn(x, factor);
points.push(new Point(x,y));
}
return points;
};
相关学术工作
我一直在研究这篇论文,描述了一种用于选择重要数据点的算法,但我的程序还不能很好地工作。如果我能让这个东西工作,我会报告回来。