最小二乘法似合直线

今天给高个范师兄写了一个SVD分解,关于SVD的具体应用还不清楚,所以到网上看了一下,也没整太明白。偶然看到最小二乘法的原理,觉得以后可能会用的着,于是便试着写了一个简单的似合直线的。

我们在研究两个变量X,Y之间的关系时,通常可以得到一系列成对的数据(x1,y1),(x2,y2)…(xn,yn),将这些数据描绘在X-Y直角坐标系中时,若发现这些点在一条直线附近,可令这条直线的方程如下:
Y=aX+b
其中a b是任意常数,为了得到这条直线方程就要求出a b的值。
这里不深究具体的求a b的步骤,我们只要最终的计算公式就可以了。

    a0  =  (∑Yi)  /  m  -  a1(∑Xi)  /  m
a1 
=  [∑Xi Yi  -  (∑Xi ∑Yi) /  m]  /  [∑Xi2  -  (∑Xi) 2   /  m)] 

下面是最小二乘法似合直线的源程序:

#include  < stdio.h >

double  k[ 2 ][ 3 ]; // 变量X,Y 线性方程系数k 

// ∑Xi2 ∑Xi*Yi ∑Xi^2 等值
double
fsum (
double  a[],  double  b[],  int  c)
{
  
double sum = 0;
  
for (int i = 0; i < c; i++)
    sum 
+= a[i] * b[i];
  
return sum;
}


// 求矩阵
double
fmatrix (
int  m,  int  n)
{
  
double matrix;
  matrix 
= k[0][m] * k[1][n] - k[0][n] * k[1][m];
  
return matrix;
}


int  
main ()
{
  
int N=3,i=0,j=0;
  
double mi[N];        //大小为1的数列,矩阵求和时匹配使用
  double x[N];    //初始化三组数据
  double y[N];
  
for(i=0; i<N; i++)
  
{
      x[i]
=i*1.0;
      y[i]
=i*2.0;
  }

  
double m1, m2, m0;

  
//求线性方程系数
  k[0][0= fsum (x, x, N);
  k[
0][1= fsum (x, mi, N);
  k[
0][2= -fsum (x, y, N);
  k[
1][0= fsum (x, mi, N);
  k[
1][1= N;
  k[
1][2= -fsum (mi, y, N);

  
//输出线性方程系数
  printf (" The modulus is: ");
  
for (i = 0; i < 2; i++)
    
{
      
for (j = 0; j < 3; j++)
    printf (
"%15lf    ", k[i][j]);
      printf(
" ");
    }


  
//线性方程矩阵m0 m1 m2
  m0 = fmatrix (01);
  m1 
= fmatrix (12);
  m2 
= fmatrix (20);
  printf (
" %lf %lf %lf ", m0, m1, m2);
  
if (m0 == 0)
    printf (
"此直线为X=%d!",x[0]);
  
else
    printf (
"The function should be: Y= %lf X %+lf ", m1 / m0, m2 / m0);
    /*
    double a1=(-k[0][2]+k[0][1]*k[1][2]/N) / (k[0][0]-k[0][1]*k[0][1]/N);
    double a0=-k[1][2]/N-a1*k[0][1]/N;
    printf("Y= %lf X+%lf/n",a1,a0);
    */
  
return 0;
}

你可能感兴趣的:(c,Matrix)