久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: 最小2乘法 [打印本頁]

作者: liuqq    時間: 2015-5-21 22:35
標題: 最小2乘法

[tr][/tr]
[tr][/tr]
低階擬合算法的優化:
當階數比較低時,如直線或者拋物線,解行列式可以優化,不需要做成遞推模式,直接強行解就是,而且一般不會出現溢出問題。
還有pow(double x, double y)函數應該自己寫替換,原因是在我們的應用中y肯定是整數,而這個函數按照double運算的,效率應該會差很多,所以來個閹割版的pow(double x, int y).在結束低的時候,直接寫兩個宏定義。
#define     my_pow0(x)      (1.0)
#define     my_pow1(x)      (x)
#define     my_pow2(x)      (my_pow1(x) * my_pow1(x))
#define     my_pow2(x)      (my_pow1(x) * my_pow2(x))
#define     my_pow4(x)      (my_pow2(x) * my_pow2(x))
#define     my_pow5(x)      (my_pow2(x) * my_pow3(x))
#define     my_pow6(x)      (my_pow3(x) * my_pow3(x))
直線擬合的簡化:
假設最后擬合直線:
y = a * x + b
殘差方程:
(a * x + b – y)^2 = x^2 * a^2 + b^2 + y^2 + 2 * (x * a * b – x * y * a – y * b)
殘差方程對a偏導:
x^2 * a + x^1 * b – y * x^1
殘差方程對a偏導:
x^1 * a + x^0 * b – y * x^0
當殘差方程之和取極值時,偏導為零。
a * ∑x^2 + b * ∑x^1 = ∑(y * x^1)
a * ∑x^1 + b * ∑x^0 = ∑(y * x^0)
(1)首先是定義一個2行3列的系數矩陣,并初始化
double Para[2] [3] = {0.0};
int ParaInit(const double* X, const double* Y, int Amount)
{
        Para[1][1] = Amount;
        for ( ; Amount; Amount--, X++, Y++)
{
        Para[0][0]  +=  my_pow2(*X);
Para[0][1]  +=  my_pow1(*X);
//Para[1][1]  +=  my_pow0(*Y);
Para[0][2]  +=  my_pow1(*X) * my_pow1(*Y);
//Para[1][2]  +=  my_pow0(*X) * my_pow1(*Y);
Para[1][2]  +=  my_pow1(*Y);
}
Para[1][0] = Para[0][1];
return 0;
}

(2)解行列式:
由方程組
a * ∑x^2 + b * ∑x^1 = ∑(y * x^1)
a * ∑x^1 + b * ∑x^0 = ∑(y * x^0)
首先可以看到:
A,Para[0][0]和Para[1][1]肯定大于0
B,Para[0][1] = Para[1][0]
C,        可以證明[2][2]行列式的值
Para[0][0] * Para[1][1] - Para[0][1] * Para[1][0]
(∑x^2) * (∑x^0) - (∑x^1) * (∑x^1)> 0
也即是說,方陣正定,偏導為零的點就是最優值的點
可以看出,第1行的系數比第0行的系數要小很多,所以先采用第1行消第0行,再采用第0行消第1行。
int ParaDeal(void)
{
/*先把Para[0][1]消成0,由于有Para[1][1]肯定大于0,所以用乘法(除法),除法更好一些,數據溢出的問題幾乎不存在,適應性會更好*/
Para[0][0] = Para[0][0] - Para[1][0] * (Para[0][1] / Para[1][1];
Para[0][2] = Para[0][2] - Para[1][2] * (Para[0][1] / Para[1][1];
Para[0][1] = 0;
//再把Para[1][0] 消成0
Para[1][2] = Para[1][2] - Para[0][2] * (Para[1][0] / Para[0][0]);
Para[1][0] = 0;
//把Para[0][0],Para[1][1] 消成1
Para[0][2] /= Para[0][0];//這個就是最后a的值
Para[0][0] = 1.0;
Para[1][2] /= Para[1][1]; //這個就是最后b的值
Para[1][1] = 1.0;
return 0;
}
至此,一階直線擬合的推導過程和C代碼全部完畢,可以看出運算量可以說很小,兩個函數均只需調用一次即可得到結果,在源數據的個數和大小不是特別大的時候,完全可以移植到MCU中進行運算,實用價值比較高。
再來個二階拋物線擬合的優化:
前期推導和一階直線差不多,略去,系數矩陣方程組:
a * ∑x^4 + b * ∑x^3 + c * ∑x^2 = ∑(y * x^2)
a * ∑x^3 + b * ∑x^2 + c * ∑x^1 = ∑(y * x^1)
a * ∑x^2 + b * ∑x^1 + c * ∑x^0 = ∑(y * x^0)
(1)首先是定義一個3行4列的系數矩陣,并初始化
double Para[3] [4] = {0.0};
int ParaInit(const double* X, const double* Y, int Amount)
{
        Para[1][1] = Amount;
        for ( ; Amount; Amount--, X++, Y++)
{
Para[0][0]  +=  my_pow4(*X);
Para[0][1]  += my_pow3(*X);
Para[0][2]  += my_pow2(*X);
Para[1][2]  += my_pow1(*X);
//Para[2][2] +=  my_pow0(*X);
Para[0][3]  +=  my_pow2(*X) * my_pow1(*Y);
Para[1][3]  +=  my_pow1(*X) * my_pow1(*Y);
Para[2][3]  +=  my_pow0(*X) * my_pow1(*Y);
}
Para[1][0] = Para[0][1];
Para[1][1] = Para[0][2];
Para[2][0] = Para[1][1];
Para[2][1] = Para[1][2];
return 0;
}

a * ∑x^4 + b * ∑x^3 + c * ∑x^2 = ∑(y * x^2)
a * ∑x^3 + b * ∑x^2 + c * ∑x^1 = ∑(y * x^1)
a * ∑x^2 + b * ∑x^1 + c * ∑x^0 = ∑(y * x^0)
首先可以看到:
A,Para[0][0],Para[1][1], Para[2][2]肯定大于0
B,左邊3*3的方陣是對稱矩陣
D,        可以證明[3][3]行列式的值 > 0,也即是說,方陣正定,偏導為零的點就是最優值的點
可以看出,第k + 1行的系數比第k行的系數要小很多,所以先采用第k +1行消第k行,再采用第k行消第k + 1行。

int ParaDeal(void)
{
//用Para[2][2]把Para[0][2]消成0
Para[0][0] = Para[0][0] - Para[2][0] * (Para[0][2] / Para[2][2]);
Para[0][1] = Para[0][1] - Para[2][1] * (Para[0][2] / Para[2][2]);
Para[0][3] = Para[0][3] - Para[2][3] * (Para[0][2] / Para[2][2]);
Para[0][2] = 0;
//用Para[2][2]把Para[1][2] 消成0
Para[1][0] = Para[1][0] - Para[2][0] * (Para[1][2] / Para[2][2]);
Para[1][1] = Para[1][1] - Para[2][1] * (Para[1][2] / Para[2][2]);
Para[1][3] = Para[1][3] - Para[2][3] * (Para[1][2] / Para[2][2]);
Para[1][2] = 0;
//用Para[1][1]把Para[0][1]消成0
Para[0][0] = Para[0][0] - Para[1][0] * (Para[0][1] / Para[1][1]);
Para[0][3] = Para[0][3] - Para[1][3] * (Para[0][1] / Para[1][1] );
Para[0][1] = 0;
//至此,已經成成為三角矩陣
//用Para[0][0]把Para[1][0]消成0
Para[1][3] = Para[1][3] - Para[0][3] * (Para[1][0] / Para[0][0]);
Para[1][0] = 0;
//用Para[0][0]把Para[2][0]消成0
Para[2][3] = Para[2][3] - Para[0][3] * (Para[2][0] / Para[0][0]);
Para[2][0] = 0;
//用Para[1][1]把Para[2][1]消成0
Para[2][3] = Para[2][3] - Para[1][3] * (Para[2][1] / Para[1][1]);
Para[2][1] = 0;
//至此,已經成成為對角矩陣
//把Para[0][0],Para[1][1],Para[2][2]消成1
Para[0][3] /= Para[0][0];//這個就是最后a的值
Para[0][0] = 1.0;
Para[1][3] /= Para[1][1]; //這個就是最后b的值
Para[1][1] = 1.0;
Para[2][3] /= Para[2][2]; //這個就是最后c的值
Para[2][2] = 1.0;
return 0;
}













歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 一区二区视频在线 | 欧美激情视频一区二区三区在线播放 | cao视频 | 亚洲一区二区三区在线播放 | 日韩成人| 亚洲精品国产成人 | 欧美三级电影在线播放 | 午夜精品久久 | 欧美九九| 国产午夜精品久久久 | 国产精品久久久久久模特 | 五月激情婷婷六月 | 国产96色在线 | 99久久夜色精品国产亚洲96 | 精品久久久久久久人人人人传媒 | 国产日韩欧美一区二区 | 精品欧美一区二区在线观看视频 | 91国内精品| 亚洲色图综合 | 亚洲精品久久久一区二区三区 | 羞羞色在线观看 | 九九热精品在线 | 国产精品久久久久久久久久久久冷 | 亚洲国产欧美在线人成 | 欧美成人精品一区二区三区 | 久久久久久久一区二区三区 | 日本成人一区二区 | 午夜性色a√在线视频观看9 | 精品国产18久久久久久二百 | 中文字幕在线视频免费视频 | 亚洲精品久久久久久一区二区 | 欧美日韩一区二区在线观看 | 亚洲精品一区中文字幕乱码 | 日韩不卡一区二区 | 久久蜜桃av一区二区天堂 | 日韩中文字幕在线 | 国产精品婷婷 | 国产精品一区二区欧美黑人喷潮水 | 99久久婷婷国产综合精品电影 | 午夜电影福利 | 91在线网站|