Skip to content

Conversation

@gruberchr
Copy link
Contributor

This is a proposal for fixing analog filter design (see bug #341). For this frequency normalization has been shifted to function digitalfilter(). And function analogfilter() doesn't require any sampling frequency now. All affected tests have been adapted by simply providing sampling frequency to function digitalfilter() instead of FilterType construction.

Documentation has not been changed yet, I'll do this next. Additionally some new tests should be appended for analog filter design, I guess.

Any remarks?

…er design

When designing a digital filter using function digitalfilter() the
sampling frequency is not passed to the FilterType definition anymore,
but to function digitalfilter(). That means frequency normalization is
not done during construction of FilterType anymore, but during filter
design inside function digitalfilter().

For this the sampling frequency has to be passed to the internal
functions prewarp(), firprototype() and scalefactor() as well.

The intended side effect is, that an analog filter can now be designed
by specifying analog frequencies directly without any frequency
normalization and without a sampling frequency.
@martinholters
Copy link
Member

Haven't reviewed the code in detail, but conceptually, this makes sense to be. Downside is that this would be breaking. We're still at an 0.x version number to be able to do precisely such changes, but we should still be careful. Are we otherwise happy with the filter design API or should we take the opportunity and do more redesign work?

@gruberchr
Copy link
Contributor Author

Are we otherwise happy with the filter design API or should we take the opportunity and do more redesign work?

I was also thinking about introducing domain specifiers :s and :z for the FilterType as well as it is already the case for the FilterCoefficients type. This way it could be distinguished between "unnormalized" (:s domain) and "normalized" (:z domain) FilterTypes. This would extend the flexibility for the user. One could decide to do frequency normalization during filter type specification already, as it is currently implemented, or doing frequency normalization during filter design, as proposed in this PR. Analog filter design would still be possible by using an unnormalized FilterType.

Christian Gruber added 2 commits February 10, 2022 11:00
Extend test case 'digital IIR' to test digital filter design with
non-normalized frequency values in the filter response definition and
specified sampling frequency.
@gruberchr
Copy link
Contributor Author

I had a look on the test cases in test/filter_design.jl now. I think the test cases should be extended as follows:

  1. Test cases for function analogfilter() with non-normalized frequency values in the filter response definition.
  2. Test cases for function digitalfilter() with non-normalized frequency values in the filter response definition and a sampling frequency specification.

I can find the following test cases for analog filter design:

  • freq. scaling (By the way, is this a typo? Should be lowpass I guess)
  • highpass
  • bandpass
  • bandstop

Should these test cases be changed to use arbitrary (non-normalized) frequency values or should we add new test cases?

All test cases are based on a MATLAB reference implementation. I don't have MATLAB, but could use Octave instead. Accuracy seems to be sufficient as well. Is Octave a problem?

For digital filter design I can find the following test case:

  • digital IIR

We could use the existing reference implementation and simply add some code lines to design the same digital filter using non-normalized frequency values. I've provided a proposal (0d05b11). Or should we add new test cases?

What do you think?

@gruberchr
Copy link
Contributor Author

Off topic: On my PC the test case TF to ZPK fails. There seems to be an accuracy problem. If I set relerr=4 in the function call zpkfilter_accuracy() the test runs successfully.

Does anybody know, what could be the problem? I don't really understand function zpkfilter_accuracy() at the moment.

@gruberchr
Copy link
Contributor Author

@martinholters Did you have the time to take a look at the code and the tests?

@martinholters
Copy link
Member

Makes sense to me and from an admittedly not-yet-too-close look at the code and tests, everything looks good, but we should probably add tests for what this is solving: analog filters with frequencies outside the "normalized" range.

@gruberchr
Copy link
Contributor Author

gruberchr commented Jul 6, 2022

I updated analog filter design tests now using non-normalized frequency values in the filter response definition.

Unfortunately Octave's elliptic filter design function ellip() generates different filter coefficients than Julia when designing a 20th order analog filter. Maybe this is a bug in Octave's signal package. For instance when I plot a frequency response from Octave's filter coefficients, the stop band attenuation doesn't seem to be as expected (20 dB). But I couldn't find any related issue in Octave's bug tracker. Therefore I changed the test to design a Chebyshev type II filter instead of an elliptic filter.

Additionally I fixed the organization and naming of the analog filter design test set.

gruberchr added 4 commits July 7, 2022 00:11
This is an amendment to commit 54bc9d5
where test sets have been introduced. The code following the current
test set "freq. scaling" is actually a "lowpass" test. It seems that a
corresponding comment on this low pass filter test was already missing
before this commit. And the comment "Freqency scaling" seems to be meant
for all four following test sets "lowpass", "highpass", "bandpass" and
"bandstop".
The new test set name relates to the name of the tested function
`analogfilter()` and not to what it is doing.
In the current version the function `analogfilter()` already generates
a `ZeroPoleGain` filter representation. It seems, that in earlier
versions this wasn't the case (see e.g. commit
7fd2102)
For providing new test data I had no MATLAB available and therefore
switched to Octave. Unfortunatelly Octave's elliptic filter design
function `ellip()` generates different filter coefficients than Julia
when designing a 20th order analog filter. Maybe this is a bug in
Octave's 'signal' package. I changed the test to design a Chebyshev
type II filter instead.
@gruberchr gruberchr force-pushed the analog_filter_design_#341 branch from e0f2141 to a899b41 Compare July 6, 2022 22:13
@gruberchr
Copy link
Contributor Author

@martinholters Any progress on this MR?

@codecov
Copy link

codecov bot commented Feb 5, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (2637592) 97.46% compared to head (537cc75) 97.46%.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #458   +/-   ##
=======================================
  Coverage   97.46%   97.46%           
=======================================
  Files          18       18           
  Lines        3080     3080           
=======================================
  Hits         3002     3002           
  Misses         78       78           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ViralBShah
Copy link
Contributor

I know this was reviewed a long time ago - but wondering if it is good to pull in and merge?

Copy link
Member

@martinholters martinholters left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, let's go ahead with this.
As it is a breaking change, we might want to bump the version number to 0.8.0-dev as part of this PR so that we don't forget. Opinions? @ViralBShah?

@ViralBShah
Copy link
Contributor

Yes, makes sense to go to 0.8-dev.

@martinholters
Copy link
Member

Now that #532 bumped the version to 0.8, let's try this.

@martinholters martinholters merged commit 3ad3c1c into JuliaDSP:master Feb 7, 2024
@martinholters
Copy link
Member

Thanks @gruberchr and sorry for the long delay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants