@@ -34,13 +34,13 @@ ZeroPoleGain{D}(z::Vector{Z}, p::Vector{P}, k::K) where {D,Z<:Number,P<:Number,K
3434Base. promote_rule (:: Type{ZeroPoleGain{D,Z1,P1,K1}} , :: Type{ZeroPoleGain{D,Z2,P2,K2}} ) where {D,Z1,P1,K1,Z2,P2,K2} =
3535 ZeroPoleGain{D,promote_type (Z1,Z2),promote_type (P1,P2),promote_type (K1,K2)}
3636
37- * (f:: ZeroPoleGain{D} , g:: Number ) where {D} = ZeroPoleGain {D} (f. z, f. p, f. k* g)
38- * (g:: Number , f:: ZeroPoleGain{D} ) where {D} = ZeroPoleGain {D} (f. z, f. p, f. k* g)
37+ * (f:: ZeroPoleGain{D} , g:: Number ) where {D} = ZeroPoleGain {D} (f. z, f. p, f. k * g)
38+ * (g:: Number , f:: ZeroPoleGain{D} ) where {D} = ZeroPoleGain {D} (f. z, f. p, f. k * g)
3939* (f1:: ZeroPoleGain{D} , f2:: ZeroPoleGain{D} ) where {D} =
40- ZeroPoleGain {D} ([f1. z; f2. z], [f1. p; f2. p], f1. k* f2. k)
40+ ZeroPoleGain {D} ([f1. z; f2. z], [f1. p; f2. p], f1. k * f2. k)
4141* (f1:: ZeroPoleGain{D} , fs:: ZeroPoleGain{D} ...) where {D} =
4242 ZeroPoleGain {D} (vcat (f1. z, map (f -> f. z, fs)... ), vcat (f1. p, map (f -> f. p, fs)... ),
43- f1. k* prod (f. k for f in fs))
43+ f1. k * prod (f. k for f in fs))
4444
4545Base. inv (f:: ZeroPoleGain{D} ) where {D} = ZeroPoleGain {D} (f. p, f. z, inv (f. k))
4646
5656# Transfer function form
5757#
5858
59- function shiftpoly (p:: LaurentPolynomial{T} , i:: Integer ) where {T<: Number }
59+ function shiftpoly (p:: LaurentPolynomial{T,D } , i:: Integer ) where {T<: Number ,D }
6060 if ! iszero (i)
61- return p * LaurentPolynomial ([one (T)], i, indeterminate (p) )
61+ return p * LaurentPolynomial {T,D} ([one (T)], i)
6262 end
6363 return p
6464end
@@ -122,20 +122,35 @@ PolynomialRatio{:s, Int64}(LaurentPolynomial(3 + 2*s + s²), LaurentPolynomial(4
122122
123123"""
124124PolynomialRatio (b, a) = PolynomialRatio {:z} (b, a)
125- function PolynomialRatio {:z} (b:: LaurentPolynomial{T1} , a:: LaurentPolynomial{T2} ) where {T1,T2}
126- return PolynomialRatio {:z,typeof(one(T1)/one(T2))} (b, a)
127- end
128- function PolynomialRatio {:s} (b:: LaurentPolynomial{T1} , a:: LaurentPolynomial{T2} ) where {T1,T2}
129- return PolynomialRatio {:s,promote_type(T1, T2)} (b, a)
130- end
125+ const PolynomialRatioArgTs{T} = Union{T,Vector{T},LaurentPolynomial{T}} where {T<: Number }
126+ PolynomialRatio {:z} (b:: PolynomialRatioArgTs{T1} , a:: PolynomialRatioArgTs{T2} ) where {T1<: Number ,T2<: Number } =
127+ PolynomialRatio {:z,typeof(one(T1) / one(T2))} (b, a)
128+ PolynomialRatio {:s} (b:: PolynomialRatioArgTs{T1} , a:: PolynomialRatioArgTs{T2} ) where {T1<: Number ,T2<: Number } =
129+ PolynomialRatio {:s,promote_type(T1, T2)} (b, a)
130+
131+ """
132+ _polyprep(D::Symbol, x::Union{T,Vector{T}}, ::Type) where {T<:Number}
133+
134+ Converts `x` to polynomial form. If x is a `Number`, it has to be converted into
135+ a `Vector`, otherwise `LaurentPolynomial` dispatch goes into stack overflow
136+ trying to collect a 0-d array into a `Vector`.
131137
132- # The DSP convention for Laplace domain is highest power first. The Polynomials.jl
133- # convention is lowest power first.
134- _polyprep (D:: Symbol , x, T... ) = LaurentPolynomial {T...} (reverse (x), D === :z ? - length (x)+ 1 : 0 , D)
135- PolynomialRatio {D,T} (b:: Union{Number,Vector{<:Number}} , a:: Union{Number,Vector{<:Number}} ) where {D,T} =
136- PolynomialRatio {D,T} (_polyprep (D, b, T), _polyprep (D, a, T))
137- PolynomialRatio {D} (b:: Union{Number,Vector{<:Number}} , a:: Union{Number,Vector{<:Number}} ) where {D} =
138- PolynomialRatio {D} (_polyprep (D, b), _polyprep (D, a))
138+ !!! warning
139+
140+ The DSP convention for Laplace domain is highest power first.\n
141+ The Polynomials.jl convention is lowest power first.
142+ """
143+ @inline _polyprep (D:: Symbol , x:: Union{T,Vector{T}} , :: Type{V} ) where {T<: Number ,V} =
144+ LaurentPolynomial {V,D} (x isa Vector ? reverse (x) : [x], D === :z ? - length (x) + 1 : 0 )
145+
146+ function PolynomialRatio {:z,T} (b:: Union{Number,Vector{<:Number}} , a:: Union{Number,Vector{<:Number}} ) where {T<: Number }
147+ if isempty (a) || iszero (a[1 ])
148+ throw (ArgumentError (" filter must have non-zero leading denominator coefficient" ))
149+ end
150+ return PolynomialRatio {:z,T} (_polyprep (:z , b / a[1 ], T), _polyprep (:z , a / a[1 ], T))
151+ end
152+ PolynomialRatio {:s,T} (b:: Union{Number,Vector{<:Number}} , a:: Union{Number,Vector{<:Number}} ) where {T<: Number } =
153+ PolynomialRatio {:s,T} (_polyprep (:s , b, T), _polyprep (:s , a, T))
139154
140155PolynomialRatio {D,T} (f:: PolynomialRatio{D} ) where {D,T} = PolynomialRatio {D,T} (f. b, f. a)
141156PolynomialRatio {D} (f:: PolynomialRatio{D,T} ) where {D,T} = PolynomialRatio {D,T} (f)
@@ -159,16 +174,14 @@ function ZeroPoleGain{D}(f::PolynomialRatio{D,T}) where {D,T}
159174 return ZeroPoleGain {D} (z, p, f. b[end ]/ f. a[end ])
160175end
161176
162- * (f:: PolynomialRatio{D} , g:: Number ) where {D} = PolynomialRatio {D} (g* f. b, f. a)
163- * (g:: Number , f:: PolynomialRatio{D} ) where {D} = PolynomialRatio {D} (g* f. b, f. a)
177+ * (f:: PolynomialRatio{D} , g:: Number ) where {D} = PolynomialRatio {D} (g * f. b, f. a)
178+ * (g:: Number , f:: PolynomialRatio{D} ) where {D} = PolynomialRatio {D} (g * f. b, f. a)
164179* (f1:: PolynomialRatio{D} , f2:: PolynomialRatio{D} ) where {D} =
165- PolynomialRatio {D} (f1. b* f2. b, f1. a* f2. a)
180+ PolynomialRatio {D} (f1. b * f2. b, f1. a * f2. a)
166181* (f1:: PolynomialRatio{D} , fs:: PolynomialRatio{D} ...) where {D} =
167- PolynomialRatio {D} (f1. b* prod (f. b for f in fs), f1. a* prod (f. a for f in fs))
182+ PolynomialRatio {D} (f1. b * prod (f. b for f in fs), f1. a * prod (f. a for f in fs))
168183
169- Base. inv (f:: PolynomialRatio{D} ) where {D} = begin
170- PolynomialRatio {D} (f. a, f. b)
171- end
184+ Base. inv (f:: PolynomialRatio{D} ) where {D} = PolynomialRatio {D} (f. a, f. b)
172185
173186function Base.:^ (f:: PolynomialRatio{D,T} , e:: Integer ) where {D,T}
174187 if e < 0
@@ -312,7 +325,7 @@ function Biquad{D,T}(f::SecondOrderSections{D}) where {D,T}
312325 if length (f. biquads) != 1
313326 throw (ArgumentError (" only a single second order section may be converted to a biquad" ))
314327 end
315- Biquad {D,T} (f. biquads[1 ]* f. g)
328+ Biquad {D,T} (f. biquads[1 ] * f. g)
316329end
317330Biquad {D} (f:: SecondOrderSections{D,T,G} ) where {D,T,G} = Biquad {D,promote_type(T,G)} (f)
318331
@@ -418,7 +431,7 @@ function SecondOrderSections{D,T,G}(f::ZeroPoleGain{D,Z,P}) where {D,T,G,Z,P}
418431 npairs = length (groupedp) >> 1
419432 odd = isodd (n)
420433 for i = 1 : npairs
421- pairidx = 2 * (npairs- i)
434+ pairidx = 2 * (npairs - i)
422435 biquads[odd+ i] = convert (Biquad, ZeroPoleGain {D} (groupedz[pairidx+ 1 : min (pairidx+ 2 , length (groupedz))],
423436 groupedp[pairidx+ 1 : pairidx+ 2 ], one (T)))
424437 end
@@ -439,12 +452,12 @@ SecondOrderSections{D,T,G}(f::Biquad{D}) where {D,T,G} = SecondOrderSections{D,T
439452SecondOrderSections {D} (f:: Biquad{D,T} ) where {D,T} = SecondOrderSections {D,T,Int} (f)
440453SecondOrderSections {D} (f:: FilterCoefficients{D} ) where {D} = SecondOrderSections {D} (ZeroPoleGain (f))
441454
442- * (f:: SecondOrderSections{D} , g:: Number ) where {D} = SecondOrderSections {D} (f. biquads, f. g* g)
443- * (g:: Number , f:: SecondOrderSections{D} ) where {D} = SecondOrderSections {D} (f. biquads, f. g* g)
455+ * (f:: SecondOrderSections{D} , g:: Number ) where {D} = SecondOrderSections {D} (f. biquads, f. g * g)
456+ * (g:: Number , f:: SecondOrderSections{D} ) where {D} = SecondOrderSections {D} (f. biquads, f. g * g)
444457* (f1:: SecondOrderSections{D} , f2:: SecondOrderSections{D} ) where {D} =
445- SecondOrderSections {D} ([f1. biquads; f2. biquads], f1. g* f2. g)
458+ SecondOrderSections {D} ([f1. biquads; f2. biquads], f1. g * f2. g)
446459* (f1:: SecondOrderSections{D} , fs:: SecondOrderSections{D} ...) where {D} =
447- SecondOrderSections {D} (vcat (f1. biquads, map (f -> f. biquads, fs)... ), f1. g* prod (f. g for f in fs))
460+ SecondOrderSections {D} (vcat (f1. biquads, map (f -> f. biquads, fs)... ), f1. g * prod (f. g for f in fs))
448461
449462* (f1:: Biquad{D} , f2:: Biquad{D} ) where {D} = SecondOrderSections {D} ([f1, f2], 1 )
450463* (f1:: Biquad{D} , fs:: Biquad{D} ...) where {D} = SecondOrderSections {D} ([f1, fs... ], 1 )
0 commit comments