搜索
bottom↓
回复: 22

那位有最小二乘法曲线拟合的单片机C子程序,先谢了!

[复制链接]

出0入0汤圆

发表于 2007-5-19 09:31:18 | 显示全部楼层 |阅读模式
搞一个项目,需要对AD采样的数据进行修正,那位有最小二乘法曲线拟合的单片机C子程序,谢谢!

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2007-5-19 10:31:51 | 显示全部楼层
我以前写的:



double sum(double *x, int n)

{

        double sum = 0.0;

        int i;



        for(i = 0; i < n; i ++)

                sum += x;



        return sum;

}



double average(double *x, int n)

{

        return sum(x, n) / n;

}



void linearregression(double *x, double *y, int n, double *a, double *b)

{

        double xavg, yavg;

        double a1, a2;

        int i;



        xavg = average(x, n);

        yavg = average(y, n);



        a1 = 0.0;

        a2 = 0.0;

        for(i = 0; i < n; i ++)

        {

                a1 += (x - xavg) * (y - yavg);

                a2 += (x - xavg) * (x - xavg);

        }



        *a = a1 / a2;

        *b = yavg - *a * xavg;

}

出0入0汤圆

 楼主| 发表于 2007-5-19 11:33:31 | 显示全部楼层
感谢小俊兄! 正试用之!

出0入0汤圆

发表于 2007-5-19 12:03:22 | 显示全部楼层
参考Metlab中的polyfit和polyval函数

出0入0汤圆

发表于 2007-5-19 12:17:33 | 显示全部楼层
举个例子,有5个点,做最高项为2次项的拟和:

1.计算V矩阵:

V = |x(1)*x(1),x(2)*x(2),x(3)*x(3),x(4)*x(4),x(5)*x(5)|

    |x(1)     ,x(2)     ,x(3)     ,x(4)     ,x(5)     |

    |1        ,1        ,1        ,1        ,1        |



2.计算T矩阵,T = V' * V

3.计算上右三角矩阵R,使得R' * R = T

4.计算Q矩阵,Q * R = V

5.计算结果,p = R / (Q' * y)



程序记得以前在这里发过,找不到了

出0入0汤圆

 楼主| 发表于 2007-5-21 09:45:00 | 显示全部楼层
网上找到几个算法程序,贴出来讨论一下:

  

第一个,没学过C++,谁能解释一下定义部分:



//最小二乘法曲线拟合

typedef CArray<double,double>CDoubleArray;

BOOL CalculateCurveParameter(CDoubleArray *X,CDoubleArray *Y,long M,long N,CDoubleArray *A)

{

//X,Y --  X,Y两轴的坐标

//M   --  结果变量组数

//N   --  采样数目

//A   --  结果参数

  register long i,j,k;

  double Z,D1,D2,C,P,G,Q;

  CDoubleArray B,T,S;

  B.SetSize(N);

  T.SetSize(N);

  S.SetSize(N);

  if(M>N)M=N;

  for(i=0;i<M;i++)

    (*A)=0;

  Z=0;

  B[0]=1;

  D1=N;

  P=0;

  C=0;

  for(i=0;i<N;i++)

  {

    P=P+(*X)-Z;

    C=C+(*Y);

  }

  C=C/D1;

  P=P/D1;

  (*A)[0]=C*B[0];

  if(M>1)

  {

    T[1]=1;

    T[0]=-P;

    D2=0;

    C=0;

    G=0;

    for(i=0;i<N;i++)

    {

      Q=(*X)-Z-P;

      D2=D2+Q*Q;

      C=(*Y)*Q+C;

      G=((*X)-Z)*Q*Q+G;

    }

    C=C/D2;

    P=G/D2;

    Q=D2/D1;

    D1=D2;

    (*A)[1]=C*T[1];

    (*A)[0]=C*T[0]+(*A)[0];

   }

   for(j=2;j<M;j++)

   {

     S[j]=T[j-1];

     S[j-1]=-P*T[j-1]+T[j-2];

     if(j>=3)

     {

       for(k=j-2;k>=1;k--)

         S[k]=-P*T[k]+T[k-1]-Q*B[k];

     }

     S[0]=-P*T[0]-Q*B[0];

     D2=0;

     C=0;

     G=0;

     for(i=0;i<N;i++)

     {

       Q=S[j];

       for(k=j-1;k>=0;k--)

       Q=Q*((*X)-Z)+S[k];

       D2=D2+Q*Q;

       C=(*Y)*Q+C;

       G=((*X)-Z)*Q*Q+G;

     }

     C=C/D2;

     P=G/D2;

     Q=D2/D1;

     D1=D2;

     (*A)[j]=C*S[j];

     T[j]=S[j];

     for(k=j-1;k>=0;k--)

     {

       (*A)[k]=C*S[k]+(*A)[k];

       B[k]=T[k];

       T[k]=S[k];

     }

   }

   return TRUE;

}

出0入0汤圆

 楼主| 发表于 2007-5-21 09:47:04 | 显示全部楼层
另外一个:



/***************************************************************

* 本算法用最小二乘法依据指定的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);

}



还有:

http://community.csdn.net/Expert/topic/5478/5478010.xml?temp=.8542139



如果假定坐标轴下面的5~10个点的坐标,分别存放在x[],y[]数组里面,现在需要根据已知点的坐标求出曲线拟合的2次多项式的3个系数,哪一个算法简化一些?
-----此内容被dzxujin于2007-05-21,09:53:59编辑过

出0入85汤圆

发表于 2009-12-25 12:52:38 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-12-25 13:25:27 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-12-25 21:07:33 | 显示全部楼层
谢谢

出0入0汤圆

发表于 2009-12-25 21:52:19 | 显示全部楼层
不错,我以前也写过一个,不过没大家的好

出0入0汤圆

发表于 2009-12-25 22:49:02 | 显示全部楼层
MARK 最小二乘法

出0入0汤圆

发表于 2009-12-25 23:10:14 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-6-23 16:40:11 | 显示全部楼层
最小二乘法MARK

出0入0汤圆

发表于 2011-6-23 17:00:25 | 显示全部楼层
最小二乘法MARK

出0入0汤圆

发表于 2011-9-10 14:41:46 | 显示全部楼层
最小二乘法MARK

出0入0汤圆

发表于 2011-9-10 14:52:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-9-12 13:56:04 | 显示全部楼层
MARK

出0入0汤圆

发表于 2012-11-7 16:14:21 | 显示全部楼层
mark,正在学习啊,我想根据AD采集到的数据拟合出正弦曲线,要圆滑的,这个应该怎么做呢?

出0入0汤圆

发表于 2013-2-22 09:46:57 | 显示全部楼层
正在看。。。。。。

出0入0汤圆

发表于 2013-2-22 12:41:04 | 显示全部楼层
mark,学习

出0入0汤圆

发表于 2014-8-12 17:32:22 | 显示全部楼层
mark,曲线拟合

出0入42汤圆

发表于 2014-8-12 17:47:02 | 显示全部楼层

MARK,TOO.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 13:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表