青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 12,  comments - 54,  trackbacks - 0
考慮用有M個未定參數aj(j=1,...,M)的模型來擬合N個數據點(xi, yi),i= 1, 2, ..., N。
因變量與自變量的一個函數關系可以如下給出:
y(x) = y( x; a1, a2, ..., aM)
如果所給的N個數據點(xi, yi)誤差都是獨立的,并且服從具有相同常數方差的正態分布,那么最小二乘方擬合就是擬合參數aj的最大似然估計
X2 = \sum_{i=1}^N [ yi - y(xi; a1, a2, ..., aM )]2

如果這個模型是x的任意M個特定函數的線性組合,如
y(x) = a0 + a1 cos(k1x+2) + a2 sin(k2x+3)
一般形式可以寫為
y(x) = \sum_{k=1}^N ak Xk(x)

那么它的優值函數為
X2 = \sum_{i=1}^N [yi - \sum_{k=1}^M ak Xk(xi)]2

將上式分別對M個參數ak求偏導數,并令其等于0, 可以得到X2的最小值。
于是得到M個方程
\sum_{i=1}^N [yi-\sum_{j=1}^M aj Xj(xi)]Xk(xi) = 0    k= 1, 2, ..., M

用克萊姆法則求解這個M元一次方程組,可以得到 a1, a2, ..., aM的解,即為所求的aj的最大似然估計。

接下來估計數據與模型的契合度
由平移伽瑪近似計算
ssq = gammq((N-2)/2, X2/2)


以下為c++實現
regression.h
  1 template<size_t SIZE, size_t N>
  2 class Regression
  3 {
  4 public:
  5     //ctor
  6     Regression()
  7     {
  8         Y.resize ( SIZE );
  9         X.resize ( SIZE * N );
 10         Result.resize ( SIZE );
 11         SSQ = 0.0L;
 12     }
 13 
 14     //dtor
 15     ~Regression() {}
 16     //get Y[SIZE]
 17     void _y ( const std :: vector<long double>& y )
 18     {
 19         assert ( SIZE == y.size() );
 20         Y = y;
 21     }
 22 
 23     //set vector x[][]
 24     void _x ( const std :: vector<long double>& x )
 25     {
 26         assert ( SIZE * N == x.size() );
 27         X = x;
 28     }
 29 
 30     //set vector x[][] cloumn index
 31     void _x ( const std :: vector<long double>& x, const unsigned int& index )
 32     {
 33         assert ( index < N );
 34         assert ( SIZE == x.size() );
 35 
 36         for ( unsigned int i = 0; i < SIZE; ++i )
 37         {
 38             X[ i * N + index ] = x[i];
 39         }
 40     }
 41 
 42     //execute least square fit
 43     void fit()
 44     {
 45         //the model is
 46         //             alfa[N][N] * result[N] = beta[N]
 47         //
 48         long double alfa[N][N];
 49         long double beta[N];
 50 
 51         for ( unsigned int k = 0; k < N; ++k )
 52         {
 53             for ( unsigned int j = 0; j < N; ++j )
 54             {
 55                 long double tmp = 0.0L;
 56                 for ( unsigned int i = 0; i < SIZE; ++i )
 57                 {
 58                     tmp += X[i*N+k] * X[i*N+j];
 59                 }//end of i loop
 60                 alfa[k][j] = tmp;
 61             }//end of j loop
 62 
 63             long double tmp = 0.0L;
 64             for ( unsigned int i = 0; i < SIZE; ++i )
 65             {
 66                 tmp += Y[i] * X[i*N+k];
 67             }//end of i loop
 68             beta[k] = tmp;
 69         }//end of k loop
 70 
 71         std::vector<long double> a;
 72         a.clear();
 73         for ( unsigned int i = 0; i < N; ++i )
 74             for ( unsigned int j = 0; j < N; ++j )
 75             {
 76                 a.push_back ( alfa[i][j] );
 77             }
 78 
 79         std::vector<long double> b;
 80         b.clear();
 81         for ( unsigned int i = 0; i < N; ++i )
 82             b.push_back ( beta[i] );
 83 
 84         //calculate Result[N]
 85         lq<long double> ( a, b, N, Result );
 86 
 87         //calculate chi-square
 88         long double chi = 0.0L;
 89         for ( unsigned int i = 0; i < SIZE; ++i )
 90         {
 91             long double tmp = 0.0L;
 92             for ( unsigned int j = 0; j < N; ++j )
 93             {
 94                 tmp += Result[j] * X[i*j+j];
 95             }
 96             tmp -= Y[i];
 97             chi += tmp * tmp;
 98         }
 99 
100         SSQ = gammq ( static_cast<long double> ( SIZE - 2 ) / 2.0L, chi / 2.0L );
101 
102 
103     }//end of k loop
104 
105     std :: vector< long double> result() const
106     {
107         return Result;
108     }
109 
110     long double ssq() const
111     {
112         return SSQ;
113     }
114 
115 private:
116     std :: vector<long double> Y;       // -- Y[SIZE]
117     std :: vector<long double> X;       // -- X[N][SIZE]
118     std :: vector<long double> Result;  // -- Result[N]
119     long double SSQ;                      //fitness of the model
120 };
121 
122 

其中SIZE即為所要擬合的aj的數量M,而N為原始數據點數(xi, yi)的數量N。

給出gamma函數計算代碼
#include <cmath>
#include 
<cstdlib>

static long double
gammln ( 
const long double &xx )
{
    
long double     x,
    tmp,
    ser;
    
static long double cof[6= { 76.18009173-86.5053203324.01409822,
                                  
-1.2317395160.120858003e-2-0.536382e-5
                                };
    
int             j;

    x 
= xx - 1.0;
    tmp 
= x + 5.5;
    tmp 
-= ( x + 0.5 ) * log ( tmp );
    ser 
= 1.0;
    
for ( j = 0; j <= 5; j++ )
    {
        x 
+= 1.0;
        ser 
+= cof[j] / x;
    }
    
return -tmp + log ( 2.50662827465 * ser );
}

static void
gcf ( 
long double *gammcf,
      
const long double &a, const long double &x, long double *gln )
{
    
const unsigned int ITMAX = 100;
    
const long double EPS = 3.0e-7;
    unsigned 
int    n = 0;
    
long double     gold = 0.0,
                           g,
                           fac 
= 1.0,
                                 b1 
= 1.0;
    
long double     b0 = 0.0,
                         anf,
                         ana,
                         an,
                         a1,
                         a0 
= 1.0;

    
*gln = gammln ( a );
    a1 
= x;
    
for ( n = 1; n <= ITMAX; n++ )
    {
        an 
= ( float ) n;
        ana 
= an - a;
        a0 
= ( a1 + a0 * ana ) * fac;
        b0 
= ( b1 + b0 * ana ) * fac;
        anf 
= an * fac;
        a1 
= x * a0 + anf * a1;
        b1 
= x * b0 + anf * b1;
        
if ( a1 )
        {
            fac 
= 1.0 / a1;
            g 
= b1 * fac;
            
if ( fabs ( ( g - gold ) / g ) < EPS )
            {
                
*gammcf = exp ( -+ a * log ( x ) - ( *gln ) ) * g;
                
return;
            }
            gold 
= g;
        }
    }
    
if ( "a too large, ITMAX too small in routine GCF" )
        exit ( EXIT_FAILURE );
}

static void
gser ( 
long double *gamser,
       
const long double &a, const long double &x, long double *gln )
{
    
const unsigned int ITMAX = 100;
    
const long double EPS = 3.0e-7;
    unsigned 
int    n = 0;
    
long double     sum,
    del,
    ap;

    
*gln = gammln ( a );
    
if ( x <= 0.0 )
    {
        
if ( x < 0.0 )
            
if ( "x less than 0 in routine GSER" )
                exit ( EXIT_FAILURE );
        
*gamser = 0.0;
        
return;
    }
    
else
    {
        ap 
= a;
        del 
= sum = 1.0 / a;
        
for ( n = 1; n <= ITMAX; n++ )
        {
            ap 
+= 1.0;
            del 
*= x / ap;
            sum 
+= del;
            
if ( fabs ( del ) < fabs ( sum ) * EPS )
            {
                
*gamser = sum * exp ( -+ a * log ( x ) - ( *gln ) );
                
return;
            }
        }
        
if ( "a too large, ITMAX too small in routine GSER" )
            exit ( EXIT_FAILURE );

        
return;
    }
}

long double
gammq ( 
const long double &a, const long double &x )
{
    
long double     gamser,
    gammcf,
    gln;

    
if ( x < 0.0 || a <= 0.0 )
        
if ( "Invalid arguments in routine gammq." )
            exit ( EXIT_FAILURE );

    
if ( x < ( a + 1.0 ) )
    {
        gser ( 
&gamser, a, x, &gln );
        
return 1.0 - gamser;
    }
    
else
    {
        gcf ( 
&gammcf, a, x, &gln );
        
return gammcf;
    }
}

利用克萊姆法則求解線性方程組
lq.h
 1 #include "det.h"
 2 
 3 #include <vector>
 4 #include <cassert>
 5 #include <cstdlib>
 6 
 7 //
 8 //for solution of the linear equation
 9 //                  A X = B
10 //
11 template<class T>
12 void lq ( const std :: vector<T>& a,    //store A[size][size]
13           const std :: vector<T>& b,     //store B[size]
14           const unsigned int& order, //store size
15           std :: vector<T>& result       //store X[size]
16         )
17 {
18     unsigned int Order = order;
19     //if order is set to default, calculate
20     if ( 0 == Order )
21     {
22         Order = b.size();
23     }
24 
25     assert ( Order * Order == a.size() );
26     assert ( Order == b.size() );
27 
28     result.clear();
29 
30     const T _D = det ( a, Order );  //store D
31 
32     if ( 0 == _D )
33     {
34         if ( "Failed to solve the linear equation" )
35             exit ( EXIT_FAILURE );
36     }
37 
38     for ( unsigned int i = 0; i < Order; ++i )
39     {
40         std :: vector<T> A = a;
41         for ( unsigned int j = 0; j < Order; ++j )
42         {
43             A[i+j*Order] = b[j];
44         }
45         const T D = det ( A, Order );   //store D[i]
46 
47         result.push_back ( D / _D );    //get X[i]
48     }
49 }
50 




在lq.h中有提到一個det函數,這個是用來計算矩陣的行列式值的,因為克萊姆法則就是幾個行列式的值之間除來除去罷了,代碼如下
det.h
 1 //return the determinant of a square matrix arr whose size is order by order
 2 template< class T >
 3 T det ( const std :: vector<T>& arr, const unsigned int& order = 0 )
 4 {
 5     unsigned int Order = order;
 6 
 7     //if order is set to default, calculate it
 8     if ( 0 == Order )
 9     {
10         Order = sqrt ( arr.size() );
11     }
12 
13     assert ( Order * Order == arr.size() );
14 
15 
16     if ( 1 == Order )
17         return ( arr[0] ) ;
18 
19     T sum = 0;
20     std ::vector<T> arr2 ;
21     int sign = 1;
22 
23     for ( unsigned int i = 0 ; i < Order ; ++i, sign *= -1 )
24     {
25         /* copy n-1 by n-1 array into another array */
26         const unsigned int newsize = ( Order - 1 ) * ( Order - 1 ) ;
27 
28         arr2.resize ( newsize );
29         for ( unsigned int j = 1 ; j < Order ; ++j )
30         {
31             for ( unsigned int k = 0, count = 0 ; k < Order ; ++k )
32             {
33                 if ( k == i )
34                     continue ;//jump out of k loop
35 
36                 const unsigned int pos = j * Order + k ;
37                 const unsigned int newpos = ( j - 1 ) *
38                                             ( Order - 1 ) + count ;
39                 arr2[newpos] = arr[pos] ;
40                 count++ ;
41             }//end of k loop
42         }//end of j loop
43 
44         /*  find determinant value of n-1 by n-1 array and  add it to sum */
45         sum += arr[i] * sign * det ( arr2, Order - 1 ) ;
46     }
47     return sum;
48 }
49 


下邊給出一個示例
要擬合的參數方程為
a1 x1 + a2 x2 + a3 x3 + a4 x4 + a5 x5 = y
給出5組數據進行擬合,分別是(1 0 0 0 0 1)(0 1 0 0 0 2)(0 0 1 0 0 3)(0 0 0 1 0 4)(0 0 0 0 1 5)
 1 #include "regression.h"
 2 #include <iostream>
 3 #include <vector>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     const unsigned int N = 5;
10 
11     Regression<N, N> r;
12     vector<long double> y;
13     vector<long double> x;
14     vector<long double> result;
15 
16 
17     for ( unsigned int i = 0; i < N; ++i )
18         y.push_back( 1.0L + i );
19     r._y( y );
20 
21     for ( unsigned int i = 0; i < N; ++i )
22     {
23         x.clear();
24         for ( unsigned int j = 0; j < N; ++j )
25         {
26             if ( i == j )
27                 x.push_back( 1.0L );
28             else
29                 x.push_back( 0.0L );
30         }
31         r._x( x, i );
32     }
33 
34     r.fit();
35 
36     result = r.result();
37 
38     for ( unsigned int i = 0; i < N; ++i )
39         cout << result[i] << endl;
40 
41 
42     return 0;
43 }





posted on 2008-04-15 22:38 Wang Feng 閱讀(4963) 評論(2)  編輯 收藏 引用 所屬分類: Numerical C++

FeedBack:
# re: 一般線性模型的最小二次方擬合方法
2008-11-06 20:07 | cdy20
這個blog好多算法  回復  更多評論
  
# re: 一般線性模型的最小二次方擬合方法
2008-11-06 20:07 | cdy20
膜拜  回復  更多評論
  

<2025年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用鏈接

留言簿(4)

隨筆分類

隨筆檔案

Link List

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            一区二区精品国产| 午夜久久美女| 日韩午夜电影av| 欧美破处大片在线视频| 亚洲欧洲精品一区| 亚洲黄色一区| 欧美日韩国产综合视频在线观看中文| 亚洲精品午夜精品| 亚洲欧美日韩成人| 国产综合一区二区| 欧美成人tv| 在线视频欧美日韩| 久久九九99视频| 日韩午夜在线电影| 国产精品久久久久久久久久ktv | 欧美1区2区视频| 亚洲精品国产拍免费91在线| 亚洲欧美在线观看| 亚洲高清激情| 国产精品亚洲成人| 久久免费高清视频| 亚洲精品久久久久久久久久久久久| 国产精品99久久不卡二区| 国产精品一区二区久久久| 久久先锋资源| 中日韩美女免费视频网站在线观看 | 亚洲在线中文字幕| 国产一区二区三区av电影 | 亚洲一区二区在线| 女人天堂亚洲aⅴ在线观看| 一本久久综合亚洲鲁鲁| 国产精品一区二区在线观看不卡| 牛人盗摄一区二区三区视频| 亚洲午夜免费福利视频| 欧美成人精品三级在线观看| 西西裸体人体做爰大胆久久久| 亚洲大片av| 国产精品亚洲激情| 欧美另类videos死尸| 久久精品国产欧美亚洲人人爽| 99成人精品| 欧美丰满高潮xxxx喷水动漫| 欧美专区中文字幕| 夜夜爽夜夜爽精品视频| 激情av一区| 国产精品亚洲综合久久| 欧美福利电影网| 久久久人成影片一区二区三区| 亚洲一区二区三区久久| 亚洲美女黄网| 亚洲国产精品热久久| 久久久亚洲高清| 欧美一级久久| 亚洲一二三区精品| 亚洲精品久久7777| 精品动漫av| 国产综合视频| 国产一区导航| 国产三级精品三级| 国产精品日韩| 欧美四级电影网站| 欧美女同视频| 欧美精品99| 欧美精品麻豆| 欧美全黄视频| 欧美精品福利| 欧美人成在线视频| 欧美日本三级| 欧美日本在线| 欧美日韩亚洲一区二区| 欧美久久精品午夜青青大伊人| 免费亚洲网站| 欧美成年人网站| 欧美 日韩 国产一区二区在线视频| 久久天堂国产精品| 久久婷婷人人澡人人喊人人爽 | 国产亚洲欧美中文| 国产精品美女久久久浪潮软件| 国产精品二区影院| 欧美高清在线视频| 国产情人节一区| 国产精品亚洲综合一区在线观看| 欧美日韩一区二区免费视频| 欧美日韩午夜剧场| 欧美日本韩国一区| 欧美日韩在线视频一区二区| 欧美日韩在线亚洲一区蜜芽| 国产精品久久久久久久app | 国产精品国产三级国产aⅴ入口 | 亚洲第一区色| 亚洲国产成人在线| 亚洲国产精品成人久久综合一区| 最新69国产成人精品视频免费| 韩国欧美一区| 亚洲第一精品夜夜躁人人爽| 国产精品婷婷| 国产精品电影在线观看| 国产精品久久久久婷婷| 国产日韩精品一区二区三区在线 | 日韩午夜在线视频| 亚洲小视频在线| 性做久久久久久免费观看欧美 | 欧美.日韩.国产.一区.二区| 欧美日韩 国产精品| 欧美体内she精视频| 国产欧美日韩亚洲一区二区三区| 黄色亚洲在线| av成人老司机| 久久久精品五月天| 欧美黄在线观看| 亚洲午夜久久久| 欧美ed2k| 国产欧美日韩在线播放| 亚洲破处大片| 久久久www成人免费无遮挡大片| 欧美激情在线观看| 亚洲午夜视频在线| 久久综合九色九九| 国产精品家庭影院| 国内精品免费在线观看| 一本色道久久综合狠狠躁的推荐| 久久国产毛片| 亚洲欧洲日产国产网站| 午夜在线视频观看日韩17c| 美国成人直播| 国产欧美日韩综合一区在线观看| 亚洲国产mv| 欧美一区二区在线视频| 亚洲国产老妈| 午夜天堂精品久久久久| 开心色5月久久精品| 国产精品第三页| 亚洲人妖在线| 久久影音先锋| 亚洲女同性videos| 美女主播视频一区| 国产精品毛片大码女人| 亚洲国产成人av在线| 欧美一区二区大片| 亚洲国产精品精华液网站| 亚洲欧美区自拍先锋| 欧美日韩国产美女| 在线观看日产精品| 久久超碰97人人做人人爱| 91久久精品美女高潮| 欧美一区日本一区韩国一区| 日韩视频久久| 欧美成人精品在线观看| 在线亚洲激情| 欧美精彩视频一区二区三区| 精品1区2区3区4区| 这里只有精品电影| 欧美国产一区视频在线观看| 欧美一区二区三区四区高清 | 欧美高清在线观看| 国产日韩欧美综合一区| 亚洲天堂av高清| 欧美xx69| 久久久久久久综合日本| 国产女主播一区| 欧美一区二区成人6969| 亚洲精品视频啊美女在线直播| 欧美高清视频一区| 经典三级久久| 免费成人av| 久久亚洲视频| 亚洲精品1区| 欧美激情乱人伦| 欧美11—12娇小xxxx| 亚洲国产精品久久久久婷婷老年| 欧美成人一区二免费视频软件| 久久综合电影一区| 又紧又大又爽精品一区二区| 欧美成人按摩| 欧美jizz19性欧美| 日韩系列在线| 制服丝袜亚洲播放| 国产精品蜜臀在线观看| 羞羞答答国产精品www一本 | 亚洲精品网站在线播放gif| 亚洲大胆在线| 欧美日韩亚洲一区在线观看| 亚洲午夜视频在线观看| 亚洲精品中文字| 亚洲美女啪啪| 国产精品久久久久久久久免费樱桃| 亚洲一区二区在线看| 亚洲午夜精品一区二区| 国产一区二区三区高清播放| 美女视频黄 久久| 欧美成人伊人久久综合网| 亚洲午夜国产一区99re久久| 午夜精品影院| 亚洲国内自拍| 日韩视频在线播放| 亚洲天堂第二页| 伊人久久大香线蕉综合热线 | 亚洲精品久久久久久久久久久久久| 欧美日韩一区二区视频在线| 亚洲欧洲av一区二区三区久久|