在哪里可以获得Parks-McClellan最佳FIR滤波器设计算法的开源实现?


20

背景:通常,我在执行某种信号处理任务,需要一个唯一的滤波器。通常在这一点上,我进入MATLAB并使用生成一个新的唯一过滤器。MATLAB 函数实现了该Parks-McClellan算法。现在,我有了一个过滤器,并将该过滤器放入一个硬编码的数组中。但是,这里的问题是我现在有一个仅适用于一种情况的硬编码过滤器。firpm()firpm()

问题:我现在可以解决信号处理问题,但仅适用于非常特殊的单采样率或特殊情况。

目标:我希望能够调用firpm()从C代码或其他某种语言并使我的信号处理代码更通用。我找不到的开源实现firpm()

在哪里可以获得Parks-McClellan最佳FIR滤波器设计算法(在MATLAB中又称为开源实现?firpm()

  • PS我知道我可以使用开窗或其他方式设计不同的过滤器...请在评论中随意提及。但是,这个问题的重点不是要问“还有什么其他的滤波器设计技术?” 关键是找到非常有用的开源实现firpm() ...或类似的东西。

  • PPS这个问题的目标之一是通过首先查看代码来学习Parks-McClellan算法的工作原理,然后计划阅读一些背景知识。


免费提供解决方案是否重要?您是否研究过Matlab C API?

2
最高优先级是我想查看源代码(最好不要使用fortran,这样就不必费神了)。我不会限制它必须是自由的(也许有某种开源但非自由的源代码)。
特雷弗·博伊德·史密斯

3
我知道您可以使用Matlab编译器编译Matlab,然后使用Matlab Runtime进行分发...因此从技术上讲,您的客户不必为Matlab许可付费。我也知道Matlab引擎(又名C到Matlab API)。这两个都是无关紧要的,因为我通常在没有可用的嵌入式平台上运行。
特雷弗·博伊德·史密斯

1
@TrevorBoydSmith由于您只想查看源代码,因此您是否type firpm.m在MATLAB中进行过尝试?那将向您展示MATLAB函数的实现。
Lorem Ipsum

1
FIR滤波器设计对于信号处理非常有用,并且parks-mcclelan是一个重要的主题。但是,我一直被问到有关IMO是否完全符合dsp.stackexchange章程的主题而被否决。请解释一下你的投票。
特雷弗·博伊德·史密斯,

Answers:


5

这是Remez交换算法的LGPL版本。倍频程代码似乎是从中得出的。它是从Wikipedia页面Parks McClellan页面上链接的。
原始的Janovetz代码可能没有项目的八度调用,因此可能更容易在您的项目中使用,但是明智的是在octz-forge svn changelog中挖掘有关remez.cc文件中的错误修正或加速的任何信息。 。


我同意在项目中使用Janovetz代码会更容易,因为它是C语言。我也绝对同意检查八度实现的更改日志非常聪明。
特雷弗·博伊德·史密斯

Janovetz代码IMO可能是第一稿或第二稿...但是没有像Octave代码那样被大量使用。
特雷弗·博伊德·史密斯

重要提示:Janovetz代码是LGPL,因此您可以在商业环境中使用它。
特雷弗·博伊德·史密斯

答案中的第一个链接已断开,因此这里是指向使用相同实现的库的链接。
Machta 2014年

11

GNU Octave中有Parks-McClellan的开源实现(也称为Remez交换算法),这是类似MATLAB的环境的免费软件实现。该函数称为“ remez”,包含在Octave-Forge中托管的“ signal”包中。如果下载了该软件包,则会找到“ remez.cc”,该算法的C ++实现。

关于Octave的一件好事是,它几乎与MATLAB代码兼容,因此您可以根据需要轻松地移植代码以在其中使用。这是深入了解MATLAB中以MEX形式提供的算法实现的好方法。


“ Parks-McClellan算法是Remez算法或Remez交换算法的变体,它的变化是专门为FIR滤波器设计的,已成为FIR滤波器设计的标准方法。” 同样在SciPy中:docs.scipy.org/doc/scipy/reference/genic/…– endolith
2011年


2

这是C语言中Parks McClellan算法的另一个来源。此代码与上述SciPy代码的不同之处在于,它删除了原始的69个goto语句中的61个(SciPy代码仍然具有约37个goto语句)。它还将代码固定在可能发生被零除的3个位置,并且还具有一些范围检查频带边缘值的附加代码。

http://www.iowahills.com/A7ExampleCodePage.html


1

也许您已经知道这一点,但是如果您有matlab,则可以使用matlab编码器,并创建一个使用要检查的功能的简单函数。然后运行它,并查看创建的C代码。我尝试使用FFT和QR分解,虽然有点混乱,但可以理解。


1

这是完成“核心”补救算法的实际Matlab版本的论文。“遵循Remez多重交换算法的原始思想的基于MATLAB的最佳多频带FIR滤波器设计程序” -2011 IEEE电路与系统国际研讨会(ISCAS)-作者(Ahsan,萨拉马基)

本文在解释基本算法方面做得很好。本文的目的是避免使用原始的Fortran代码-该代码不能很好地解释该算法,通常只能直接翻译成其他各种语言。

我将评论一件事。该算法的核心思想之一是拟合曲线,然后找到极值点。通常,使用拉格朗日插值法来解释此想法,但是拉格朗日插值法具有较差的数值属性。在原始算法中,使用Lagrange插值的重心实现-避免了许多相关的Lagrangian插值陷阱。因此,如果您想完全理解代码,则可能需要查找重心插值。


查看该文件-它是Parks-McClellan代码的修改版本。它仍然基于Remez交换算法,但是它往往具有更好的性能,并且允许您设计比从PM算法(或Matlab的实现)获得的滤波器更长的滤波器。
大卫

1

注意Matlab的firpm和Scipy.signal的补救措施之间的差异。例如,这两个语句是等效的:

% Matlab
firpm(10,[.2 .8],[1 1],'Hilbert')
# Python
from scipy.signal import remez

remez(11, [0.1, 0.4], [1], type='hilbert')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.