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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2713|回復: 0
打印 上一主題 下一主題
收起左側

最小2乘法

[復制鏈接]
跳轉到指定樓層
樓主
ID:80436 發表于 2015-5-21 22:35 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式

[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;
}








分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 九九亚洲精品 | 国产亚洲精品精品国产亚洲综合 | 羞羞视频在线观看 | 91色视频在线观看 | 成人一区二区三区视频 | 国产成人精品久久二区二区91 | 久久精品小视频 | 精国产品一区二区三区 | 成人在线视频免费观看 | 色吊丝2288sds中文字幕 | 中文字幕一区二区在线观看 | 欧美日韩一区二区三区四区五区 | 欧美一级α片 | 玖玖玖在线观看 | 精品成人 | 成人小视频在线观看 | 成人一区二区三区在线观看 | 日韩最新网站 | 国产精品久久福利 | 毛片黄片免费看 | 亚洲国产午夜 | 亚洲视频一区二区三区四区 | 在线观看涩涩视频 | 美女毛片免费看 | 综合久久av| 午夜视频在线 | 久草视频在线播放 | 日本中文字幕视频 | 精品综合久久久 | 久草福利 | 国产98色在线 | 日韩精品久久久久 | 午夜电影福利 | 日韩在线视频观看 | 男女视频在线观看免费 | 久久久青草婷婷精品综合日韩 | h片在线看 | 91精品国模一区二区三区 | 日韩在线一区二区 | 青青草国产在线观看 | 国产精品亚洲一区 |