Skip to content

Commit 20e8af0

Browse files
committed
refactor function name and inputs
1 parent 6b9de92 commit 20e8af0

File tree

4 files changed

+43
-81
lines changed

4 files changed

+43
-81
lines changed

scipy/signal/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
-- defined as pass and stop bands.
8787
firwin2 -- Windowed FIR filter design, with arbitrary frequency
8888
-- response.
89-
fwind1 -- Windowed FIR filter design, with frequency response for
89+
firwin_2d -- Windowed FIR filter design, with frequency response for
9090
-- 2D using 1D design.
9191
freqs -- Analog filter frequency response from TF coefficients.
9292
freqs_zpk -- Analog filter frequency response from ZPK coefficients.

scipy/signal/_fir_filter_design.py

Lines changed: 27 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717

1818
__all__ = ['kaiser_beta', 'kaiser_atten', 'kaiserord',
19-
'firwin', 'firwin2', 'fwind1', 'remez', 'firls', 'minimum_phase']
19+
'firwin', 'firwin2', 'firwin_2d', 'remez', 'firls', 'minimum_phase']
2020

2121

2222
# Some notes on function parameters:
@@ -1283,15 +1283,15 @@ def minimum_phase(h: np.ndarray,
12831283
return h_minimum[:n_out]
12841284

12851285

1286-
def fwind1(hsize, window, *, fc=None, fs=2, circular=False):
1286+
def firwin_2d(hsize, window, *, fc=None, fs=2, circular=False, pass_zero=True, scale=True):
12871287
"""
12881288
2D FIR filter design using the window method.
12891289
12901290
This function computes the coefficients of a 2D finite impulse response
12911291
filter. The filter is separable with linear phase; it will be designed
12921292
as a product of two 1D filters with dimensions defined by `hsize`.
12931293
Additionally, it can create approximately circularly symmetric 2-D windows.
1294-
1294+
12951295
Parameters
12961296
----------
12971297
hsize : tuple or list of length 2
@@ -1302,79 +1302,41 @@ def fwind1(hsize, window, *, fc=None, fs=2, circular=False):
13021302
Desired window to use for each 1D filter or a single window type
13031303
for creating circularly symmetric 2-D windows. Each element should be
13041304
a string or tuple of string and parameter values. See
1305-
'~scipy.signal.get_window' for a list of windows and required
1305+
`~scipy.signal.get_window` for a list of windows and required
13061306
parameters.
13071307
fc : float or 1-D array_like, optional
1308-
Cutoff frequency of filter (expressed in the same units as `fs`).
1309-
Required if `circular` is False.
1308+
Cutoff frequency of the filter in the same units as `fs`. This defines
1309+
the frequency at which the filter's gain drops to approximately -6 dB
1310+
(half power) in a low-pass or high-pass filter. For multi-band filters,
1311+
`fc` can be an array of cutoff frequencies (i.e., band edges) in the
1312+
range [0, fs/2], with each band specified in pairs. Required if
1313+
`circular` is False.
13101314
fs : float, optional
13111315
The sampling frequency of the signal. Default is 2.
13121316
circular : bool, optional
13131317
Whether to create a circularly symmetric 2-D window. Default is False.
1318+
pass_zero : {True, False, 'bandpass', 'lowpass', 'highpass', 'bandstop'}, optional
1319+
If True, the gain at the frequency 0 (i.e., the "DC gain") is 1.
1320+
If False, the DC gain is 0. Can also be a string argument for the
1321+
desired filter type (equivalent to ``btype`` in IIR design functions).
1322+
1323+
.. versionadded:: 1.3.0
1324+
Support for string arguments.
1325+
scale : bool, optional
1326+
Set to True to scale the coefficients so that the frequency
1327+
response is exactly unity at a certain frequency.
1328+
That frequency is either:
1329+
1330+
- 0 (DC) if the first passband starts at 0 (i.e. pass_zero
1331+
is True)
1332+
- `fs/2` (the Nyquist frequency) if the first passband ends at
1333+
`fs/2` (i.e the filter is a single band highpass filter);
1334+
center of first passband otherwise
13141335
13151336
Returns
13161337
-------
13171338
filter_2d : (hsize[0], hsize[1]) ndarray
13181339
Coefficients of 2D FIR filter.
1319-
1320-
Raises
1321-
------
1322-
ValueError
1323-
If `hsize` and `window` are not 2-element tuples or lists.
1324-
If `cutoff` is None when `circular` is True.
1325-
If `cutoff` is outside the range [0, fs / 2] and `circular` is False.
1326-
If any of the elements in `window` are not recognized.
1327-
RuntimeError
1328-
If `firwin` fails to converge when designing the filter.
1329-
1330-
See Also
1331-
--------
1332-
scipy.signal.firwin, scipy.signal.get_window
1333-
1334-
Examples
1335-
--------
1336-
Generate a 5x5 low-pass filter with cutoff frequency 0.1.
1337-
1338-
>>> import numpy as np
1339-
>>> from scipy.signal import get_window
1340-
>>> from scipy.signal import fwind1
1341-
>>> hsize = (5, 5)
1342-
>>> window = (("kaiser", 5.0), ("kaiser", 5.0))
1343-
>>> fc = 0.1
1344-
>>> filter_2d = fwind1(hsize, window, fc=fc)
1345-
>>> filter_2d
1346-
array([[0.00025366, 0.00401662, 0.00738617, 0.00401662, 0.00025366],
1347-
[0.00401662, 0.06360159, 0.11695714, 0.06360159, 0.00401662],
1348-
[0.00738617, 0.11695714, 0.21507283, 0.11695714, 0.00738617],
1349-
[0.00401662, 0.06360159, 0.11695714, 0.06360159, 0.00401662],
1350-
[0.00025366, 0.00401662, 0.00738617, 0.00401662, 0.00025366]])
1351-
1352-
Generate a circularly symmetric 5x5 low-pass filter with Hamming window.
1353-
1354-
>>> filter_2d = fwind1((5, 5), 'hamming', fc=fc, circular=True)
1355-
>>> filter_2d
1356-
array([[-0.00020354, -0.00020354, -0.00020354, -0.00020354, -0.00020354],
1357-
[-0.00020354, 0.01506844, 0.09907658, 0.01506844, -0.00020354],
1358-
[-0.00020354, 0.09907658, -0.00020354, 0.09907658, -0.00020354],
1359-
[-0.00020354, 0.01506844, 0.09907658, 0.01506844, -0.00020354],
1360-
[-0.00020354, -0.00020354, -0.00020354, -0.00020354, -0.00020354]])
1361-
1362-
Plotting the generated 2D filters (optional).
1363-
1364-
>>> import matplotlib.pyplot as plt
1365-
>>> hsize, fc = (50, 50), 0.05
1366-
>>> window = (("kaiser", 5.0), ("kaiser", 5.0))
1367-
>>> filter0_2d = fwind1(hsize, window, fc=fc)
1368-
>>> filter1_2d = fwind1((50, 50), 'hamming', fc=fc, circular=True)
1369-
...
1370-
>>> fg, (ax0, ax1) = plt.subplots(1, 2, tight_layout=True, figsize=(6.5, 3.5))
1371-
>>> ax0.set_title("Product of 2 Windows")
1372-
>>> im0 = ax0.imshow(filter0_2d, cmap='viridis', origin='lower', aspect='equal')
1373-
>>> fg.colorbar(im0, ax=ax0, shrink=0.7)
1374-
>>> ax1.set_title("Circular Window")
1375-
>>> im1 = ax1.imshow(filter1_2d, cmap='plasma', origin='lower', aspect='equal')
1376-
>>> fg.colorbar(im1, ax=ax1, shrink=0.7)
1377-
>>> plt.show()
13781340
"""
13791341
if len(hsize) != 2:
13801342
raise ValueError("hsize must be a 2-element tuple or list")

scipy/signal/fir_filter_design.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
__all__ = [ # noqa: F822
88
'kaiser_beta', 'kaiser_atten', 'kaiserord',
99
'firwin', 'firwin2', 'remez', 'firls', 'minimum_phase',
10-
'fwind1',
10+
'firwin_2d',
1111
]
1212

1313

scipy/signal/tests/test_fir_filter_design.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from scipy.signal import kaiser_beta, kaiser_atten, kaiserord, \
1313
firwin, firwin2, freqz, remez, firls, minimum_phase, \
1414
convolve2d
15-
from scipy.signal._fir_filter_design import fwind1
15+
from scipy.signal._fir_filter_design import firwin_2d
1616

1717
def test_kaiser_beta():
1818
b = kaiser_beta(58.7)
@@ -654,36 +654,36 @@ def test_hilbert(self):
654654
xp_assert_close(m, k, rtol=2e-3)
655655

656656

657-
class TestFwind1:
657+
class Testfirwin_2d:
658658
def test_invalid_args(self):
659659
with pytest.raises(ValueError,
660660
match="hsize must be a 2-element tuple or list"):
661-
fwind1((50,), window=(("kaiser", 5.0), "boxcar"), fc=0.4)
661+
firwin_2d((50,), window=(("kaiser", 5.0), "boxcar"), fc=0.4)
662662

663663
with pytest.raises(ValueError,
664664
match="window must be a 2-element tuple or list"):
665-
fwind1((51, 51), window=("hamming",), fc=0.5)
665+
firwin_2d((51, 51), window=("hamming",), fc=0.5)
666666

667667
with pytest.raises(ValueError,
668668
match="window must be a 2-element tuple or list"):
669-
fwind1((51, 51), window="invalid_window", fc=0.5)
669+
firwin_2d((51, 51), window="invalid_window", fc=0.5)
670670

671671
def test_filter_design(self):
672672
hsize = (51, 51)
673673
window = (("kaiser", 8.0), ("kaiser", 8.0))
674674
fc = 0.4
675-
taps_kaiser = fwind1(hsize, window, fc=fc)
675+
taps_kaiser = firwin_2d(hsize, window, fc=fc)
676676
assert taps_kaiser.shape == (51, 51)
677677

678678
window = ("hamming", "hamming")
679-
taps_hamming = fwind1(hsize, window, fc=fc)
679+
taps_hamming = firwin_2d(hsize, window, fc=fc)
680680
assert taps_hamming.shape == (51, 51)
681681

682682
def test_impulse_response(self):
683683
hsize = (31, 31)
684684
window = ("hamming", "hamming")
685685
fc = 0.4
686-
taps = fwind1(hsize, window, fc=fc)
686+
taps = firwin_2d(hsize, window, fc=fc)
687687

688688
impulse = np.zeros((63, 63))
689689
impulse[31, 31] = 1
@@ -697,7 +697,7 @@ def test_frequency_response(self):
697697
hsize = (31, 31)
698698
window = ("hamming", "hamming")
699699
fc = 0.4
700-
taps = fwind1(hsize, window, fc=fc)
700+
taps = firwin_2d(hsize, window, fc=fc)
701701

702702
freq_response = fftshift(fft2(taps))
703703

@@ -711,13 +711,13 @@ def test_symmetry(self):
711711
hsize = (51, 51)
712712
window = ("hamming", "hamming")
713713
fc = 0.4
714-
taps = fwind1(hsize, window, fc=fc)
714+
taps = firwin_2d(hsize, window, fc=fc)
715715
xp_assert_close(taps, np.flip(taps), rtol=1e-5)
716716

717717
def test_circular_symmetry(self):
718718
hsize = (51, 51)
719719
window = "hamming"
720-
taps = fwind1(hsize, window, circular=True, fc=0.5)
720+
taps = firwin_2d(hsize, window, circular=True, fc=0.5)
721721
center = hsize[0] // 2
722722
for i in range(hsize[0]):
723723
for j in range(hsize[1]):
@@ -728,11 +728,11 @@ def test_circular_symmetry(self):
728728
def test_edge_case_circular(self):
729729
hsize = (3, 3)
730730
window = "hamming"
731-
taps_small = fwind1(hsize, window, circular=True, fc=0.5)
731+
taps_small = firwin_2d(hsize, window, circular=True, fc=0.5)
732732
assert taps_small.shape == (3, 3)
733733

734734
hsize = (101, 101)
735-
taps_large = fwind1(hsize, window, circular=True, fc=0.5)
735+
taps_large = firwin_2d(hsize, window, circular=True, fc=0.5)
736736
assert taps_large.shape == (101, 101)
737737

738738
def test_known_result(self):
@@ -745,7 +745,7 @@ def test_known_result(self):
745745
col_filter = firwin(hsize[1], cutoff=fc, window=window, fs=fs)
746746
known_result = np.outer(row_filter, col_filter)
747747

748-
taps = fwind1(hsize, (window, window), fc)
748+
taps = firwin_2d(hsize, (window, window), fc)
749749
assert taps.shape == known_result.shape, (
750750
f"Shape mismatch: {taps.shape} vs {known_result.shape}"
751751
)

0 commit comments

Comments
 (0)