diff --git a/.travis.yml b/.travis.yml index cc6fd42..73029c7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,11 +4,7 @@ os: - linux - osx julia: - - release + - 1.0 - nightly notifications: email: false -# uncomment the following lines to override the default test script -#script: -# - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi -# - julia -e 'Pkg.clone(pwd()); Pkg.build("Hilbert"); Pkg.test("Hilbert"; coverage=true)' diff --git a/README.md b/README.md index 03410e4..a69344d 100644 --- a/README.md +++ b/README.md @@ -1 +1,15 @@ -# Hilbert +# Hilbert.jl + +Compute the Hilbert transform of a signal in Julia. + +```julia +julia> using Hilbert + +julia> signal = [1 2 3 4] +1×4 Array{Int64,2}: + 1 2 3 4 + +julia> hilbert(signal) +1×4 Array{Complex{Float64},2}: + 1.0+1.0im 2.0-1.0im 3.0-1.0im 4.0+1.0im +``` \ No newline at end of file diff --git a/REQUIRE b/REQUIRE index d5d6467..3be62f5 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1 +1,2 @@ -julia 0.4 +julia 0.7 +FFTW \ No newline at end of file diff --git a/src/Hilbert.jl b/src/Hilbert.jl index a8ab1bd..7fa33ee 100644 --- a/src/Hilbert.jl +++ b/src/Hilbert.jl @@ -1,5 +1,9 @@ module Hilbert +using FFTW + +export hilbert + """ hilbert(x) hilbert(x, n) @@ -15,49 +19,44 @@ x = randn(10,10) y = hilbert(x) ``` """ -function hilbert{T<:Real}(x::AbstractArray{T,2}, n::Int64=0) - - x_ = copy(x) - - if(eltype(x_) <: Complex) - warn("Using real part, ignoring complex part") - x_ = real(x_) - end - - # work along columns - size(x_,1)==1 ? x_ = permutedims(x_,[2 1]) : nothing - - if(n>0 && n0 && n>size(x_,1)) - x_ = cat(1,x_,zeros(n-size(x_,1),size(x_,2))) - else - n = size(x_,1) - end - - xf = fft(x_,1) - h = zeros(Int64,n) - if n>0 && n % 2 == 0 - #even, nonempty - h[1:div(n,2)+1] = 1 - h[2:div(n,2)] = 2 - elseif n>0 - #odd, nonempty - h[1] = 1 - h[2:div(n + 1,2)] = 2 - end - x_ = ifft(xf .* h[:,ones(Int64,size(xf,2))],1) - - # restore to original shape if necessary - size(x,1)==1 ? x_ = permutedims(x_,[2 1]) : nothing - - return x_ +function hilbert(x::AbstractArray{T,2}, n::Int64=0) where T <: Real + + x_ = copy(x) + + # work along columns + size(x_,1)==1 ? x_ = permutedims(x_,[2 1]) : nothing + + if(n>0 && n0 && n>size(x_,1)) + x_ = cat(1,x_,zeros(n-size(x_,1),size(x_,2))) + else + n = size(x_,1) + end + + xf = fft(x_,1) + h = zeros(Int64,n) + if n>0 && n % 2 == 0 + #even, nonempty + h[1:div(n,2)+1] .= 1 + h[2:div(n,2)] .= 2 + elseif n>0 + #odd, nonempty + h[1] = 1 + h[2:div(n + 1,2)] .= 2 + end + x_ = ifft(xf .* h[:,ones(Int64,size(xf,2))],1) + + # restore to original shape if necessary + size(x,1)==1 ? x_ = permutedims(x_,[2 1]) : nothing + + return x_ end -function hilbert{T<:Complex}(x::AbstractArray{T}, n::Int64=0) - warn("Using real part, ignoring complex part") - Hilbert.hilbert(real(x)) +function hilbert(x::AbstractArray{T}, n::Int64=0) where T <: Complex + @warn("Using real part, ignoring complex part") + Hilbert.hilbert(real(x)) end end # module diff --git a/test/runtests.jl b/test/runtests.jl index e5ceb22..d3f5657 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,18 @@ using Hilbert -using Base.Test +using Test -# write your own tests here -@test 1 == 1 +# Example from https://www.mathworks.com/help/signal/ref/hilbert.html +@testset "Real vector" begin + signal = [1 2 3 4] + analytical_signal = hilbert(signal) + @test analytical_signal == [1+1im 2-1im 3-1im 4+im] +end + +@testset "Complex numbers" begin + complex_signal = Complex.([1 2 3 4]) + # verify that the warning is thrown + @test_logs (:warn, "Using real part, ignoring complex part") hilbert(complex_signal) + # verify that the output is correct assuming only the real part is used + analytical_signal = hilbert(complex_signal) + @test analytical_signal == [1+1im 2-1im 3-1im 4+im] +end \ No newline at end of file