C#使用MathNet庫來對進行曲線擬合


 下面是用來求取一條直線和一條擬合曲線交點的代碼

        /// <summary>
        /// 擬合曲線所篩選的點的個數
        /// </summary>
        const int CurveNums = 10;

        /// <summary>
        /// 擬合曲線的階數
        /// </summary>
        public int m =2;

        /// <summary>
        /// 取直線上的點的個數
        /// </summary>
        const int XNums = 50;
        /// <summary>
        ///  最小二乘法擬合曲線
        /// </summary>
        /// <param name="X">X軸數組</param>
        /// <param name="Y">Y軸數組</param>
        /// <param name="m">階數</param>
        /// <returns>返回曲線方程的各階系數(由高階到低階,一般m=2)</returns>
        public double[] FittingCurveByLeastSquare(double[] X, double[] Y, int m = 2)
        {
            /// https://blog.csdn.net/qq_23062949/article/details/119700640?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-3.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-3.no_search_link
            double[] res = new double[m + 1];
            if (X.Length > m && Y.Length > m)
            {
                res = Fit.Polynomial(X, Y, m);
            }
            return res;
        }

        /// <summary>
        /// 計算直線方程
        /// </summary>
        /// <param name="StartPoint">直線起點</param>
        /// <param name="angle">直線的角度</param>
        /// <returns>返回k,b的數組</returns>
        public double[] CalculateLine(Point StartPoint, double angle)
        {
            double k = Math.Tan(angle / 180 * Math.PI);
            double b = StartPoint.Y - k * StartPoint.X;
            return new double[] { k, b };
        }

        /// <summary>
        /// 計算交點
        /// </summary>
        /// <param name="LineResult">直線的k,b</param>
        /// <param name="CurveResult">擬合曲線的系數數組</param>
        /// <param name="LineX">直線上的點的X坐標</param>
        /// <param name="m">階數</param>
        /// <returns></returns>
        public EPoint CalculateInterPoint(double[] LineResult, double[] CurveResult, double[] LineX, int m)
        {
            EPoint InterPoint = new EPoint();
            if (LineResult.Length == 2 && CurveResult.Length == (m + 1))
            {
                double k = LineResult[0];
                double b = LineResult[1];
                for (int i = 0; i < LineX.Count(); i++)
                {
                    double x = LineX[i];
                    double y_Line = k * x + b;
                    double y_Curve = 0;
                    for (int n = 0; n <= m; n++)
                    {
                        y_Curve += CurveResult[n] * Math.Pow(x, n);
                    }
                    bool IsSuccessFind = false;
                    for (int t = 1; t <= 50; t++)
                    {
                        if (Math.Abs(y_Line - y_Curve) < 5)
                        {
                            InterPoint = new EPoint((int)x, (int)y_Line);
                            IsSuccessFind = true;
                            break;//跳出內循環
                        }
                    }
                    if (IsSuccessFind)
                    {
                        break;//跳出外循環
                    }
                }
            }
            return InterPoint;
        }

        /// <summary>
        /// 計算R^2,R^2這個值越接近1,說明擬合出來的曲線跟原曲線就越接近
        /// </summary>
        /// <param name="Y">實際的Y</param>
        /// <param name="Ytest">代入擬合曲線方程得到的Y</param>
        /// <returns>返回R^2</returns>
        public double CalculateRSquared(double[] Y, double[] Ytest)
        {
            double RSquared = GoodnessOfFit.RSquared(Y, Ytest);
            return RSquared;
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM