C++——多项式拟合

目标:利用C++对txt或者xml中的数据,进行高阶或低阶多项式拟合

为方便以后查找,代码以及详细资料已打包,并上传至云盘(链接:https://pan.baidu.com/s/1bvUBIoxv7Avxeq_Cz6xOZQ 密码:u9qe)

打包的内容如下:

运行结果:

上图是C++代码运行的结果,在Matlab中显示的效果;下图是Matlab中利用Curve Fitting Tool拟合的效果(四阶多项式拟合)。注意横坐标与纵坐标不一样额,那是因为这里的原始数据与一般的数据不同:一个x坐标可能对应多个y值。这种情况直接将横纵坐标反着写就行了。

C++代码:

一、cpp文件

1、主函数curveFittingMain.cpp:

#include <iostream>
#include <fstream>
#include <Linequ.h>
#include <LS.h>
#include <Matrix.h>
#include <vector>
#include <fstream>
using namespace std;vector<double> fitCurve(vector<double> arr_1, vector<double> arr_2, int n);
vector<double> getFitPoint(vector<double> coArr, vector<double> pointArr);int main(int argc, char* argv[])
{//step1: 读取txt文件中的数据string file_x = "C:\\Users\\Zhangwei\\Desktop\\TEST\\多坐标点\\Quadrant_finalX.txt";string file_y = "C:\\Users\\Zhangwei\\Desktop\\TEST\\多坐标点\\Quadrant_finalY.txt";ifstream infile_x,infile_y;infile_x.open(file_x);infile_y.open(file_y);if (!infile_x && !infile_y) cout << "error" << endl;double temp;vector<double> Data_x, Data_y;while (infile_x >> temp){Data_x.push_back(temp);}while (infile_y >> temp){Data_y.push_back(temp);}//step2:调用拟合函数// CoArr 表示多项式拟合的系数// myRes 表示拟合的系数与拟合前的横坐标,计算得到新的纵坐标vector<double> CoArr = fitCurve(Data_y, Data_x, 4); //调用函数,4表示阶数,(可以随意取,1—线性拟合,2—平方拟合,3—立方拟合,>=4,高阶拟合)vector<double> myRes = getFitPoint(CoArr, Data_y); //生成拟合数据//step3:将myRes保存为txt文档ofstream outfile;outfile.open("C:\\Users\\Zhangwei\\Desktop\\TEST\\多坐标点\\Quadrant_Final.txt");for (int j = 0; j < myRes.size(); j++){outfile << myRes[j] << endl;}outfile.close();//system("pause");return 0;
}//getFitPoint函数用于获取拟合后的数据点
vector<double> getFitPoint(vector<double> coArr, vector<double> pointArr)
{vector<double> finalPoint;if (pointArr.size() == 0 || coArr.size() == 0){cout << "数据点有误!" << endl;}if (pointArr.size() > 0 && coArr.size() > 0){for (int i = 0; i < pointArr.size(); i++){double temp = 0;for (int j = 0; j < coArr.size(); j++){temp += pow(pointArr[i], j)*coArr[j];}finalPoint.push_back(temp);}}return finalPoint;
}//fitCurve函数用于曲线拟合
vector<double> fitCurve(vector<double> arr_1, vector<double> arr_2, int n)
{CLS m_cls;vector<double> coefficientsSet;if (arr_1.size() != arr_2.size()){cout << " 输入数据有误!" << endl;}if (arr_1.size() == arr_2.size()){for (int i = 0; i < arr_1.size(); i++){m_cls.addPoint(arr_1[i], arr_2[i]);}m_cls.setN(n);m_cls.Solve();double *t_paracof = m_cls.getSolution();for (int i = 0; i < n + 1; i++){coefficientsSet.push_back(t_paracof[i]); //多项式的系数项,第一项为常数项,最后一项为x^n项}}return coefficientsSet;
}

2、Linequ.cpp

// Linequ.cpp: implementation of the CLinequ class.
//
////#include "stdafx.h"
#include "math.h"
#include "Linequ.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
//#define new DEBUG_NEW
#endif//
// Construction/Destruction
//CLinequ::CLinequ(int dims)
{index = dims;sums = new double[dims];MatrixA = new double[dims * dims];solu = new double[dims];
}CLinequ::~CLinequ()
{delete[] sums;delete[] MatrixA;delete[] solu;
}void CLinequ::setMatrix(double *rmatr)                   //设置矩阵
{for (int i = 0; i<index*index; i++){*(MatrixA + i) = rmatr[i];                          //矩阵成员赋初值}
}void CLinequ::setLinequ(double *a, double *b)             //设置线性方程组
{setMatrix(a);                                       //调用基类函数for (int i = 0; i<index; i++)sums[i] = b[i];
}int CLinequ::Solve()                                     //全选主元高斯消去法求解方程
{int *js, l, k, i, j, is, p, q;double d, t;js = new int[index];l = 1;for (k = 0; k <= index - 2; k++){                             //消去过程d = 0.0;for (i = k; i <= index - 1; i++)for (j = k; j <= index - 1; j++){t = fabs(MatrixA[i*index + j]);if (t>d){d = t; js[k] = j; is = i;}}if (d + 1.0 == 1.0) l = 0;else{if (js[k] != k)for (i = 0; i <= index - 1; i++){p = i*index + k; q = i*index + js[k];t = MatrixA[p]; MatrixA[p] = MatrixA[q]; MatrixA[q] = t;}if (is != k){for (j = k; j <= index - 1; j++){p = k*index + j; q = is*index + j;t = MatrixA[p]; MatrixA[p] = MatrixA[q]; MatrixA[q] = t;}t = sums[k]; sums[k] = sums[is]; sums[is] = t;}}if (l == 0){delete[] js;//fail to solvereturn(0);}d = MatrixA[k*index + k];for (j = k + 1; j <= index - 1; j++){p = k*index + j; MatrixA[p] = MatrixA[p] / d;}sums[k] = sums[k] / d;for (i = k + 1; i <= index - 1; i++){for (j = k + 1; j <= index - 1; j++){p = i*index + j;MatrixA[p] = MatrixA[p] - MatrixA[i*index + k] * MatrixA[k*index + j];}sums[i] = sums[i] - MatrixA[i*index + k] * sums[k];}}d = MatrixA[(index - 1)*index + index - 1];if (fabs(d) + 1.0 == 1.0){delete[] js;//fail to solvereturn(0);}solu[index - 1] = sums[index - 1] / d;                               //回代过程for (i = index - 2; i >= 0; i--){t = 0.0;for (j = i + 1; j <= index - 1; j++)t = t + MatrixA[i*index + j] * solu[j];solu[i] = sums[i] - t;}js[index - 1] = index - 1;for (k = index - 1; k >= 0; k--)if (js[k] != k){t = solu[k]; solu[k] = solu[js[k]]; solu[js[k]] = t;}delete[] js;return(1);
}double *CLinequ::getSolution() const
{return solu;
}

3、LS.cpp

// LS.cpp: implementation of the CLS class.
//
////#include "stdafx.h"
#include "LS.h"
#include "Matrix.h"
#include "Linequ.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
//#define new DEBUG_NEW
#endif//
// Construction/Destruction
//CLS* CLS::_instance = 0;CLS::CLS()
{pSolution = 0;m = 0;n = 0;_instance = this;
}CLS::~CLS()
{if (pSolution)delete[] pSolution;
}CLS *CLS::getInstance()
{if (!_instance)new CLS();return _instance;
}void CLS::setN(int t)
{n = t + 1;if (pSolution)delete[] pSolution;pSolution = new double[n];
}void CLS::addPoint(double x, double y)
{pVertex[m][0] = x;pVertex[m][1] = y;m++;
}bool CLS::Solve()
{if (m <= 0 || n <= 0)return false;CMatrix *A = new CMatrix(m, n);int i, j;for (j = 0; j < m; j++)A->setData(j, 0, 1.0);for (i = 1; i < n; i++){for (j = 0; j < m; j++){A->setData(j, i, A->getData(j, i - 1) * pVertex[j][0]);}}CMatrix *B = A->getRev();CMatrix *b = new CMatrix(m, 1);for (i = 0; i < m; i++)b->setData(i, 0, pVertex[i][1]);CMatrix *C = B->getMul(A);CMatrix *d = B->getMul(b);CLinequ *pL = new CLinequ(n);pL->setLinequ(C->getMatrix(), d->getMatrix());pL->Solve();double *t = pL->getSolution();for (i = 0; i < n; i++)pSolution[i] = t[i];return true;
}double *CLS::getSolution() const
{return pSolution;
}double CLS::calcY(double x)
{double y = 0.0, temp = 1.0;for (int i = 0; i < n; i++){y += pSolution[i] * temp;temp *= x;}return y;
}void CLS::restart()
{m = 0;if (pSolution)delete[] pSolution;pSolution = 0;n = 0;
}

4、Matrix.cpp

// Matrix.cpp: implementation of the CMatrix class.
//
////#include "stdafx.h"
#include "Matrix.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
//#define new DEBUG_NEW
#endif//
// Construction/Destruction
//void CMatrix::setMatrix(double *rmatr)                   //设置矩阵
{for (int i = 0; i < m * n; i++){*(pMatrix + i) = rmatr[i];                          //矩阵成员赋初值}
}CMatrix::CMatrix(int a, int b)                               //矩阵Matrix类的构造函数
{m = a; n = b;                                         //保护数据赋值pMatrix = new double[m * n];                    //动态分配内存
}CMatrix::~CMatrix()                                       //矩阵Matrix类的析构函数
{delete[] pMatrix;                                   //内存释放
}CMatrix *CMatrix::getRev()
{CMatrix *pR = new CMatrix(n, m);for (int j = 0; j < n; j++){for (int i = 0; i < m; i++)*(pR->pMatrix + i + m * j) = *(pMatrix + i * n + j);}return pR;
}CMatrix *CMatrix::getMul(CMatrix *b)
{if (b->m != n)return 0;CMatrix *pR = new CMatrix(m, b->n);for (int i = 0; i < m; i++){for (int j = 0; j < b->n; j++){double temp = 0.0;for (int k = 0; k < n; k++)temp += *(pMatrix + i * n + k) * *(b->pMatrix + k * b->n + j);*(pR->pMatrix + i * b->n + j) = temp;}}return pR;
}int CMatrix::getM() const
{return m;
}int CMatrix::getN() const
{return n;
}double *CMatrix::getMatrix() const
{return pMatrix;
}double CMatrix::getData(int i, int j) const
{if (i < m && j < n && i >= 0 && j >= 0)return *(pMatrix + i * n + j);elsereturn 0.0;
}void CMatrix::setData(int i, int j, double t)
{if (i < m && j < n && i >= 0 && j >= 0){*(pMatrix + i * n + j) = t;}
}

二、头文件(.h文件)

1、Linequ.h

// Linequ.h: interface for the CLinequ class.
//
//#if !defined(AFX_LINEQU_H__3673E7FC_1154_436A_9D22_B472DD858F13__INCLUDED_)
#define AFX_LINEQU_H__3673E7FC_1154_436A_9D22_B472DD858F13__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000class CLinequ
{
public:                                   //外部接口CLinequ(int dims = 2);                   //构造函数virtual ~CLinequ();                            //析构函数void setLinequ(double *a, double *b);  //方称赋值void setMatrix(double *rmatr);int Solve();                          //全选主元高斯消去法求解方程double *getSolution() const;private:double *sums;                         //方程右端项double *MatrixA;double *solu;                         //方程的解int index;
};#endif // !defined(AFX_LINEQU_H__3673E7FC_1154_436A_9D22_B472DD858F13__INCLUDED_)

2、LS.h

// LS.h: interface for the CLS class.
//
//#if !defined(AFX_LS_H__208D279A_F391_4DA8_BBE3_3895A9800FFE__INCLUDED_)
#define AFX_LS_H__208D279A_F391_4DA8_BBE3_3895A9800FFE__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000class CLS
{
private:static CLS *_instance;double pVertex[2000][2];//最多可以拟合2000个点int m;  //点的个数int n;    //多项式次数double *pSolution;   //多项式系数public:CLS();virtual ~CLS();static CLS *getInstance();void setN(int t);  //n次多项式拟合void addPoint(double x, double y); //添加一个点void restart();bool Solve();double *getSolution() const; //获得多项式系数double calcY(double x);    //根据x坐标计算y
};#endif // !defined(AFX_LS_H__208D279A_F391_4DA8_BBE3_3895A9800FFE__INCLUDED_)

3、Matrix.h

// Matrix.h: interface for the CMatrix class.
//
//#if !defined(AFX_MATRIX_H__AEE89FA3_05E2_44AC_AA96_5FBCB3608C13__INCLUDED_)
#define AFX_MATRIX_H__AEE89FA3_05E2_44AC_AA96_5FBCB3608C13__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000class CMatrix
{
public:CMatrix(int a = 2, int b = 2);virtual ~CMatrix();void setMatrix(double *rmatr);CMatrix *getRev();CMatrix *getMul(CMatrix *b);int getM() const; //获得行数int getN() const; //获得列数double getData(int i, int j) const;void setData(int i, int j, double t);double *getMatrix() const;    //获得矩阵protected:int m, n;double *pMatrix;
};#endif // !defined(AFX_MATRIX_H__AEE89FA3_05E2_44AC_AA96_5FBCB3608C13__INCLUDED_)

C++——多项式拟合相关推荐

  1. 利用numpy对已知样本点进行多项式拟合

    0.导入相关包: import matplotlib.pyplot as plt import numpy as np 1.假设有如下样本点: #使用随机数产生样本点 x=[1,2,3,4,5,6,7 ...

  2. matlab 多项式拟合 ployval

    多项式拟合 ployval clc,clear; x=[19 25 31 38 44]'; y=[19.0 32.3 49.0 73.3 97.8]'; r=[ones(5,1),x.^2]; ab= ...

  3. NASA科学家联名求撤稿:金星有生命迹象是大乌龙,12阶多项式拟合不靠谱

    萧箫 鱼羊 发自 凹非寺 量子位 报道 | 公众号 QbitAI 还记得9月14号那篇"金星上有生命"的Nature子刊论文吗? 天文学家在金星"大气层"中观测 ...

  4. pytho作线性拟合、多项式拟合、对数拟合

    python opencv拟合: width是总宽,height是总高: [vx, vy, x, y] = cv2.fitLine(np.float32(values[j]), cv2.DIST_L2 ...

  5. java 多项式拟合最多的项数_牛顿插值法、曲线拟合、多项式拟合

    2020年10月4日研究了一下牛顿插值法,其用途是使用x.y两组数值,根据新的x值返回对应的y值,与TREND.FORECAST函数不同,这种方法可应对非线性数据.其作用类似于图表中的曲线拟合或LIN ...

  6. matlab的多项式拟合,函数求导,画函数曲线

    给一列数据. 拟合出该数据的函数曲线.多项式拟合. 然后画出函数曲线来.以及给出函数形式. 求导. 再画出导数的曲线.以及给出导数函数形式. matlab代码: clc close all clear ...

  7. java 多项式拟合最多的项数_机器学习(1)--线性回归和多项式拟合

    机器学习(1)--线性回归和多项式拟合 机器学习(2)逻辑回归 (数学推导及代码实现) 机器学习(3)softmax实现Fashion-MNIST分类 一 线性回归 线性回归,顾名思义是利用线性模型对 ...

  8. 多项式拟合缺点_曲线拟合方法的选择

    曲线拟合方法的选择 目    录 摘要 1 前言 2 1 问题提出 3 2 插值介绍 4 2.1拉格朗日公式求解 4 2.1.1 算法分析 5 2.1.2 程序设计 5 2.1.3 计算结果 8 2. ...

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

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

  10. excel 多项式拟合数据

    有如下一组数据和其对应的曲线波形,如何快速得到其数据函数表达式? x y 996 1250 1988 2250 3000 3550 4000 4900 要得到原始的函数表达式是比较难的,不过我们可以用 ...

最新文章

  1. Go 2将添加错误处理和泛型
  2. 微服务后如何做一次系统梳理
  3. 创建文档库时指定文件夹(路径)
  4. J2ME程序开发新手入门九大要点
  5. 用c语言链表做一个词典,电子字典C语言链表版
  6. 初中计算机职称答辩,晋升中学语文高级教师职称答辩内容举例
  7. drools 规则流_约束流–没有Drools规则语言的现代Java约束
  8. java mongodb 插入数据_mongoDB 插入数据 用java实现
  9. 计算机基础知识试卷并附答案,计算机基础知识_试卷及答案.doc
  10. JAVA数组子集_【Java虚拟机】JVM系列学习之JVM体系(一)
  11. recyclerview简单实现单选多选反选全选
  12. 天煌计算机组成原理控制软件,天煌THTJZ-2型计算机组成原理课程设计.doc
  13. FPGA 控制 RGMII 接口 PHY芯片基础
  14. win7网上邻居_CentOS7 Linux访问Win7的共享文件夹
  15. 飞秋2013正式版有偿修改在线等
  16. 苹果手机闹钟声音大小怎么调_偷偷安利5款让手机体验到爆的app,乐趣满满
  17. oppo reno5什么时候上市
  18. 有密码的PDF文件如何编辑?
  19. 5G标准设立 智慧城市还有哪四大挑战?
  20. java实现FTP协议:wireshark抓包解析

热门文章

  1. Tomcat应用服务器被黑客 肉鸡攻击 记录
  2. postMessage - 跨域消息传递
  3. spring xml 配置transactionManager事务管理器踩的坑
  4. MD5算法的应用及原理
  5. golang力扣leetcode 297.二叉树的序列化与反序列化
  6. C#判断中文和英文字符长度
  7. [计蒜客][字符串]最长的名字
  8. vs2015vb.net水晶报表连接oracle入门示例
  9. overflow滚动条样式
  10. LVGL8.1笔记1--显示移植(2022-0515)