今天给高个范师兄写了一个SVD分解,关于SVD的具体应用还不清楚,所以到网上看了一下,也没整太明白。偶然看到最小二乘法的原理,觉得以后可能会用的着,于是便试着写了一个简单的似合直线的。
我们在研究两个变量X,Y之间的关系时,通常可以得到一系列成对的数据(x1,y1),(x2,y2)…(xn,yn),将这些数据描绘在X-Y直角坐标系中时,若发现这些点在一条直线附近,可令这条直线的方程如下:
Y=aX+b
其中a b是任意常数,为了得到这条直线方程就要求出a b的值。
这里不深究具体的求a b的步骤,我们只要最终的计算公式就可以了。
下面是最小二乘法似合直线的源程序:
我们在研究两个变量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)]
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 (0, 1);
m1 = fmatrix (1, 2);
m2 = fmatrix (2, 0);
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;
}
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 (0, 1);
m1 = fmatrix (1, 2);
m2 = fmatrix (2, 0);
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;
}