22
33abstract FilterCoefficients
44
5+ realtype (x:: DataType ) = x
6+ realtype {T} (:: Type{Complex{T}} ) = T
7+ complextype (T:: DataType ) = Complex{T}
8+ complextype {T} (:: Type{Complex{T}} ) = Complex{T}
9+
510#
611# Zero-pole gain form
712#
@@ -12,6 +17,19 @@ immutable ZeroPoleGain{Z<:Number,P<:Number,K<:Number} <: FilterCoefficients
1217 k:: K
1318end
1419
20+ Base. promote_rule {Z1,P1,K1,Z2,P2,K2} (:: Type{ZeroPoleGain{Z1,P1,K1}} , :: Type{ZeroPoleGain{Z2,P2,K2}} ) =
21+ ZeroPoleGain{promote_type (Z1,Z2),promote_type (P1,P2),promote_type (K1,K2)}
22+ Base. convert {Z,P,K} (:: Type{ZeroPoleGain{Z,P,K}} , f:: ZeroPoleGain{Z,P,K} ) = f
23+ Base. convert {Z,P,K} (:: Type{ZeroPoleGain{Z,P,K}} , f:: ZeroPoleGain ) =
24+ ZeroPoleGain {Z,P,K} (f. z, f. p, f. k)
25+
26+ * (f:: ZeroPoleGain , g:: Number ) = ZeroPoleGain (f. z, f. p, f. k* g)
27+ * (g:: Number , f:: ZeroPoleGain ) = ZeroPoleGain (f. z, f. p, f. k* g)
28+ * (f1:: ZeroPoleGain , f2:: ZeroPoleGain ) =
29+ ZeroPoleGain ([f1. z; f2. z], [f1. p; f2. p], f1. k* f2. k)
30+ * (f1:: ZeroPoleGain , fs:: ZeroPoleGain... ) =
31+ ZeroPoleGain (vcat (f1. z, [f. z for f in fs]. .. ), vcat (f1. p, [f. p for f in fs]. .. ), f1. k* prod ([f. k for f in fs]))
32+
1533#
1634# Transfer function form
1735#
@@ -34,77 +52,100 @@ function PolynomialRatio{T<:Number,S<:Number}(b::Union(T,Vector{T}), a::Union(S,
3452 PolynomialRatio {promote_type(T,S)} (Poly (b[end : - 1 : findfirst (b)]), Poly (a[end : - 1 : findfirst (a)]))
3553end
3654
37- function Base. convert (:: Type{PolynomialRatio} , f:: ZeroPoleGain )
55+ Base. promote_rule {T,S} (:: Type{PolynomialRatio{T}} , :: Type{PolynomialRatio{S}} ) = PolynomialRatio{promote_type (T,S)}
56+ Base. convert {T} (:: Type{PolynomialRatio{T}} , f:: PolynomialRatio{T} ) = f
57+ Base. convert {T} (:: Type{PolynomialRatio{T}} , f:: PolynomialRatio ) = PolynomialRatio {T} (f. b, f. a)
58+
59+ function Base. convert {T<:Real} (:: Type{PolynomialRatio{T}} , f:: ZeroPoleGain )
3860 b = f. k* poly (f. z)
3961 a = poly (f. p)
40- PolynomialRatio (Poly (real (b. a)), Poly (real (a. a)))
62+ PolynomialRatio {T} (Poly (real (b. a)), Poly (real (a. a)))
4163end
64+ Base. convert {Z,P,K} (:: Type{PolynomialRatio} , f:: ZeroPoleGain{Z,P,K} ) =
65+ convert (PolynomialRatio{promote_type (realtype (Z),realtype (P),K)}, f)
4266
43- function Base. convert {T } (:: Type{ZeroPoleGain} , f:: PolynomialRatio{T} )
67+ function Base. convert {Z,P,K } (:: Type{ZeroPoleGain{Z,P,K}} , f:: PolynomialRatio )
4468 k = real (f. b[end ])
45- b = f. b / k
46- z = convert (Vector{Complex{T}}, roots (b))
47- p = convert (Vector{Complex{T}}, roots (f. a))
48- ZeroPoleGain (z, p, k)
69+ ZeroPoleGain {Z,P,K} (roots (f. b / k), roots (f. a), k)
4970end
71+ Base. convert {T} (:: Type{ZeroPoleGain} , f:: PolynomialRatio{T} ) =
72+ convert (ZeroPoleGain{complextype (T),complextype (T),T}, f)
73+
74+ * (f:: PolynomialRatio , g:: Number ) = PolynomialRatio (g* f. b, f. a)
75+ * (g:: Number , f:: PolynomialRatio ) = PolynomialRatio (g* f. b, f. a)
76+ * (f1:: PolynomialRatio , f2:: PolynomialRatio ) =
77+ PolynomialRatio (f1. b* f2. b, f1. a* f2. a)
78+ * (f1:: PolynomialRatio , fs:: PolynomialRatio... ) =
79+ PolynomialRatio (f1. b* prod ([f. b for f in fs]), f1. a* prod ([f. a for f in fs]))
5080
5181coefb (f:: PolynomialRatio ) = reverse (f. b. a)
5282coefa (f:: PolynomialRatio ) = reverse (f. a. a)
5383
5484#
5585# Biquad filter in transfer function form
56- # A separate immutable to improve efficiency of filtering using SecondOrderSectionss
86+ # A separate immutable to improve efficiency of filtering using SecondOrderSections
5787#
5888
59- immutable Biquad{T} <: FilterCoefficients
89+ immutable Biquad{T<: Number } <: FilterCoefficients
6090 b0:: T
6191 b1:: T
6292 b2:: T
6393 a1:: T
6494 a2:: T
6595end
66- Biquad {T} (b0:: T , b1:: T , b2:: T , a0:: T , a1:: T , a2:: T , g:: Real = 1 ) =
96+ Biquad {T} (b0:: T , b1:: T , b2:: T , a0:: T , a1:: T , a2:: T , g:: Number = 1 ) =
6797 Biquad (g* b0/ a0, g* b1/ a0, g* b2/ a0, a1/ a0, a2/ a0)
6898
69- Base. convert (:: Type{ZeroPoleGain} , f:: Biquad ) = convert (ZeroPoleGain, convert (PolynomialRatio, f))
99+ Base. promote_rule {T,S} (:: Type{Biquad{T}} , :: Type{Biquad{S}} ) = Biquad{promote_type (T,S)}
100+ Base. convert {T} (:: Type{Biquad{T}} , f:: Biquad{T} ) = f
101+ Base. convert {T} (:: Type{Biquad{T}} , f:: Biquad ) = Biquad {T} (f. b0, f. b1, f. b2, f. a1, f. a2)
70102
71- function Base. convert {T} (:: Type{PolynomialRatio} , f:: Biquad{T} )
103+ Base. convert {Z,P,K} (:: Type{ZeroPoleGain{Z,P,K}} , f:: Biquad ) =
104+ convert (ZeroPoleGain{Z,P,K}, convert (PolynomialRatio, f))
105+ Base. convert (:: Type{ZeroPoleGain} , f:: Biquad ) =
106+ convert (ZeroPoleGain, convert (PolynomialRatio, f))
107+
108+ function Base. convert {T} (:: Type{PolynomialRatio{T}} , f:: Biquad )
72109 if f. b2 == zero (T) && f. a2 == zero (T)
73110 if f. b1 == zero (T) && f. a1 == zero (T)
74- b = [f. b0]
75- a = [one (T)]
111+ b = T [f. b0]
112+ a = T [one (T)]
76113 else
77- b = [f. b0, f. b1]
78- a = [one (T), f. a1]
114+ b = T [f. b0, f. b1]
115+ a = T [one (T), f. a1]
79116 end
80117 else
81- b = [f. b0, f. b1, f. b2]
82- a = [one (T), f. a1, f. a2]
118+ b = T [f. b0, f. b1, f. b2]
119+ a = T [one (T), f. a1, f. a2]
83120 end
84121
85122 PolynomialRatio (b, a)
86123end
124+ Base. convert {T} (:: Type{PolynomialRatio} , f:: Biquad{T} ) = convert (PolynomialRatio{T}, f)
87125
88- Base. convert (:: Type{Biquad} , f:: ZeroPoleGain ) = convert (Biquad, convert (PolynomialRatio, f))
89-
90- function Base. convert {T} (:: Type{Biquad} , f:: PolynomialRatio{T} )
126+ function Base. convert {T} (:: Type{Biquad{T}} , f:: PolynomialRatio )
91127 a, b = f. a, f. b
92128 xs = max (length (b), length (a))
93129
94130 if xs == 3
95- Biquad (b[2 ], b[1 ], b[0 ], a[1 ], a[0 ])
131+ Biquad {T} (b[2 ], b[1 ], b[0 ], a[1 ], a[0 ])
96132 elseif xs == 2
97- Biquad (b[1 ], b[0 ], zero (T), a[0 ], zero (T))
133+ Biquad {T} (b[1 ], b[0 ], zero (T), a[0 ], zero (T))
98134 elseif xs == 1
99- Biquad (b[0 ], zero (T), zero (T), zero (T), zero (T))
135+ Biquad {T} (b[0 ], zero (T), zero (T), zero (T), zero (T))
100136 elseif xs == 0
101137 throw (ArgumentError (" cannot convert an empty PolynomialRatio to Biquad" ))
102138 else
103139 throw (ArgumentError (" cannot convert a filter of length > 3 to Biquad" ))
104140 end
105141end
142+ Base. convert {T} (:: Type{Biquad} , f:: PolynomialRatio{T} ) = convert (Biquad{T}, f)
143+
144+ Base. convert {T} (:: Type{Biquad{T}} , f:: ZeroPoleGain ) = convert (Biquad{T}, convert (PolynomialRatio, f))
145+ Base. convert (:: Type{Biquad} , f:: ZeroPoleGain ) = convert (Biquad, convert (PolynomialRatio, f))
106146
107147* (f:: Biquad , g:: Number ) = Biquad (f. b0* g, f. b1* g, f. b2* g, f. a1, f. a2)
148+ * (g:: Number , f:: Biquad ) = Biquad (f. b0* g, f. b1* g, f. b2* g, f. a1, f. a2)
108149
109150#
110151# Second-order sections (array of biquads)
@@ -115,27 +156,40 @@ immutable SecondOrderSections{T,G} <: FilterCoefficients
115156 g:: G
116157end
117158
118- realtype (x:: DataType ) = x
119- realtype {T} (:: Type{Complex{T}} ) = T
120- complextype (T:: DataType ) = Complex{T}
121- complextype {T} (:: Type{Complex{T}} ) = Complex{T}
159+ Base. promote_rule {T1,G1,T2,G2} (:: Type{SecondOrderSections{T1,G1}} , :: Type{SecondOrderSections{T2,G2}} ) =
160+ SecondOrderSections{promote_type (T1,T2),promote_type (G1,G2)}
161+ Base. convert {T,G} (:: Type{SecondOrderSections{T,G}} , f:: SecondOrderSections{T,G} ) = f
162+ Base. convert {T,G} (:: Type{SecondOrderSections{T,G}} , f:: SecondOrderSections ) =
163+ SecondOrderSections {T,G} (f. biquads, f. g)
122164
123- function Base. convert {T} (:: Type{ZeroPoleGain} , f:: SecondOrderSections{T} )
124- t = complextype (T)
125- z = t[]
126- p = t[]
165+ function Base. convert {Z,P,K} (:: Type{ZeroPoleGain{Z,P,K}} , f:: SecondOrderSections )
166+ z = Z[]
167+ p = P[]
127168 k = f. g
128169 for biquad in f. biquads
129170 biquadzpk = convert (ZeroPoleGain, biquad)
130171 append! (z, biquadzpk. z)
131172 append! (p, biquadzpk. p)
132173 k *= biquadzpk. k
133174 end
134- ZeroPoleGain (z, p, k)
175+ ZeroPoleGain {Z,P,K} (z, p, k)
135176end
177+ Base. convert {T,G} (:: Type{ZeroPoleGain} , f:: SecondOrderSections{T,G} ) =
178+ convert (ZeroPoleGain{complextype (T),complextype (T),G}, f)
136179
137- Base. convert (to:: Union(Type{PolynomialRatio}, Type{Biquad}) , f:: SecondOrderSections ) =
138- convert (to, convert (ZeroPoleGain, f))
180+ function Base. convert {T} (:: Type{Biquad{T}} , f:: SecondOrderSections )
181+ if length (f. biquads) != 1
182+ throw (ArgumentError (" only a single second order section may be converted to a biquad" ))
183+ end
184+ convert (Biquad{T}, f. biquads[1 ]* f. g)
185+ end
186+ Base. convert {T,G} (:: Type{Biquad} , f:: SecondOrderSections{T,G} ) =
187+ convert (Biquad{promote_type (T,G)}, f)
188+
189+ Base. convert {T} (:: Type{PolynomialRatio{T}} , f:: SecondOrderSections ) =
190+ convert (PolynomialRatio{T}, convert (ZeroPoleGain, f))
191+ Base. convert (:: Type{PolynomialRatio} , f:: SecondOrderSections ) =
192+ convert (PolynomialRatio, convert (ZeroPoleGain, f))
139193
140194# Group each pole in p with its closest zero in z
141195# Remove paired poles from p and z
@@ -252,4 +306,18 @@ function Base.convert{Z,P}(::Type{SecondOrderSections}, f::ZeroPoleGain{Z,P})
252306 SecondOrderSections (biquads, f. k)
253307end
254308
309+ Base. convert {T,G} (:: Type{SecondOrderSections{T,G}} , f:: Biquad ) = SecondOrderSections {T,G} ([f], one (G))
310+ Base. convert {T} (:: Type{SecondOrderSections} , f:: Biquad{T} ) = convert (SecondOrderSections{T,Int}, f)
255311Base. convert (:: Type{SecondOrderSections} , f:: FilterCoefficients ) = convert (SecondOrderSections, convert (ZeroPoleGain, f))
312+
313+ * (f:: SecondOrderSections , g:: Number ) = SecondOrderSections (f. biquads, f. g* g)
314+ * (g:: Number , f:: SecondOrderSections ) = SecondOrderSections (f. biquads, f. g* g)
315+ * (f1:: SecondOrderSections , f2:: SecondOrderSections ) =
316+ SecondOrderSections ([f1. biquads; f2. biquads], f1. g* f2. g)
317+ * (f1:: SecondOrderSections , fs:: SecondOrderSections... ) =
318+ SecondOrderSections (vcat (f1. biquads, [f. biquads for f in fs]. .. ), f1. g* prod ([f. g for f in fs]))
319+
320+ * (f1:: Biquad , f2:: Biquad ) = SecondOrderSections ([f1, f2], 1 )
321+ * (f1:: Biquad , fs:: Biquad... ) = SecondOrderSections ([f1, fs... ], 1 )
322+ * (f1:: SecondOrderSections , f2:: Biquad ) = SecondOrderSections ([f1. biquads; f2], f1. g)
323+ * (f1:: Biquad , f2:: SecondOrderSections ) = SecondOrderSections ([f1; f2. biquads], f2. g)
0 commit comments