c++ 曲線擬合的最小二乘法 公式 二次多項式和三次多項式

struct Hisnum//直方圖結構體 進行多項式擬合
{
    int gray;
    int num;
};

struct Hisnum//直方圖結構體 進行多項式擬合
{
	int gray;
	int num;
};
struct xishu
{
	double A1;
	double A2;
	double A3;
	double A4;
};

xishu polfit2(Hisnum his[], int n)//最小二乘 二次多項式擬合 y=A1+A2*x+A3*x*x  x爲灰度 y爲灰度數量
{

	//-----------------公式---------------------------
	//n A1     + sumX A2   + sumXX A3 = sumY
	//sumX A1  + sumXX A2  + sumXXX A3 = sumXY
	//sumXX A1 + sumXXX A2 + sumXXXX A3 = sumXXY
	//--------------------------------------------目的:求係數A1 A2 A3  
	int jiange = 10;//相隔十個點選一個點進行計算
	n = n / jiange + 1;
	long long int sumX = 0, sumY = 0, sumXX = 0, sumXXX = 0, sumXXXX = 0, sumXY = 0, sumXXY = 0;//建立方程組
	for (int i = 0; i < 256; i = i + jiange)
	{
		cout << "number:" << his[i].num << endl;
		cout << "gray:" << his[i].gray << endl;
		sumX = sumX + his[i].gray;
		sumY = sumY + his[i].num;
		sumXX = sumXX + his[i].gray*his[i].gray;
		sumXXX = sumXXX + his[i].gray*his[i].gray*his[i].gray;
		sumXXXX = sumXXXX + his[i].gray*his[i].gray*his[i].gray*his[i].gray;
		sumXY = sumXY + his[i].gray*his[i].num;
		sumXXY = sumXXY + his[i].gray*his[i].num*his[i].gray;
	}
	cout << "n:" << n << " sumX: " << sumX << " sumXX: " << sumXX << " sumXXX: " << sumXXX << " sumXXXX: " << sumXXXX << endl;
	cout << " sumY: " << sumY << " sumXY: " << sumXY << " sumXXY: " << sumXXY << endl;

	double a11 = n;      double  a12 = sumX;   double  a13 = sumXX;   double  b1 = sumY;      //構造矩陣   求解方程係數   a11 第一行第一列
	double  a21 = sumX;  double  a22 = sumXX;  double  a23 = sumXXX;  double  b2 = sumXY;
	double  a31 = sumXX; double  a32 = sumXXX; double  a33 = sumXXXX; double  b3 = sumXXY;

	//double a11 = 2;      double  a12 = 4;   double  a13 = -2;   double  b1 = 2;      //構造矩陣   求解方程係數   a11 第一行第一列
	//double  a21 = 1;  double  a22 = -3;  double  a23 = -3;  double  b2 = -1;
	//double  a31 = 4; double  a32 = 2; double  a33 = 2; double  b3 = 3;

	//R2-(a21/a11)*R1     ------------------------------------------------------------ - 進行消元    高斯消元法
	double a21x, a22x, a23x, b2x;
	a21x = a21 - a21 / a11*a11; a22x = a22 - a21 / a11*a12; a23x = a23 - a21 / a11*a13; b2x = b2 - a21 / a11*b1;
	//R3-(a31/a11)*R1
	double a31x, a32x, a33x, b3x;
	a31x = a31 - a31 / a11*a11; a32x = a32 - a31 / a11*a12; a33x = a33 - a31 / a11*a13; b3x = b3 - a31 / a11*b1;

	//R3-(a32/a22)*R2
	double a32xx, a33xx, b3xx;
	a32xx = a32x - a32x / a22x*a22x; a33xx = a33x - a32x / a22x*a23x; b3xx = b3x - a32x / a22x*b2x;

	//------------------------------------------------------------求得係數矩陣未知數
	double A3 = b3xx / a33xx;
	double A2 = (b2x - a23x*A3) / a22x;
	double A1 = (b1 - A2*a12 - A3*a13) / a11;
	cout << " A1: " << A1 << " A2: " << A2 << " A3: " << A3 << endl;

	xishu A;
	A.A1 = A1;
	A.A2 = A2;
	A.A3 = A3;
	return A;
}

 

 

xishu polfit3(Hisnum his[], int n)//最小二乘 三次多項式擬合 y=A1 + A2*x + A3*x*x + A4*x*x*x  x爲灰度 y爲灰度數量
{

	//-----------------公式---------------------------
	//n A1     + sumX A2   + sumXX A3   +  sumXXX A4   = sumY
	//sumX A1  + sumXX A2  + sumXXX A3  +  sumXXXX A4  = sumXY
	//sumXX A1 + sumXXX A2 + sumXXXX A3 +  sumXXXXX A4 = sumXXY
	//sumXXX A1+sumXXXX A2 + sumXXXXX A3+  sumXXXXXX A4 =sumXXXY

	//--------------------------------------------目的:求係數A1 A2 A3  
	int jiange = 10;//相隔十個點選一個點進行計算
	n = n / jiange + 1;
	long double sumX = 0, sumY = 0, sumXX = 0, sumXXX = 0, sumXXXX = 0, sumXXXXX = 0, sumXXXXXX = 0, sumXXXXXXX = 0, sumXY = 0, sumXXY = 0, sumXXXY = 0;//建立方程組
	for (int i = 0; i < 256; i = i + jiange)
	{
		cout << "number:" << his[i].num << endl;
		cout << "gray:" << his[i].gray << endl;
		sumX = sumX + his[i].gray;
		sumY = sumY + his[i].num;
		sumXX = sumXX + his[i].gray*his[i].gray;
		sumXXX = sumXXX + his[i].gray*his[i].gray*his[i].gray;
		sumXXXX = sumXXXX + his[i].gray*his[i].gray*his[i].gray*his[i].gray;
		sumXXXXX = sumXXXXX + his[i].gray*his[i].gray*his[i].gray*his[i].gray*his[i].gray;//
		sumXXXXXX = sumXXXXXX + his[i].gray*his[i].gray*his[i].gray*his[i].gray*his[i].gray*his[i].gray;
		//	sumXXXXXXX = sumXXXXXXX + his[i].gray*his[i].gray*his[i].gray*his[i].gray*his[i].gray*his[i].gray*his[i].gray;
		sumXY = sumXY + his[i].gray*his[i].num;
		sumXXY = sumXXY + his[i].gray*his[i].num*his[i].gray;
		sumXXXY = sumXXXY + his[i].gray*his[i].num*his[i].gray*his[i].gray;

	}
	cout << "n:" << n << " sumX: " << sumX << " sumXX: " << sumXX << " sumXXX: " << sumXXX << " sumXXXX: " << sumXXXX << " sumXXXXX: " << sumXXXXX << " sumXXXXXX: " << sumXXXXXX << " sumXXXXXXX: " << sumXXXXXXX << endl;
	cout << " sumY: " << sumY << " sumXY: " << sumXY << " sumXXY: " << sumXXY << " sumXXXY: " << sumXXXY << endl;

	double  a11 = n;      double  a12 = sumX;    double  a13 = sumXX;    double  a14 = sumXXX;    double  b1 = sumY;      //構造矩陣   求解方程係數   a11 第一行第一列
	double  a21 = sumX;   double  a22 = sumXX;   double  a23 = sumXXX;   double  a24 = sumXXXX;   double  b2 = sumXY;
	double  a31 = sumXX;  double  a32 = sumXXX;  double  a33 = sumXXXX;  double  a34 = sumXXXXX;  double  b3 = sumXXY;
	double  a41 = sumXXX; double  a42 = sumXXXX; double  a43 = sumXXXXX; double  a44 = sumXXXXXX; double  b4 = sumXXXY;
	//double a11 = 2;      double  a12 = 4;   double  a13 = -2;   double  b1 = 2;      //構造矩陣   求解方程係數   a11 第一行第一列
	//double  a21 = 1;  double  a22 = -3;  double  a23 = -3;  double  b2 = -1;
	//double  a31 = 4; double  a32 = 2; double  a33 = 2; double  b3 = 3;

	//R2=R2-(a21/a11)*R1     ------------------------------------------------------------ - 進行消元    高斯消元法  第一例消元
	double a21x, a22x, a23x, a24x, b2x;
	a21x = a21 - a21 / a11*a11; a22x = a22 - a21 / a11*a12; a23x = a23 - a21 / a11*a13; a24x = a24 - a21 / a11*a14; b2x = b2 - a21 / a11*b1;
	//R3=R3-(a31/a11)*R1
	double a31x, a32x, a33x, a34x, b3x;
	a31x = a31 - a31 / a11*a11; a32x = a32 - a31 / a11*a12; a33x = a33 - a31 / a11*a13; a34x = a34 - a31 / a11*a14; b3x = b3 - a31 / a11*b1;
	//R4=R4-(a41/a11)*R1
	double a41x, a42x, a43x, a44x, b4x;
	a41x = a41 - a41 / a11*a11; a42x = a42 - a41 / a11*a12; a43x = a43 - a41 / a11*a13; a44x = a44 - a41 / a11*a14; b4x = b4 - a41 / a11*b1;

	//------------------------------------------------------------ - 進行消元    高斯消元法  第二例消元
	//R3=R3-(a32/a22)*R2
	double a32xx, a33xx, a34xx, b3xx;
	a32xx = a32x - a32x / a22x*a22x; a33xx = a33x - a32x / a22x*a23x; a34xx = a34x - a32x / a22x*a24x; b3xx = b3x - a32x / a22x*b2x;
	//R4=R4-(a42/a22)*R2
	double a42xx, a43xx, a44xx, b4xx;
	a42xx = a42x - a42x / a22x*a22x; a43xx = a43x - a42x / a22x*a23x; a44xx = a44x - a42x / a22x*a24x; b4xx = b4x - a42x / a22x*b2x;

	//------------------------------------------------------------ - 進行消元    高斯消元法  第三例消元
	//R4=R4-(a43/a33)R3
	double a43xxx, a44xxx, b4xxx;
	a43xxx = a43xx - a43xx / a33xx*a33xx; a44xxx = a44xx - a43xx / a33xx*a34xx; b4xxx = b4xx - a43xx / a33xx*b3xx;


	//------------------------------------------------------------求得係數矩陣未知數
	double A4 = b4xxx / a44xxx;
	double A3 = (b3xx - a34xx*A4) / a33xx;
	double A2 = (b2x - a23x*A3 - a24x*A4) / a22x;
	double A1 = (b1 - a12*A2 - a13*A3 - a14*A4) / a11;
	cout << " A1: " << A1 << " A2: " << A2 << " A3: " << A3 << " A4: " << A4 << endl;

	xishu A;
	A.A1 = A1;
	A.A2 = A2;
	A.A3 = A3;
	A.A4 = A4;
	return A;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章