对于给定的一组数据(xi,yi),假定它满足n次多项式:
为了求取各阶参数的最优解,对于每个xi,通过n次多项式计算的值和yi之间的差值的平方和应该最小,即:
由于其拟合函数为多项式,这样的曲线拟合问题又叫多项式拟合问题,特别的,当n=1时,一次多项式拟合又叫直线拟合。将a0,a1…an作为变量,对上式进行偏分求导,得到n+1组方程:
可以简化为:MA=B,则A=M-1B;或者通过消元法求解各个a的值。其中:
对于给定的一组数据(x1,y1),其矩阵表示为:
对于m个点对来说,可以组合成矩阵的模式:
利用矩阵表示为XA=Y,其中此种超定方程的最小二乘解为:
以两次多项式为例,各阶求和函数,2阶:
double average2(double* x0, double* y0, int Num)
{
double addsum = 0;
double addaverage = 0;
for (int i = 0; i < Num; i++)
{
addsum = addsum + x0[i] * y0[i];
}
addaverage = addsum / Num;
return addaverage;
}
3阶:
double average3(double* x0, double* y0, double* z0, int Num)
{
double addsum = 0;
double addaverage = 0;
for (int i = 0; i < Num; i++)
{
addsum = addsum + x0[i] * y0[i] * z0[i];
}
addaverage = addsum / Num;
return addaverage;
}
其它阶次的函数可参考实现。多项式系数求解:
bool calcPolFit2(double * ValidX, double * ValidY, int Num)
{
int validNum = Num;
arma::mat matM(3, 3);
arma::vec matB(3, 1);
arma::vec result(3, 1);
//组织矩阵M
matM(0, 0) = average4(ValidX, ValidX, ValidX, ValidX, validNum);
matM(0, 1) = average3(ValidX, ValidX, ValidX, validNum);
matM(0, 2) = average2(ValidX, ValidX, validNum);
matM(1, 0) = matM(0, 1);
matM(1, 1) = matM(0, 2);
matM(1, 2) = average1(ValidX, validNum);
matM(2, 0) = matM(0, 2);
matM(2, 1) = matM(1, 2);
matM(2, 2) = 1;
//组织矩阵B
matB(0) = average3(ValidX, ValidX, ValidY, validNum);
matB(1) = average2(ValidX, ValidY, validNum);
matB(2) = average1(ValidY, validNum);
result = inv(matM)*matB;
A = result(0);
B = result(1);
C = result(2);
return true;
}