@@ -4,7 +4,7 @@ using LinearAlgebra: Transpose, mul!
44using IterTools: subsets
55using FFTW
66
7- export conv, conv!, xcorr, nextfastfft
7+ export conv, conv!, deconv, xcorr, nextfastfft
88
99# Get next fast FFT size for a given signal length
1010const FAST_FFT_SIZES = (2 , 3 , 5 , 7 )
@@ -690,6 +690,67 @@ function dsp_reverse(v::AbstractVector, vaxes::Tuple{AbstractUnitRange})
690690 copyto! (out, reflected_start, Iterators. reverse (v), 1 , vsize)
691691end
692692
693+ """
694+ deconv(b, a) -> c
695+
696+ Construct vector `c` such that `b = conv(a,c) + r`.
697+ This is equivalent to polynomial division of `b` by `a`.
698+
699+ # Examples
700+ ```jldoctest
701+ julia> b = [1.0, 2.0, 3.0, 4.0]; a = [1.0, 1.0];
702+
703+ julia> c = deconv(b, a)
704+ 3-element Vector{Float64}:
705+ 1.0
706+ 1.0
707+ 2.0
708+
709+ julia> conv(a, c)
710+ 4-element Vector{Float64}:
711+ 1.0
712+ 2.0
713+ 3.0
714+ 2.0
715+ ```
716+ """
717+ function deconv (b:: StridedVector{T} , a:: StridedVector{T} ) where T
718+ lb = length (b)
719+ la = length (a)
720+
721+ # If b is shorter than a, return [0] since polynomial division is impossible
722+ if lb < la
723+ return [zero (T)]
724+ end
725+
726+ if iszero (a[1 ])
727+ throw (ArgumentError (" Leading coefficient of divisor must be non-zero" ))
728+ end
729+
730+ V = typeof (one (T) / one (T))
731+ c = zeros (V, lb - la + 1 )
732+
733+ if la == 1
734+ c .= b ./ a[1 ]
735+ else
736+ # Initialize remainder with b
737+ r = collect (V, b)
738+
739+ # Polynomial long division algorithm
740+ for i in 1 : (lb- la+ 1 )
741+ # Next coefficient is ratio of leading terms
742+ c_i = r[i] / a[1 ]
743+ c[i] = c_i
744+
745+ # Subtract a * c[i] from remaining terms
746+ for j in 1 : la
747+ @inbounds r[i+ j- 1 ] -= a[j] * c_i
748+ end
749+ end
750+ end
751+
752+ return c
753+ end
693754
694755"""
695756 xcorr(u; padmode::Symbol=:none, scaling::Symbol=:none)
0 commit comments