waysun一路陽光

          不輕易服輸,不輕言放棄.--心是夢的舞臺,心有多大,舞臺有多大。踏踏實實做事,認(rèn)認(rèn)真真做人。

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            167 隨筆 :: 1 文章 :: 64 評論 :: 0 Trackbacks
          因為我所在的項目要用到最小二乘法擬合,所有我抽時間將C++實現(xiàn)的程序改為JAVA實現(xiàn),現(xiàn)在貼出來,供大家參考使用。
          /**
           * <p>函數(shù)功能:最小二乘法曲線擬合</p>
           * @param x 實型一維數(shù)組,長度為 n 。存放給定 n 個數(shù)據(jù)點的 X 坐標(biāo)
           * @param y 實型一維數(shù)組,長度為 n 。存放給定 n 個數(shù)據(jù)點的 Y 坐標(biāo)
           * @param n 變量。給定數(shù)據(jù)點的個數(shù)
           * @param a 實型一維數(shù)組,長度為 m 。返回 m-1 次擬合多項式的 m 個系數(shù)
           * @param m 擬合多項式的項數(shù),即擬合多項式的最高次數(shù)為 m-1.
           *          要求 m<=n 且m<=20。若 m>n 或 m>20 ,則本函數(shù)自動按 m=min{n,20} 處理.
           * <p>Date:2007-12-25 16:21 PM</p>
           * @author qingbao-gao
           * @return 
           */
           public static double[] PolyFit(double x[], double y[], int n, double a[], int m)
           {
            int i, j, k;
            double z, p, c, g, q = 0, d1, d2; 
            double []s=new double[20];
            double []t=new double[20];
            double[] b=new double[20];
            double[]dt=new double[3];
            for (i = 0; i <= m-1; i++)
            {
             a[i] = 0.0;
            }
            if (m > n)
            {
             m = n;
            }
            if (m > 20)
            {
             m = 20;
            }
            z = 0.0;
            for (i = 0; i <= n-1; i++)
            {
             z = z+x[i]/(1.0 *n);
            }
            b[0] = 1.0;
            d1 = 1.0 * n;
            p = 0.0;
            c = 0.0;
            for (i = 0; i <= n-1; i++)
            {
             p = p+(x[i]-z);
             c = c+y[i];
            }
            c = c/d1;
            p = p/d1;
            a[0] = c * b[0];
            if (m > 1)
            {
             t[1] = 1.0;
             t[0] = -p;
             d2 = 0.0;
             c = 0.0;
             g = 0.0;
             for (i = 0; i <= n-1; i++)
             {
              q = x[i]-z-p;
              d2 = d2+q * q;
              c = c+y[i] *q;
              g = g+(x[i]-z) *q * q;
             }
             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-1; 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.0;
             c = 0.0;
             g = 0.0;
             for (i = 0; i <= n-1; i++)
             {
              q = s[j];
              for (k = j-1; k >= 0; k--)
              {
               q = q *(x[i]-z)+s[k];
              }
              d2 = d2+q * q;
              c = c+y[i] *q;
              g = g+(x[i]-z) *q * q;
             }
             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];
             }
            }
            dt[0] = 0.0;
            dt[1] = 0.0;
            dt[2] = 0.0;
            for (i = 0; i <= n-1; i++)
            {
             q = a[m-1];
             for (k = m-2; k >= 0; k--)
             {
              q = a[k]+q *(x[i]-z);
             }
             p = q-y[i];
             if (Math.abs(p) > dt[2])
             {
              dt[2] = Math.abs(p);
             }
             dt[0] = dt[0]+p * p;
             dt[1] = dt[1]+Math.abs(p);
            }
            return a;
           }
          /**
            * <p>對X軸數(shù)據(jù)節(jié)點球平均值</p>
            * @param x 存儲X軸節(jié)點的數(shù)組
            * <p>Date:2007-12-25 20:21 PM</p>
            * @author qingbao-gao
            * @return  平均值
            */
           public static double ave(double []x)
           {
            double ave=0;
            double sum=0;
            if(x!=null)
            {
             for(int i=0;i<x.length;i++)
             {
              sum+=x[i];
             }
             System.out.println("sum-->"+sum);
             ave=sum/x.length;
             System.out.println("ave"+ave+"x.length"+x.length);
            }
            return ave;
           }
           /**
            * <p>由X值獲得Y值</p>
            * @param x  當(dāng)前X軸輸入值,即為預(yù)測的月份
            * @param xx 當(dāng)前X軸輸入值的前X數(shù)據(jù)點
            * @param a  存儲多項式系數(shù)的數(shù)組
            * @param m  存儲多項式的最高次數(shù)的數(shù)組
            * <p>Date:2007-12-25 PM 20:07</p>
            * <P>Author:qingbao-gao</P>
            * @return   對應(yīng)X軸節(jié)點值的Y軸值
            */
           public static double getY(double x,double[]xx,double[]a,int m)
           {
            double y=0;
            double ave=ave(xx);
            
            double l=0;
            for(int i=0;i<m;i++)
            {
             l=a[0];
             if(i>0)
             {
              y+=a[i]*Math.pow((x-ave),i );
              System.out.println(i+"--|-->"+y+"--a[i]--"+a[i]);
             }
             System.out.println("a[0]|"+a[0]);
            }
            System.out.println("l--|"+(l));
            return (y+l);
           }

          //--------------------------------------------測試代碼

          public static void main(String []args)throws DBException
           {  

            double []x={200401,200402,200403,200404,200405,200406,200407,200408,200409,2004010,2004011,2004012,200501,200502,200503,200504};
            double []y={51,51,53,53,54,55,57,60,63,64,66,66,69,71,72,75};
            double[]a=new double[20];
            double[]aa= PolyFit(x,  y,  16,a, 3);
            double yy=0;
            System.out.println("擬合-->"+getY(200505,x,aa,3));

           }

          測試結(jié)果為:擬合-->72.38898870320554
          效果還可以。

          posted on 2009-04-15 22:28 weesun一米陽光 閱讀(5662) 評論(1)  編輯  收藏 所屬分類: JAVA源碼總結(jié)備用

          評論

          # re: 最小二乘法擬合java實現(xiàn)源程序【原創(chuàng) 】[未登錄] 2013-07-21 13:37 aa
          getY 函數(shù)這個xx【】數(shù)組是用來干嘛的  回復(fù)  更多評論
            

          主站蜘蛛池模板: 韶关市| 万载县| 民勤县| 贵南县| 尚志市| 福泉市| 焉耆| 启东市| 天峨县| 阳山县| 宣汉县| 上蔡县| 嵊泗县| 太仆寺旗| 西和县| 昭觉县| 绩溪县| 安塞县| 长兴县| 雷波县| 望江县| 灵山县| 诸暨市| 孝感市| 台北县| 新乐市| 高安市| 高要市| 财经| 稷山县| 呼玛县| 三门峡市| 江达县| 巴青县| 裕民县| 合山市| 红安县| 额尔古纳市| 蓬莱市| 奈曼旗| 兰州市|