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

问题:我现在可以解决信号处理问题,但仅适用于非常特殊的单个样本目标:我希望能够从C代码或其他某种语言调用$ \ tt firpm()$,并使我的信号处理代码更通用。我找不到firpm()的开源实现!

在哪里可以找到Parks-McClellan最佳FIR滤波器设计算法的开源实现(在MATLAB中也称为$ \ tt firpm()$) ?


PS我知道我可以使用开窗或其他方式来设计过滤器...随意在评论中提及这些过滤器。但是,这个问题的重点不是要问“还有什么其他的滤波器设计技术?”关键是要找到非常有用的$ \ tt firpm()$ ...或类似的东西的开源实现。
P.P.S.这个问题的目的之一是通过先看代码来学习Parks-McClellan算法的工作原理,然后计划阅读一些背景知识。


评论

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

最高优先级是我想查看源代码(最好不要使用fortran,这样我就不必to目结舌了)。我不会限制它必须是免费的(也许有某种开源但非免费的源代码)。

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

@TrevorBoydSmith由于您只想看源代码,您是否尝试过在MATLAB中键入firpm.m?那将向您展示MATLAB函数的实现。

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

#1 楼

这是Remez交换算法的LGPL版本。倍频程代码似乎是从中得出的。它是从Wikipedia页面上的Parks McClellan页面上链接的。 svn changelog可获取remez.cc文件中有关错误修正或加速的任何信息。

评论


$ \ begingroup $
我同意在项目中使用Janovetz代码会更容易,因为它是C语言。我也绝对同意检查八度实现的更改日志非常聪明。
$ \ endgroup $
–特雷弗·博伊德·史密斯
2011年9月13日下午16:25

$ \ begingroup $
Janovetz代码IMO可能是第一稿或第二稿...但是没有像Octave代码那样被大量使用。
$ \ endgroup $
–特雷弗·博伊德·史密斯
2011年9月13日下午16:25

$ \ begingroup $
非常重要的注意:Janovetz代码是LGPL,因此您可以在商业环境中使用它。
$ \ endgroup $
–特雷弗·博伊德·史密斯
2011年9月13日下午16:26

$ \ begingroup $
答案的第一个链接已断开,因此这里是指向使用相同实现的库的链接。
$ \ endgroup $
–马赫塔
2014年2月17日在16:12

#2 楼

GNU Octave中有一个Parks-McClellan的开源实现(也称为Remez交换算法),这是类似MATLAB的环境的免费软件实现。该函数称为“ remez”,包含在Octave-Forge的“ signal”包中。如果下载了该软件包,则会发现该算法的C ++实现“ remez.cc”。如果您愿意,可以轻松地将代码移植到那里使用。这是深入了解MATLAB中以MEX形式提供的算法实现的好方法。

评论


$ \ begingroup $
“ Parks-McClellan算法是Remez算法或Remez交换算法的变体,它的变化是专门为FIR滤波器设计的,已成为FIR滤波器设计的标准方法。”同样在SciPy中:docs.scipy.org/doc/scipy/reference/generated/…
$ \ endgroup $
– Endolith
2011年8月22日14:35

#3 楼

可以在Python的scipy.signal.remez中找到一个方便的版本。很好,如果使用numpy / scipy。

评论


$ \ begingroup $
C源​​代码似乎在这里:github.com/scipy/scipy/blob/master/scipy/signal / ...
$ \ endgroup $
–戴夫C
13年2月11日下午5:00



#4 楼

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

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

#5 楼

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

#6 楼

这是一篇完成Matlab版本的“核心” remez算法的论文。
“遵循Remez多重交换算法的初衷,基于MATLAB的最佳多频带FIR滤波器设计程序” -2011 IEEE国际电路研讨会与系统(ISCAS)-作者(萨拉曼基阿桑(Ahsan))

本文在解释基本算法方面做得很好。本文的目的是避免使用原始的Fortran代码-该代码不能很好地解释算法,通常只能直接将其翻译成其他各种语言。该算法的核心思想之一是拟合曲线,然后找到极值点。通常,用拉格朗日插值法来解释这个想法,但是拉格朗日插值法具有较差的数值特性。在原始算法中,使用Lagrange插值的重心实现-避免了许多相关的Lagrangian插值陷阱。因此,如果您想完全理解代码,则可能需要查找重心插值。

评论


$ \ begingroup $
查看本文-它是Parks-McClellan代码的修改版本。它仍然基于Remez交换算法,但是它往往具有更好的性能,并且允许您设计比从PM算法(或Matlab的实现)获得的过滤器更长的过滤器。
$ \ endgroup $
–大卫
2014年1月23日下午13:42

#7 楼

注意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')