c++ 多项式拟合算法

c++ 多项式拟合算法ifndefCZY MATH FIT defineCZY MATH FIT include vector 多项式拟合 namespaceczy brief 曲线拟合类 classFit std vector double factor double vector

#ifndef CZY_MATH_FIT #define CZY_MATH_FIT #include 
  
    /* 多项式拟合 */ namespace czy{ /// /// \brief 曲线拟合类 /// class Fit{ std::vector 
   
     factor; /// 
    <拟合后的方程系数 double="" ssr;="" <回归平方和="" sse;="" <(剩余平方和)="" rmse;="" 
      fitedYs;/// 
     <存放拟合后的y值,在拟合时可设置为不保存节省内存 public:="" fit()="" :ssr(0),="" sse(0),="" rmse(0){="" factor.resize(2,="" 0);="" }="" ~fit(){}="" \brief="" 直线拟合-一元回归,拟合的结果可以使用getfactor获取,或者使用getslope获取斜率,getintercept获取截距="" \param="" x="" 观察值的x="" y="" 观察值的y="" issavefitys="" 拟合后的数据是否保存,默认否="" template
       bool linearFit(const std::vector 
      
        & x, const std::vector 
       
         & y, bool isSaveFitYs = false) { return linearFit(&x[0], &y[0], getSeriesLength(x, y), isSaveFitYs); } template 
        
          bool linearFit(const T* x, const T* y, int length, bool isSaveFitYs = false) { factor.resize(2, 0); typename T t1 = 0, t2 = 0, t3 = 0, t4 = 0; for (int i = 0; i < length; ++i) { t1 += x[i] * x[i]; t2 += x[i]; t3 += x[i] * y[i]; t4 += y[i]; } factor[1] = (t3*length - t2*t4) / (t1*length - t2*t2); factor[0] = (t1*t4 - t2*t3) / (t1*length - t2*t2); // //计算误差 calcError(x, y, length, this->ssr, this->sse, this->rmse, isSaveFitYs); return true; } /// /// \brief 多项式拟合,拟合y=a0+a1*x+a2*x^2+……+apoly_n*x^poly_n /// \param x 观察值的x /// \param y 观察值的y /// \param poly_n 期望拟合的阶数,若poly_n=2,则y=a0+a1*x+a2*x^2 /// \param isSaveFitYs 拟合后的数据是否保存,默认是 /// template 
         
           void polyfit(const std::vector 
          
            & x , const std::vector 
           
             & y , int poly_n , bool isSaveFitYs = true) { polyfit(&x[0], &y[0], getSeriesLength(x, y), poly_n, isSaveFitYs); } template 
            
              void polyfit(const T* x, const TD* y, int length, int poly_n, bool isSaveFitYs = true) { factor.resize(poly_n + 1, 0); int i, j; //double *tempx,*tempy,*sumxx,*sumxy,*ata; std::vector 
             
               tempx(length, 1.0); std::vector 
              
                tempy(y, y + length); std::vector 
               
                 sumxx(poly_n * 2 + 1); std::vector 
                
                  ata((poly_n + 1)*(poly_n + 1)); std::vector 
                 
                   sumxy(poly_n + 1); for (i = 0; i < 2 * poly_n + 1; i++){ for (sumxx[i] = 0, j = 0; j < length; j++) { sumxx[i] += tempx[j]; tempx[j] *= x[j]; } } for (i = 0; i < poly_n + 1; i++){ for (sumxy[i] = 0, j = 0; j < length; j++) { sumxy[i] += tempy[j]; tempy[j] *= x[j]; } } for (i = 0; i < poly_n + 1; i++) for (j = 0; j < poly_n + 1; j++) ata[i*(poly_n + 1) + j] = sumxx[i + j]; gauss_solve(poly_n + 1, ata, factor, sumxy); //计算拟合后的数据并计算误差 fitedYs.reserve(length); calcError(&x[0], &y[0], length, this->ssr, this->sse, this->rmse, isSaveFitYs); } /// /// \brief 获取系数 /// \param 存放系数的数组 /// void getFactor(std::vector 
                  
                    & factor){ factor = this->factor; } /// /// \brief 获取拟合方程对应的y值,前提是拟合时设置isSaveFitYs为true /// void getFitedYs(std::vector 
                   
                     & fitedYs){ fitedYs = this->fitedYs; } /// /// \brief 根据x获取拟合方程的y值 /// \return 返回x对应的y值 /// template 
                    
                      double getY(const T x) const { double ans(0); for (int i = 0; i < (int)factor.size(); ++i) { ans += factor[i] * pow((double)x, (int)i); } return ans; } /// /// \brief 获取斜率 /// \return 斜率值 /// double getSlope(){ return factor[1]; } /// /// \brief 获取截距 /// \return 截距值 /// double getIntercept(){ return factor[0]; } /// /// \brief 剩余平方和 /// \return 剩余平方和 /// double getSSE(){ return sse; } /// /// \brief 回归平方和 /// \return 回归平方和 /// double getSSR(){ return ssr; } /// /// \brief 均方根误差 /// \return 均方根误差 /// double getRMSE(){ return rmse; } /// /// \brief 确定系数,系数是0~1之间的数,是数理上判定拟合优度的一个量 /// \return 确定系数 /// double getR_square(){ return 1 - (sse / (ssr + sse)); } /// /// \brief 获取两个vector的安全size /// \return 最小的一个长度 /// template 
                     
                       int getSeriesLength(const std::vector 
                      
                        & x , const std::vector 
                       
                         & y) { return (x.size() > y.size() ? y.size() : x.size()); } /// /// \brief 计算均值 /// \return 均值 /// template 
                        
                          static T Mean(const std::vector 
                         
                           & v) { return Mean(&v[0], v.size()); } template 
                          
                            static T Mean(const T* v, int length) { T total(0); for (int i = 0; i < length; ++i) { total += v[i]; } return (total / length); } /// /// \brief 获取拟合方程系数的个数 /// \return 拟合方程系数的个数 /// int getFactorSize(){ return factor.size(); } /// /// \brief 根据阶次获取拟合方程的系数, /// 如getFactor(2),就是获取y=a0+a1*x+a2*x^2+……+apoly_n*x^poly_n中a2的值 /// \return 拟合方程的系数 /// double getFactor(int i){ return factor.at(i); } private: template 
                           
                             void calcError(const T* x , const TD* y , int length , double& r_ssr , double& r_sse , double& r_rmse , bool isSaveFitYs = true ) { TD mean_y = Mean (y, length); T yi(0); fitedYs.reserve(length); for (int i = 0; i < length; ++i) { yi = getY(x[i]); r_ssr += ((yi - mean_y)*(yi - mean_y));//计算回归平方和 r_sse += ((yi - y[i])*(yi - y[i]));//残差平方和 if (isSaveFitYs) { fitedYs.push_back(double(yi)); } } r_rmse = sqrt(r_sse / (double(length))); } template 
                            
                              void gauss_solve(int n , std::vector 
                             
                               & A , std::vector 
                              
                                & x , std::vector 
                               
                                 & b) { gauss_solve(n, &A[0], &x[0], &b[0]); } template 
                                
                                  void gauss_solve(int n , T* A , T* x , T* b) { int i, j, k, r; double max; for (k = 0; k < n - 1; k++) { max = fabs(A[k*n + k]); /*find maxmum*/ r = k; for (i = k + 1; i < n - 1; i++){ if (max < fabs(A[i*n + i])) { max = fabs(A[i*n + i]); r = i; } } if (r != k){ for (i = 0; i < n; i++) /*change array:A[k]&A[r] */ { max = A[k*n + i]; A[k*n + i] = A[r*n + i]; A[r*n + i] = max; } } max = b[k]; /*change array:b[k]&b[r] */ b[k] = b[r]; b[r] = max; for (i = k + 1; i < n; i++) { for (j = k + 1; j < n; j++) A[i*n + j] -= A[i*n + k] * A[k*n + j] / A[k*n + k]; b[i] -= A[i*n + k] * b[k] / A[k*n + k]; } } for (i = n - 1; i >= 0; x[i] /= A[i*n + i], i--) for (j = i + 1, x[i] = b[i]; j < n; j++) x[i] -= A[i*n + j] * x[j]; } }; } #endif 
                                 
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
    
  
用法: void CDTData::Polyfit_Fun(WSDATA &wData, int nOrder, int nDataCnt) { vector 
  
    vecX; vector 
   
     vecY; int nBeginPoints = 0; // 开始拟合点 //保存所有点用于拟合 for (int i = 0; i < nDataCnt - nBeginPoints; ++i) { vecX.push_back(i); vecY.push_back(wData[i + nBeginPoints]); } int poly_n = nOrder; //拟合阶数 //拟合 czy::Fit fit; fit.polyfit(vecX, vecY, poly_n); //获取所有拟合后的值 vector 
    
      vecYPloy; fit.getFitedYs(vecYPloy); //减去拟合值 for (int i = nBeginPoints; i < nDataCnt; ++i) { wData[i] = wData[i] - vecYPloy[i - nBeginPoints]; } } 
     
    
  

忘记从哪里弄的了

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/209573.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 上午8:56
下一篇 2026年3月19日 上午8:56


相关推荐

  • 文心X1.1发布!这三大能力突出,一手实测在此

    文心X1.1发布!这三大能力突出,一手实测在此

    2026年3月12日
    2
  • pycharm每次新建项目都要重新安装一些第三方库解决办法

    pycharm每次新建项目都要重新安装一些第三方库解决办法目前有三个解决办法,也是亲测有用的:第一个方法:因为之前有通过pycharm的projectinterpreter里的+号添加过一些库,但添加的库只是指定的项目用的,如果想要用,就必须用之前的项目的python解释器,举个例子:这个是我之前的项目的解释器,这个项目解释器是继承的python的解释器,同时又安装了上面你看到的这些库,包含numpy和opencv-python等,然后我新…

    2022年5月17日
    42
  • rabbitmq 启动异常_Rabbitmq启动失败

    rabbitmq 启动异常_Rabbitmq启动失败我的 RabbitMQ 服务器出现故障 无法重新启动 我试图重新启动 重新安装它 我仍然不明白错误 这就是我得到的 Rabbitmq 启动失败 BOOTFAILED Errordescrip could not start rabbit bad return rabbit start normal EXIT rabbit failure du

    2026年3月16日
    2
  • 2.1 一行代码值多少钱?

    2.1 一行代码值多少钱?

    2022年3月1日
    41
  • 无法创建目录或文件问题的解决办法

    无法创建目录或文件问题的解决办法问题现象 我们的软件运行在 Windowsserve 系统上 软件是一个接受文件软件 将接受的文件存于一个文件夹下 当运行到一定的时候 大概文件夹下有 10w 个文件的时候 就弹出 无法创建目录或文件 对话框 这是是我们 catch 到的异常 问题原因 可能有两种

    2026年3月17日
    2
  • TPS和QPS的区别和理解

    TPS和QPS的区别和理解TPS transactionp 是单位时间内处理事务的数量 QPS queryperseco 是单位时间内请求的数量 TPS 代表一个事务的处理 可以包含了多次请求 很多公司用 QPS 作为接口吞吐量的指标 也有很多公司使用 TPS 作为标准 两者都能表现出系统的吞吐量的大小 TPS 的一次事务代表一次用户操作到服务器返回结果 QPS 的一次请求代表一个接口的一次请求到服务器返回结

    2026年3月26日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号