C
chgangly
Unregistered / Unconfirmed
GUEST, unregistred user!
我想通过一些坐标点采用最小二乘法来拟合曲线,次数最好大于3次。我找了一些程序,可是不知道怎样调用函数(例如下面的),哪位大侠能举个例子告诉我怎样用吗??
***************************************************************
* 本算法用最小二乘法依据指定的M个基函数及N个已知数据进行曲线拟和
* 输入: m--已知数据点的个数M
* f--M维基函数向量
* n--已知数据点的个数N-1
* x--已知数据点第一坐标的N维列向量
* y--已知数据点第二坐标的N维列向量
* a--无用
* 输出: 函数返回值为曲线拟和的均方误差
* a为用基函数进行曲线拟和的系数,
* 即a[0]f[0]+a[1]f[1]+...+a[M]f[M].
****************************************************************/
double mini_product(int m,double(*f[M])(double),int n,double x[N],
double y[N],double a[M])
{
double e,ff,b[M][M],c[M][1];
int i,j,k;
for(j=0;j<m;j++) /*计算最小均方逼近矩阵及常向量*/
{
for(k=0;k<m;k++)
{
b[j][k]=0.0;
for(i=0;i<n;i++)
b[j][k]+=(*f[j])(x)*(*f[k])(x);
}
c[j][0]=0.0;
for(i=0;i<n;i++)
c[j][0]+=(*f[j])(x)*y;
}
gaussian_elimination(m,b,1,c);
/*求拟和系数*/
for(i=0;i<m;i++)
a=c[0];
e=0.0;
for(i=0;i<n;i++) /*计算均方误差*/
{
ff=0.0;
for(j=0;j<m;j++)
ff+=a[j]*(*f[j])(x);
e+=(y-ff)*(y-ff);
}
return(e);
}
/*************************************************************************
* 高斯列主元素消去法求解矩阵方程AX=B,其中A是N*N的矩阵,B是N*M矩阵
* 输入: n----方阵A的行数
* a----矩阵A
* m----矩阵B的列数
* b----矩阵B
* 输出: det----矩阵A的行列式值
* a----A消元后的上三角矩阵
* b----矩阵方程的解X
**************************************************************************/
double gaussian_elimination(int n,double a[M][M],int m,double b[M][1])
{
int i,j,k,mk;
double det,mm,f;
det = 1.0;
for(k = 0;k<n-1;k++) /*选主元并消元*/
{
mm=a[k][k];
mk = k;
for(i=k+1;i<n;i++) /*选择第K列主元素*/
{
if(fabs(mm)<fabs(a[k]))
{
mm = a[k];
mk = i;
}
}
if(fabs(mm)<EPS)
return(0);
if(mk!=k) /* 将第K列主元素换行到对角线上*/
{
for(j=k;j<n;j++)
{
f = a[k][j];
a[k][j]=a[mk][j];
a[mk][j]=f;
}
for(j=0;j<m;j++)
{
f = b[k][j];
b[k][j]=b[mk][j];
b[mk][j]=f;
}
det = -det;
}
for(i=k+1;i<n;i++) /*将第K列对角线以下消元为零*/
{
mm = a[k]/a[k][k];
a[k]=0.0;
for(j=k+1;j<n;j++)
a[j]=a[j]-mm*a[k][j];
for(j=0;j<m;j++)
b[j]=b[j]-mm*b[k][j];
}
det = det*a[k][k];
}
if(fabs(a[k][k])<EPS)
return 0;
det=det*a[k][k];
for(i=0;i<m;i++) /*回代求解*/
{
b[n-1]=b[n-1]/a[n-1][n-1];
for(j=n-2;j>=0;j--)
{
for(k=j+1;k<n;k++)
b[j]=b[j]-a[j][k]*b[k];
b[j]=b[j]/a[j][j];
}
}
return(det);
}
***************************************************************
* 本算法用最小二乘法依据指定的M个基函数及N个已知数据进行曲线拟和
* 输入: m--已知数据点的个数M
* f--M维基函数向量
* n--已知数据点的个数N-1
* x--已知数据点第一坐标的N维列向量
* y--已知数据点第二坐标的N维列向量
* a--无用
* 输出: 函数返回值为曲线拟和的均方误差
* a为用基函数进行曲线拟和的系数,
* 即a[0]f[0]+a[1]f[1]+...+a[M]f[M].
****************************************************************/
double mini_product(int m,double(*f[M])(double),int n,double x[N],
double y[N],double a[M])
{
double e,ff,b[M][M],c[M][1];
int i,j,k;
for(j=0;j<m;j++) /*计算最小均方逼近矩阵及常向量*/
{
for(k=0;k<m;k++)
{
b[j][k]=0.0;
for(i=0;i<n;i++)
b[j][k]+=(*f[j])(x)*(*f[k])(x);
}
c[j][0]=0.0;
for(i=0;i<n;i++)
c[j][0]+=(*f[j])(x)*y;
}
gaussian_elimination(m,b,1,c);
/*求拟和系数*/
for(i=0;i<m;i++)
a=c[0];
e=0.0;
for(i=0;i<n;i++) /*计算均方误差*/
{
ff=0.0;
for(j=0;j<m;j++)
ff+=a[j]*(*f[j])(x);
e+=(y-ff)*(y-ff);
}
return(e);
}
/*************************************************************************
* 高斯列主元素消去法求解矩阵方程AX=B,其中A是N*N的矩阵,B是N*M矩阵
* 输入: n----方阵A的行数
* a----矩阵A
* m----矩阵B的列数
* b----矩阵B
* 输出: det----矩阵A的行列式值
* a----A消元后的上三角矩阵
* b----矩阵方程的解X
**************************************************************************/
double gaussian_elimination(int n,double a[M][M],int m,double b[M][1])
{
int i,j,k,mk;
double det,mm,f;
det = 1.0;
for(k = 0;k<n-1;k++) /*选主元并消元*/
{
mm=a[k][k];
mk = k;
for(i=k+1;i<n;i++) /*选择第K列主元素*/
{
if(fabs(mm)<fabs(a[k]))
{
mm = a[k];
mk = i;
}
}
if(fabs(mm)<EPS)
return(0);
if(mk!=k) /* 将第K列主元素换行到对角线上*/
{
for(j=k;j<n;j++)
{
f = a[k][j];
a[k][j]=a[mk][j];
a[mk][j]=f;
}
for(j=0;j<m;j++)
{
f = b[k][j];
b[k][j]=b[mk][j];
b[mk][j]=f;
}
det = -det;
}
for(i=k+1;i<n;i++) /*将第K列对角线以下消元为零*/
{
mm = a[k]/a[k][k];
a[k]=0.0;
for(j=k+1;j<n;j++)
a[j]=a[j]-mm*a[k][j];
for(j=0;j<m;j++)
b[j]=b[j]-mm*b[k][j];
}
det = det*a[k][k];
}
if(fabs(a[k][k])<EPS)
return 0;
det=det*a[k][k];
for(i=0;i<m;i++) /*回代求解*/
{
b[n-1]=b[n-1]/a[n-1][n-1];
for(j=n-2;j>=0;j--)
{
for(k=j+1;k<n;k++)
b[j]=b[j]-a[j][k]*b[k];
b[j]=b[j]/a[j][j];
}
}
return(det);
}