1. 程式人生 > 其它 >C#使用MathNet庫來對進行曲線擬合

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; }
4556