用C++实现二阶低通滤波器,如何计算系数?

2024-01-10

我正在努力寻找合适的算法来生成低通滤波器的系数。我写了以下内容butterworthLowPass代码来自another https://stackoverflow.com/a/20932062/2612235那么问题:

class Filter {
    float fs;
    float a1, a2, b0, b1, b2;
    float v1, v2;

   public:
    Filter(float fs) : fs(fs) {}

    float compute(float x)
    {
        float v0 = x - a1 * v1 - a2 * v2;
        float y = b0 * v0 + b1 * v1 + b2 * v2;
        v2 = v1;
        v1 = v0;
        return y;
    }

    void butterworthLowPass(float fc)
    {
        const float ita = 1.0 / tan(M_PI * fc / fs);
        const float q = sqrt(2.0);
        b0 = 1.0 / (1.0 + q * ita + ita * ita);
        b1 = 2 * b0;
        b2 = b0;
        a1 = 2.0 * (ita * ita - 1.0) * b0;
        a2 = -(1.0 - q * ita + ita * ita) * b0;
    }

    void chebyshevLowPass(float f, float ripple)
    {
        // TODO: implement
    }

    void ellipticLowPass(float f, float ripple, float stopband)
    {
        // TODO: implement
    }

    void displayCoefficients()
    {
        fprintf(stderr, "a = [ %f, %f, %f ]\n", 1.f, a1, a2);
        fprintf(stderr, "b = [ %f, %f, %f ]\n", b0, b1, b2);
    }
};

这里主要:

int main()
{
    const float fs = 10000;
    Filter biquad(fs);
    biquad.butterworthLowPass(1000);
    biquad.displayCoefficients();
}

当采用计算出的系数并使用 Matlab 显示滤波器响应时,我得到 -15dB 增益,这不是我所期望的。

a = [ 1.000000, 1.142980, -0.412802 ];
b = [ 0.067455, 0.134911, 0.067455 ];
[mag, phase, wout] = bode(tf(b,a,1/(fs/2)));
subplot(2,1,1);
semilogx(wout(:,1)/(2*pi), 20*log10(squeeze(mag)), '-b'); zoom on; grid on;
axis tight
ylim([-40 0])
title('magnitude'); xlabel('Frequency (Hz)'); ylabel('Magnitude (dB)');
subplot(2,1,2);
semilogx(wout(:,1)/(2*pi), squeeze(phase), '-r'); zoom on; grid on;
axis tight

Matlab 给了我一些非常不同的东西:

>> fs = 10000;
>> fc = 1000;    
>> [b, a] = butter(2, 1000/10000)
b =
    0.0201    0.0402    0.0201
a =
    1.0000   -1.5610    0.6414

进一步的实验

我尝试克隆ruohoruotsi/Butterworth-Filter-Design.git并测试:

#include "Butterworth.h"

using namespace std;

int main() {
  float fs = 20000;
  float fc = 500;
  int order = 2;

  vector<Biquad> coeffs; // second-order sections (sos)
  Butterworth butterworth;

  bool designedCorrectly = butterworth.loPass(fs, fc, 0, order, coeffs, 1.0f);

  std::cout << "Designed correctly? " << designedCorrectly << std::endl;
  std::cout << "a = [" << 1.f << ", " << coeffs[0].a1 << ", " << coeffs[0].a2
            << "]" << std::endl;
  std::cout << "b = [" << coeffs[0].b0 << ", " << coeffs[0].b1 << ", "
            << coeffs[0].b2 << "]" << std::endl;
}

它给了我:

a = [1, 1.77863, -0.800803]
b = [1, 2, 1]

这又不太适合。


如果 z 变换后的传递函数定义为

H(z) = ( b0 + b1/z + b2/z^2 ) / ( a0 + a1/z + a2/z^2 )

那么我认为系数 a1 和 a2 的公式产生了错误符号的值。 (至少,这是我在返工时发现的,但我可能是错的)。

以下代码给出了 a1 和 a2 的相反符号。

#include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <cmath>
using namespace std;

const double PI = 4.0 * atan( 1.0 );
const complex<double> iPI( 0.0, PI );
const double SQRT2 = sqrt( 2.0 );

// const double factor = 0.5;    // use for Matlab comparison
const double factor = 1.0;       // as original post

//----------------------------------------------------------------------

void getCoefficients( double fd, double fs, vector<double> &a, vector<double> &b )
{
   double alpha = 1.0 / tan( factor * PI * fd / fs );
   b[0] = 1.0 / ( 1.0 + SQRT2 * alpha + alpha * alpha );
   b[1] = 2 * b[0];
   b[2] = b[0];
   a[0] = 1.0;
   a[1] = 2.0 * ( 1.0 - alpha * alpha ) * b[0];
   a[2] = ( 1.0 - SQRT2 * alpha + alpha * alpha ) * b[0];
}

//----------------------------------------------------------------------

void bode( const vector<double> &a, const vector<double> &b, double f, double fs, double &mag, double &phase )
{
   complex<double> invz = ( 1.0 - iPI * factor * f / fs ) / ( 1.0 + iPI * factor * f / fs );
   complex<double> H = ( b[0] + b[1] * invz + b[2] * invz * invz ) / ( a[0] + a[1] * invz + a[2] * invz * invz );
   mag = abs( H );
   phase = atan2( H.imag(), H.real() );
}

//----------------------------------------------------------------------

int main()
{
   vector<double> a(3), b(3);
   double fs = 10000;
   double fd = 1000;

   // Get Butterworth coefficients in H(z) = ( b0 + b1/z + b2/z^2 ) / ( a0 + a1/z + a2/z^2 )
   getCoefficients( fd, fs, a, b );
   cout << "a:\t";
   for ( double e : a ) cout << e << '\t';
   cout << "\nb:\t";
   for ( double e : b ) cout << e << '\t';
   cout << "\n\n";

   double logmin = 1.0, logmax = 4.0;
   int nw = 31;
   double dlog = ( logmax - logmin ) / ( nw - 1 );
   #define FMT << scientific << setw(15) << setprecision(4) <<

   cout FMT "f(Hz)" FMT "mag" FMT "db" FMT "phase(deg)" << '\n';
   for ( int i = 0; i < nw; i++ )
   {
      double f, mag, phase;
      f = pow( 10.0, logmin + i * dlog );
      bode( a, b, f, fs, mag, phase );

      double phasedeg = phase * 180.0 / PI;
      double db = 20.0 * log( mag ) / log( 10.0 );
      cout FMT f FMT mag FMT db FMT phasedeg << '\n';
   }
}

Output:

a:  1   -1.14298    0.412802    
b:  0.0674553   0.134911    0.0674553   

          f(Hz)            mag             db     phase(deg)
     1.0000e+01     1.0000e+00    -3.7956e-08    -7.8347e-01
     1.2589e+01     1.0000e+00    -9.5341e-08    -9.8635e-01
     1.5849e+01     1.0000e+00    -2.3949e-07    -1.2418e+00
     1.9953e+01     1.0000e+00    -6.0156e-07    -1.5634e+00
     2.5119e+01     1.0000e+00    -1.5111e-06    -1.9683e+00
     3.1623e+01     1.0000e+00    -3.7956e-06    -2.4783e+00
     3.9811e+01     1.0000e+00    -9.5341e-06    -3.1205e+00
     5.0119e+01     1.0000e+00    -2.3949e-05    -3.9296e+00
     6.3096e+01     9.9999e-01    -6.0156e-05    -4.9494e+00
     7.9433e+01     9.9998e-01    -1.5110e-04    -6.2354e+00
     1.0000e+02     9.9996e-01    -3.7954e-04    -7.8588e+00
     1.2589e+02     9.9989e-01    -9.5331e-04    -9.9113e+00
     1.5849e+02     9.9972e-01    -2.3942e-03    -1.2513e+01
     1.9953e+02     9.9931e-01    -6.0114e-03    -1.5821e+01
     2.5119e+02     9.9826e-01    -1.5084e-02    -2.0052e+01
     3.1623e+02     9.9566e-01    -3.7791e-02    -2.5501e+01
     3.9811e+02     9.8920e-01    -9.4310e-02    -3.2581e+01
     5.0119e+02     9.7352e-01    -2.3312e-01    -4.1849e+01
     6.3096e+02     9.3720e-01    -5.6339e-01    -5.3957e+01
     7.9433e+02     8.6132e-01    -1.2967e+00    -6.9313e+01
     1.0000e+03     7.3050e-01    -2.7276e+00    -8.7273e+01
     1.2589e+03     5.5943e-01    -5.0451e+00    -1.0563e+02
     1.5849e+03     3.9180e-01    -8.1387e+00    -1.2189e+02
     1.9953e+03     2.5949e-01    -1.1718e+01    -1.3493e+02
     2.5119e+03     1.6715e-01    -1.5538e+01    -1.4496e+02
     3.1623e+03     1.0636e-01    -1.9464e+01    -1.5262e+02
     3.9811e+03     6.7339e-02    -2.3435e+01    -1.5850e+02
     5.0119e+03     4.2546e-02    -2.7423e+01    -1.6305e+02
     6.3096e+03     2.6859e-02    -3.1418e+01    -1.6660e+02
     7.9433e+03     1.6951e-02    -3.5416e+01    -1.6939e+02
     1.0000e+04     1.0696e-02    -3.9415e+01    -1.7159e+02

至于 Matlab...好吧,如果将该代码顶部的因子更改为注释掉的值 (0.5),那么您将获得 Matlab 值:

a:      1       -1.56102        0.641352        
b:      0.0200834       0.0401667       0.0200834  

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

用C++实现二阶低通滤波器,如何计算系数? 的相关文章

  • Dapper 强类型查询返回默认对象值

    刚刚开始使用 Dapper 并喜欢它 我遇到了问题 它返回正确数量的对象 但它们的属性都有默认值 using var dbConnection Connection await dbConnection OpenAsync const st
  • 警告:从指针目标类型中丢弃“const”限定符

    没有const char s意味着 s 是一个指向常量 char 的指针 那么为什么它给我这个警告 我并不是想改变价值观 在第一个函数中警告是return discards const qualifiers from pointer tar
  • Matlab:如何显示数组的“真实”值?

    我有一个在脚本中计算的向量 计算后 我将值显示到命令窗口 显示如下 finalResults 1 0e 05 0 0001 0 0 0005 0 0002 0 0001 0 0027 0 0033 0 0001 0 0000 0 0000
  • C#9 顶级语句文件上的属性

    我正在尝试向顶级语句文件添加属性 但没有找到任何相关信息 是否可以 对于某些上下文 我想仅在该文件中禁用规则 SuppressMessage StyleCop CSharp LayoutRules SA1516 ElementsMustBe
  • .NET Windows 服务中调用 C# 的 wait 的 I/O 回调是否可以不阻塞?

    我知道在 ASP NET 中 当使用 wait 时工作线程会返回到池中 而 I O 发生在后台 这对于可扩展性非常有用 我的 Windows 服务是一个套接字服务器 它使用 Begin End 样式的异步套接字 I O 混合我的魔法 我知道
  • 可选参数“必须是编译时常量”

    我有一个类分为两个部分文件 如下所示 public partial class PersonRepository BaseRepository
  • WPF - 按多列排序时使用自定义比较器

    我有一个 ListView GridView 我想按 2 列排序 因此如果第 1 列中有 2 个以上的项目具有相同的值 它将按第 2 列排序 非常简单 但是在对 A Z 进行排序时 空字符串会出现在顶部 我想把它们移到底部 我制作了一个比较
  • 为什么 LinkedList 通常比 List 慢?

    我开始在我的一些 C 算法中使用一些 LinkedList 而不是列表 希望能够加快速度 然而 我注意到他们只是感觉更慢 像任何优秀的开发人员一样 我认为我应该尽职调查并验证我的感受 所以我决定对一些简单的循环进行基准测试 我认为用一些随机
  • 浏览器收集哪些值作为回发数据?

    当页面被发送回服务器时 浏览器收集每个控件的当前值并将其粘贴到一个字符串中 然后 该回发数据通过 HTTP POST 发送回服务器 Q1 除了控件的 Text 属性和 SelectedIndexchanged 因此除了用户输入数据 之外 控
  • C# ConfigurationManager 从 app.config 检索错误的连接字符串

    我有一个简单的 WinForms 应用程序 它最终将成为一个游戏 现在 我正在研究它的数据访问层 但遇到了障碍 我创建了一个单独的项目 名为DataAccess在其中 我创建了一个本地 mdfSQL Server 数据库文件 我还创建了一个
  • Windows 程序如何临时更改其时区?

    我写了一个函数来返回time t与给定日期的午夜相对应的值 当给定日期没有午夜时 它返回最早可用的时间 例如 当埃及进入夏令时时 这种情况就可能发生 今年 时间更改于 4 月 29 日晚上午夜生效 因此时钟直接从 23 59 转到 01 0
  • 首先EntityFramework数据库 - 类型映射 - 将binary(8)从SQL映射到C#中的int

    在 SQL 内部 我有一个主键为二进制 8 的表 当我使用该表添加到我的模型中时Update Model from Database我可以看到该列有 type Binary 在 C 中 我将该列设为byte 我可以将该列映射到 int 吗
  • 使用 cudamalloc()。为什么是双指针?

    我目前正在浏览有关的教程示例http code google com p stanford cs193g sp2010 http code google com p stanford cs193g sp2010 学习CUDA 演示的代码 g
  • IEnumerable.比带中断的 for 循环更快吗?

    我们的代码打开表单时遇到了一些缓慢的情况 这可能是由于for循环与break这需要很长时间才能执行 我把它切换到IEnumerable Any 并看到表格很快打开 我现在试图弄清楚是否单独进行此更改会提高性能 或者是否正在访问Product
  • 如何使用eclipse构建C++应用程序

    我已经从以下位置下载了 Eclipse Juno for C here http www eclipse org downloads download php file technology epp downloads release ju
  • 停止 TcpListener 的正确方法

    我目前正在使用 TcpListener 来处理传入连接 每个连接都有一个线程用于处理通信 然后关闭该单个连接 代码如下 TcpListener listener new TcpListener IPAddress Any Port Syst
  • 向每个收件人发送一封包含不同内容的电子邮件(使用抄送字段)

    在你因为这个问题 毫无意义 和 不可能 而驳回之前 请听我说完 问题 我们在使用我们的系统发送的每封电子邮件中实施跟踪像素 即具有唯一 URL 的可下载 GIF 文件 这有助于我们跟踪电子邮件的打开情况 问题是 当我们抄送一些收件人时 跟踪
  • 请解释为什么Java和C对此代码给出不同的答案

    public class Test public static void main String args int i 10 i i System out println value of i is i 输出是 10 当我在中执行类似的代码
  • 如何设置 Swashbuckle 与 Microsoft.AspNetCore.Mvc.Versioning

    我们有asp net core webapi 我们添加了Microsoft AspNetCore Mvc Versioning and Swashbuckle拥有招摇的用户界面 我们将控制器指定为 ApiVersion 1 0 Route
  • 如何获取通过网络驱动器访问的文件的 UNC 路径?

    我正在 VC 中开发一个应用程序 其中网络驱动器用于访问文件 驱动器由用户手动分配 然后在应用程序中选择驱动器 这会导致驱动器并不总是映射到相同的服务器 我该如何获取此类文件的 UNC 路径 这主要是为了识别目的 这是我用来将普通路径转换为

随机推荐

  • PhoneGap FileReader/readAsDataURL 不触发回调

    我正在使用 PhoneGap Build 构建 iOS v7 1 应用程序并使用weinre http people apache org pmuellr weinre docs latest 进行调试 我正在使用媒体捕获插件和文件 API
  • 获取中间件中的路由定义

    有谁知道是否可以获取用于触发路线的路径 例如 假设我有这个 app get user id function req res 使用以下简单的中间件 function req res next req 我希望能够得到 user id在中间件中
  • Instagram Streaming API 的 Logstash 输入插件

    我想阅读 Instagram 上的活动 我想知道我是否可以使用 Logstash 来做到这一点 类似于使用 Twitter 输入插件从 Twitter 读取事件 但 Instagram 没有输入插件 还有其他方法可以使用 Logstash
  • Pygame 中自上而下的运动

    如果这个问题之前已经被问过 我很抱歉 但我到处都检查过 但找不到答案 如何在 pygame 中进行自上而下的移动 如果我只使用矩形 这会很容易 但我将使用单个字符精灵 例如 如果我按d为了让玩家向右走 它会向我显示他向右走的角色精灵并将角色
  • Android KitKat 中的 WebView 渲染问题

    我一直在开发一个具有 WebView 的应用程序 其中从资产加载静态页面 也使用 JavaScript 此 WebView 在 KitKat 中不起作用 它保持空白 我知道在 kitkat 的 WebView 中发生的渲染引擎 webkit
  • Azure 存储模拟器无法初始化,并显示“数据库‘AzureStorageEmulatorDb57’不存在”

    我在使用 Azure 存储模拟器时遇到问题 我尝试重新初始化数据库并收到以下错误 这是在安装 Visual Studio 2019 预览版之后发生的 但这可能只是巧合 我尝试了一个小时左右让它运行 然后放弃了 只是使用 保留我的文件 选项重
  • 减少功能如何工作?

    据我了解 reduce 函数需要一个列表l和一个函数f 然后 它调用该函数f列表的前两个元素 然后重复调用该函数f与下一个列表元素和上一个结果 因此 我定义了以下函数 以下函数计算阶乘 def fact n if n 0 or n 1 re
  • 该模型没有从输入中返回损失 - LabSE 错误

    我想使用小队数据集微调 LabSE 以进行问答 我收到这个错误 ValueError The model did not return a loss from the inputs only the following keys last
  • Cassandra Nodejs DataStax 驱动程序不会通过准备好的语句执行返回新添加的列

    在架构中添加一对列后 我想通过以下方式选择它们select 反而select 返回旧的列集并且没有新的列 根据文档推荐 我使用 prepare true 来平滑 JavaScript 浮点数和 Cassandra ints bigints
  • 如何使用温莎城堡实例化基于 web.config 文件的类?

    我正在开发一个 ASP NET MVC 应用程序 我想根据 web config 中编写的设置实例化一个类
  • 如何在 Django 中使用单个查询集选择记录并更新它?

    我如何运行update and select相同的声明queryset而不必执行两个查询 一项选择对象 和一个更新对象 SQL 中的等效内容类似于 update my table set field 1 some value where p
  • 如何使用正则表达式格式化数字[重复]

    这个问题在这里已经有答案了 我遇到了涉及格式化数字的问题 在巴西 我们有一种称为 CPF 的文件 这是每个公民都拥有的一种个人身份证 以下是格式正确的 CPF 号码示例 096 156 487 09 我正在尝试使用正则表达式来格式化包含 C
  • ‘php.exe’不被识别为内部或外部命令、可运行程序或批处理文件

    php exe 不被识别为内部或外部命令 可运行的程序或批处理文件 即使我已将 PHP 添加到环境变量中 为什么仍会出现该错误 我的环境变量PATH如下所示 C Program Files NVIDIA Corporation PhysX
  • 如何在8086汇编中减去两个64位整数

    编写一个名为 SUB64 的程序 用 0x0160 和 0x0164 中的 64 位整数减去内存位置 0x0150 和 0x0154 中的 64 位整数 将结果存储在内存位置 0x0170 和 0x0174 中 我理解将其分成更小的部分背后
  • python re.findall() 与交替的子字符串

    如果我在正则表达式交替中有另一个字符串或模式的子字符串 或 子模式 如下所示 r abcd bc 预期的行为是什么re compile r abcd bc findall abcd bcd bc ab 尝试一下 我得到了 正如预期的那样 a
  • 使用 Square Connect API 访问客户信息

    是否可以使用 Square Connect API 访问有关商家客户的任何信息 最理想的信息是客户输入的收据电子邮件地址 但某种类型的唯一客户 ID 可以很好地确定回头客 纵观整个Square Connect API 文档 https co
  • 为什么通过提取方法进行重构会触发借用检查器错误?

    我的网络应用程序的架构可以简化为以下内容 use std collections HashMap Represents remote user Usually has fields but we omit them for the sake
  • UIStackview 左对齐

    我试图将 UIStackview 中的项目水平向左对齐 有没有办法以编程方式执行此操作 我尝试通过故事板来做到这一点 但没有成功 由于某种原因 UIStackView 中的项目会自行居中 如果您使用 StackView 将 axis 属性设
  • ASP.Net 应用程序作为 IIS_USR 执行 powershell 脚本

    我正在构建一个 asp net mvc 应用程序 它将作为我们编写的许多 powershell 脚本的包装器来运行 以管理日常任务 最终目标是让非技术人员轻松使用这些脚本 我已经设法让脚本很好地执行 var ctx System Web H
  • 用C++实现二阶低通滤波器,如何计算系数?

    我正在努力寻找合适的算法来生成低通滤波器的系数 我写了以下内容butterworthLowPass代码来自another https stackoverflow com a 20932062 2612235那么问题 class Filter