当前位置: 首页 > news >正文

C/C++编程-算法学习-数字滤波器

数字滤波器

  • 一阶低通滤波器
    • 结论
    • 推导1
      • 1. 基本公式推导
      • 2. 截止频率 和 采样频率 推导
    • 实现
  • 二阶低通滤波器
    • 实现1
    • 实现2

一阶低通滤波器

结论

其基本原理基于以下公式:
o u t p u t [ n ] = α ∗ i n p u t [ n ] + ( 1 − α ) ∗ o u t p u t [ n − 1 ] output[n] = α * input[n] + (1 - α) * output[n - 1] output[n]=αinput[n]+(1α)output[n1]

  • output[n] 是当前的输出值
  • input[n] 是当前的输入值
  • α是滤波系数,取值范围在 0 到 1 之间。α值越大,对输入的响应越迅速,但滤波效果相对较弱;α值越小,滤波效果越强,但对输入的响应越慢
  • output[n - 1] 是上一次的输出值
    例如,如果 alpha = 0.1,输入值在短时间内快速变化,由于 (1 - alpha) 的权重较大,上一次的输出值对当前输出值的影响较大,从而起到平滑和抑制高频变化的作用。

推导1

1. 基本公式推导

对应电路模型一阶RC滤波器
Y ( s ) / X ( s ) = H ( s ) = 1 r c s + 1 = 1 r ⋅ j w c + 1 = 1 τ s + 1 Y(s)/X(s)=H(s) = \frac{1}{rcs +1} = \frac{1}{r·jwc + 1} =\frac{1}{\tau s + 1} Y(s)/X(s)=H(s)=rcs+11=rjwc+11=τs+11
在自控中称为一阶惯性环节
转成时域方程
X ( s ) = Y ( s ) / H ( s ) = Y ( s ) ( τ s + 1 ) X(s) = Y(s)/H(s) = Y(s)(\tau s +1) X(s)=Y(s)/H(s)=Y(s)(τs+1)
x ( t ) = τ y ′ ( t ) + y ( t ) x(t) = \tau y'(t) + y(t) x(t)=τy(t)+y(t)
将导数拆开(使用一阶后向差分法,对上面微分方程进行离散化)
x ( t ) = τ ( y ( t ) − y ( t − T ) T ) + y ( t ) x(t) = \tau (\frac {y(t) - y(t-T)}{T}) + y(t) x(t)=τ(Ty(t)y(tT))+y(t)
整理成可递归迭代函数
y ( t ) = ( 1 − T T + τ ) ⋅ y ( t − T ) + T T + τ x ( t ) y(t) = (1-\frac {T}{T+\tau})·y(t-T) + \frac{T}{T+\tau}x(t) y(t)=(1T+τT)y(tT)+T+τTx(t)
a = T T + τ a = \frac{T}{T+\tau} a=T+τT 则可得一般表达式
y ( t ) = ( 1 − a ) y ( t − T ) + a x ( t ) y(t) = (1-a)y(t-T)+ax(t) y(t)=(1a)y(tT)+ax(t)

2. 截止频率 和 采样频率 推导

实现

#include <stdio.h>
#include <stdlib.h>// 一阶低通滤波器函数
float lowPassFilter(float input, float prevOutput, float alpha) {return alpha * input + (1 - alpha) * prevOutput;
}int main() {float input = 10.0;  // 输入值float prevOutput = 5.0;  // 上一次的输出值float alpha = 0.2;  // 滤波系数for(int i=0; i<20; i++){float output = lowPassFilter(input, prevOutput, alpha);prevOutput = output;printf("filter current result: %f\n", output);}system("pause");return 0;
}

运行结果
在这里插入图片描述

二阶低通滤波器

实现1

#include <stdio.h>
// #include </lib/gcc/x86_64-linux-gnu/9/math.h>
#include <math.h>// 二阶低通滤波器参数
#define SAMPLING_FREQ 1000  // 采样频率
#define CUTOFF_FREQ 100  // 截止频率// 计算滤波器系数
void calculateFilterCoefficients(double *a, double *b) {double omega = 2 * M_PI * CUTOFF_FREQ / SAMPLING_FREQ;double alpha = sin(omega) / (2 * 0.707);double beta = cos(omega);double a0 = 1 + alpha;double a1 = -2 * beta;double a2 = 1 - alpha;double b0 = (1 - beta) / 2;double b1 = 1 - beta;double b2 = (1 - beta) / 2;*a = a0;*(a + 1) = a1;*(a + 2) = a2;*b = b0;*(b + 1) = b1;*(b + 2) = b2;
}// 二阶低通滤波函数
double lowPassFilter(double input, double *prevInputs, double *prevOutputs, double *a, double *b) {double output = *b * input + *b * prevInputs[0] + *b * prevInputs[1] - *a * prevOutputs[0] - *a * prevOutputs[1];prevInputs[1] = prevInputs[0];prevInputs[0] = input;prevOutputs[1] = prevOutputs[0];prevOutputs[0] = output;return output;
}int main() {double a[3], b[3];calculateFilterCoefficients(a, b);double prevInputs[2] = {0};double prevOutputs[2] = {0};double input = 10;  // 输入值,可根据实际情况修改double filteredOutput = lowPassFilter(input, prevInputs, prevOutputs, a, b);printf("滤波后的输出: %f\n", filteredOutput);return 0;
}/**
如果你在使用gcc编译含数学函数的 C 程序时,出现undefined reference to 'sin'、undefined reference to 'cos'等错误,一般是由于缺少库造成的。因为在 Ubuntu 系统中,gcc的数学函数(如sin、cos等)是定义在libm.so里面的,而数学库不在默认路径下。通过添加-lm选项,就可以告诉编译器到正确的库中查找这些函数。注意:在使用cmake进行编译时,需要添加命令target_link_libraries(your_target_name m)来链接数学库,其中your_target_name是你的目标名称。
*/

经我实际验证ubuntu20,的math库在如下路径
dpkg -l | grep math
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

实现2

#include <stdio.h>
#include <math.h>// 二阶低通滤波器系数
typedef struct {double a0, a1, a2, b1, b2;
} FilterCoefficients;// 计算二阶低通滤波器系数
void calculateFilterCoefficients(double cutoffFrequency, double samplingFrequency, FilterCoefficients *coefficients) {double omega = 2.0 * 3.14159 * cutoffFrequency / samplingFrequency;double cosOmega = cos(omega);double sinOmega = sin(omega);double alpha = sinOmega / (2.0 * 0.707);double a0 =  1 + alpha;double a1 = -2 * cosOmega;double a2 =  1 - alpha;double b1 = -2 * cosOmega;double b2 =  1 - alpha;coefficients->a0 = 1.0 / a0;coefficients->a1 = a1 / a0;coefficients->a2 = a2 / a0;coefficients->b1 = b1 / a0;coefficients->b2 = b2 / a0;
}// 二阶低通滤波器函数
void secondOrderLowPassFilter(double input[], double output[], int length, FilterCoefficients coefficients) {output[0] = input[0];output[1] = coefficients.a0 * input[1] + coefficients.a1 * input[0] + coefficients.b1 * output[0];for (int i = 2; i < length; i++) {output[i] = coefficients.a0 * input[i] + coefficients.a1 * input[i - 1] + coefficients.a2 * input[i - 2]- coefficients.b1 * output[i - 1] - coefficients.b2 * output[i - 2];}
}int main() {double cutoffFrequency = 10.0;  // 截止频率double samplingFrequency = 50.0;  // 采样频率FilterCoefficients coefficients;calculateFilterCoefficients(cutoffFrequency, samplingFrequency, &coefficients);double input[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};double output[10];int length = 10;secondOrderLowPassFilter(input, output, length, coefficients);for (int i = 0; i < length; i++) {printf("Output[%d] = %f\n", i, output[i]);}return 0;
}

实验结果:

在这里插入图片描述

相关文章:

C/C++编程-算法学习-数字滤波器

数字滤波器 一阶低通滤波器结论推导11. 基本公式推导2. 截止频率 和 采样频率 推导 实现 二阶低通滤波器实现1实现2 一阶低通滤波器 结论 其基本原理基于以下公式&#xff1a; o u t p u t [ n ] α ∗ i n p u t [ n ] ( 1 − α ) ∗ o u t p u t [ n − 1 ] output[n] …...

maven介绍 搭建Nexus3(maven私服搭建)

Maven是一个强大的项目管理工具&#xff0c;它基于项目对象模型&#xff08;POM&#xff1a;Project Object Model&#xff09;的概念&#xff0c;通过XML格式的配置文件&#xff08;pom.xml&#xff09;来管理项目的构建 Maven确实可以被视为一种工程管理工具或项目自动化构…...

电商项目之如何判断线程池是否执行完所有任务

文章目录 1 问题背景2 前言3 4种常用的方法4 代码4.1 isTerminated()4.2 线程池的任务总数是否等于已执行的任务数4.3 CountDownLatch计数器4.4 CyclicBarrier计数器 1 问题背景 真实生产环境的电商项目&#xff0c;常使用线程池应用于执行大批量操作达到高性能的效果。应用场景…...

【前端 15】Vue生命周期

Vue生命周期 在Vue.js中&#xff0c;了解组件的生命周期对于开发者来说是至关重要的。Vue的生命周期指的是Vue实例从创建到销毁的一系列过程&#xff0c;每个阶段都对应着特定的生命周期钩子&#xff08;或称为生命周期方法&#xff09;&#xff0c;允许我们在不同的时间点加入…...

PCIe总线-Linux内核PCIe软件框架分析(十一)

1.简介 Linux内核PCIe软件框架如下图所示&#xff0c;按照PCIe的模式&#xff0c;可分为RC和EP软件框架。RC的软件框架分为五层&#xff0c;第一层为RC Controller Driver&#xff0c;和RC Controller硬件直接交互&#xff0c;不同的RC Controller&#xff0c;其驱动实现也不相…...

视觉SLAM第二讲

SLAM分为定位和建图两个问题。 定位问题 定位问题是通过传感器观测数据直接或间接求解位置和姿态。 通常可以分为两类&#xff1a;基于已知地图的定位和基于未知地图的定位。 基于已知地图的定位 利用预先构建的地图&#xff0c;结合传感器数据进行全局定位。SLAM中的全局…...

mysql1055报错解决方法

目录 一、mysql版本 二、 问题描述 三、解决方法 1.方法一&#xff08;临时&#xff09; 2.方法二&#xff08;永久&#xff09; 一、mysql版本 mysql版本&#xff1a;5.7.23 二、 问题描述 在查询时使用group by语句&#xff0c;出现错误代码&#xff1a;1055&#xf…...

Java的@DateTimeFormat注解与@JsonFormat注解的使用对比

Java的DateTimeFormat注解与JsonFormat注解的使用对比 在Java开发中&#xff0c;处理日期和时间格式时&#xff0c;我们经常会使用到DateTimeFormat和JsonFormat注解。这两个注解主要用于格式化日期和时间&#xff0c;但在使用场景和功能上有所不同。本文将详细介绍这两个注解…...

德国云手机:企业移动办公解决方案

在现代商业环境中&#xff0c;移动办公已经成为一种趋势。德国云手机作为一种高效的解决方案&#xff0c;为企业提供了强大的支持。本文将探讨德国云手机如何优化企业的移动办公环境。 一、德国云手机的主要优势 高灵活性 德国云手机具有高度的灵活性&#xff0c;能够根据用户需…...

【React】useState:状态管理的基石

文章目录 一、什么是 useState&#xff1f;二、useState 的基本用法三、useState 的工作原理四、高级用法五、最佳实践 在现代前端开发中&#xff0c;React 是一个非常流行的库&#xff0c;而 useState 是 React 中最重要的 Hook 之一。useState 使得函数组件能够拥有自己的状态…...

商品中心关于缓存热key的解决方案

缓存热key一旦被击穿&#xff0c;流量势必会打到数据库&#xff0c;如果数据库崩了&#xff0c;游戏直接结束。 从两点来讨论&#xff1a;如何监控、如何解决。 如何监控 通过业务评估&#xff1a;比如营销活动推出的商品或者热卖的商品。基于LRU的命令&#xff0c;redis-cl…...

【Python系列】Parquet 数据处理与合并:高效数据操作实践

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

大脑自组织神经网络通俗讲解

大脑自组织神经网络的核心概念 大脑自组织神经网络&#xff0c;是指大脑中的神经元通过自组织的方式形成复杂的网络结构&#xff0c;从而实现信息的处理和存储。这一过程涉及到神经元的生长、连接和重塑&#xff0c;是大脑学习和记忆的基础。其核心公式涉及神经网络的权重更新…...

org.springframework.context.annotation.DeferredImportSelector如何使用?

DeferredImportSelector 是 Spring 框架中一个比较高级的功能&#xff0c;主要用于在 Spring 应用上下文的配置阶段延迟导入某些组件或配置。这个功能特别有用&#xff0c;比如在处理依赖于其他自动配置的场景&#xff0c;或者当你想基于某些条件来决定是否导入特定的配置类时。…...

缓慢变化维

缓慢变化维 缓慢变化维&#xff08;Slowly Changing Dimensions&#xff0c;简称SCD&#xff09;是数据仓库中的一个重要概念&#xff0c;用于处理维度表中数据随时间发生的变化。以下是一个具体的例子来描述缓慢变化维&#xff1a; 假设我们有一个销售数据仓库&#xff0c;其…...

Vue常用的指令都有哪些?都有什么作用?什么是自定义指令?

常用指令&#xff1a; 1、v-model 多用于表单元素实现双向数据绑定 (同angular中的ng-model) 2、v-for格式&#xff1a; v-for"字段名in(of)数组json"循环数组或json(同angular中的ng repeat),需要注意从vue2开始取消了$index 3、v-show 4、v-hide 隐藏内容 (同a…...

kettle从入门到精通 第八十一课 ETL之kettle kettle中的json对象字段写入postgresql中的json字段正确姿势

1、上一节可讲解了如何将json数据写入pg数据库表中的json字段&#xff0c;虽然实现了效果&#xff0c;但若客户继续使用表输出步骤则仍然无法解决问题。 正确的的解决方式是设置数据库连接参数stringtypeunspecified 2、stringtypeunspecified 参数的作用&#xff1a; 当设置…...

计算机网络实验-RIP配置与分析

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、相关知识 路由信息协议&#xff08;Routing Information Protocol&#xff0c;RIP&#xff09;是一种基于距离向量&#xff08;Distance-Vector&…...

33.【C语言】实践扫雷游戏

预备知识&#xff1a; 第13篇 一维数组 第13.5篇 二维数组 第28篇 库函数 第29篇 自定义函数 第30篇 函数补充 0x1游戏的运行&#xff1a; 1.随机布置雷 2.排雷 基本规则&#xff1a; 点开一个格子后&#xff0c;显示1&#xff0c;对于9*9&#xff0c;代表以1为中心的去…...

git学习笔记(总结了常见命令与学习中遇到的问题和解决方法)

前言 最近学习完git&#xff0c;学习过程中也遇到了很多问题&#xff0c;这里给大家写一篇总结性的博客&#xff0c;主要大概讲述git命令和部分难点问题&#xff08;简单的知识点这里就不再重复讲解了&#xff09; 一.git概述 1.1什么是git Git是一个分布式的版本控制软件。…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...