Skip to content

Commit 7aea0dc

Browse files
committed
Change term arg-type for nuttall and blackmanharris
To preserve the conventional kwargs structure of all windows, the `term` argument for blackmanharris and nuttall are change into normal positional arguments. This implies some updates for the tests and the make_matrix function, but it works quite well. Now it is even possible to create a two-dimensional nuttall window, where the first dimension consists of a 4-term nuttall window of arbitrary length while the second dimension consists of a 3-term nuttall window of a different length.
1 parent 1599ccf commit 7aea0dc

2 files changed

Lines changed: 56 additions & 15 deletions

File tree

src/windows.jl

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -462,8 +462,9 @@ end
462462
"""
463463
$blackmanharris_winplot
464464
465-
blackmanharris(n::Integer; term::Integer=4, padding::Integer=0, zerophase::Bool=false)
466-
blackmanharris(dims; term::Integer=4, padding=0, zerophase=false)
465+
blackmanharris(n::Integer, term::Integer=4; padding::Integer=0, zerophase::Bool=false)
466+
blackmanharris(dims, term::Integer; padding=0, zerophase=false)
467+
blackmanharris(dims, Tuple{term::Integer, term::Integer}; padding=0, zerophase=false)
467468
468469
Blackman-Harris window of length `n` with `padding` zeros. The Blackman-Harris
469470
window is a linear combination of three or four trigonometric terms, optimized
@@ -475,7 +476,6 @@ optimized ones in [Nuttall, A. H. (1981). Some windows with very good sidelobe
475476
behavior. IEEE Transactions on Acoustics, Speech, Signal Processing, 29,
476477
84-91](https://ieeexplore.ieee.org/document/1163506).
477478
478-
479479
The 3-term window `w3(x)` and the 4-term window `w4(x)` are defined by sampling
480480
the following continuous functions in the range `[-0.5, 0.5]`:
481481
@@ -499,7 +499,7 @@ $(twoD_docs())
499499
500500
$zerophase_docs
501501
"""
502-
function blackmanharris(n::Integer; term::Integer=4, padding::Integer=0, zerophase::Bool=false)
502+
function blackmanharris(n::Integer, term::Integer=4; padding::Integer=0, zerophase::Bool=false)
503503
if term == 4
504504
a0, a1, a2, a3 = 0.35875, 0.48829, 0.14128, 0.01168
505505
makewindow(n, padding, zerophase) do x
@@ -518,8 +518,9 @@ end
518518
"""
519519
$nuttall_winplot
520520
521-
nuttall(n::Integer; term::Integer=4, padding::Integer=0, zerophase::Bool=false)
522-
nuttall(dims; term::Integer=4, padding=0, zerophase=false)
521+
nuttall(n::Integer, term::Integer=4; padding::Integer=0, zerophase::Bool=false)
522+
nuttall(dims, term::Integer; padding=0, zerophase=false)
523+
nuttall(dims, Tuple{term_x::Integer, term_y::Integer}; padding=0, zerophase=false)
523524
524525
Nuttall window of length `n` with `padding` zeros. These windows can be seen as
525526
the improved version of the Blackman-Harris windows with regard to maximum
@@ -550,7 +551,7 @@ $(twoD_docs())
550551
551552
$zerophase_docs
552553
"""
553-
function nuttall(n::Integer; term::Integer=4, padding::Integer=0, zerophase::Bool=false)
554+
function nuttall(n::Integer, term::Integer=4; padding::Integer=0, zerophase::Bool=false)
554555
if term == 4
555556
a0, a1, a2, a3 = 0.3635819, 0.4891775, 0.1365995, 0.0106411
556557
makewindow(n, padding, zerophase) do x
@@ -781,7 +782,7 @@ const IntegerOr2 = Union{Tuple{Integer, Integer}, Integer}
781782
const RealOr2 = Union{Tuple{Real, Real}, Real}
782783
const BoolOr2 = Union{Tuple{Bool, Bool}, Bool}
783784

784-
function matrix_window(func::F, dims::Tuple{Integer,Integer}, arg::Union{RealOr2,Nothing}=nothing;
785+
function matrix_window(func::F, dims::Tuple{Integer,Integer}, arg::Union{RealOr2,IntegerOr2,Nothing}=nothing;
785786
padding::IntegerOr2=0, zerophase::BoolOr2=false) where {F}
786787
paddings = argdup(padding)
787788
zerophases = argdup(zerophase)
@@ -797,7 +798,7 @@ function matrix_window(func::F, dims::Tuple{Integer,Integer}, arg::Union{RealOr2
797798
end
798799

799800
for func in (:rect, :hanning, :hamming, :cosine, :lanczos,
800-
:triang, :bartlett, :bartlett_hann, :blackman, :blackmanharris, :nuttall, :flattop)
801+
:triang, :bartlett, :bartlett_hann, :blackman, :flattop)
801802
@eval function $func(dims::Tuple{Integer,Integer}; padding::IntegerOr2=0, zerophase::BoolOr2=false)
802803
return matrix_window($func, dims; padding, zerophase)
803804
end
@@ -809,4 +810,10 @@ for func in (:tukey, :gaussian, :kaiser)
809810
end
810811
end
811812

813+
for func in (:blackmanharris, :nuttall)
814+
@eval function $func(dims::Tuple{Integer,Integer}, arg::IntegerOr2; padding::IntegerOr2=0, zerophase::BoolOr2=false)
815+
return matrix_window($func, dims, arg; padding, zerophase)
816+
end
817+
end
818+
812819
end # end module definition

test/windows.jl

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,15 @@ end
8383
@test blackman_jl blackman_ml
8484
@test minimum(blackman_jl) == 0.0
8585

86-
blackmanharris_3term_jl = blackmanharris(128;term=3)
86+
blackmanharris_3term_jl = blackmanharris(128, 3)
8787
blackmanharris_3term_ref = read_reference_data("blackmanharris_3term_128.txt")
8888
@test blackmanharris_3term_jl blackmanharris_3term_ref
8989

9090
blackmanharris_4term_jl = blackmanharris(128)
9191
blackmanharris_4term_ml = read_reference_data("blackmanharris_4term_128.txt")
9292
@test blackmanharris_4term_jl blackmanharris_4term_ml
9393

94-
nuttall_3term_jl = nuttall(128;term=3)
94+
nuttall_3term_jl = nuttall(128, 3)
9595
nuttall_3term_ref = read_reference_data("nuttall_3term_128.txt")
9696
@test nuttall_3term_jl nuttall_3term_ref
9797

@@ -125,14 +125,14 @@ end
125125
cosine_ref = read_reference_data("cosine128.txt")
126126
@test cosine_jl cosine_ref
127127

128-
@test_throws ArgumentError blackmanharris(128;term=2)
129-
@test_throws ArgumentError nuttall(128;term=2)
128+
@test_throws ArgumentError blackmanharris(128, 2)
129+
@test_throws ArgumentError nuttall(128, 2)
130130
end
131131

132132
zeroarg_wins = [rect, hanning, hamming, cosine, lanczos,
133-
bartlett, bartlett_hann, blackman, blackmanharris,
134-
nuttall, triang, flattop]
133+
bartlett, bartlett_hann, blackman, triang, flattop]
135134
onearg_wins = [gaussian, kaiser, tukey]
135+
termarg_wins = [blackmanharris, nuttall]
136136
@testset "zero-phase windows" begin
137137
for winf in zeroarg_wins
138138
if winf == triang
@@ -156,6 +156,16 @@ onearg_wins = [gaussian, kaiser, tukey]
156156
@test winf(9, 0.5, zerophase=true) == ifftshift(winf(19, 0.5)[2:2:end])
157157
end
158158

159+
# Test the window functions that have the term arg (number of ceofficients)
160+
for winf in termarg_wins
161+
@test winf(8, 4, zerophase=true) == ifftshift(winf(9, 4)[1:8])
162+
@test winf(9, 4, zerophase=true) == ifftshift(winf(19, 4)[2:2:end])
163+
end
164+
# 3-term blackmanharris and nuttall are a spocial case because of their odd
165+
# number of coefficients
166+
@test blackmanharris(6, 3, zerophase=true) [1.0, 0.632395, 0.134845, 0.0049, 0.134845, 0.632395]
167+
@test nuttall(6, 3, zerophase=true) [1.0, 0.63391075, 0.13657015, 0.0053188, 0.13657015, 0.63391075]
168+
159169
@test dpss(8, 2, 1, zerophase=true)[:] == ifftshift(dpss(9, 2, 1)[1:8])
160170
# odd-length zerophase dpss windows not currently supported
161171
@test_throws ArgumentError dpss(9, 2, 1, zerophase=true)
@@ -173,6 +183,10 @@ end
173183
@test Array{ft,1} == typeof(gaussian(n, 0.4)) && length(gaussian(n, 0.4)) == n
174184
@test Array{ft,1} == typeof(kaiser(n, 0.4)) && length(kaiser(n, 0.4)) == n
175185
@test Array{ft,2} == typeof(dpss(n, 1.5)) && size(dpss(n, 1.5),1) == n # size(,2) depends on the parameters
186+
@test Array{ft,1} == typeof(blackmanharris(n, 4)) && length(blackmanharris(n, 4)) == n
187+
@test Array{ft,1} == typeof(blackmanharris(n, 3)) && length(blackmanharris(n, 3)) == n
188+
@test Array{ft,1} == typeof(nuttall(n, 4)) && length(nuttall(n, 4)) == n
189+
@test Array{ft,1} == typeof(nuttall(n, 3)) && length(nuttall(n, 3)) == n
176190
end
177191

178192
@testset "tensor product windows" begin
@@ -212,4 +226,24 @@ end
212226
@test w3 w1 * w2'
213227
end
214228
end
229+
230+
for winf in termarg_wins,
231+
arg in (3, 4)
232+
for padding in (nothing, 4, (4,5)),
233+
zerophase in (nothing, true, (true,false))
234+
w1_expr = :($winf(15))
235+
w2_expr = :($winf(20))
236+
w3_expr = :($winf((15,20)))
237+
w_all = (w1_expr, w2_expr, w3_expr)
238+
239+
push_args!(w_all, arg, Integer, identity)
240+
push_args!(w_all, padding, Integer, s -> Expr(:kw, :padding, s))
241+
push_args!(w_all, zerophase, Bool, s -> Expr(:kw, :zerophase, s))
242+
243+
w1 = eval(w1_expr)
244+
w2 = eval(w2_expr)
245+
w3 = eval(w3_expr)
246+
@test w3 w1 * w2'
247+
end
248+
end
215249
end

0 commit comments

Comments
 (0)