当我们拥有一组散点图数据时,通常更愿意看到其走势。

对现有数据进行拟合,并输出拟合优度是常用的方法之一。

拟合结果正确性的验证,可以使用excel自带的功能。

下面是c++代码的实现:

#ifndef __Fit_h__
#define __Fit_h__ #include <vector> template<size_t Degree>
class CFit
{
public:
CFit(std::vector<double>& xArr,std::vector<double>& yArr):m_xArr(xArr),m_yArr(yArr),m_ssr(0.0),m_sse(0.0),m_rmse(0.0){m_bFitYet = false;} ~CFit(){}
protected:
//- 高斯消除
template<size_t realDegree>
static void GaussianElimination(double (&matrix)[realDegree+1][realDegree+2]
,double (&coeArr)[realDegree+1])
{
int i,j,k;
for (i = 0; i< realDegree; i++ ) //loop to perform the gauss elimination
{
for (k = i+1; k < (realDegree+1); k++)
{
double t = matrix[k][i]/matrix[i][i];
for (j=0;j<=(realDegree+1);j++)
matrix[k][j] -= t*matrix[i][j]; //make the elements below the pivot elements equal to zero or elimnate the variables
}
}
for (i = realDegree; i >= 0; i--) //back-substitution
{ //x is an array whose values correspond to the values of x,y,z..
coeArr[i] = matrix[i][realDegree+1]; //make the variable to be calculated equal to the rhs of the last equation
for (j=0;j<(realDegree+1);j++)
if (j!=i) //then subtract all the lhs values except the coefficient of the variable whose value is being calculated
coeArr[i] -= matrix[i][j]*coeArr[j];
coeArr[i] = coeArr[i]/matrix[i][i]; //now finally divide the rhs by the coefficient of the variable to be calculated
}
} ///
/// \brief 根据x获取拟合方程的y值
/// \return 返回x对应的y值
///
template<typename T>
double getY(const T x) const
{
double ans(0);
for (size_t i=0;i<(Degree+1);++i)
{
ans += m_coefficientArr[i]*pow((double)x,(int)i);
}
return ans;
} ///
/// \brief 计算均值
/// \return 均值
///
template <typename T>
static T Mean(const std::vector<T>& v)
{
return Mean(&v[0],v.size());
}
template <typename T>
static T Mean(const T* v,size_t length)
{
T total(0);
for (size_t i=0;i<length;++i)
{
total += v[i];
}
return (total / length);
} template<typename T>
void calcError(const T* x
,const T* y
,size_t length
,double& r_ssr
,double& r_sse
,double& r_rmse
)
{
T mean_y = Mean<T>(y,length);
T yi(0); for (size_t 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]));//残差平方和
}
r_rmse = sqrt(r_sse/(double(length)));
} /**
* @brief 根据两组数据进行一元多项式拟合
* @author
* @param [in] int N,数据个数
[in] const std::vector<double>& xArr,横坐标数据
[in] const std::vector<double>& yArr,纵坐标数据
* @param [out] double (&coefficientArr)[Degree+1],拟合结果.一元多项式系数,从低到高
* @return none
* @note none
*/
static void PolynomialFit(int N,const std::vector<double>& xArr,const std::vector<double>& yArr,double (&coefficientArr)[Degree+1])
{
int i = 0,j = 0,k = 0;
//const int realDegree = Degree -1;
double X[2*Degree+1] = {0}; //Array that will store the values of sigma(xi),sigma(xi^2),sigma(xi^3)....sigma(xi^2n)
for (i=0;i<2*Degree+1;i++)
{
for (j=0;j<N;j++)
X[i] += pow(xArr[j],i); //consecutive positions of the array will store N,sigma(xi),sigma(xi^2),sigma(xi^3)....sigma(xi^2n)
}
double Y[Degree+1] = {0}; //Array to store the values of sigma(yi),sigma(xi*yi),sigma(xi^2*yi)...sigma(xi^n*yi)
for (i=0;i<Degree+1;i++)
{
for (j=0;j<N;j++)
Y[i] += pow(xArr[j],i)*yArr[j]; //consecutive positions will store sigma(yi),sigma(xi*yi),sigma(xi^2*yi)...sigma(xi^n*yi)
} double B[Degree+1][Degree+2] = {0}; //B is the Normal matrix(augmented) that will store the equations
for (i=0;i<=Degree;i++)
{
for (j=0;j<=Degree;j++)
{
B[i][j] = X[i+j]; //Build the Normal matrix by storing the corresponding coefficients at the right positions except the last column of the matrix
}
B[i][Degree+1] = Y[i]; //load the values of Y as the last column of B(Normal Matrix but augmented)
} GaussianElimination<Degree>(B,coefficientArr);
}
public:
void PolyFit()
{
if (m_xArr.size() == m_yArr.size())
{
PolynomialFit(static_cast<int>(m_xArr.size()),m_xArr,m_yArr,m_coefficientArr);
m_bFitYet = true;
calcError(&m_xArr[0],&m_yArr[0],static_cast<int>(m_xArr.size()),m_ssr,m_sse,m_rmse);
}
}
//- 一元多项式计算
double UnaryPolynomialCalc(double dX)
{
double dY = 0.0;
for (size_t ulDegree = 0; ulDegree <= Degree; ++ulDegree)
{
dY += pow(dX,(double)ulDegree) * m_coefficientArr[ulDegree];
}
return m_bFitYet ? dY : 0.0;
} ///
/// \brief 剩余平方和
/// \return 剩余平方和
///
double getSSE(){return m_sse;}
///
/// \brief 回归平方和
/// \return 回归平方和
///
double getSSR(){return m_ssr;}
///
/// \brief 均方根误差
/// \return 均方根误差
///
double getRMSE(){return m_rmse;}
///
/// \brief 确定系数,系数是0~1之间的数,是数理上判定拟合优度(goodness-of-fit)的一个量
/// \return 确定系数
///
double getR_square(){return 1-(m_sse/(m_ssr+m_sse));} ///
/// \brief 根据阶次获取拟合方程的系数,
/// 如getFactor(2),就是获取y=a0+a1*x+a2*x^2+……+apoly_n*x^poly_n中a2的值
/// \return 拟合方程的系数
///
double getFactor(size_t i)
{
return (i <= Degree) ? m_coefficientArr[i] : 0.0;
} private:
double m_coefficientArr[Degree+1];
const std::vector<double>& m_xArr;
const std::vector<double>& m_yArr;
bool m_bFitYet;//- 一元多项式计算时多项式拟合是否完成 [1/6/2017 wWX210786] double m_ssr; ///<回归平方和
double m_sse; ///<(剩余平方和)
double m_rmse; ///<RMSE均方根误差
}; #endif // __Fit_h__

  使用起来也很方便:

        double y[] = {7,16,6,18,6,6,10,8};
double x[] = {-109.71,-101.81,-103.83,-99.89,-90,-112.17,-93.5,-96.13};
std::vector<double> xArr(std::begin(x),std::end(x));
std::vector<double> yArr(std::begin(y),std::end(y));
typedef CFit<4> LineFit;
LineFit objPolyfit(xArr,yArr);
objPolyfit.PolyFit();
std::wstring coeArr[] = {L"",L"x",L"x²",L"x\u00b3",L"x "};
CString info(_T("y = "));
for (int i=1;i>=0;i--)
info.AppendFormat(_T("+( %f%s )"),objPolyfit.m_coefficientArr[i],coeArr[i].c_str()); std::wcout << info.GetString() << "\n"; //std::wcout << "斜率 = " << objPolyfit.getFactor(1) << "\n";
//std::wcout << "截距 = " << objPolyfit.getFactor(0) << "\n";
std::wcout << "goodness-of-fit = "<< objPolyfit.getR_square() << "\n";

  

多项式拟合的cpp实现的更多相关文章

  1. 最小二乘法多项式拟合的Java实现

    背景 由项目中需要根据一些已有数据学习出一个y=ax+b的一元二项式,给定了x,y的一些样本数据,通过梯度下降或最小二乘法做多项式拟合得到a.b,解决该问题时,首先想到的是通过spark mllib去 ...

  2. 数据拟合:多项式拟合polynomial curve fitting

    http://blog.csdn.net/pipisorry/article/details/49804441 常见的曲线拟合方法 1.使偏差绝对值之和最小 2.使偏差绝对值最大的最小       3 ...

  3. matlab练习程序(最小二乘多项式拟合)

    最近在分析一些数据,就是数据拟合的一些事情,用到了matlab的polyfit函数,效果不错. 因此想了解一下这个多项式具体是如何拟合出来的,所以就搜了相关资料. 这个文档介绍的还不错,我估计任何一本 ...

  4. numpy多项式拟合

    关于解决使用numpy.ployfit进行多项式拟合的时候请注意数据类型,解决问题的思路就是统一把数据变成浮点型,就可以了.这是numpy里面的一个bug,非常low希望后面改善. # coding: ...

  5. MATLAB多项式及多项式拟合

    多项式均表示为数组形式,数组元素为多项式降幂系数 1.      polyval函数 求多项式在某一点或某几个点的值. p = [1,1,1];%x^2+x+1 x = [-1,0,1];y = po ...

  6. Matlab多项式拟合測试

    x=0:0.2:4; %生成等差数列 rnd=rand(1,size(x,2))*5; %生成一组随机数 y=x.*x.*x+x.*x+6+rnd; %生成y=x^3+x^2+6函数在垂直方向5个尺度 ...

  7. python多项式拟合:np.polyfit 和 np.polyld

    python数据拟合主要可采用numpy库,库的安装可直接用pip install numpy等. 1. 原始数据:假如要拟合的数据yyy来自sin函数,np.sin import numpy as ...

  8. 利用Python进行多项式拟合

    多项式拟合的简单代码: import matplotlib.pyplot as plt import numpy as np x=[,,,,,,,] y=[,,,,,,,] a=np.polyfit( ...

  9. matlab多项式拟合以及指定函数拟合

    clc;clear all;close all;%% 多项式拟合指令:% X = [1 2 3 4 5 6 7 8 9 ];% Y = [9 7 6 3 -1 2 5 7 20]; % P= poly ...

随机推荐

  1. Linux基础:uniq命令总结

    本文只总结一些常用的用法,更详细的说明见man uniq和 uniq --help. uniq命令 uniq命令主要用于去重. 需要注意的是,不相邻的行不算重复值. 语法格式 Usage: uniq ...

  2. 爬虫系列(十二) selenium的基本使用

    一.selenium 简介 随着网络技术的发展,目前大部分网站都采用动态加载技术,常见的有 JavaScript 动态渲染和 Ajax 动态加载 对于爬取这些网站,一般有两种思路: 分析 Ajax 请 ...

  3. P1040 加分二叉树(树上记忆化搜素)

    这道题很水 但我没做出来……………………………… 我写的时候状态设计错了,设计dp[l][m][r]为从l到r以m为根的值 这样写遍历状态就是n^3的,会TLE. 而且写路径的时候是用结构体写的,这样 ...

  4. 《奋斗吧!菜鸟》 第八次作业:Alpha冲刺 Scrum meeting 5

    项目 内容 这个作业属于哪个课程 任课教师链接 作业要求 https://www.cnblogs.com/nwnu-daizh/p/11012922.html 团队名称 奋斗吧!菜鸟 作业学习目标 A ...

  5. Vue packages version mismatch

    开发过程中,之前做的vue项目,一段时间后拿出来重新运行,报错: 打开vue-template-compiler/index.js查看错误提示,如下: 当安装的vue版本和package.json中的 ...

  6. 在做公司项目是时,昨天晚上还好的,但是第二天启动tomcat发现tomcat启动了,但是没把项目启动起来

    1.问题:在做公司项目是时,昨天晚上还好的,但是第二天启动tomcat发现tomcat启动了,但是没把项目启动起来 2.问题排除: 1)昨天晚上还好着呢,并且没改动代码,排除代码问题.日志中无报错信息 ...

  7. JavaSE 学习笔记之封装(四)

    封 装(面向对象特征之一):是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. 好处:将变化隔离:便于使用:提高重用性:安全性. 封装原则:将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共 ...

  8. Nikita and stack

    Nikita and stack time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  9. How to pass external configuration properties to storm topology?

    How to pass external configuration properties to storm topology? I want to pass some custom configur ...

  10. Windows XP时代终结:假设你还在用它怎么办

    2014 年 4 月 8 日.是Windows XP退休的日子. 4 月 8 日过后,Windows XP 的安全性更新将停止了. watermark/2/text/aHR0cDovL2Jsb2cuY ...