sfilip / firpm

A scalable C++ implementation of the Parks-McClellan algorithm for designing FIR filters

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

firpmRS fails in some cases where firpm succeeds

jlwehle opened this issue · comments

My understanding is that ideally firpmRS should succeed for any
specification where firpm succeeded.

Attach is a test case based on a CIC compensation filter where
firpm succeeds and firpmRS fails. The code is built like so:

clang++ -I/usr/local/include -O2 -march=amdfam10 \
  -o firpm_tc firpm_tc.cxx -L/usr/local/lib -lfirpm

and running it results in:

  START Parks-McClellan with uniform initialization
  Final delta = 0.04104066019515401947
  Iteration count = 12
  FINISH Parks-McClellan with uniform initialization
  START Parks-McClellan with reference scaling
  The exchange algorithm did not converge.
  TRIGGER: Not enough alternating extrema!
  POSSIBLE CAUSE: Nmax too small
  Failed to do reference scaling since x is empty!
[firpm_tc.cxx.txt](https://github.com/sfilip/firpm/files/3822819/firpm_tc.cxx.txt)


This is using firpm_ld.

Thanks for sharing this example! firpmRS should work in most cases where firpm works, provided the filter length is not too small (i.e., not close to the number of bands). It is not guaranteed though that it will be faster (although in many cases it should). firpmRS is expected to work very well for really long filters. firpmAFP should work better for smaller length filters, but I only implemented it so far in firpm_d.

I'm currently working on refactoring the code and solving issues that I find (in the fix-refactor branch). So far, I started with firpm_d. I added to the tests the CIC filter you provided on that branch. On the two machines that I have access to (Mac OS X 10.14.6 with Apple clang 11.0.0 and Manjaro Linux with g++ 9.2.0), both firpm and firpmRS now succeed. firpmAFP also works.

The results on Mac:

START Parks-McClellan with uniform initialization
Final Delta     = 0.040972936487531606831
Iteration count = 10
FINISH Parks-McClellan with uniform initialization
START Parks-McClellan with reference scaling
Final Delta     = 0.04104287175555475925
Iteration count = 16
FINISH Parks-McClellan with reference scaling
START Parks-McClellan with AFP
Final Delta     = 0.041180126818751494611
Iteration count = 8
FINISH Parks-McClellan with AFP
Iteration count reduction for final filter  RS: -0.60000000000000008882
Iteration count reduction for final filter AFP: 0.19999999999999995559

The results on Linux:

START Parks-McClellan with uniform initialization
Final Delta     = 0.040972936487531606831
Iteration count = 10
FINISH Parks-McClellan with uniform initialization
START Parks-McClellan with reference scaling
Final Delta     = 0.040694242962436455446
Iteration count = 16
FINISH Parks-McClellan with reference scaling
START Parks-McClellan with AFP
Final Delta     = 0.041180126818751494611
Iteration count = 8
FINISH Parks-McClellan with AFP
Iteration count reduction for final filter  RS: -0.60000000000000008882
Iteration count reduction for final filter AFP: 0.19999999999999995559

Hope to find time to finish this some time next week. I still have to revise the code for type III and IV FIR filters if firpm_d and take care of the complete refactoring of firpm_ld and firpm_mp.

Thanks.