Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: signal.cheby1: wrong gain and cut-off frequency #20571

Open
rcasperson opened this issue Apr 24, 2024 · 5 comments
Open

BUG: signal.cheby1: wrong gain and cut-off frequency #20571

rcasperson opened this issue Apr 24, 2024 · 5 comments
Labels
defect A clear bug or issue that prevents SciPy from being installed or used as expected scipy.signal

Comments

@rcasperson
Copy link

Describe your issue.

At a low pass |G(0)| shall be 0 dB and and |G(fcutoff)| shall be -3 dB according to the definition of the characteristics of a low pass filter.
At scipy.signal.cheby1 |G(0)| is either 0 dB or -rp depending on the order of the filter and |G(fcutoff)| is -rp.

The same issue occurs at cheby1 high pass and band pass filters.

Reproducing Code Example

import numpy as np
from scipy.signal import cheby1,freqs
f = np.arange(0,10E3,10)
b,a = cheby1(4,5,f[100],'lowpass',True)
_,G = freqs(b,a,f)
for i in [0,100]: print(f"|G({f[i]:4.0f} Hz)| = {20*np.log10(np.abs(G[i])):2.0f} dB")

Error message

No error message but wrong values calculated.

SciPy/NumPy/Python version and system information

1.11.4 1.26.4 sys.version_info(major=3, minor=11, micro=7, releaselevel='final', serial=0)
lapack_armpl_info:
  NOT AVAILABLE
lapack_mkl_info:
    libraries = ['mkl_rt']
    library_dirs = ['C:/Users/rcaspers/AppData/Local/anaconda3\\Library\\lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['C:/Users/rcaspers/AppData/Local/anaconda3\\Library\\include']
lapack_opt_info:
    libraries = ['mkl_rt']
    library_dirs = ['C:/Users/rcaspers/AppData/Local/anaconda3\\Library\\lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['C:/Users/rcaspers/AppData/Local/anaconda3\\Library\\include']
blas_armpl_info:
  NOT AVAILABLE
blas_mkl_info:
    libraries = ['mkl_rt']
    library_dirs = ['C:/Users/rcaspers/AppData/Local/anaconda3\\Library\\lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['C:/Users/rcaspers/AppData/Local/anaconda3\\Library\\include']
blas_opt_info:
    libraries = ['mkl_rt']
    library_dirs = ['C:/Users/rcaspers/AppData/Local/anaconda3\\Library\\lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['C:/Users/rcaspers/AppData/Local/anaconda3\\Library\\include']
Supported SIMD extensions in this NumPy install:
    baseline = SSE,SSE2,SSE3
    found = SSSE3,SSE41,POPCNT,SSE42,AVX,F16C,FMA3,AVX2
    not found = AVX512F,AVX512CD,AVX512_SKX,AVX512_CLX,AVX512_CNL,AVX512_ICL
@rcasperson rcasperson added the defect A clear bug or issue that prevents SciPy from being installed or used as expected label Apr 24, 2024
@j-bowhay
Copy link
Member

@DietBru maybe you would be interested in taking a look?

@lucascolley lucascolley changed the title scipy.signal.cheby1 wrong gain and cut-off frequency BUG: signal.cheby1: wrong gain and cut-off frequency Apr 24, 2024
@DietBru
Copy link
Contributor

DietBru commented Apr 24, 2024

Depending on the application, the way low-pass filters are characterized varies quite a bit and is often inconsistent across the literature. The parametrization of cheby1() adheres to the established conventions (as described in Wikipedia): The allowed ripples are confined to the interval [-rp, 0] dB and the edge frequency of the pass-band is defined as the crossing of the level -rp dB. As documented even order filters have a gain of -rp dB and odd orders have unity gain.

Wikipedia also provides a formula relating the 3 dB cut-off frequency f_c to Wp:

N = 5  # order of filter
rp = 5  # width of ripple band in dB
eps = np.sqrt(10**(rp/10) - 1)
s = np.cosh(1 / np.cosh(1/eps) / N)
b, a = cheby1(N, rp, f_c * s, 'lowpass', analog=True)

To obtain unity gain at 0 Hz for even order filters, just multiply the output b by 10**(rp/20) or alternatively a by 10**(-rp/20).

For practical purposes, I can recommend the nice graphical filter design tool pyFDA which allows interactive twiddling of filter parameters to a required specification.

My opinion on modifying cheby1():

  • I am -1 on adding an option to scale to unity gain at 0 Hz. IMO that use case is too specific and can be easily done by adding an additional line.
  • I am -0 on adding an option for specifying the 3 dB cut-off frequencies instead of rp. In my experience filter design is usually a bit of twiddling where the cut-off frequency is just one constraint which needs to be balanced among many others.

@rcasperson
Copy link
Author

@DietBru: Thanks for your fast reply.

I think, one ore two additional options like cutoff="3dB" and gain="unity" would be nice.

Your explanation and sample code should be added to the API reference at https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.cheby1.html. Than additional options are not necessary.

@lucascolley
Copy link
Member

Your explanation and sample code should be added to the API reference

@rcasperson would you be interested in making a docs PR for this, for @DietBru to review?

@rcasperson
Copy link
Author

rcasperson commented Apr 25, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
defect A clear bug or issue that prevents SciPy from being installed or used as expected scipy.signal
Projects
None yet
Development

No branches or pull requests

5 participants
@DietBru @rcasperson @lucascolley @j-bowhay and others