最小二乘曲线拟合——C语言算法实现一

2023-10-27

最小二乘曲线拟合

 

给定一组数据,我们要对这组数据进行曲线拟合。

假定要拟合的曲线方程为 y=a0 + a1*x^1 + a2*x^2 + a3*x^3 + ...+ an*x^n

    x             y

0.995119      -7.620000
2.001185      -2.460000
2.999068     108.760000
4.001035     625.020000
4.999859     2170.500000
6.004461     5814.580000
6.999335     13191.840000
7.999433     26622.060000
9.002257      49230.220000
10.003888    85066.500000
11.004076    139226.280000
12.001602     217970.140000
13.003390     328843.860000
14.001623    480798.420000
15.003034    684310.000000
16.002561    951499.980000
17.003010   1296254.940000
18.003897   1734346.660000
19.002563   2283552.120000
20.003530    2963773.500000

代码如下:

#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include <time.h>
#define ParaBuffer(Buffer,Row,Col) (*(Buffer + (Row) * (SizeSrc + 1) + (Col)))
 /***********************************************************************************
 ***********************************************************************************/
 static int GetXY(const char* FileName, double* X, double* Y, int* Amount)
 {
     FILE* File = fopen(FileName, "r");
     if (!File)
		return -1;
     for (*Amount = 0; !feof(File); X++, Y++, (*Amount)++)
         if (2 != fscanf(File, (const char*)"%lf %lf", X, Y))
            break;
     fclose(File);
     return 0;
 }
 /***********************************************************************************
 ***********************************************************************************/
 static int PrintPara(double* Para, int SizeSrc)
 {
     int i, j;
     for (i = 0; i < SizeSrc; i++)
     {
         for (j = 0; j <= SizeSrc; j++)
         printf("%10.6lf ", ParaBuffer(Para, i, j));
         printf("\r\n");
     }
     printf("\r\n");
     return 0;
 }
 /***********************************************************************************
 ***********************************************************************************/
 static int ParalimitRow(double* Para, int SizeSrc, int Row)
 {
     int i;
     double Max, Min, Temp;
     for (Max = abs(ParaBuffer(Para, Row, 0)), Min = Max, i = SizeSrc; i; i--)
     {
         Temp = abs(ParaBuffer(Para, Row, i));
         if (Max < Temp)
             Max = Temp;
         if (Min > Temp)
             Min = Temp;
     }
     Max = (Max + Min) * 0.000005;
     for (i = SizeSrc; i >= 0; i--)
         ParaBuffer(Para, Row, i) /= Max;
     return 0;
 }
 /***********************************************************************************
 ***********************************************************************************/
 static int Paralimit(double* Para, int SizeSrc)
 {
     int i;
     for (i = 0; i < SizeSrc; i++)
          if (ParalimitRow(Para, SizeSrc, i))
             return -1;
     return 0;
 }
 /***********************************************************************************
 ***********************************************************************************/
 static int ParaPreDealA(double* Para, int SizeSrc, int Size)
 {
     int i, j;
     for (Size -= 1, i = 0; i < Size; i++)
     {
         for (j = 0; j < Size; j++)
         ParaBuffer(Para, i, j) = ParaBuffer(Para, i, j) * ParaBuffer(Para, Size, Size) - ParaBuffer(Para, Size, j) * ParaBuffer(Para, i, Size);
         ParaBuffer(Para, i, SizeSrc) = ParaBuffer(Para, i, SizeSrc) * ParaBuffer(Para, Size, Size) - ParaBuffer(Para, Size, SizeSrc) * ParaBuffer(Para, i, Size);
         ParaBuffer(Para, i, Size) = 0;
         ParalimitRow(Para, SizeSrc, i);
     }
     return 0;
 }
 /***********************************************************************************
 ***********************************************************************************/
 static int ParaDealA(double* Para, int SizeSrc)
 {
     int i;
     for (i = SizeSrc; i; i--)
         if (ParaPreDealA(Para, SizeSrc, i))
             return -1;
     return 0;
 }
 /***********************************************************************************
 ***********************************************************************************/
 static int ParaPreDealB(double* Para, int SizeSrc, int OffSet)
 {
     int i, j;
     for (i = OffSet + 1; i < SizeSrc; i++)
     {
         for (j = OffSet + 1; j <= i; j++)
         ParaBuffer(Para, i, j) *= ParaBuffer(Para, OffSet, OffSet);
         ParaBuffer(Para, i, SizeSrc) = ParaBuffer(Para, i, SizeSrc) * ParaBuffer(Para, OffSet, OffSet) - ParaBuffer(Para, i, OffSet) * ParaBuffer(Para, OffSet, SizeSrc);
         ParaBuffer(Para, i, OffSet) = 0;
         ParalimitRow(Para, SizeSrc, i);
     }
     return 0;
 }
 /***********************************************************************************
 ***********************************************************************************/
 static int ParaDealB(double* Para, int SizeSrc)
 {
     int i;
     for (i = 0; i < SizeSrc; i++)
             if (ParaPreDealB(Para, SizeSrc, i))
                     return -1;
     for (i = 0; i < SizeSrc; i++)
     {
         if (ParaBuffer(Para, i, i))
         {
             ParaBuffer(Para, i, SizeSrc) /= ParaBuffer(Para, i, i);
             ParaBuffer(Para, i, i) = 1.0;
         }
     }
     return 0;
 }
 /***********************************************************************************
 ***********************************************************************************/
 static int ParaDeal(double* Para, int SizeSrc)
 {
     PrintPara(Para, SizeSrc);
     Paralimit(Para, SizeSrc);
     PrintPara(Para, SizeSrc);
     if (ParaDealA(Para, SizeSrc))
             return -1;
     PrintPara(Para, SizeSrc);
     if (ParaDealB(Para, SizeSrc))
             return -1;
     return 0;
 }
 /***********************************************************************************
 ***********************************************************************************/
 static int GetParaBuffer(double* Para, const double* X, const double* Y, int Amount, int SizeSrc)
 {
     int i, j;
     for (i = 0; i < SizeSrc; i++)
             for (ParaBuffer(Para, 0, i) = 0, j = 0; j < Amount; j++)
                     ParaBuffer(Para, 0, i) += pow(*(X + j), 2 * (SizeSrc - 1) - i);
     for (i = 1; i < SizeSrc; i++)
             for (ParaBuffer(Para, i, SizeSrc - 1) = 0, j = 0; j < Amount; j++)
                     ParaBuffer(Para, i, SizeSrc - 1) += pow(*(X + j), SizeSrc - 1 - i);
     for (i = 0; i < SizeSrc; i++)
             for (ParaBuffer(Para, i, SizeSrc) = 0, j = 0; j < Amount; j++)
                     ParaBuffer(Para, i, SizeSrc) += (*(Y + j)) * pow(*(X + j), SizeSrc - 1 - i);
     for (i = 1; i < SizeSrc; i++)
             for (j = 0; j < SizeSrc - 1; j++)
                     ParaBuffer(Para, i, j) = ParaBuffer(Para, i - 1, j + 1);
     return 0;
 }
 //***********************************************************************************
 //***********************************************************************************
 int Cal(const double* BufferX, const double* BufferY, int Amount, int SizeSrc, double* ParaResK)
 {
     double* ParaK = (double*)malloc(SizeSrc * (SizeSrc + 1) * sizeof(double));
     GetParaBuffer(ParaK, BufferX, BufferY, Amount, SizeSrc);
     ParaDeal(ParaK, SizeSrc);
     for (Amount = 0; Amount < SizeSrc; Amount++, ParaResK++)
             *ParaResK = ParaBuffer(ParaK, Amount, SizeSrc);
     free(ParaK);
     return 0;
 }
 /***********************************************************************************
 ***********************************************************************************/
 int main(int argc, char* argv[])
 {
     int Amount;
	 clock_t StartTime, FinishTime;	//	声明两个时间变量
	 double DiffTime;
	 StartTime = clock();		//	开始计时

     double BufferX[1024], BufferY[1024], ParaK[6];	//	5次拟合, 一共6个系数(包含常数项)
	 //	读入要拟合的数据
     if (GetXY((const char*)"test.txt", (double*)BufferX, (double*)BufferY, &Amount))
          return 0;
	
	  printf("Amount: %d\n", Amount);
     Cal((const double*)BufferX, (const double*)BufferY, Amount, sizeof(ParaK) / sizeof(double), (double*)ParaK);
	 printf("拟合系数为:\n");
	 printf("按升序排列\n");
     for (Amount = 0; Amount < sizeof(ParaK) / sizeof(double); Amount++)
             printf("ParaK[%d] = %lf\r\n", Amount, ParaK[Amount]);

	 FinishTime = clock();	//	结束计时
	 DiffTime = FinishTime - StartTime;	//拟合时间
	 printf("拟合时间为: %lf\n", DiffTime);
     return 0;
 }
 

输出结果为:

Amount: 20

拟合系数为:
按升序排列
ParaK[0] = 0.999157
ParaK[1] = -1.450258
ParaK[2] = -0.529332
ParaK[3] = 0.236626
ParaK[4] = 6.725930
ParaK[5] = -18.544115
拟合时间为: 9.000000ms

Matlab代码:

其中test.txt文件为上面的x,y向量

load test.txt;
 x = test(:, 1)';
 y = test(:, 2)';
 para = polyfit(x, y, 5)
 
 figure,
 plot(x,y,'b.')
 hold on
 plot(x,y,'r-')

Matlab拟合系数,降序排列:

para =   0.9992   -1.4503   -0.5293    0.2366    6.7259  -18.5441

Matlab拟合曲线结果图:

 


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

最小二乘曲线拟合——C语言算法实现一 的相关文章

  • VC++ 制作滤镜效果(底片效果、雕刻效果、黑白效果)

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家提出意见 一起讨论 需要源码的请单独与我联系 滤镜是一种改变图像相貌的程序 其本身并不属于图像处理研究的范畴 滤镜程序的核心算法源自数字图像处理
  • 最大公约数、最小公倍数、辗转相除法的求解和证明

    两个正整数的最大公约数 Greatest Common Divisor GCD 在计算机中通常使用辗转相除法计算 最小公倍数 Least Common Multiple LCM 可以使用GCD来计算 下面首先介绍GCD和LCM 然后介绍辗转
  • 第七讲:构造函数与析构函数

    第七讲 构造函数与析构函数 本讲基本要求 掌握 构造和析构函数概念 初始化 作用 理解 构造构函的重载 带参数的构造函数两种表达格式 重点 难点 构造和析构函数概念 初始化 作用 通过前两章的学习 我们已经对类和对象有了初步的了解 在本章中
  • LNK2005: _DllMain@12 already defined in LIBCMTD.lib(dllmain.obj)

    今天使用VS2003创建一个MFC 的dll工程时 出现以下错误 VPR error LNK2005 DllMain 12 already defined in LIBCMTD lib dllmain obj VPR error LNK20
  • PNG透明窗体全攻略(控件不透明)vc++程序指导

    这两天在研究透明窗体 总算略有小成 网上大部分文章都是介绍到把窗体弄透明就没有下文 其实窗体透明并不难 难就难在透明的窗体上还要放控件 今 天我就把窗体透明一直到控件不透明怎么制作一块给写了吧 先截张图诱惑下你们 如果你没兴趣就没必要再看下
  • Error:fatal error C1010: unexpected end of file while looking for precompiled head

    场景 在VC6 0进行编写C 代码时 创建了一个 简单的程序 s 然后编译就爆出这个错误 场景复现 创建流程 点击左上角的 文件 然后点击 新建 在左上方选择工程 然后下方选择 Win32 Console Application 在右侧填写
  • 图像特征提取三大算法:HOG特征,LBP特征,Haar特征

    一 HOG特征 from http dataunion org 20584 html 1 HOG特征 方向梯度直方图 Histogram of Oriented Gradient HOG 特征是一种在计算机视觉和图像处理中用来进行物体检测的
  • curl,libssh2,openssl,zlib的编译

    前年 客户要求ATM客户端程序添加sftp功能 领导发给我4个静态库 分别是libcurl lib libeay32 lib ssleay32 lib libssh2 lib 使用这4个库成功实现了sftp功能 当时从网络上查到该四个静态库
  • 【小宝解惑】VC++中delete和delete [] 的区别

    我们通常从教科书上看到这样的说明 delete 释放new分配的单个对象指针指向的内存 delete 释放new分配的对象数组指针指向的内存 那么 按照教科书的理解 我们看下下面的代码 int a new int 10 delete a 方
  • VS2010 LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 的解决方法

    因为同一个电脑上安装多个VS 有多个cvtres exe 按照下面的操作如果还是不行就在C盘搜索cvtres exe 然后挨个重命名 看看是调用的哪个 然后修改就可以了 用VS2010编译C 项目时出现这样的错误 LNK1123 转换到 C
  • windows上bug崩溃定位分析(Qt或者VS)

    任何情况下 都不能保证自己写的代码不会发生崩溃 崩溃不可怕 可怕的是无法定位哪里崩溃 特别是客户那边崩溃 开发者这边不崩溃 问题陷入僵局 自从有了下面这个神奇的代码 再也不怕了 以下代码亲自测试没问题 1 如果是在VC 中 那么只需要将下列
  • 免费C/C++编译器

    不好意思 等到现在才想到要写这篇文章 怎么说呢 情况是这样的 刚开始我学习C语言时 是想在机器上安装visual c 的 因为Turbo C太古老了 用起来不方便 所以很自然地想安装vc 不过不知道大家有没有发现vc很大 而且有些机子就是安
  • C语言和mfc按格式读取文件数据

    fscanf 函数的功能是从文件中按格式读取一个或多个数据 例如文件中有一行数据 22 3 34 hello 则使用 fscanf fp d f s a f str 可一次读取整型 浮点 字符串三个数据 此函数位于C标准库头文件
  • 最大熵算法及简单例子

    最近在学模式识别 正在看Introduction to Pattern Recognition这本书 挺不错的一本书 好 下面和大家一起来学习最大熵算法 首先 最大熵算法是干什么的呢 一般是用来估计一个分布 至于把分布估计出来之后用来干什么
  • 什么是模式识别,模式识别概念的基本介绍

    模式识别又常称作模式分类 从处理问题的性质和解决问题的方法等角度 模式识别分为有监督的分类 Supervised Classification 和无监督的分类 Unsupervised Classification 两种 模式还可分成抽象的
  • 计算机视觉、模式识别、机器学习常用牛人主页链接

    牛人主页 主页有很多论文代码 Serge Belongie at UC San Diego Antonio Torralba at MIT Alexei Ffros at CMU Ce Liu at Microsoft Research N
  • 算法笔记-DTW动态时间规整

    算法笔记 DTW动态时间规整 简介 简单的例子 定义 讨论 约束条件 步模式 标准化 点与点的距离函数 具体应用场景 分类 点到点匹配 算法笔记 DTW动态时间规整 动态时间规整 规划 Dynamic Time Warping DTW 是一
  • 一些主流IDE(VC6、VS2010、Code::Blocks、Eclipse)使用过程中常见问题集锦

    关于主流IDE使用的一些常见问题 本文由CSDN 蚍蜉撼青松 主页 http blog csdn net howeverpf 整理原创 转载请注明出处 一 在Win7下使用VC6 0应该注意的几个问题 我们知道 Win7和VC6 0本身是不
  • win7安装了vc++6.0打开已保存文件项目就会崩溃

    我用win7安装了vc 6 0的英文完整版 绿色中文版 发现当运行程序时 要打开已保存文件项目就会崩溃 系统对话筐就说 Microsoft R Developer Studio已停止工作 选择调试或者关闭 office 2010 与vc 6
  • "无法找到“XXX.exe”的调试信息,或者调试信息不匹配

    今天调试一C 程序 按下F5 老是弹出一对话框显示信息 debugging information for myproject exe cannot be found or does not match No symbols loaded

随机推荐

  • 2023年最火副业;Python爬虫兼职,一周赚7800元,一天只要两小时

    现在学习Python的人越来越多了 跟大家简单如何利用python搞副业赚钱的 想要利用 Python 赚钱的方式还是比较多的 其中接单和投稿算是两种比较简单的方式了 如果你是业余学Python爬虫 可以去淘宝上加了找了几个店铺直接问需要爬
  • Linux虚拟机CentOS永久修改分辨率的方法

    Linux虚拟机CentOS永久修改分辨率的方法 写在前面 1修改command的分辨率 2修改GUI的分辨率 写在前面 CentOS等Linux系统分为两大部分 底层的command模式 就是命令行模式 和GUI 图形化界面 两者各有其独
  • 快手极速版脚本代码(仅供参考)

    home sleep 1500 while click 快手极速版 sleep 5000 等待5s var num 200 想要循环几次 自己输入 nextVideo 1 num 下一个视频 function nextVideo i num
  • 百度离线SDK的调用(Linux+win)

    这两天弄了一下百度离线SDK的识别调用 分享一下心得 1 百度离线SDK的识别 获取条件 企业账号 使用认证后的企业帐号创建项目申请免费激活码 一台设备一个激活码 如果是一台电脑有双系统的话 亲测 同一个激活码并不好使 会报错 提示你激活码
  • 数据结构与算法总结

    文章目录 线性数据结构 1 数组 2 链表 2 1 链表简介 2 2 链表分类 2 2 1 单链表 2 2 2 循环链表 2 2 3 双向链表 2 2 4 双向循环链表 2 3 应用场景 2 4 数组 vs 链表 3 栈 3 1 栈简介 3
  • redis基础6——缓存穿透、缓存击穿、缓存雪崩

    文章目录 一 缓存穿透 双库为空 1 1 基础概念 1 2 解决办法 1 2 1 业务层校验 1 2 2 设置key过期时间 1 2 3 布隆过滤器 1 2 3 1 原理 1 2 3 1 1 哈希函数使用 1 2 3 1 2 布隆过滤器数据
  • JVM运行原理

    JAVA和JVM运行原理揭秘 JVM是java的核心和基础 在java编译器和os平台之间的虚拟处理器 它是一种利用软件方法实现的抽象的计算机基于下层的操作系统和硬件平台 可以在上面执行java的字节码程序 AD 这里和大家简单分享一下JA
  • 机器学习之特征工程

    机器学习之特征工程 1 特征工程介绍 1 1 为什么需要特征工程 1 2 什么是特征工程 1 3 特征工程内容 2 特征提取 2 1 字典特征提取 2 2 文本特征提取 2 3 Tf idf文本特征提取 3 特征预处理 3 1 什么是特征预
  • springboot +mybatis遇到的(no found)找不到或者找到不匹配mapper的问题

    1 在springboot里面进行junit单元测试的时候 一直提示org apache ibatis binding BindingException Invalid bound statement not found 这样的错误 苦寻答
  • 【C++图解专栏】手撕数据结构与算法,探寻算法的魅力

    个人博客 https blog csdn net Newin2020 spm 1011 2415 3001 5343 专栏定位 为 0 基础刚入门数据结构与算法的小伙伴提供详细的讲解 也欢迎大佬们一起交流 专栏简介 在这个专栏 我将带着大家
  • npm yarn pnpm 包管理器区别

    npm yarn和pnpm都是JavaScript的包管理工具 它们的主要区别如下 性能 在处理依赖安装时 yarn和pnpm相对于npm会更快 因为它们支持并行安装 但是在其他方面 如缓存等 各自的性能表现可能有所不同 安全性 yarn和
  • 关于Linux内核编译

    关于生成配置文件 1 首先执行以下命令从老的 xxxx defconfig 文件生成临时使用的 config 文件 根据硬件平台生成临时配置文件 config 比如 make xxxx defconfig make vexpress def
  • MacOS下终端可以连接mysql但是MySQLWorkbench无法连接

    亲测有效 很早前安装了mysql 一直在终端里使用 最近安装了MySQLWorkbench但始终无法连接 整个人都给晕了 但是在MySQLWorkbench的连接界面下始终无法连接成功 在终端测试同样的ip和端口是可以连接成功的 mysql
  • 一网打尽时钟树综合Clock Skew

    一网打尽时钟树综合Clock Skew 文章右侧广告为官方硬广告 与吾爱IC社区无关 用户勿点 点击进去后出现任何损失与社区无关 时间过得很快 今天又上班了 最重要的是公众号还得对得起各位粉丝一直以来的支持 所以必须抽时间码字更文 在五一期
  • C++ 自定义QPushButton有参信号

    C 自定义QPushButton有参信号 ifndef MYWINDOW H define MYWINDOW H include
  • 【无奈】Invalid byte 1 of 1-byte UTF-8 sequence解决方案

    今天在eclipse中编写pom xml文件时 注释中的中文被eclipse识别到错误 Invalid byte 1 of 1 byte UTF 8 sequence 曾多次遇到该问题 问题的根源是 The cause of this is
  • Vue路由hash模式下锚点滚动实现

    1 Vue路由在hash模式下 已被占用 无法使用浏览器的锚点功能 使用js实现锚点滚动功能 使用js实现锚点滚动功能 字符串需要是 id 锚点格式 数字的话标识要滚动的位置 param String Number selector exp
  • qt中自定义关闭按钮的时候绑定关闭事件

    qt中自定义了关闭按钮 如何简单的只用绑定信号跟槽就直接调用事件呢 1 首先在界面中放置一个按钮 重命名为CloseBtn 然后接下来就只需要在构造函数中加上如下的这句 connect ui gt CloseBtn SIGNAL click
  • DFS时,出现内存超限 Memory Limit Exceeded

    DFS时 出现内存超限 Memory Limit Exceeded 很大可能由于dfs死循环 比如 vis 数组一定优先赋值再dfs
  • 最小二乘曲线拟合——C语言算法实现一

    最小二乘曲线拟合 给定一组数据 我们要对这组数据进行曲线拟合 假定要拟合的曲线方程为 y a0 a1 x 1 a2 x 2 a3 x 3 an x n x y 0 995119 7 620000 2 001185 2 460000 2 99