@@ -2,6 +2,7 @@ module DSP
2
2
3
3
importall Base. FFTW
4
4
import Base. FFTW. normalization
5
+ import Base. trailingsize
5
6
6
7
export FFTW, filt, filt!, deconv, conv, conv2, xcorr, fftshift, ifftshift,
7
8
dct, idct, dct!, idct!, plan_dct, plan_idct, plan_dct!, plan_idct!,
@@ -10,19 +11,17 @@ export FFTW, filt, filt!, deconv, conv, conv2, xcorr, fftshift, ifftshift,
10
11
plan_fft, plan_bfft, plan_ifft, plan_rfft, plan_brfft, plan_irfft,
11
12
fft!, bfft!, ifft!, plan_fft!, plan_bfft!, plan_ifft!
12
13
13
- function filt {T<:Number} (b:: Union(AbstractVector{T}, T) , a:: Union(AbstractVector{T}, T) ,
14
- x:: AbstractVector{T} ; si:: AbstractVector{T} = zeros (T, max (length (a), length (b))- 1 ))
15
- filt! (Array (T, size (x)), b, a, x, si)
14
+ _zerosi (b,a,T) = zeros (promote_type (eltype (b), eltype (a), T), max (length (a), length (b))- 1 )
15
+
16
+ function filt {T,S} (b:: Union(AbstractVector, Number) , a:: Union(AbstractVector, Number) ,
17
+ x:: AbstractArray{T} , si:: AbstractArray{S} = _zerosi (b,a,T))
18
+ filt! (Array (promote_type (eltype (b), eltype (a), T, S), size (x)), b, a, x, si)
16
19
end
17
20
18
21
# in-place filtering: returns results in the out argument, which may shadow x
19
22
# (and does so by default)
20
- function filt! {T<:Number} (b:: Union(AbstractVector{T}, T) , a:: Union(AbstractVector{T}, T) , x:: AbstractVector{T} ;
21
- si:: AbstractVector{T} = zeros (T, max (length (a), length (b))- 1 ), out:: AbstractVector{T} = x)
22
- filt! (out, b, a, x, si)
23
- end
24
- function filt! {T<:Number} (out:: AbstractVector{T} , b:: Union(AbstractVector{T}, T) , a:: Union(AbstractVector{T}, T) ,
25
- x:: AbstractVector{T} , si:: AbstractVector{T} )
23
+ function filt! {T,S,N} (out:: AbstractArray , b:: Union(AbstractVector, Number) , a:: Union(AbstractVector, Number) ,
24
+ x:: AbstractArray{T} , si:: AbstractArray{S,N} = _zerosi (b,a,T))
26
25
isempty (b) && error (" b must be non-empty" )
27
26
isempty (a) && error (" a must be non-empty" )
28
27
a[1 ] == 0 && error (" a[1] must be nonzero" )
@@ -33,6 +32,10 @@ function filt!{T<:Number}(out::AbstractVector{T}, b::Union(AbstractVector{T}, T)
33
32
sz = max (as, bs)
34
33
silen = sz - 1
35
34
xs = size (x,1 )
35
+ ncols = trailingsize (x,2 )
36
+
37
+ size (si, 1 ) != silen && error (" si must have max(length(a),length(b))-1 rows" )
38
+ N > 1 && trailingsize (si,2 ) != ncols && error (" si must either be a vector or have the same number of columns as x" )
36
39
37
40
xs == 0 && return out
38
41
sz == 1 && return scale! (out, x, b[1 ]/ a[1 ]) # Simple scaling without memory
@@ -44,29 +47,33 @@ function filt!{T<:Number}(out::AbstractVector{T}, b::Union(AbstractVector{T}, T)
44
47
b ./= norml
45
48
end
46
49
# Pad the coefficients with zeros if needed
47
- bs< sz && (b = copy! (zeros (T, sz), b))
48
- 1 < as< sz && (a = copy! (zeros (T, sz), a))
50
+ bs< sz && (b = copy! (zeros (eltype (b), sz), b))
51
+ 1 < as< sz && (a = copy! (zeros (eltype (a), sz), a))
49
52
50
- si = copy! (Array (T, silen), si)
51
- if as > 1
52
- @inbounds for i= 1 : xs
53
- xi = x[i]
54
- val = si[1 ] + b[1 ]* xi
55
- for j= 1 : (silen- 1 )
56
- si[j] = si[j+ 1 ] + b[j+ 1 ]* xi - a[j+ 1 ]* val
53
+ initial_si = si
54
+ for col = 1 : ncols
55
+ # Reset the filter state
56
+ si = initial_si[:, N > 1 ? col : 1 ]
57
+ if as > 1
58
+ @inbounds for i= 1 : xs
59
+ xi = x[i,col]
60
+ val = si[1 ] + b[1 ]* xi
61
+ for j= 1 : (silen- 1 )
62
+ si[j] = si[j+ 1 ] + b[j+ 1 ]* xi - a[j+ 1 ]* val
63
+ end
64
+ si[silen] = b[silen+ 1 ]* xi - a[silen+ 1 ]* val
65
+ out[i,col] = val
57
66
end
58
- si[silen] = b[silen + 1 ] * xi - a[silen + 1 ] * val
59
- out[i] = val
60
- end
61
- else
62
- @inbounds for i = 1 : xs
63
- xi = x[i]
64
- val = si[ 1 ] + b[ 1 ] * xi
65
- for j = 1 : ( silen- 1 )
66
- si[j ] = si[j + 1 ] + b[j + 1 ] * xi
67
+ else
68
+ @inbounds for i = 1 : xs
69
+ xi = x[i,col]
70
+ val = si[ 1 ] + b[ 1 ] * xi
71
+ for j = 1 : (silen - 1 )
72
+ si[j] = si[j + 1 ] + b[j + 1 ] * xi
73
+ end
74
+ si[silen] = b[ silen+ 1 ] * xi
75
+ out[i,col ] = val
67
76
end
68
- si[silen] = b[silen+ 1 ]* xi
69
- out[i] = val
70
77
end
71
78
end
72
79
return out
0 commit comments