Skip to content

Commit

Permalink
Implement time-domain convolution and use it for integers
Browse files Browse the repository at this point in the history
  • Loading branch information
martinholters committed Feb 26, 2024
1 parent 93e9ee7 commit 3bb56ca
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/dspbase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,25 @@ function _conv(u, v, su, sv)
_conv!(out, u, v, su, sv, outsize)
end

function _conv_td(u::AbstractArray{<:Number, N}, v::AbstractArray{<:Number, N}) where {N}
output_indices = CartesianIndices(map(axes(u), axes(v)) do au, av
r = (first(au)+first(av)):(last(au)+last(av))
if au isa Base.OneTo && av isa Base.OneTo
return r
else
return Base.IdentityUnitRange(r)
end
end)
return [
sum(u[m] * v[n-m]
for m in CartesianIndices(ntuple(Val(N)) do d
max(firstindex(u,d),n[d]-lastindex(v,d)):min(lastindex(u,d), n[d]-firstindex(v,d))
end)
)
for n in output_indices
]
end

# We use this type definition for clarity
const RealOrComplexFloat = Union{AbstractFloat, Complex{T} where T<:AbstractFloat}

Expand Down Expand Up @@ -704,7 +723,7 @@ function conv(u::AbstractArray{<:RealOrComplexFloat, N},
end

conv(u::AbstractArray{<:Integer, N}, v::AbstractArray{<:Integer, N}) where {N} =
round.(Int, conv(float(u), float(v)))
_conv_td(u, v)

conv(u::AbstractArray{<:Number, N}, v::AbstractArray{<:Number, N}) where {N} =
conv(float(u), float(v))
Expand Down
7 changes: 7 additions & 0 deletions test/dsp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,16 @@ end
@test conv(f32a, b) fexp
@test conv(fb, a) fexp

# issue #410
n = 314159265
@test conv([n], [n]) == [n^2]

offset_arr = OffsetVector{Int}(undef, -1:2)
offset_arr[:] = a
@test conv(offset_arr, 1:3) == OffsetVector(expectation, 0:5)
offset_arr_f = OffsetVector{Float64}(undef, -1:2)
offset_arr_f[:] = fa
@test conv(offset_arr_f, 1:3) OffsetVector(fexp, 0:5)
# Issue #352
@test conv([1//2, 1//3, 1//4], [1, 2]) [1//2, 4//3, 11//12, 1//2]
# Non-numerical arrays should not be convolved
Expand Down

0 comments on commit 3bb56ca

Please sign in to comment.