您可以对一条线进行最小二乘拟合。
function LineFitter()
{
this.count = 0;
this.sumX = 0;
this.sumX2 = 0;
this.sumXY = 0;
this.sumY = 0;
}
LineFitter.prototype = {
'add': function(x, y)
{
this.count++;
this.sumX += x;
this.sumX2 += x*x;
this.sumXY += x*y;
this.sumY += y;
},
'project': function(x)
{
var det = this.count * this.sumX2 - this.sumX * this.sumX;
var offset = (this.sumX2 * this.sumY - this.sumX * this.sumXY) / det;
var scale = (this.count * this.sumXY - this.sumX * this.sumY) / det;
return offset + x * scale;
}
};
function linearProject(data, x)
{
var fitter = new LineFitter();
for (var i = 0; i < data.length; i++)
{
fitter.add(i, data[i]);
}
return fitter.project(x);
}
例子:
>>> linearProject([
21410, 21886, 21837, 21895, 21564, 21714, 21571, 21324, 21310, 21390,
21764, 21598, 21493, 21352, 21478, 21058, 20942, 20825, 21321, 20950,
21039, 21117, 20733, 20773, 20929, 20900, 20687, 20999
], 60);
19489.614121510676
对平方多项式做类似的事情要复杂一些:
function SquareFitter()
{
this.count = 0;
this.sumX = 0;
this.sumX2 = 0;
this.sumX3 = 0;
this.sumX4 = 0;
this.sumY = 0;
this.sumXY = 0;
this.sumX2Y = 0;
}
SquareFitter.prototype = {
'add': function(x, y)
{
this.count++;
this.sumX += x;
this.sumX2 += x*x;
this.sumX3 += x*x*x;
this.sumX4 += x*x*x*x;
this.sumY += y;
this.sumXY += x*y;
this.sumX2Y += x*x*y;
},
'project': function(x)
{
var det = this.count*this.sumX2*this.sumX4 - this.count*this.sumX3*this.sumX3 - this.sumX*this.sumX*this.sumX4 + 2*this.sumX*this.sumX2*this.sumX3 - this.sumX2*this.sumX2*this.sumX2;
var offset = this.sumX*this.sumX2Y*this.sumX3 - this.sumX*this.sumX4*this.sumXY - this.sumX2*this.sumX2*this.sumX2Y + this.sumX2*this.sumX3*this.sumXY + this.sumX2*this.sumX4*this.sumY - this.sumX3*this.sumX3*this.sumY;
var scale = -this.count*this.sumX2Y*this.sumX3 + this.count*this.sumX4*this.sumXY + this.sumX*this.sumX2*this.sumX2Y - this.sumX*this.sumX4*this.sumY - this.sumX2*this.sumX2*this.sumXY + this.sumX2*this.sumX3*this.sumY;
var accel = this.sumY*this.sumX*this.sumX3 - this.sumY*this.sumX2*this.sumX2 - this.sumXY*this.count*this.sumX3 + this.sumXY*this.sumX2*this.sumX - this.sumX2Y*this.sumX*this.sumX + this.sumX2Y*this.count*this.sumX2;
return (offset + x*scale + x*x*accel)/det;
}
};
function squareProject(data)
{
var fitter = new SquareFitter();
for (var i = 0; i < data.length; i++)
{
fitter.add(i, data[i]);
}
return fitter.project(60);
}
示例 2:
>>> squareProject([
21410, 21886, 21837, 21895, 21564, 21714, 21571, 21324, 21310, 21390,
21764, 21598, 21493, 21352, 21478, 21058, 20942, 20825, 21321, 20950,
21039, 21117, 20733, 20773, 20929, 20900, 20687, 20999
], 60);
19282.85862700518
我可以对更高次的多项式执行此操作,但表达式会变得更长。对于任意程度,您将不得不查看矩阵。