最小二乘法拟合曲线

	    /// <summary>
        ///  最小二乘法拟合曲线
        /// </summary>
        /// <param name="X">X轴数组</param>
        /// <param name="Y">Y轴数组</param>
        /// <param name="m">阶数</param>
        /// <returns>返回曲线方程的各阶系数(由高阶到低阶,一般m=2)</returns>
        /// <example>
        // 使用的时候, y = res[4]*x* x*x* x + res[3]*x* x*x + res[2]*x* x + res[1]*x + res[0]
        // </example.>
        public double[] FittingCurveByLeastSquare(double[] X, double[] Y, int m = 2)
        {
            /// https://blog.csdn.net/qq_23062949/article/details/119700640
            double[] res = new double[m + 1];
            if (X.Length > m && Y.Length > m)
            {
                res = Fit.Polynomial(X, Y, m);
            }
            return res;
            // 返回结果的 res 使用代码如下
           // y = res[4] * x * x * x * x + res[3] * x * x * x + res[2] * x * x + res[1] * x + res[0]
        }
        
      	/// <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;
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值