Polynomial fitting of the least squares method
Given a series of points, use the least squares method to fit the polynomial curve function of these points. Assume that the fitted polynomial (k term) function is:
and assume that the real curve function is:
then for a given n points (xi, yi), 0<i≤n, the deviation between the fitted curve and the actual should be the smallest, that is :
Then the problem is transformed into: find a set of solutions (a0,a1,a2,...,ak)^T, so that the value of the function L is the smallest . It can be seen from the extreme value conditions that when L takes the minimum value of a set of solutions, the partial derivative of L to it is 0; in order to solve the problem, the partial derivative of ai is calculated for L and set to 0: Simplification can be obtained: expressed as
a
matrix For:
Obviously the above formula is a problem of solving linear equations: A*X=B.
When programming, it is not necessary to calculate (k+1)^2 times for the acquisition of A, and it can be found that there are only 2k+1 elements in A: so when programming, you only need to calculate
the 2k+1 items first, and then calculate them according to the law Just fill in A. The following sample code demonstrates solving the A*X=B problem using the Qr decomposition algorithm of the Eigen library.
#include <Eigen/Dense>
//--Input
//---x:数据点的x坐标值数组
//---y:数据点的y坐标值数组
//---n:数据点的个数
//---k:多项式的阶
//--Output
//---返回A*X=B中的解X
Eigen::VectorXd polynomialFitting(double*x, double*y, unsigned n, unsigned k)
{
Eigen::MatrixXd A=Eigen::MatrixXd::Zero(k+1,k+1);
Eigen::VectorXd B=Eigen::VectorXd::Zero(k+1);
double*x_pow_sum=new double[2*k+1];//存放A中2k+1项不重复元素
for(unsigned i=0;i<2*k+1;i++)
{
double sum=0.;
for(unsigned j=0;j<n;j++)
{
sum+=pow(x[j],i);//计算每项幂的和
}
x_pow_sum[i]=sum;//
}
for(unsigned i=0;i<k+1;i++)
{
for(unsigned j=0;j<k+1;j++)
{
A(i,j)=x_pow_sum[i+j];//按规律将2k+1项不重复元素填入矩阵A
}
}
for(unsigned i=0;i<k+1;i++)
{
double sum=0;
for(unsigned j=0;j<n;j++)
{
sum=sum+pow(x[j],i)*y[j];//计算B的每个元素
}
B[i]=sum;
}
//利用Eigen库中的Qr分解求解X
Eigen::VectorXd X=A.colPivHouseholderQr().solve(B);
return X;
}
If the Eigen library is not installed, you can use the Gaussian elimination method or the selected pivot method to write the solution code.