创建博客 登录  
 加关注
   显示下一条  |  关闭

(((silence)))

#define if(...) if(!(__VA_ARGS__))

 
 
 

日志

 
 

期末实现了一坨C++数值算法[3] 最小二乘法  

2009-12-30 11:40:08|  分类: 编程 |  标签: |字号 订阅

算法描述

1.2.1最小二乘法基本思路

已知数据对(xj, yj)(j=1,2,…,n),求多项式

wps_clip_image-83

使得wps_clip_image-113为最小,这就是一个最小二乘问题。

2.2.2 最小二乘法计算步骤

用线性函数p(x)=a+bx为例,拟合给定数据(xi, yi)(i=1,2,…,n)。

算法描述:

步骤1:输入m值,及(xi, yi)(i=1,2,…,m)。

步骤2:建立法方程组 ATA X=A Y。

步骤3:解法方程组。

步骤4:输出 a, b。

 

===== 上面其实还是抄的 =====

=====   下面是我的实现  =====

依赖项:向量和矩阵类回代过程的高斯消去法

 

// 内部使用,计算阶次
static inline double f ( double x, int n )
{
    double db=1;
    if (n==0) {
        db = 1;
    } else if (n>0) {
        for(;n--;db*=x);
    } else {
        for(;n++;db/=x);
    }
    return db;
}

// 最小二乘法拟合一元多项式曲线
// 返回值:
//     成功返回对应的多项式系数
//     失败返回空向量
NA::VecDP leastSquare ( NA::VecDP const& vx, // x 坐标
                        NA::VecDP const& vy, // 对应的 y 坐标
                        int power )          // 阶次
{
    int dim = power+1;
    int len = vx.size();
    NA_ASSERT( len == vy.size() );
    NA::MatDP mx(0.0, dim, dim), my(0.0, dim, 1);
    int i, j, k;
    double db;
    // init {{{
    /*
       mx =
                                          2
                  1           X          X
            -----------------------------------
           |                                  2
        1  | sum(1 x 1)  sum(1 x X)  sum(1 x X )
           |
           |                                  2
        X  | sum(X x 1)  sum(X x X)  sum(X x X )
           |
         2 |      2           2           2   2
        X  | sum(X x 1)  sum(X x X)  sum(X x X )
           |
     */
    for (i=0; i<dim; ++i) {
        for (j=i; j<dim; ++j) {
            db=0;
            for (k=0; k<len; ++k) {
                db += f(vx[k], i) * f(vx[k], j);
            }
            mx[i][j]=mx[j][i]=db;
        }
    }

    /*
       my =

                   Y
           ----------------
        1  |  sum(X x Y)
           |
           |
        X  |  sum(X x Y)
           |
         2 |       2
        X  |  sum(X x Y)
           |
     */
    for (j=0; j<dim; ++j) {
        db = 0.0;
        for (k=0; k<len; ++k) {
            db += vy[k] * f(vx[k], j);
        }
        my[j][0]=db;
    }
    // }}}

    // have a look {{{
#if DEBUG
    for (i=0; i<dim; ++i) {
        cout<<"| ";
        for (j=0; j<dim; ++j)
            cout<<mx[i][j]<<"\t";
        cout<<"|\t"<<my[i][0]<<endl;
    }
#endif
    // }}}

    if (!gaussianBackSubstitution (mx, my)) { // 直接用高斯消元法求解
        return NA::VecDP(0);
    } else {
        return NA::VecDP(my.bits(), dim);
    }
}

 

 

OVER

  评论这张
转发至微博
转发至微博
0   分享到:        
阅读(738)| 评论(1)| 不可引用 |举报
<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--相关文章--> <#--历史上的今天--> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2012