用最小二乘法擬合任意次函數曲線(C#)

///<summary>
   ///用最小二乘法擬合二元多次曲線
   ///</summary>
   ///<param name="arrX">已知點的x座標集合</param>
   ///<param name="arrY">已知點的y座標集合</param>
   ///<param name="length">已知點的個數</param>
   ///<param name="dimension">方程的最高次數</param>
   
    public static double[] MultiLine(double[] arrX, double[] arrY, int length, int dimension)//二元多次線性方程擬合曲線
    {
       int n = dimension + 1;                 //dimension次方程需要求 dimension+1個 係數
       double[,] Guass=new double[n,n+1];     //高斯矩陣 例如:y=a0+a1*x+a2*x*x
       for(int i=0;i<n;i++)
       {
           int j;
           for(j=0;j<n;j++)
           {
               Guass[i,j] = SumArr(arrX, j + i, length);
           }
           Guass[i,j] = SumArr(arrX,i,arrY,1,length);          
       }

      return ComputGauss(Guass,n);

    }

    public static double SumArr(double[] arr, int n, int length) //求數組的元素的n次方的和
    {
       double s = 0;
       for (int i = 0; i < length; i++)
       {
           if (arr[i] != 0 || n != 0)         
               s = s + Math.Pow(arr[i], n);
           else
               s = s + 1;
       }
       return s;
    }
    public static double SumArr(double[] arr1, int n1, double[] arr2, int n2, int length)
    {
       double s=0;
       for (int i = 0; i < length; i++)
       {
           if ((arr1[i] != 0 || n1 != 0) && (arr2[i] != 0 || n2 != 0))
               s = s + Math.Pow(arr1[i], n1) * Math.Pow(arr2[i], n2);
           else
               s = s + 1;
       }
       return s;
 
    }

    public static double[] ComputGauss(double[,] Guass,int n)
    {
       int i, j;
       int k,m;
       double temp;
       double max;
       double s;
       double[] x = new double[n];

       for (i = 0; i < n; i++)          x[i] = 0.0;//初始化
       

       for (j = 0; j < n; j++)
       {
           max = 0;         

           k = j;    
           for (i = j; i < n; i++)
           {
               if (Math.Abs(Guass[i, j]) > max)
               {
                   max = Guass[i, j];
                   k = i;
               }
           }


           
           if (k != j)
           {
               for (m = j; m < n + 1; m++)
               {
                   temp = Guass[j, m];
                   Guass[j, m] = Guass[k, m];
                   Guass[k, m] = temp;

               }
           }

           if (0 == max)
           {
               // "此線性方程爲奇異線性方程" 

               return x;
           }

           
           for (i = j + 1; i < n; i++) 
           {

               s = Guass[i, j];
               for (m = j; m < n + 1; m++)
               {
                   Guass[i, m] = Guass[i, m] - Guass[j, m] * s / (Guass[j, j]);

               }
           }


       }//結束for (j=0;j<n;j++)

       
       for (i = n-1; i >= 0; i--)
       {           
           s = 0;
           for (j = i + 1; j < n; j++)
           {
               s = s + Guass[i,j] * x[j];
           }

           x[i] = (Guass[i,n] - s) / Guass[i,i];

       }

      return x;
   }//返回值是函數的係數

例如:y=a0+a1*x 返回值則爲a0 a1

例如:y=a0+a1*x+a2*x*x 返回值則爲a0 a1 a2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章