-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Closed
Labels
defectA clear bug or issue that prevents SciPy from being installed or used as expectedA clear bug or issue that prevents SciPy from being installed or used as expectedscipy.signal
Milestone
Description
Describe your issue.
I was looking at resonance filter implementations in scipy.signal
, specifically iirpeak
, iirnotch
and iircomb
and I noticed that part of the formulas for gain computation could mathematically just simplify to 1.
Formulas are correct (double checked from the reference reported in the docs) however, this could lead to a small rounding error of the coefficients due to the extra computations.
Lines where this computations are performed can be found here at lines: 5154
, 5157
, 5348
.
Reproducing Code Example
import numpy as np
def notch_peak_rounding_error(w0, Q, ftype, fs=2.0):
# Guarantee that the inputs are floats
w0 = float(w0)
Q = float(Q)
w0 = 2*w0/fs
# Checks if w0 is within the range
if w0 > 1.0 or w0 < 0.0:
raise ValueError("w0 should be such that 0 < w0 < 1")
# Get bandwidth
bw = w0/Q
# Normalize inputs
bw = bw*np.pi
w0 = w0*np.pi
# Compute -3dB attenuation
gb = 1/np.sqrt(2)
if ftype == "notch":
# Compute beta: formula 11.3.4 (p.575) from reference [1]
beta = (np.sqrt(1.0-gb**2.0)/gb)*np.tan(bw/2.0)
elif ftype == "peak":
# Compute beta: formula 11.3.19 (p.579) from reference [1]
beta = (gb/np.sqrt(1.0-gb**2.0))*np.tan(bw/2.0)
else:
raise ValueError("Unknown ftype.")
# This constants just simplify to 1:
# (np.sqrt(1.0-gb**2.0)/gb) = 1
# (gb/np.sqrt(1.0-gb**2.0)) = 1
beta2 = 1.0 * np.tan(bw/2.0)
return np.abs(beta - beta2)
def iircomb_rounding_error(w0, Q, ftype='notch', fs=2.0, *, pass_zero=False):
# Convert w0, Q, and fs to float
w0 = float(w0)
Q = float(Q)
# Check for invalid cutoff frequency or filter type
ftype = ftype.lower()
if not 0 < w0 < fs / 2:
raise ValueError(f"w0 must be between 0 and {fs / 2}"
f" (nyquist), but given {w0}.")
if ftype not in ('notch', 'peak'):
raise ValueError('ftype must be either notch or peak.')
# Compute the order of the filter
N = round(fs / w0)
# Check for cutoff frequency divisibility
if abs(w0 - fs/N)/fs > 1e-14:
raise ValueError('fs must be divisible by w0.')
# Compute frequency in radians and filter bandwidth
# Eq. 11.3.1 (p. 574) from reference [1]
w0 = (2 * np.pi * w0) / fs
w_delta = w0 / Q
# Define base gain values depending on notch or peak filter
# Compute -3dB attenuation
# Eqs. 11.4.1 and 11.4.2 (p. 582) from reference [1]
if ftype == 'notch':
G0, G = 1, 0
elif ftype == 'peak':
G0, G = 0, 1
GB = 1 / np.sqrt(2)
# Compute beta
# Eq. 11.5.3 (p. 591) from reference [1]
beta = np.sqrt((GB**2 - G0**2) / (G**2 - GB**2)) * np.tan(N * w_delta / 4)
# This constant just simplify to 1:
# np.sqrt((GB**2 - G0**2) / (G**2 - GB**2)) = 1
beta2 = 1.0 * np.tan(N * w_delta / 4)
return np.abs(beta - beta2)
print("IIR peak filter rounding error:", notch_peak_rounding_error(50, 10, "peak", 500))
print("IIR notch filter rounding error:", notch_peak_rounding_error(50, 10, "notch", 500))
print("IIR comb peak filter rounding error:", iircomb_rounding_error(50, 10, "peak", 500))
print("IIR comb notch filter rounding error:", iircomb_rounding_error(50, 10, "notch", 500))
Error message
Output from code snippet:
IIR peak filter rounding error: 6.938893903907228e-18
IIR notch filter rounding error: 6.938893903907228e-18
IIR comb peak filter rounding error: 2.7755575615628914e-17
IIR comb notch filter rounding error: 2.7755575615628914e-17
SciPy/NumPy/Python version and system information
1.10.1 1.23.0 sys.version_info(major=3, minor=9, micro=19, releaselevel='final', serial=0)
Build Dependencies:
blas:
detection method: pkgconfig
found: true
include directory: c:/opt/openblas/if_32/64/include
lib directory: c:/opt/openblas/if_32/64/lib
name: openblas
openblas configuration: USE_64BITINT= DYNAMIC_ARCH=1 DYNAMIC_OLDER= NO_CBLAS=
NO_LAPACK= NO_LAPACKE= NO_AFFINITY=1 USE_OPENMP= PRESCOTT MAX_THREADS=4
pc file directory: c:/opt/openblas/if_32/64/lib/pkgconfig
version: 0.3.18
lapack:
detection method: pkgconfig
found: true
include directory: c:/opt/openblas/if_32/64/include
lib directory: c:/opt/openblas/if_32/64/lib
name: openblas
NO_LAPACK= NO_LAPACKE= NO_AFFINITY=1 USE_OPENMP= PRESCOTT MAX_THREADS=4
pc file directory: c:/opt/openblas/if_32/64/lib/pkgconfig
version: 0.3.18
Compilers:
c:
commands: cc
linker: ld.bfd
name: gcc
version: 10.3.0
c++:
commands: c++
linker: ld.bfd
name: gcc
version: 10.3.0
cython:
commands: cython
linker: cython
name: cython
version: 0.29.33
fortran:
commands: gfortran
linker: ld.bfd
name: gcc
version: 10.3.0
pythran:
include directory: C:\Users\runneradmin\AppData\Local\Temp\pip-build-env-u63ta2f1\overlay\Lib\site-packages\py
thran
version: 0.12.1
Machine Information:
build:
cpu: x86_64
endian: little
family: x86_64
system: windows
cross-compiled: false
host:
cpu: x86_64
endian: little
family: x86_64
system: windows
Python Information:
path: C:\Users\runneradmin\AppData\Local\Temp\cibw-run-a1px0t3e\cp39-win_amd64\build\venv\Scripts\python.exe
version: '3.9'
Metadata
Metadata
Assignees
Labels
defectA clear bug or issue that prevents SciPy from being installed or used as expectedA clear bug or issue that prevents SciPy from being installed or used as expectedscipy.signal