FittingApproximation.inl
上传用户:fxromeo
上传日期:2010-04-08
资源大小:89k
文件大小:12k
开发平台:

Visual C++

  1. //FittingApproximation.inl 拟合与逼近头文件
  2. // Ver 1.0.0.0
  3. // 版权所有(C) 何渝, 2002
  4. // 最后修改: 2002.5.31.
  5. #ifndef _FITTINGAPPROXIMATION_INL //避免多次编译
  6. #define _FITTINGAPPROXIMATION_INL
  7. //最小二乘曲线拟合 
  8. template <class _Ty>
  9. void FitCurveLeastSquares(valarray<_Ty>& x, valarray<_Ty>& y, 
  10. valarray<_Ty>& a, valarray<_Ty>& dt)
  11. {
  12. //int i,j,k;
  13.     _Ty g,q,d2,s[20],t[20],b[20];
  14. int n = x.size(); //给定数据点的个数
  15. int m = a.size(); //拟合多项式的项数,即拟合多项式的最高次数为m-1
  16. //要求m<=n且m<=20。若m>n或m>20,本函数自动按m=min{n,20}处理。
  17.     for(int i=0; i<m; i++) a[i]=0.0;
  18.     if(m>n) m = n;
  19.     if(m>20) m=20;
  20.     _Ty z(0), p(0), c(0);;
  21.     for(i=0; i<n; i++) z = z + x[i] / n;
  22.     b[0]=1.0;
  23. _Ty d1 = n;
  24.     for(i=0; i<n; i++)
  25.     { 
  26. p=p+(x[i]-z);
  27. c=c+y[i];}
  28. c=c/d1; 
  29. p=p/d1;
  30. a[0]=c*b[0];
  31. if(m>1)
  32. {
  33. t[1]=1.0;
  34. t[0]=-p;
  35. d2=0.0;
  36. c=0.0; 
  37. g=0.0;
  38.         for(i=0; i<n; i++)
  39.         { 
  40. q=x[i]-z-p; d2=d2+q*q;
  41.             c=c+y[i]*q;
  42.             g=g+(x[i]-z)*q*q;
  43. }
  44.         c=c/d2;
  45. p=g/d2;
  46. q=d2/d1;
  47.         d1=d2;
  48.         a[1]=c*t[1]; 
  49. a[0]=c*t[0]+a[0];
  50.     }
  51.     for(int j=2; j<m; j++)
  52.     { 
  53. s[j]=t[j-1];
  54.         s[j-1]=-p*t[j-1]+t[j-2];
  55.         if(j>=3)
  56.           for(int k=j-2; k>=1; k--) s[k]=-p*t[k]+t[k-1]-q*b[k];
  57.         s[0]=-p*t[0]-q*b[0];
  58.         d2=0.0;
  59. c=0.0;
  60. g=0.0;
  61.         for(i=0; i<n; i++)
  62.         { 
  63. q=s[j];
  64.             for(int k=j-1; k>=0; k--) q=q*(x[i]-z)+s[k];
  65.             d2=d2+q*q; c=c+y[i]*q;
  66.             g=g+(x[i]-z)*q*q;
  67.         }
  68.         c=c/d2; 
  69. p=g/d2; 
  70. q=d2/d1;
  71.         d1=d2;
  72.         a[j]=c*s[j]; t[j]=s[j];
  73.         for(int k=j-1; k>=0; k--)
  74.         {
  75. a[k]=c*s[k]+a[k];
  76.             b[k]=t[k]; t[k]=s[k];
  77.         }
  78.     }
  79.     dt[0]=0.0;
  80. dt[1]=0.0;
  81. dt[2]=0.0;
  82.     for(i=0; i<n; i++)
  83.     { 
  84. q=a[m-1];
  85.         for(int k=m-2; k>=0; k--) q=a[k]+q*(x[i]-z);
  86.         p=q-y[i];
  87.         if(Abs(p)>dt[2]) dt[2]=fabs(p);
  88.         dt[0]=dt[0]+p*p;
  89.         dt[1]=dt[1]+fabs(p);
  90.     }
  91. }
  92. //切比雪夫曲线拟合
  93. template <class _Ty>
  94. void FitCurveChebyshev(valarray<_Ty>& x, valarray<_Ty>& y, valarray<_Ty>& a)
  95. {
  96. int ii,k,im,ix[21];
  97.     _Ty h[21],y1,y2,h1,h2,d,hm;
  98. int n = x.size(); //给定数据点的个数
  99. int m = a.size()-1; //拟合多项式的项数,即拟合多项式的最高次数为m-1
  100. //要求m<n且m<=20。若m>=n或m>20,本函数自动按m=min{n-1,20}处理。
  101.     for(int i=0; i<=m; i++) a[i]=0.0;
  102.     if(m>=n) m=n-1;
  103.     if(m>=20) m=19;
  104.     int m1 = m + 1;
  105.     _Ty ha(0);
  106.     ix[0] = 0; 
  107. ix[m] = n - 1;
  108.     int l = (n - 1) / m; 
  109. int j = l;
  110.     for(i=1; i<m; i++)
  111.     {
  112. ix[i]=j;
  113. j=j+l;
  114. }
  115.     while(1)
  116.     {
  117. _Ty hh=1.0;
  118.         for(i=0; i<=m; i++)
  119.         {
  120. a[i]=y[ix[i]];
  121. h[i]=-hh;
  122. hh=-hh;
  123. }
  124.         for(int j=1; j<=m; j++)
  125.         {
  126. ii=m1;
  127. y2=a[ii-1]; 
  128. h2=h[ii-1];
  129.             for(i=j; i<=m; i++)
  130.             {
  131. d=x[ix[ii-1]]-x[ix[m1-i-1]];
  132.                 y1=a[m-i+j-1];
  133.                 h1=h[m-i+j-1];
  134.                 a[ii-1]=(y2-y1)/d;
  135.                 h[ii-1]=(h2-h1)/d;
  136.                 ii=m-i+j;
  137. y2=y1;
  138. h2=h1;
  139.             }
  140.         }
  141.         hh=-a[m]/h[m];
  142.         for(i=0; i<=m; i++) a[i]=a[i]+h[i]*hh;
  143.         for(j=1; j<m; j++)
  144.         {
  145. ii=m-j;
  146. d=x[ix[ii-1]];
  147.             y2=a[ii-1];
  148.             for(k=m1-j; k<=m; k++)
  149.             {
  150. y1=a[k-1];
  151. a[ii-1]=y2-d*y1;
  152.                 y2=y1; 
  153. ii=k;
  154.             }
  155.         }
  156.         hm = Abs(hh);
  157.         if(hm < ha || FloatEqual(hm, ha))
  158. {
  159. a[m] = -hm;
  160. return;
  161. }
  162.         a[m]=hm; 
  163. ha=hm; 
  164. im=ix[0]; 
  165. h1=hh;
  166.         j=0;
  167.         for(i=0; i<n; i++)
  168.         {
  169. if (i==ix[j])
  170.             { 
  171. if (j<m) j=j+1;
  172. }
  173. else
  174. h2=a[m-1];
  175. for(k=m-2; k>=0; k--) h2=h2*x[i]+a[k];
  176. h2=h2-y[i];
  177. if(Abs(h2)>hm)
  178. {
  179. hm=Abs(h2); 
  180. h1=h2;
  181. im=i;
  182. }
  183. }
  184. }
  185. if(im==ix[0]) return;
  186. i=0;
  187. l=1;
  188. while(l==1)
  189. l=0;
  190. if(im>=ix[i])
  191. {
  192. i=i+1;
  193. if (i<=m) l=1;
  194. }
  195. }
  196. if(i>m) i=m;
  197. if(i==(i/2)*2) h2=-hh;
  198. else h2=hh;
  199. if(h1*h2>=0.0) ix[i]=im;
  200. else
  201. {
  202. if(im<ix[0])
  203. for(j=m-1; j>=0; j--) ix[j+1]=ix[j];
  204. ix[0]=im;
  205. }
  206. else
  207. {
  208. if(im>ix[m])
  209. {
  210. for(j=1; j<=m; j++) ix[j-1]=ix[j];
  211. ix[m]=im;
  212. }
  213. else 
  214. ix[i-1]=im;
  215. }
  216. }
  217. }
  218. }
  219. //最佳一致逼近多项式里米兹法
  220. template <class _Ty>
  221. void ApproximationRemez(_Ty a, _Ty b, valarray<_Ty>& p, _Ty eps)
  222. {
  223.     _Ty x[21],g[21],t,s,xx,x0,h,yy;
  224. int n = p.size()-1; //n-1次最佳一致逼近多项式的项数
  225. //要求n<=20; 若n>20,函数自动取n=20
  226.     if(n>20) n=20;
  227.     int m=n+1; 
  228. _Ty d(1.0e+35);
  229.     for(int k=0; k<=n; k++)
  230.     {
  231. t = cos((n - k) * 3.1415926 / n);
  232.         x[k] = (b + a + (b-a) * t) / 2.0;
  233.     }
  234.     while(1)
  235.     {
  236. _Ty u(1);
  237.         for(int i=0; i<m; i++)
  238.         {
  239. p[i]=FunctionValueAR(x[i]);
  240.             g[i]=-u;
  241. u=-u;
  242.         }
  243.         for(int j=0; j<n; j++)
  244.         {
  245. k=m;
  246. s=p[k-1];
  247. xx=g[k-1];
  248.             for(i=j; i<n; i++)
  249.             {
  250. t=p[n-i+j-1];
  251. x0=g[n-i+j-1];
  252.                 p[k-1]=(s-t)/(x[k-1]-x[m-i-2]);
  253.                 g[k-1]=(xx-x0)/(x[k-1]-x[m-i-2]);
  254.                 k=n-i+j;
  255. s=t;
  256. xx=x0;
  257.             }
  258.         }
  259.         u=-p[m-1]/g[m-1];
  260.         for(i=0; i<m; i++) p[i]=p[i]+g[i]*u;
  261.         for(j=1; j<n; j++)
  262.         {
  263. k=n-j; 
  264. h=x[k-1];
  265. s=p[k-1];
  266.             for(i=m-j; i<=n; i++)
  267.             {
  268. t=p[i-1];
  269. p[k-1]=s-h*t;
  270.                 s=t; 
  271. k=i;
  272.             }
  273.         }
  274.         p[m-1]=Abs(u);
  275. u=p[m-1];
  276.         if(Abs(u-d) <= eps) return;
  277.         d=u; 
  278. h=0.1*(b-a)/(1.0*n);
  279.         xx=a; 
  280. x0=a;
  281.         while(x0<=b)
  282.         {
  283. s=FunctionValueAR(x0);
  284. t=p[n-1];
  285.             for(i=n-2; i>=0; i--) t=t*x0+p[i];
  286.             s=Abs(s-t);
  287.             if(s>u) 
  288. {
  289. u=s; 
  290. xx=x0;
  291. }
  292.             x0=x0+h;
  293.         }
  294.         s=FunctionValueAR(xx); 
  295. t=p[n-1];
  296.         for(i=n-2; i>=0; i--) t=t*xx+p[i];
  297.         yy=s-t; 
  298. i=1;
  299. j=n+1;
  300.         while((j-i)!=1)
  301.         {
  302. k=(i+j)/2;
  303.             if(xx<x[k-1]) j=k;
  304.             else i=k;
  305.         }
  306.         if(xx<x[0])
  307.         {
  308. s=FunctionValueAR(x[0]); 
  309. t=p[n-1];
  310.             for(k=n-2; k>=0; k--) t=t*x[0]+p[k];
  311.             s=s-t;
  312.             if(s*yy>0.0) x[0]=xx;
  313.             else
  314.             {
  315. for(k=n-1; k>=0; k--) x[k+1]=x[k];
  316.                 x[0]=xx;
  317.             }
  318.         }
  319.         else
  320.         {
  321. if(xx>x[n])
  322.             {
  323. s=FunctionValueAR(x[n]); 
  324. t=p[n-1];
  325.                 for(k=n-2; k>=0; k--) t=t*x[n]+p[k];
  326.                 s=s-t;
  327.                 if(s*yy>0.0) x[n]=xx;
  328.                 else
  329.                 {
  330. for(k=0; k<n; k++) x[k]=x[k+1];
  331.                     x[n]=xx;
  332.                 }
  333.             }
  334.             else
  335.             {
  336. i=i-1;
  337. j=j-1;
  338.                 s=FunctionValueAR(x[i]);
  339. t=p[n-1];
  340.                 for(k=n-2; k>=0; k--) t=t*x[i]+p[k];
  341.                 s=s-t;
  342.                 if(s*yy>0.0) x[i]=xx;
  343.                 else x[j]=xx;
  344.             }
  345.         }
  346.     }
  347. }
  348. //矩形域的最小二乘曲面拟合
  349. template <class _Ty>
  350. void FitSurfaceLeastSquares(valarray<_Ty>& x, valarray<_Ty>& y, 
  351. matrix<_Ty>& z, matrix<_Ty>& a, valarray<_Ty>& dt)
  352. {
  353. int l,kk;
  354.     _Ty apx[20],apy[20],bx[20],by[20];
  355.     _Ty t[20],t1[20],t2[20],d2,g,g1,g2;
  356.     _Ty x2,dd,y1,x1;
  357. int n = x.size(); //给定数据点的X坐标个数
  358. int m = y.size(); //给定数据点的Y坐标个数
  359. matrix<_Ty> v(20,m), u(20,20);
  360. int p = a.GetRowNum(); //拟合多项式中变量x的最高次数加1
  361. //并要求p<=n且p<=20; 否则在本函数中自动取p=min{n,20}处理
  362. int q = a.GetColNum(); //拟合多项式中变量y的最高次数加1
  363. //并要求q<=m且q<=20; 否则在本函数中自动取q=min{m,20}处理
  364.     for(int i=0; i<p; i++)
  365.         for(int j=0; j<q; j++) a(i,j)=0.0;
  366.     if(p>n) p=n;
  367.     if(p>20) p=20;
  368.     if(q>m) q=m;
  369.     if(q>20) q=20;
  370.     _Ty xx(0), yy(0), d1(n); 
  371.     for(i=0; i<n; i++) xx = xx + x[i] / n;
  372.     for(i=0; i<m; i++)  yy = yy + y[i] / m;
  373.     apx[0]=0.0;
  374.     for(i=0; i<n; i++) apx[0] = apx[0] + x[i] - xx;
  375.     apx[0] = apx[0] / d1;
  376.     for(int j=0; j<m; j++) //?????
  377.     { 
  378. v(0,j)=0.0;
  379.         for(i=0; i<n; i++) v(0,j)=v(0,j)+z(i,j);
  380.         v(0,j)=v(0,j)/d1;
  381.     }
  382.     if(p>1)
  383.     { 
  384. d2=0.0;
  385. apx[1]=0.0;
  386.         for(i=0; i<n; i++)
  387.         {
  388. g=x[i]-xx-apx[0];
  389.             d2=d2+g*g;
  390.             apx[1]=apx[1]+(x[i]-xx)*g*g;
  391.         }
  392.         apx[1]=apx[1]/d2;
  393.         bx[1]=d2/d1;
  394.         for(j=0; j<m; j++)
  395.         { 
  396. v(1,j)=0.0;
  397.             for(i=0; i<n; i++)
  398.             {
  399. g=x[i]-xx-apx[0];
  400.                 v(1,j)=v(1,j)+z(i,j)*g;
  401.             }
  402.             v(1,j)=v(1,j)/d2;
  403.         }
  404.         d1=d2;
  405.     }
  406.     for(int k=2; k<p; k++)
  407.     { 
  408. d2=0.0; 
  409. apx[k]=0.0;
  410.         for(j=0; j<m; j++) v(k,j)=0.0;
  411.         for(i=0; i<n; i++)
  412.         {
  413. g1=1.0; g2=x[i]-xx-apx[0];
  414.             for(j=2; j<=k; j++)
  415.             {
  416. g=(x[i]-xx-apx[j-1])*g2-bx[j-1]*g1;
  417.                 g1=g2; g2=g;
  418.             }
  419.             d2=d2+g*g;
  420.             apx[k]=apx[k]+(x[i]-xx)*g*g;
  421.             for(j=0; j<m; j++) v(k,j)=v(k,j)+z(i,j)*g;
  422.         }
  423.         for(j=0; j<m; j++) v(k,j)=v(k,j)/d2;
  424.         apx[k]=apx[k]/d2;
  425.         bx[k]=d2/d1;
  426.         d1=d2;
  427.     }
  428.     d1=m; 
  429. apy[0]=0.0;
  430.     for(i=0; i<m; i++) apy[0]=apy[0]+y[i]-yy;
  431.     apy[0]=apy[0]/d1;
  432.     for(j=0; j<p; j++)
  433.     { 
  434. u(j,0)=0.0;
  435.         for(i=0; i<m; i++) u(j,0)=u(j,0)+v(j,i);
  436. u(j,0)=u(j,0)/d1;
  437.     }
  438.     if(q>1)
  439.     { 
  440. d2=0.0; 
  441. apy[1]=0.0;
  442.         for(i=0; i<m; i++)
  443.         {
  444. g=y[i]-yy-apy[0];
  445.             d2=d2+g*g;
  446.             apy[1]=apy[1]+(y[i]-yy)*g*g;
  447.         }
  448.         apy[1]=apy[1]/d2;
  449.         by[1]=d2/d1;
  450.         for(j=0; j<p; j++)
  451. {
  452. u(j,1)=0.0;
  453.             for(i=0; i<m; i++)
  454.             {
  455. g=y[i]-yy-apy[0];
  456. u(j,1)=u(j,1)+v(j,i)*g;
  457.             }
  458. u(j,1)=u(j,1)/d2;
  459.         }
  460.         d1=d2;
  461.     }
  462.     for(k=2; k<q; k++)
  463.     { 
  464. d2=0.0;
  465. apy[k]=0.0;
  466. for(j=0; j<p; j++) u(j,k)=0.0;
  467.         for(i=0; i<m; i++)
  468.         {
  469. g1=1.0;
  470.             g2=y[i]-yy-apy[0];
  471.             for(j=2; j<=k; j++)
  472.             {
  473. g=(y[i]-yy-apy[j-1])*g2-by[j-1]*g1;
  474.                 g1=g2;
  475. g2=g;
  476.             }
  477.             d2=d2+g*g;
  478.             apy[k]=apy[k]+(y[i]-yy)*g*g;
  479.             for(j=0; j<p; j++) u(j,k)=u(j,k)+v(j,i)*g;
  480.         }
  481.         for(j=0; j<p; j++) u(j,k)=u(j,k)/d2;
  482.         apy[k]=apy[k]/d2;
  483.         by[k]=d2/d1;
  484.         d1=d2;
  485.     }
  486.     v(0,0)=1.0;
  487. v(1,0)=-apy[0]; 
  488. v(1,1)=1.0;
  489.     for(i=0; i<p; i++)
  490.       for(j=0; j<q; j++) a(i,j)=0.0;
  491.     for(i=2; i<q; i++)
  492.     {
  493. v(i,i)=v(i-1,i-1);
  494.         v(i,i-1)=-apy[i-1]*v(i-1,i-1)+v(i-1,i-2);
  495.         if(i>=3)
  496.           for(k=i-2; k>=1; k--)
  497.             v(i,k)=-apy[i-1]*v(i-1,k)+v(i-1,k-1)-by[i-1]*v(i-2,k);
  498.         v(i,0)=-apy[i-1]*v(i-1,0)-by[i-1]*v(i-2,0);
  499.     }
  500.     for(i=0; i<p; i++)
  501.     { 
  502. if(i==0)
  503. {
  504. t[0]=1.0;
  505. t1[0]=1.0;
  506. }
  507.         else
  508.         {
  509. if(i==1)
  510.             {
  511. t[0]=-apx[0];
  512. t[1]=1.0;
  513.                 t2[0]=t[0];
  514. t2[1]=t[1];
  515.             }
  516.             else
  517.             { 
  518. t[i]=t2[i-1];
  519.                 t[i-1]=-apx[i-1]*t2[i-1]+t2[i-2];
  520.                 if(i>=3)
  521.                   for(k=i-2; k>=1; k--)
  522.                     t[k]=-apx[i-1]*t2[k]+t2[k-1]
  523.                          -bx[i-1]*t1[k];
  524.                 t[0]=-apx[i-1]*t2[0]-bx[i-1]*t1[0];
  525.                 t2[i]=t[i];
  526.                 for(k=i-1; k>=0; k--)
  527.                 { 
  528. t1[k]=t2[k];
  529. t2[k]=t[k];
  530. }
  531.             }
  532.         }
  533.         for(j=0; j<q; j++)
  534.           for(k=i; k>=0; k--)
  535.             for(l=j; l>=0; l--)
  536. a(k,l)=a(k,l)+u(i,j)*t[k]*v(j,l);
  537.     }
  538.     dt[0]=0.0; 
  539. dt[1]=0.0;
  540. dt[2]=0.0;
  541.     for(i=0; i<n; i++)
  542.     {
  543. x1=x[i]-xx;
  544.         for(j=0; j<m; j++)
  545.         {
  546. y1=y[j]-yy;
  547.             x2=1.0; 
  548. dd=0.0;
  549.             for(k=0; k<p; k++)
  550.             {
  551. g=a(k,q-1);
  552.                 for(kk=q-2; kk>=0; kk--) g=g*y1+a(k,kk);
  553.                 g=g*x2;
  554. dd=dd+g;
  555. x2=x2*x1;
  556.             }
  557.             dd=dd-z(i,j);
  558.             if(Abs(dd)>dt[2]) dt[2]=Abs(dd);
  559.             dt[0]=dt[0]+dd*dd;
  560.             dt[1]=dt[1]+Abs(dd);
  561.         }
  562.     }
  563. }
  564. #endif // _FITTINGAPPROXIMATION_INL