【Matlab】最小二乘法拟合多项式

2023-05-16

前言

在最近的电机项目中,有遇到有传感器数据并不线性的问题,然后想要用最小二乘法做个曲线拟合,反过来去校准不线性的传感器的数据,因此记录一下使用最小二乘法来拟合多项式的曲线的步骤。本篇从最小二乘法的原始公式入手编写M文件,目的是方便使用单片机实现,或者说是方便用C来实现。

拟合一次函数:

我们先试着拟合一个简单一点的,从一元一次函数开始。最小二乘法拟合曲线需要首先知道曲线的通用公式。一次函数的通用公式为y = k * x + b,使用matlab编写很容易实现。这里我直接写入了几个点,随便编了一组数据。

%*************************************************************************%
                %最小二乘法
%**********************************************************************%

clc;
clear;

%假定拟合曲线的公式为:y = ax^2 +b^x + c;
x = [1 2 3 4 5 6 7 8 9];
y = [1.2  2.5  3.6  4.8  5.6  7.4  8.0  9.8  12.0];
[m , n] = size(x);
sumx = 0;
sumy = 0;
sumxx = 0;
sumxy = 0;
Xaver = 0;
Yaver = 0;
XYaver = 0;
XXaver = 0;

%求平均
for i = 1 : n
    sumx = sumx + x(i);
    sumy = sumy + y(i);
    sumxy = sumxy + x(i) * y(i);
    sumxx = sumxx + x(i) * x(i);
end
Xaver = sumx / n;
Yaver = sumy / n;
XYaver = sumxy / n;
XXaver = sumxx / n;

k = (XYaver - Xaver * Yaver) / (XXaver - Xaver * Xaver);
b = Yaver - k * Xaver;

plot(x,y,'s');   %画数据点不连线
hold on;  %不加此句,两个图形将显示在两张图像上

%画出拟合曲线
x1 = [0 : 0.1 : 10];
y1 = k * x1 + b;

plot(x1,y1);

效果:

拟合二次函数:

之后开始拟合二次函数,可以从最小二乘法的原理上进行程序编写。

最小二乘法原理:

假设我们的多项式表达式为:

之后采集x与y的样本数据:

x = [1 2 3 4 5 6 7 8 9 10 11 12 13];
y = [1.2  2.5  3.6  4.8  5.6  6.6  7.4  8.0  9.8  12.0  12.5 13.1 14.6];

最小二乘法是要达到最优函数的各项系数使的误差平方和S取得最小值,即S对各项式的偏导为0:

整理上式可得:

将其转化为矩阵形式:

即,我们需要求取样本x的和,x^2的和,,,,,x^n的加和,以及y的加和,xy的加和。。。。。x^n*y的加和。

假定我们的曲线是二次多项式,那么这个XY矩阵都是一个3行3列的矩阵,那么只需要求到x^4的加和即可,程序如下:

sumx = 0;
sumxx = 0;
sumxxx = 0;
sumxxxx = 0;
sumy = 0;
sumxy = 0;
sumxxy = 0;

%求矩阵数据
for i = 1 : n
    sumx = sumx + x(i);
    sumxx = sumxx + x(i) * x(i);
    sumxxx = sumxxx + x(i) * x(i) * x(i);
    sumxxxx = sumxxxx + x(i) * x(i) * x(i) * x(i);
    sumy = sumy + y(i);
    sumxy = sumxy + x(i) * y(i);
    sumxxy = sumxxy + x(i) * x(i) * y(i);
end

将x加和的相关项写成X矩阵,将y加和的相关项写成Y矩阵,之后:

多项式矩阵就可以通过X矩阵的逆 * Y矩阵求得:

%写出矩阵
U = [n  sumx  sumxx ; sumx  sumxx  sumxxx ; sumxx  sumxxx  sumxxxx];
W = [sumy ; sumxy ; sumxxy];

%求出矩阵的逆,进而求出多项式矩阵
V =  pinv(U) * W;   % U * V = W    V = U(-1) * W
a = V(1,1); b = V(2,1); c = V(3,1);

之后就可以画出图形:

%画出拟合曲线
x1 = [0 : 0.1 : 15];
y1 = a + b .* x1 + c .* x1 .* x1;

plot(x1,y1);

注意:有一个点乘

结果图像如下:

完整代码如下:

%*************************************************************************%
                %最小二乘法拟合多项式
%**********************************************************************%

clc;
clear;

%假定拟合曲线的公式为:y = a +b^x + c * x^2;
x = [1 2 3 4 5 6 7 8 9 10 11 12 13];
y = [1.2  2.5  3.6  4.8  5.6  6.6  7.4  8.0  9.8  12.0  12.5 13.1 14.6];
[m , n] = size(x);
a = 0;
b = 0;
c = 0;
sumx = 0;
sumxx = 0;
sumxxx = 0;
sumxxxx = 0;
sumy = 0;
sumxy = 0;
sumxxy = 0;

%求矩阵数据
for i = 1 : n
    sumx = sumx + x(i);
    sumxx = sumxx + x(i) * x(i);
    sumxxx = sumxxx + x(i) * x(i) * x(i);
    sumxxxx = sumxxxx + x(i) * x(i) * x(i) * x(i);
    sumy = sumy + y(i);
    sumxy = sumxy + x(i) * y(i);
    sumxxy = sumxxy + x(i) * x(i) * y(i);
end


%写出矩阵
U = [n  sumx  sumxx ; sumx  sumxx  sumxxx ; sumxx  sumxxx  sumxxxx];
W = [sumy ; sumxy ; sumxxy];

%求出矩阵的逆,进而求出多项式矩阵
V =  pinv(U) * W;   % U * V = W    V = U(-1) * W
a = V(1,1); b = V(2,1); c = V(3,1);

plot(x,y,'s');   %画数据点不连线
hold on;  %不加此句,两个图形将显示在两张图像上

%画出拟合曲线
x1 = [0 : 0.1 : 15];
y1 = a + b .* x1 + c .* x1 .* x1;

plot(x1,y1);

拟合多项式:

拟合多项式其实与拟合二次函数的方法是一样的,因为都是通用的矩阵。那就用一个4阶的举例,如果是4阶,那么拟合出来的多项式就是3次多项式。这里我们先随便编一个4次多项式,生成一个4次多项式的点:

for i = 1 : n
    y(i) = 0.3 + 0.04 * x(i) + 1.2 * x(i) * x(i) + 0.06 * x(i) * x(i) * x(i) + 0.003 * x(i) * x(i) * x(i) * x(i);
end

这里的y就是4次多项式了,生成了点之后,我们使用最小二乘法来拟合一个3次多项式,尽量与4次多项式的点接近。依旧是按照最小二乘法的矩阵公式,先求出需要的加和数据:

%求矩阵数据
for i = 1 : n
    sumx = sumx + x(i);
    sumxx = sumxx + x(i) * x(i);
    sumxxx = sumxxx + x(i) * x(i) * x(i);
    sumxxxx = sumxxxx + x(i) * x(i) * x(i) * x(i);
    sumxxxxx = sumxxxxx + x(i) * x(i) * x(i) * x(i) * x(i);
    sumxxxxxx = sumxxxxxx + x(i) * x(i) * x(i) * x(i) * x(i) * x(i);
    sumy = sumy + y(i);
    sumxy = sumxy + x(i) * y(i);
    sumxxy = sumxxy + x(i) * x(i) * y(i);
    sumxxxy = sumxxxy + x(i) * x(i) * x(i) * y(i);
    sumxxxxy = sumxxxxy + x(i) * x(i) * x(i) * x(i) * y(i);   
end

然后写出矩阵:

%写出矩阵
U = [n  sumx  sumxx  sumxxx; 
    sumx  sumxx  sumxxx  sumxxxx; 
    sumxx  sumxxx  sumxxxx  sumxxxxx;
    sumxxx  sumxxxx  sumxxxxx  sumxxxxxx];
W = [sumy ; sumxy ; sumxxy; sumxxxy];

求出逆矩阵之后求多项式:

%求出矩阵的逆,进而求出多项式矩阵
V =  pinv(U) * W;   % U * V = W    V = U(-1) * W
a = V(1,1); b = V(2,1); c = V(3,1);d = V(4,1);

之后将图像画出来,对比之前生成的点的图像:

plot(x,y,'s');   %画数据点不连线
hold on;  %不加此句,两个图形将显示在两张图像上

%画出拟合曲线
x1 = [0 : 0.1 : 40];
y1 = a + b .* x1 + c .* x1 .* x1 + d .* x1 .* x1 .* x1;

plot(x1,y1);

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

【Matlab】最小二乘法拟合多项式 的相关文章

  • 图像增强 - 从书写中清除给定图像

    我需要清理这张照片 删除 清理我 的字样并使其变亮 作为图像处理课程作业的一部分 我可能会使用 matlab 函数 ginput 来查找图像中的特定点 当然 在脚本中您应该对所需的坐标进行硬编码 您可以使用 conv2 fft2 ifft2
  • 如何在 R 或 MATLAB 中为散点图创建阴影误差条“框”

    我想在 R 或 MATLAB 中创建一个简单的散点图 涉及两个变量 x 和 y 它们有与之相关的错误 epsilon x 和 epsilon y 然而 我不是添加误差线 而是希望在每个 x y 对周围创建一个 阴影框 其中框的高度范围从 y
  • 在 C/C++ 中调用 MATLAB API

    我刚刚从某处听说 对于数值计算 MATLAB 确实提供了一些用户友好的 API 如果你在 C C 代码中调用这些 API 你可以显着加快计算速度 但我在MATLAB文档中没有找到这样的信息 例如http www mathworks com
  • 将组合字符串和数字输入的元胞数组写入文本文件

    考虑以下 DateTime 2007 01 01 00 00 2007 02 01 00 00 2007 03 01 00 00 Headers Datetime Data Dat 100 200 300 Data DateTime num
  • 这是 `min` 和 `nanmin` 之间的区别; Matlab 中的“max”和“nanmax”?

    Matlab描述nanmin and nanmax像这样 NANMIN最小值 忽略NaNs NANMAX最大值 忽略NaNs 但实际上 min and max ignore NaNs too 那我应该使用哪个 根据我的测试 nanmin a
  • 如何以编程方式指定 MATLAB 编辑器键绑定

    我想将键盘键绑定设置为Windows 默认设置我想在启动时使用startup m因为我希望在大量系统上设置此设置 首选项对话框中的等效设置是 MATLAB gt Keyboard gt Shortcuts gt Active Setting
  • 在 MATLAB 中用两个值替换向量值

    我必须创建一个以向量作为输入的函数v和三个标量a b and c 该函数替换了的每个元素v等于a有一个二元素数组 b c 例如 给定v 1 2 3 4 and a 2 b 5 c 5 输出将是 out 1 5 5 3 4 我的第一次尝试是尝
  • MATLAB:比较两个不同长度的数组

    我有两个长度不同的数组 由于采样率不同 需要比较 我想对较大的数组进行下采样以匹配较小的数组的长度 但是该因子不是整数而是小数 举个例子 a 1 1 375 1 75 2 125 2 5 2 875 3 25 b 1 2 3 有什么方法可以
  • 如何从绘图处理程序中绘图?

    我有绘图的处理程序或图形的处理程序 例子 h plot 1 0 2 10 xx get h xx DisplayName Annotation 1x1 handle Color 0 0 1 LineStyle LineWidth 0 500
  • Matlab Solve():未给出所有解决方案

    我试图找到两条曲线的交点 syms x y g x 20 exp x 30 3 5 1 sol x sol y solve x 22 3097 2 y 16 2497 2 25 y g x x y Real true 它只提供一种解决方案
  • 使用 R2010b 中的符号工具箱来求解和/或 linsolve

    我前几天问了一个问题here https stackoverflow com questions 20317038 matlab linear congruence solver that supports a non prime modu
  • Matlab颜色检测

    我试图一致地检测同一场景的图像之间的某种颜色 这个想法是根据颜色配置文件识别一组对象 因此 例如 如果给我一个带有绿色球的场景 并且我选择绿色作为我的调色板的一部分 我想要一个具有反映它检测到球的矩阵的函数 任何人都可以为这个项目推荐一些
  • 平衡两轮机器人而不使其向前/向后漂移

    我正在尝试设计一个控制器来平衡 2 轮机器人 约 13 公斤 并使其能够抵抗外力 例如 如果有人踢它 它不应该掉落 也不应该无限期地向前 向后漂移 我对大多数控制技术 LQR 滑模控制 PID 等 都很有经验 但我在网上看到大多数人使用 L
  • 如何为已编译的 MATLAB 创建安装程序并要求用户接受我们的许可条款?

    我正在 MATLAB 中编写程序分发给 Windows 用户 我使用 MATLAB 编译器和 MATLAB r2014a 版本来创建程序 我可以使用 MATLAB 应用程序编译器创建 Windows 安装程序 并且它的工作效果可以接受 但是
  • 如何在Matlab中绘制网络?

    我有一个矩阵AMatlab中的维数mx2每行包含两个节点的标签 显示网络中的直接链接 例如 如果网络有4矩阵的节点A可能A 1 2 1 3 2 1 2 4 3 2 4 1 4 2 其中第一行表示有一个链接来自1 to 2 第二行表示有一个链
  • 在 matlab 代码中使用 dll 文件

    我需要使用 Matlab 中由 dll 文件定义的函数 我有一个例子 那个家伙将 dll 转换为 mexw32 文件 但我知道我是如何做到这一点的 我尝试使用加载库但它没有创建任何文件 我怎样才能做到这一点 loadlibrary http
  • 在 MATLAB 中模拟 C++ 模板

    我试图找出创建 C 模板或 Java 通用对象的替代方案的最佳方法 出于多种不同的原因 我过去曾多次想这样做 但现在我想做的是为几个相关的类创建 saveobj 和 loadobj 函数 我的想法是 我想要一组通用的例程来创建默认结构 然后
  • Matlab的导入函数的范围是什么?

    我正在尝试将一些用 Matlab 编写的代码转换为独立的 编译的 Matlab 应用程序 然而 在出现一些奇怪的错误之后 我意识到代码大量使用了从路径中添加和删除的操作 以避免多次使用多个具有相同名称 但结果 计算不同 的函数这一事实 环顾
  • matlab中无限while嵌套在for循环中

    我想做一个while循环 嵌套在for在 Matlab 中循环以查找数据中不同对之间的距离 我的数据具有以下形式 ID lon lat time 1 33 56 40 89 803 2 32 45 41 03 803 3 35 78 39
  • 获取向量幂的有效方法

    我编写了一个代码 在数值上使用勒让德多项式直至某个高 n 阶 例如 case 8 p 6435 x 8 12012 x 6 6930 x 4 1260 x 2 35 128 return case 9 如果向量x太长这会变得很慢 我发现说之

随机推荐

  • 搬砖过程中常用的英文单词(代码命名规则)

    注册register用户名 用户userName user密码password pwd路径path成绩score服务器host图片img字符串str数字num
  • CAN 邮箱的理解

    对于CAN邮箱的理解 xff1a CAN总线有接收邮箱和发送邮箱 xff1a 发送邮箱 是用于CAN总线数据发送的 xff0c 总共有3个 xff0c 并且存在优先级关系 优先级越高表示其里面的数据会被优先发送 数据在发送前都会被送到优先级
  • 变量名前为什么要加_下划线

    简单来说 xff0c 含有两个下划线和下划线 43 大写字母开头的标识符是给编译器和标准库用的 xff0c 你不能用 xff0c 否则后果自负 一个下划线开头的随便用 xff0c 只要你不嫌麻烦 而我们一般在前面加 表示私有变量 一般来说
  • 23 张图细讲使用 Devtron 简化 K8S 中应用开发

    23 张图细讲使用 Devtron 简化 K8S 中应用开发 在本文中 xff0c 您将学习如何在多集群环境中使用 Devtron 在 K8S 上进行应用开发 https devtron ai Devtron 附带用于构建 部署和管理微服务
  • 企业级网关 Kong 部署 Spring Boot 项目实战

    企业级网关 Kong 部署 Spring Boot 项目实战 1 概述 在本教程中 xff0c 我们将演示使用 Kong Ingress Controller KIC 在 Kubernetes 上部署 Spring Boot 应用程序 通过
  • Linux Mint(Ubuntu)上 安装 效率神器 utools

    我的 Windows 系统的笔记本只有 256G 固态 xff0c 磁盘已经快用满了 xff0c 最近想装个 Linux 玩玩 xff0c 选择了 Linux Mint xff0c 然后就在闲置的移动硬盘上安装了 Linux Mint 21
  • 图文轻松说透 K8S Pod 各种驱逐场景

    图文轻松说透 K8S Pod 各种驱逐场景 Kubernetes Pod 被驱逐是什么意思 xff1f 它们被终止 xff0c 通常是没有足够资源的结果 但是为什么会这样呢 xff1f 驱逐是指派给节点的Pod 被终止的过程 Kuberne
  • CKA、CKAD、CKS、LFCS、LFCA、LFCE 60$ 刀优惠券

    CKA CKAD CKS LFCS LFCA LFCE 60 刀优惠券 CKA 地址 xff1a https trainingportal linuxfoundation org courses certified kubernetes a
  • 配置Docker CE 镜像

    Docker CE 是免费的 Docker 产品的新名称 xff0c Docker CE 包含了完整的 Docker 平台 xff0c 非常适合开发人员和运维团队构建容器 APP 参考阿里云官方镜像站 xff1a 阿里巴巴开源镜像站 OPS
  • ssh 连接错误 Too many authentication failures 解决方法

    ssh 连接错误 Too many authentication failures 解决方法 背景 有时候使用 ssh 登录 或者 git ssh 方式连接 时会遇到 xff1a Too many authentication failur
  • 报错解决 REMOTE HOST IDENTIFICATION HAS CHANGED

    REMOTE HOST IDENTIFICATION HAS CHANGED 报错 span class hljs meta style color 61aeee line height 26px span span class bash
  • 使用 Helm Cli 将 chart 推送到 Harbor

    使用 Helm Cli 将 chart 推送到 Harbor 背景问题 努力寻找适用于特定版本的 Harbor 和 Helm 的文档 我尝试添加我的仓库 xff08 repo xff09 helm repo span class token
  • 修改 Git 已经提交记录的 用户名 和邮箱

    修改 Git 已经提交记录的 用户名 和邮箱 有关 Git 和版本控制的常见问题 如何更改提交的作者姓名 电子邮件 xff1f 在我们进入解决方案之前 xff0c 让我们找出您到底想要完成什么 xff1a 在提交之前更改作者信息在提交后更改
  • Go 中模拟 Kubernetes 客户端进行单元测试

    是的 xff0c 我们可以模仿 K8s Client xff01 编写单元测试一直是开发人员的痛苦 这样做的主要原因是 xff0c 通常 xff0c 单元测试 xff08 功能单元测试 xff09 不得使用应用程序的任何物理组件 运行实例
  • Kubernetes 1.26 中的删除、弃用和主要更改

    Kubernetes 1 26 中的删除 弃用和主要更改 变化是 Kubernetes 生命周期不可或缺的一部分 xff1a 随着 Kubernetes 的成长和成熟 xff0c 功能可能会被弃用 删除或替换为项目健康的改进 对于 Kube
  • 提高 K8S 容器运行时的可观察性最佳方法之一

    当谈到云原生可观察性时 xff0c 可能每个人都会提到OpenTelemetry OTEL xff0c 因为社区需要依赖标准来将所有集群组件开发指向到同一方向 OpenTelemetry 使我们能够将日志 指标 xff08 metrics
  • 6 张配图通俗易懂说透 K8S 请求和限制

    6 张配图通俗易懂说透 K8S 请求和限制 在 Kubernetes 中使用容器时 xff0c 了解涉及的资源是什么以及为何需要它们很重要 有些进程比其他进程需要更多的 CPU 或内存 这很关键 xff0c 永远不应该让进程挨饿 知道了这一
  • Kubernetes 1.26 正式发布,变化重大,所有更改都在这里了!

    Kubernetes 1 26 正式发布 xff0c 变化重大 xff0c 所有更改都在这里了 xff01 Kubernetes 1 26 已经正式发布 xff0c 满载新奇 xff01 此版本带来了 37 项增强功能 xff0c 与 Ku
  • 如何修复错误:无法下载 metadata repo appstream

    如何修复错误 xff1a 无法下载 metadata repo appstream 如果您出于某种原因仍在积极使用CentOS 8 xff0c 您可能在尝试更新系统或只是安装软件包时遇到以下错误 Error Failed to downlo
  • 【Matlab】最小二乘法拟合多项式

    前言 在最近的电机项目中 xff0c 有遇到有传感器数据并不线性的问题 xff0c 然后想要用最小二乘法做个曲线拟合 xff0c 反过来去校准不线性的传感器的数据 xff0c 因此记录一下使用最小二乘法来拟合多项式的曲线的步骤 本篇从最小二