示例#1
0
void polyfit(int n,double x[],double y[],int poly_n,double a[])
{
	int i,j;
	double *tempx,*tempy,*sumxx,*sumxy,*ata;

	tempx=new double[n];
	sumxx=new double[poly_n*2+1];
	tempy=new double[n];
	sumxy=new double[poly_n+1];
	ata=new double[(poly_n+1)*(poly_n+1)];

	for (i=0;i<n;i++) {
		tempx[i]=1;
		tempy[i]=y[i];
	}

	for (i=0;i<2*poly_n+1;i++) {
		for (sumxx[i]=0,j=0;j<n;j++) {
			sumxx[i]+=tempx[j];
			tempx[j]*=x[j];
		}
	}

	for (i=0;i<poly_n+1;i++) {
		for (sumxy[i]=0,j=0;j<n;j++)
		{
			sumxy[i]+=tempy[j];
			tempy[j]*=x[j];
		}
	}
	for (i=0;i<poly_n+1;i++) {
		for (j=0;j<poly_n+1;j++) {
			ata[i*(poly_n+1)+j]=sumxx[i+j];
		}
	}

	gauss_solve(poly_n+1,ata,a,sumxy);

	delete [] tempx;
	tempx=0;
	delete [] sumxx;
	sumxx=0;
	delete [] tempy;
	tempy=0;
	delete [] sumxy;
	sumxy=0;
	delete [] ata;
	ata=0;
}
示例#2
0
void polyfit(int n, double x[], double y[], int poly_n, double a[])
{
	int i,j;
	double *tempx, *tempy, *sumxx, *sumxy, *ata;

	tempx = new double[n];
	sumxx = new double[poly_n*2+1];
	tempy = new double[n];
	sumxy = new double[poly_n+1];
	ata = new double[(poly_n+1)*(poly_n+1)];

	/**	x,y 为测量点数据,n 数目大于 poly_n+1,

		相当于求解 poly_n + 1 个解,但有 n 个方程
		Ax=y 
		
		对于这个很可能没解的方程,如何求出它的近似解呢?利用线性代数的思维来思考,思路非常直观。我们知道对于所有可能的向量x,Ax的取值
		构成了一个向量空间,叫做矩阵A的列空间,A的列空间中的所有向量都是矩阵A的列向量的线性和。(注:可以看作Ax张成完备空间中的一个子空
		间,求近似解释就相当于求y在该子空间中的投影的解)方程Ax=y无解当且仅当向量y不在A的列空间中。既然y不在A的列空间,要求得近似解,
		很自然的想法是在A的列空间中找到一个离y最近的点y',将方程变为:

			Ax = y'

		立体几何知识告诉我们,对于平面外的一点p,平面上离它最近的点,是点p在该平面上的正交投影点。即通过点p向平面做垂线,垂线与平面的交
		点,即为该平面上离点p最近的点。这个结论在高维空间中依然成立。向量(y-y')是点y与点y'的连线,所以该连线与A的列空间垂直,用向量的
		语言表达就是:

			对A的列空间中的任意向量Av:(Av)T(y-y') = 0

			化简一下:vTAT(y-y') = 0。

			由于v是任意向量,一个与任意向量点乘都等于0的向量,必然是零向量(想一下该向量与自己点乘,结果依然为0),所以AT(y-y')=0。
			事实上,如果对A的四个基本子空间比较了解的话,这个式子的得来会更加直接:因为A的列空间与AT的零空间(即ATx=0的解空间)为互补
			正交子空间,所有与A的列空间正交的向量都在AT的零空间中,所以AT(y-y')=0。

		将y' = Ax代入并化简:

			ATAx = ATy

		当Ax=y无解时,对这个式子求解就能得到x的近似解,这就是著名的最小二乘法。

		例如,假如平面上有三个不共线的点(1,1),(2,2),(3,2),要求得一条近似穿过这三个点的直线y=c1+c2x,就是求解方程:

			XTXc=XTy

		其中X=[1 1; 1 2; 1 3],y=[1;2;2]
		可以解出系数向量c = (XTX)-1XTy = [0.6667;0.5]

		多项式拟合,可以认为是一组方程,求解 a0, a1, a2 ... 
		y0 = a0 + a1x1 + a2x1*x1 + a3x1*x1*x1 + ...
					||
					|| 
					|| 
					\/  
			y   =   A                    a

				  [ 1 x1 x1^2 x1^3 ... ][a0]
 			[y] = [ 1 x2 x2^2 x2^3 ... ][a1]
				  [ .......            ][.]
				  
			其中 [y] [x1, x2, ...] 已知,求解 [a0, a1, ...]

			因为 系数矩阵有可能不可逆,两面都乘上系数矩阵的转置
				ATy = ATAa
			ATA 往往可逆
				ATAa = ATy	求解 a 向量
	 */

	for (i = 0; i < n; i++) {
		tempx[i] = 1;
		tempy[i] = y[i];
	}

	for (i = 0; i < 2*poly_n + 1; i++) {
		sumxx[i] = 0;
		for (j = 0; j < n; j++) {
			sumxx[i] += tempx[j];
			tempx[j] *= x[j];
		}
	}

	for (i = 0; i < poly_n+1; i++) {
		sumxy[i] = 0;
		for (j = 0; j < n; j++) {
			sumxy[i] += tempy[j];
			tempy[j] *= x[j];
		}
	}

	// ATA
	for (i = 0; i < poly_n+1; i++) {
		for (j = 0; j < poly_n+1; j++) {
			ata[i * (poly_n + 1) + j] = sumxx[i + j];
		}
	}

	gauss_solve(poly_n+1, ata , a, sumxy);

	delete []tempx;
	delete []sumxx;
	delete []tempy;
	delete []sumxy;
	delete []ata;
}
示例#3
0
bool solve_system(std::vector<double> & A, std::vector<double> & b, std::vector<kriging_weight_t> & weights)
{
    weights.resize(b.size());
    return gauss_solve(&A[0], &b[0], &weights[0], b.size());
}