From 2fed615fab3f52788a91285c4ffa022fb8a86a8b Mon Sep 17 00:00:00 2001 From: Gudmundur Adalsteinsson Date: Fri, 17 Oct 2014 01:44:43 +0000 Subject: [PATCH 01/26] add dsp tools --- src/util.jl | 29 ++++++++++++++++++++++++++++- test/util.jl | 27 ++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/util.jl b/src/util.jl index 8886dee24..72f38f6fb 100644 --- a/src/util.jl +++ b/src/util.jl @@ -1,7 +1,8 @@ module Util export unwrap!, unwrap, hilbert, Frequencies, fftintype, fftouttype, - fftabs2type, fftfreq, rfftfreq, nextfastfft + fftabs2type, fftfreq, rfftfreq, nextfastfft, + dB, dBa, pow2db, amp2db, db2pow, db2amp, rms, rmsfft function unwrap!{T <: FloatingPoint}(m::Array{T}, dim::Integer=ndims(m); range::Number=2pi) @@ -126,4 +127,30 @@ nextfastfft(n) = nextprod(FAST_FFT_SIZES, n) nextfastfft(n1, n2...) = tuple(nextfastfft(n1), nextfastfft(n2...)...) nextfastfft(n::Tuple) = nextfastfft(n...) + +## COMMON DSP TOOLS + +immutable dBconvert end +immutable dBaconvert end +const dB = dBconvert() +const dBa = dBaconvert() +# for using e.g. 3dB or -3dBa +*(a::Real, ::dBconvert) = db2pow(a) +*(a::Real, ::dBaconvert) = db2amp(a) +# convert dB to power ratio +db2pow(a::Real) = 10^(a/10) +# convert dB to amplitude ratio +db2amp(a::Real) = 10^(a/20) +# convert power ratio to dB +pow2db(a::Real) = 10*log10(a) +# convert amplitude ratio to dB +amp2db(a::Real) = 20*log10(a) + +# root mean square +rms{T<:Number}(s::AbstractArray{T}) = sqrt(sumabs2(s)/length(s)) +# root mean square of fft of signal +rmsfft{T<:Complex}(f::AbstractArray{T}) = sqrt(sumabs2(f))/length(f) + + + end # end module definition diff --git a/test/util.jl b/test/util.jl index 505ab1ff4..3f438f289 100644 --- a/test/util.jl +++ b/test/util.jl @@ -93,7 +93,7 @@ r = int(rand(128)*20) @test_approx_eq rfftfreq(7) [0., 1/7, 2/7, 3/7] for n = 1:7 - @test_approx_eq fftshift(fftfreq(n)) fftshift([fftfreq(n)]) + @test_approx_eq fftshift(fftfreq(n)) fftshift([fftfreq(n)]) end # nextfastfft @@ -103,3 +103,28 @@ end @test nextfastfft((64,65,127)) == (64,70,128) @test nextfastfft(64,65,127) == nextfastfft((64,65,127)) + +## COMMON DSP TOOLS + +# dB conversion +@test_approx_eq 3dB db2pow(3) +@test_approx_eq -3dB db2pow(-3) +@test_approx_eq 3dBa db2amp(3) +@test_approx_eq -3dBa db2amp(-3) +@test isa(3e0dB, Float64) +@test isa(3f0dB, Float32) +num = float64(pi) +@test_approx_eq pow2db(num) 10*log10(num) +@test_approx_eq amp2db(num) 20*log10(num) +@test_approx_eq num*dB db2pow(num) +@test_approx_eq num*dBa db2amp(num) +@test_approx_eq num db2pow(pow2db(num)) +@test_approx_eq num db2amp(amp2db(num)) + +n = (5,6) +for x in ( randn(n), randn(n)+randn(n)im ) + @test_approx_eq rms(x) sqrt(mean(abs(x).^2)) + @test_approx_eq rmsfft(fft(x)) rms(x) +end # for + + From bfe1e1e9affc7690428d74e205d6e9d0ee10b4de Mon Sep 17 00:00:00 2001 From: Gudmundur Adalsteinsson Date: Thu, 6 Nov 2014 18:33:10 +0000 Subject: [PATCH 02/26] add to util doc --- doc/util.rst | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/doc/util.rst b/doc/util.rst index 8abb30658..ce318ff0b 100644 --- a/doc/util.rst +++ b/doc/util.rst @@ -42,3 +42,33 @@ to ``n``. FFTW contains optimized kernels for these sizes and computes Fourier transforms of input that is a product of these sizes faster than for input of other sizes. + +.. function:: pow2db(a) + + Convert a power ratio to dB (decibel), or :math:`10\log_{10}(a)`. + The inverse of ``db2pow``. + +.. function:: amp2db(a) + + Convert an amplitude ratio to dB (decibel), or :math:`20 + \log_{10}(a)=10\log_{10}(a^2)`. The inverse of ``db2amp``. + +.. function:: db2pow(a) + + Convert dB to a power ratio. This function call also be called + using ``a*dB``, i.e. ``3dB == db2pow(3)``. The inverse of ``pow2db``. + +.. function:: db2amp(a) + + Convert dB to an amplitude ratio. This function call also be called + using ``a*dBa``, i.e. ``3dBa == db2amp(3)``. The inverse of ``amp2db``. + +.. function:: rms(s) + + Return the root mean square of signal ``s``. + +.. function:: rmsfft(f) + + Return the root mean square of signal ``s`` given the FFT transform + ``f = fft(s)``. Equivalent to ``rms(ifft(f))``. + From a544c7a532fbbc797150c5d1596632eb3307ef9c Mon Sep 17 00:00:00 2001 From: Clemens Date: Tue, 9 Dec 2014 11:18:51 +0100 Subject: [PATCH 03/26] Correct freqz and freqs Both functions should use element-wise division (by using ./ instead of /). --- src/Filters/response.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Filters/response.jl b/src/Filters/response.jl index f1ed40bff..80f176a6b 100644 --- a/src/Filters/response.jl +++ b/src/Filters/response.jl @@ -11,7 +11,7 @@ function freqz(filter::Filter, w::Number) filter = convert(TFFilter, filter) ejw = exp(-im * w) - polyval(filter.b, ejw) / polyval(filter.a, ejw) + polyval(filter.b, ejw) ./ polyval(filter.a, ejw) end @@ -36,7 +36,7 @@ end function freqs(filter::Filter, w::Number) filter = convert(TFFilter, filter) s = im * w - polyval(filter.b, s) / polyval(filter.a, s) + polyval(filter.b, s) ./ polyval(filter.a, s) end From c6a32439b9b522da02721e7b65514a98c557a484 Mon Sep 17 00:00:00 2001 From: Robert Luke Date: Tue, 9 Dec 2014 11:40:40 +0100 Subject: [PATCH 04/26] Remove shameless self promotion And change style of comments to match rest of DSP package --- src/Filters/response.jl | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/Filters/response.jl b/src/Filters/response.jl index 80f176a6b..00ff871ab 100644 --- a/src/Filters/response.jl +++ b/src/Filters/response.jl @@ -1,12 +1,8 @@ -# Filter response functions for Julia -# Created by Robert Luke (Robert.Luke@med.kuleuven.be) +# Filter response functions -####################################### # # Frequency response of a digital filter # -####################################### - function freqz(filter::Filter, w::Number) filter = convert(TFFilter, filter) @@ -14,24 +10,20 @@ function freqz(filter::Filter, w::Number) polyval(filter.b, ejw) ./ polyval(filter.a, ejw) end - function freqz(filter::Filter, w::AbstractVector) filter = convert(TFFilter, filter) [freqz(filter, i) for i = w] end - function freqz(filter::Filter, hz::Union(Number, AbstractVector), fs::Number) filter = convert(TFFilter, filter) freqz(filter, hz_to_radians_per_second(hz, fs)) end -####################################### # # Frequency response of an analog filter # -####################################### function freqs(filter::Filter, w::Number) filter = convert(TFFilter, filter) @@ -39,24 +31,20 @@ function freqs(filter::Filter, w::Number) polyval(filter.b, s) ./ polyval(filter.a, s) end - function freqs(filter::Filter, w::AbstractVector) filter = convert(TFFilter, filter) [freqs(filter, i) for i = w] end - function freqs(filter::Filter, hz::Union(Number, AbstractVector), fs::Number) filter = convert(TFFilter, filter) freqs(filter, hz_to_radians_per_second(hz, fs)) end -####################################### # # Helper functions # -####################################### function hz_to_radians_per_second(hz, fs) hz * ((2 * pi) / fs) From df9cf473f2543bf8d78559cc352b747eac467914 Mon Sep 17 00:00:00 2001 From: Matti Pastell Date: Mon, 29 Dec 2014 14:18:06 +0200 Subject: [PATCH 05/26] Added phasez, impz and stepz --- src/Filters/Filters.jl | 6 +++--- src/Filters/response.jl | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/Filters/Filters.jl b/src/Filters/Filters.jl index a39fabf3e..018029380 100644 --- a/src/Filters/Filters.jl +++ b/src/Filters/Filters.jl @@ -12,6 +12,6 @@ export FilterType, Butterworth, Chebyshev1, Chebyshev2, Elliptic, Lowpass, Highpass, Bandpass, Bandstop, analogfilter, digitalfilter -include("response.jl") -export freqs, freqz -end \ No newline at end of file +include("response.jl") +export freqs, freqz, phasez, impz, stepz +end diff --git a/src/Filters/response.jl b/src/Filters/response.jl index 00ff871ab..9910897cd 100644 --- a/src/Filters/response.jl +++ b/src/Filters/response.jl @@ -21,6 +21,34 @@ function freqz(filter::Filter, hz::Union(Number, AbstractVector), fs::Number) end + +# +# Phase response of a digital filter +# + +function phasez(filter::Filter, w) + h = freqz(filter, w) + unwrap(-atan2(imag(h), real(h))) +end + +# +# Impulse response of a digital filter +# + +function impz(filter::Filter, n=100) + i = [1, zeros(n-1)] + filt(filter, i) +end + +# +# Step response of a digital filter +# + +function stepz(filter::Filter, n=100) + cumsum(impz(filter, n)) +end + + # # Frequency response of an analog filter # From b3c1b9fb3e164022d94d607395cfdc4478dec27e Mon Sep 17 00:00:00 2001 From: Matti Pastell Date: Mon, 29 Dec 2014 14:54:01 +0200 Subject: [PATCH 06/26] Added functions with default w for freqz and phasez --- src/Filters/response.jl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Filters/response.jl b/src/Filters/response.jl index 9910897cd..97d65c71f 100644 --- a/src/Filters/response.jl +++ b/src/Filters/response.jl @@ -20,17 +20,27 @@ function freqz(filter::Filter, hz::Union(Number, AbstractVector), fs::Number) freqz(filter, hz_to_radians_per_second(hz, fs)) end +function freqz(filter::Filter) + filter = convert(TFFilter, filter) + w = linspace(0, π, 250) + [freqz(filter, i) for i = w] +end # # Phase response of a digital filter # -function phasez(filter::Filter, w) +function phasez(filter::Filter, w::AbstractVector) h = freqz(filter, w) unwrap(-atan2(imag(h), real(h))) end +function phasez(filter::Filter) + h = freqz(filter) + unwrap(-atan2(imag(h), real(h))) +end + # # Impulse response of a digital filter # From dc5947240f0c2a87a8e071039903136f65086a04 Mon Sep 17 00:00:00 2001 From: Matti Pastell Date: Tue, 30 Dec 2014 10:41:10 +0200 Subject: [PATCH 07/26] Fixed step response --- src/Filters/response.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Filters/response.jl b/src/Filters/response.jl index 97d65c71f..d6c8dbacb 100644 --- a/src/Filters/response.jl +++ b/src/Filters/response.jl @@ -55,7 +55,8 @@ end # function stepz(filter::Filter, n=100) - cumsum(impz(filter, n)) + i = [0, ones(n-1)] + filt(filter, i) end From d632967a27acd52430ba43d92b0428938dfbd68c Mon Sep 17 00:00:00 2001 From: Ryuichi YAMAMOTO Date: Wed, 31 Dec 2014 22:51:43 +0900 Subject: [PATCH 08/26] use the type `Plan` instead of a raw pointer to fftw_plan so that the finalizer is called property. This fixes a segfault problem which could happen when a finalizer runs before executing FFT. --- src/periodograms.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/periodograms.jl b/src/periodograms.jl index 1f4c928f4..98b44790f 100644 --- a/src/periodograms.jl +++ b/src/periodograms.jl @@ -284,9 +284,9 @@ function periodogram{T<:Real}(s::AbstractMatrix{T}; end forward_plan{T<:Union(Float32, Float64)}(X::AbstractArray{T}, Y::AbstractArray{Complex{T}}) = - FFTW.Plan(X, Y, 1, FFTW.ESTIMATE, FFTW.NO_TIMELIMIT).plan + FFTW.Plan(X, Y, 1, FFTW.ESTIMATE, FFTW.NO_TIMELIMIT) forward_plan{T<:Union(Complex64, Complex128)}(X::AbstractArray{T}, Y::AbstractArray{T}) = - FFTW.Plan(X, Y, 1, FFTW.FORWARD, FFTW.ESTIMATE, FFTW.NO_TIMELIMIT).plan + FFTW.Plan(X, Y, 1, FFTW.FORWARD, FFTW.ESTIMATE, FFTW.NO_TIMELIMIT) # Compute an estimate of the power spectral density of a signal s via Welch's # method. The resulting periodogram has length N and is computed with an overlap @@ -309,7 +309,7 @@ function welch_pgram{T<:Number}(s::AbstractVector{T}, n::Int=length(s)>>3, nover tmp = Array(fftouttype(T), T<:Real ? (nfft >> 1)+1 : nfft) plan = forward_plan(sig_split.buf, tmp) for sig in sig_split - FFTW.execute(plan, sig, tmp) + FFTW.execute(plan.plan, sig, tmp) fft2pow!(out, tmp, nfft, r, onesided) end @@ -341,7 +341,7 @@ function mt_pgram{T<:Number}(s::AbstractVector{T}; onesided::Bool=eltype(s)<:Rea for i = 1:size(window, 1) @inbounds input[i] = window[i, j]*s[i] end - FFTW.execute(plan, input, tmp) + FFTW.execute(plan.plan, input, tmp) fft2pow!(out, tmp, nfft, r, onesided) end @@ -394,7 +394,7 @@ function stft{T}(s::AbstractVector{T}, n::Int=length(s)>>3, noverlap::Int=n>>1, plan = forward_plan(sig_split.buf, tmp) offset = 0 for k = 1:length(sig_split) - FFTW.execute(plan, sig_split[k], tmp) + FFTW.execute(plan.plan, sig_split[k], tmp) if isa(psdonly, PSDOnly) fft2pow!(out, tmp, nfft, r, onesided, offset) else From 9f952c6e852b16bef341358be20fd2df29a59a4e Mon Sep 17 00:00:00 2001 From: Matti Pastell Date: Wed, 31 Dec 2014 16:17:56 +0200 Subject: [PATCH 09/26] Added tests to filter response --- src/Filters/response.jl | 2 +- test/data/responses-eg1.txt | 512 ++++++++++++++++++++++++++++++++++++ test/filter_response.jl | 38 +++ 3 files changed, 551 insertions(+), 1 deletion(-) create mode 100644 test/data/responses-eg1.txt diff --git a/src/Filters/response.jl b/src/Filters/response.jl index d6c8dbacb..192d1258c 100644 --- a/src/Filters/response.jl +++ b/src/Filters/response.jl @@ -55,7 +55,7 @@ end # function stepz(filter::Filter, n=100) - i = [0, ones(n-1)] + i = ones(n) filt(filter, i) end diff --git a/test/data/responses-eg1.txt b/test/data/responses-eg1.txt new file mode 100644 index 000000000..9bedf225b --- /dev/null +++ b/test/data/responses-eg1.txt @@ -0,0 +1,512 @@ +0.000000000000 0.000281660753 0.000281660753 0.000100000000 0.000000000000 +0.006135923152 0.000566736519 0.000848397272 0.000099863801 -0.023703934294 +0.012271846303 0.000314032076 0.001162429349 0.000099455418 -0.047414187682 +0.018407769455 -0.000988512411 0.000173916937 0.000098775501 -0.071137085527 +0.024543692606 -0.002498455836 -0.002324538899 0.000097825131 -0.094878965380 +0.030679615758 -0.002261680062 -0.004586218961 0.000096605830 -0.118646183399 +0.036815538909 0.001384751168 -0.003201467793 0.000095119561 -0.142445120628 +0.042951462061 0.006633284926 0.003431817132 0.000093368739 -0.166282189022 +0.049087385212 0.008023410369 0.011455227501 0.000091356237 -0.190163838152 +0.055223308364 0.000948538865 0.012403766366 0.000089085393 -0.214096561252 +0.061359231515 -0.011969914825 0.000433851542 0.000086560028 -0.238086902027 +0.067495154667 -0.019497372317 -0.019063520775 0.000083784450 -0.262141461463 +0.073631077819 -0.010139304084 -0.029202824859 0.000080763477 -0.286266904207 +0.079767000970 0.014645240742 -0.014557584117 0.000077502445 -0.310469965856 +0.085902924122 0.035754122487 0.021196538369 0.000074007227 -0.334757458766 +0.092038847273 0.029648093937 0.050844632305 0.000070284254 -0.359136281965 +0.098174770425 -0.008072771833 0.042771860472 0.000066340532 -0.383613425133 +0.104310693576 -0.050922194708 -0.008150334237 0.000062183664 -0.408195980052 +0.110446616728 -0.058513231117 -0.066663565353 0.000057821872 -0.432891143980 +0.116582539879 -0.013354674570 -0.080018239921 0.000053264021 -0.457706232129 +0.122718463031 0.055330963043 -0.024687276879 0.000048519644 -0.482648683126 +0.128854386182 0.088767108753 0.064079831869 0.000043598967 -0.507726068472 +0.134990309334 0.049080043099 0.113159874961 0.000038512939 -0.532946102274 +0.141126232485 -0.040435120260 0.072724754700 0.000033273255 -0.558316649195 +0.147262155637 -0.106986392723 -0.034261638002 0.000027892390 -0.583845733930 +0.153398078789 -0.088995705367 -0.123257343326 0.000022383627 -0.609541554637 +0.159534001940 0.005915721323 -0.117341621961 0.000016761083 -0.635412488092 +0.165669925092 0.101381453655 -0.015960168308 0.000011039745 -0.661467104323 +0.171805848243 0.116243987182 0.100283818796 0.000005235497 -0.687714176564 +0.177941771395 0.036613243378 0.136897062042 0.000000634849 2.427429969522 +0.184077694546 -0.070530781416 0.066366280518 0.000006553528 2.400770785512 +0.190213617698 -0.116294447662 -0.049928167134 0.000012501786 2.373891490944 +0.196349540849 -0.067655774847 -0.117583941822 0.000018459860 2.346782366498 +0.202485464001 0.027229464813 -0.090354476776 0.000024406954 2.319433431886 +0.208621387152 0.087116359976 -0.003238116634 0.000030321211 2.291834423487 +0.214757310304 0.070874383323 0.067636266672 0.000036179702 2.263974778292 +0.220893233456 0.007027752749 0.074664019217 0.000041958410 2.235843616208 +0.227029156607 -0.042794986185 0.031869032748 0.000047632219 2.207429724186 +0.233165079759 -0.044358898820 -0.012489866284 0.000053174916 2.178721536608 +0.239301002910 -0.014956865882 -0.027446732191 0.000058559193 2.149707116678 +0.245436926062 0.006274650860 -0.021172081143 0.000063756666 2.120374135119 +0.251572849213 0.003449787415 -0.017722293409 0.000068737894 2.090709847698 +0.257708772365 -0.004731018396 -0.022453311529 0.000073472422 2.060701073498 +0.263844695516 0.005127935701 -0.017325375781 0.000077928832 2.030334170332 +0.269980618668 0.028422417730 0.011097041705 0.000082074810 1.999595008009 +0.276116541819 0.035862815564 0.046959856900 0.000085877233 1.968468940920 +0.282252464971 0.008685906060 0.055645762783 0.000089302284 1.936940778896 +0.288388388123 -0.035282064679 0.020363698321 0.000092315582 1.904994756526 +0.294524311274 -0.055814842219 -0.035451143446 0.000094882346 1.872614499160 +0.300660234426 -0.030965419310 -0.066416562518 0.000096967597 1.839782988773 +0.306796157577 0.019206510081 -0.047210052748 0.000098536384 1.806482522961 +0.312932080729 0.051413655388 0.004203601943 0.000099554063 1.772694681834 +0.319068003880 0.040759013193 0.044962614662 0.000099986616 1.738400276716 +0.325203927032 0.002279238033 0.047241852959 0.000099801025 1.703579309576 +0.331339850183 -0.027751841161 0.019490012694 0.000098965705 1.668210921885 +0.337475773335 -0.028427336052 -0.008937322534 0.000097450993 1.632273342902 +0.343611696486 -0.010170183527 -0.019107505988 0.000095229719 1.595743831857 +0.349747619638 0.003114120654 -0.015993386044 0.000092277849 1.558598618888 +0.355883542789 0.002048114114 -0.013945272798 0.000088575206 1.520812837423 +0.362019465941 -0.001606505716 -0.015551778881 0.000084106295 1.482360456679 +0.368155389093 0.005829409235 -0.009722369419 0.000078861218 1.443214204715 +0.374291312244 0.020084960764 0.010362591723 0.000072836688 1.403345484459 +0.380427235396 0.022618110061 0.032980701922 0.000066037161 1.362724291493 +0.386563158547 0.003368818393 0.036349520321 0.000058476075 1.321319110508 +0.392699081699 -0.024447147243 0.011902373360 0.000050177197 1.279096820558 +0.398835004850 -0.035564187394 -0.023661813396 0.000041176084 1.236022579263 +0.404970928002 -0.018428131663 -0.042089944602 0.000031521644 1.192059699165 +0.411106851153 0.012435705992 -0.029654239018 0.000021277783 1.147169515015 +0.417242774305 0.030700082137 0.001045841804 0.000010525122 1.101311247529 +0.423378697456 0.023646797102 0.024692637542 0.000000637255 4.196034338783 +0.429514620608 0.002208942322 0.026901579559 0.000012090069 4.148108462493 +0.435650543760 -0.013058391991 0.013843188694 0.000023692184 4.099077653395 +0.441786466911 -0.013053648253 0.000789542263 0.000035279113 4.048891098452 +0.447922390063 -0.005752848590 -0.004963305053 0.000046661799 3.997494761290 +0.454058313214 -0.002951337801 -0.007914642887 0.000057625818 3.944831310550 +0.460194236366 -0.005534831269 -0.013449475292 0.000067931207 3.890839795978 +0.466330159517 -0.004296563760 -0.017746040489 0.000077313131 3.835455417936 +0.472466082669 0.006165618170 -0.011580423357 0.000085483729 3.778609156125 +0.478602005820 0.018218070741 0.006637647012 0.000092135484 3.720227393501 +0.484737928972 0.018304708487 0.024942355815 0.000096946585 3.660231538504 +0.490873852123 0.002561001140 0.027503357962 0.000099588846 3.598537530540 +0.497009775275 -0.017091665233 0.010411694266 0.000099738814 3.535055374390 +0.503145698426 -0.023843486565 -0.013431790866 0.000097092832 3.469688548303 +0.509281621578 -0.012445596896 -0.025877387433 0.000091386905 3.402333334953 +0.515417544730 0.006189898092 -0.019687490727 0.000082422246 3.332878186290 +0.521553467881 0.016492646263 -0.003194847023 0.000070097410 3.261202820554 +0.527689391033 0.012994323067 0.009799473944 0.000054447741 3.187177326402 +0.533825314184 0.003172613209 0.012972087113 0.000035692529 3.110661150816 +0.539961237336 -0.002835484747 0.010136604620 0.000014289519 3.031501914639 +0.546097160487 -0.002940386618 0.007196221087 0.000009004867 6.091126656143 +0.552233083639 -0.002724367778 0.004471855094 0.000033073526 6.006169458190 +0.558369006790 -0.006168423699 -0.001696569312 0.000056382546 5.918025995105 +0.564504929942 -0.009580887776 -0.011277459694 0.000076944658 5.826480350062 +0.570640853093 -0.006104238874 -0.017381701252 0.000092325709 5.731295330682 +0.576776776245 0.004859160113 -0.012522542237 0.000099732742 5.632209683832 +0.582912699397 0.014915538358 0.002392997051 0.000096246269 5.528934292570 +0.589048622548 0.014510306290 0.016903305479 0.000079296477 5.421148298277 +0.595184545700 0.002971809514 0.019875117022 0.000047540886 5.308493977503 +0.601320468851 -0.010277116642 0.009598001305 0.000002390605 5.190571732973 +0.607456392003 -0.014728833637 -0.005130832811 0.000049428709 8.208519429978 +0.613592315154 -0.008451628485 -0.013582462845 0.000091679554 8.078644516401 +0.619728238306 0.001381136900 -0.012201327803 0.000091842297 7.941955540852 +0.625864161457 0.006666448773 -0.005534880267 0.000009686955 10.939375974288 +0.632000084609 0.005877748872 0.000342868686 0.000316705204 10.786942955014 +0.638136007760 0.003383475695 0.003726345803 0.001004174258 10.625340363317 +0.644271930912 0.002777315891 0.006503663653 0.002360630138 10.453486736999 +0.650407854064 0.002669369068 0.009173034017 0.004854790848 10.270077195464 +0.656543777215 -0.000439193994 0.008733839874 0.009240143197 10.073504358346 +0.662679700367 -0.006349843399 0.002383995081 0.016719049047 9.861737383177 +0.668815623518 -0.009951315209 -0.007567321768 0.029199189822 9.632130813850 +0.674951546670 -0.006477875576 -0.014045198219 0.049687936250 9.381121510422 +0.681087469821 0.002674222642 -0.011370975376 0.082869030906 9.103747577307 +0.687223392973 0.010387939742 -0.000983034780 0.135817156998 8.792968541338 +0.693359316124 0.010423578514 0.009440544613 0.218348112605 8.439026632227 +0.699495239276 0.003278674209 0.012719219402 0.340920353819 8.030191003000 +0.705631162427 -0.004705013011 0.008014206683 0.505043793904 7.558888121791 +0.711767085579 -0.007679883354 0.000334323351 0.685691294646 7.037247059460 +0.717903008730 -0.005256231418 -0.004921908451 0.834747411542 6.507224396590 +0.724038931882 -0.001384213902 -0.006306123205 0.925468371634 6.015797968184 +0.730174855034 0.000676268214 -0.005629855985 0.969399793670 5.582754977991 +0.736310778185 0.001323713965 -0.004306142507 0.988058862011 5.203852340571 +0.742446701337 0.002667267633 -0.001638874392 0.995477131347 4.867655788684 +0.748582624488 0.004756126217 0.003117253057 0.998325321942 4.563915900623 +0.754718547640 0.004926020221 0.008043274450 0.999393457665 4.285138691654 +0.760854470791 0.001136020394 0.009179295179 0.999785160931 4.026085730868 +0.766990393943 -0.004786167199 0.004393127350 0.999925544613 3.783057581000 +0.773126317094 -0.008116661602 -0.003723535298 0.999974999782 3.553359390411 +0.779262240246 -0.005732022303 -0.009455558365 0.999992056423 3.334958821463 +0.785398163397 0.000647407643 -0.008808150899 0.999997688120 3.126272618113 +0.791534086549 0.005974530330 -0.002833620320 0.999999278773 2.926033550063 +0.797670009701 0.006551876168 0.003718256241 0.999999577516 2.733203816464 +0.803805932852 0.003039937052 0.006758193729 0.999999781231 2.546917382004 +0.809941856004 -0.000972050924 0.005786143302 1.000000230395 2.366439681304 +0.816077779155 -0.002802064305 0.002984079426 0.999999820565 2.191140909765 +0.822213702307 -0.002695687080 0.000288392389 0.999999905450 2.020473030416 +0.828349625458 -0.002341489493 -0.002053097669 0.999999851340 1.853956462748 +0.834485548610 -0.002236946709 -0.004290045341 0.999999906728 1.691165640408 +0.840621471761 -0.001211776959 -0.005501823057 1.000000061058 1.531721740792 +0.846757394913 0.001511842480 -0.003989980591 0.999999864689 1.375283303780 +0.852893318064 0.004502768220 0.000512788383 0.999999802450 1.221541445054 +0.859029241216 0.005037050922 0.005549840313 1.000000076089 1.070214123700 +0.865165164368 0.001950914236 0.007500755183 1.000000050775 0.921041978904 +0.871301087519 -0.002757643847 0.004743111315 0.999999882019 0.773785481501 +0.877437010671 -0.005508350864 -0.000765240067 0.999999980589 0.628221493219 +0.883572933822 -0.004373205957 -0.005138446692 0.999999974864 0.484140759515 +0.889708856974 -0.000672187079 -0.005810634330 1.000000051328 0.341346161488 +0.895844780125 0.002553482021 -0.003257152637 1.000000095484 0.199650028020 +0.901980703277 0.003398852392 0.000141699766 1.000000087704 0.058873296864 +0.908116626428 0.002343870438 0.002485570653 1.000000074302 -0.081156556736 +0.914252549580 0.000984793766 0.003470365235 1.000000021291 -0.220606710691 +0.920388472731 0.000080910436 0.003551276482 1.000000039752 -0.359640535777 +0.926524395883 -0.000833444450 0.002717832314 1.000000036542 -0.498418338026 +0.932660319034 -0.002143056975 0.000574774809 0.999999896947 -0.637098903432 +0.938796242186 -0.003057620810 -0.002482847090 1.000000066268 -0.775840766373 +0.944932165338 -0.002255848695 -0.004738696770 1.000000009448 -0.914802833544 +0.951068088489 0.000416603599 -0.004322093444 0.999999955781 -1.054146101156 +0.957204011641 0.003260363204 -0.001061729674 1.000000007038 -1.194034586751 +0.963339934792 0.004049051476 0.002987322809 1.000000016241 -1.334636504717 +0.969475857944 0.002102893451 0.005090217116 1.000000036730 -1.476126088159 +0.975611781095 -0.001044735267 0.004045482158 1.000000005334 -1.618684536728 +0.981747704247 -0.003068201904 0.000977279964 1.000000008575 -1.762502206988 +0.987883627398 -0.002871319779 -0.001894040497 1.000000051270 -1.907780269151 +0.994019550550 -0.001223924023 -0.003117965295 1.000000035972 -2.054732935271 +1.000155473701 0.000377000503 -0.002740965353 1.000000003628 -2.203590059968 +1.006291396853 0.001182539154 -0.001558426294 0.999999934072 -2.354600413417 +1.012427320005 0.001467793882 -0.000090631947 0.999999939881 -2.508034906893 +1.018563243156 0.001625438632 0.001534807526 0.999999864186 -2.664191634665 +1.024699166308 0.001413390319 0.002948198626 0.999999682396 -2.823401115585 +1.030835089459 0.000324929231 0.003273128129 0.999998872379 -2.986033446068 +1.036971012611 -0.001439334271 0.001833793467 0.999997071437 -3.152507732041 +1.043106935762 -0.002715304252 -0.000881511582 0.999992404305 -3.323303706454 +1.049242858914 -0.002334239209 -0.003215751516 0.999981057407 -3.498978547845 +1.055378782065 -0.000342610456 -0.003558362255 0.999954027746 -3.680188786308 +1.061514705217 0.001864373103 -0.001693988942 0.999891417064 -3.867722135240 +1.067650628368 0.002718693243 0.001024704794 0.999749738247 -4.062541484279 +1.073786551520 0.001806252307 0.002830957618 0.999436262143 -4.265848422637 +1.079922474671 0.000061332604 0.002892290595 0.998756283381 -4.479172677090 +1.086058397823 -0.001237675112 0.001654615631 0.997309466139 -4.704493486107 +1.092194320975 -0.001551233263 0.000103382240 0.994288627906 -4.944390865840 +1.098330244126 -0.001210673104 -0.001107291271 0.988111373044 -5.202191514912 +1.104466167278 -0.000711798408 -0.001819090240 0.975806418062 -5.481986072707 +1.110602090429 -0.000136458056 -0.001955548745 0.952204895679 -5.788189859525 +1.116738013581 0.000662785776 -0.001292763037 0.909527730576 -6.124018535120 +1.122873936732 0.001494464927 0.000201702268 0.839128029286 -6.488277906342 +1.129009859884 0.001723615371 0.001925318255 0.737337484185 -6.871523345276 +1.135145783035 0.000880590307 0.002805909071 0.612318830384 -7.255929111892 +1.141281706187 -0.000684472981 0.002121436243 0.482409400222 -7.622128594011 +1.147417629338 -0.001911343744 0.000210092278 0.365099567399 -7.957613559286 +1.153553552490 -0.001902234317 -0.001692142472 0.269133826799 -8.258934259497 +1.159689475642 -0.000709504318 -0.002401647237 0.195255611444 -8.528482729646 +1.165825398793 0.000743544107 -0.001658103445 0.140289836859 -8.770774508550 +1.171961321945 0.001497257527 -0.000160846011 0.100135047758 -8.990366817072 +1.178097245096 0.001297635498 0.001136789674 0.071084270101 -9.191120619780 +1.184233168248 0.000584303344 0.001721093464 0.050183291041 -9.376102277400 +1.190369091399 -0.000101210447 0.001619883560 0.035203119764 -9.547700383432 +1.196505014551 -0.000572517242 0.001047366681 0.024503456511 -9.707778912660 +1.202640937702 -0.000899744181 0.000147622449 0.016890702126 -9.857809945964 +1.208776860854 -0.001038145061 -0.000890523091 0.011500375562 -9.998974933973 +1.214912784005 -0.000746108875 -0.001636632615 0.007707406217 -10.132238425190 +1.221048707157 0.000071523812 -0.001565109258 0.005060009805 -10.258400927154 +1.227184630309 0.001039290675 -0.000525818607 0.003231670331 -10.378136737189 +1.233320553460 0.001481082730 0.000955264508 0.001986462452 -10.492021358113 +1.239456476612 0.001000566223 0.001955831292 0.001154040025 -10.600551568958 +1.245592399763 -0.000110542575 0.001845289178 0.000611581534 -10.704160402510 +1.251728322915 -0.001080414876 0.000764874476 0.000270735245 -10.803228498255 +1.257864246066 -0.001296506741 -0.000531632423 0.000068161259 -10.898092877256 +1.264000169218 -0.000761476417 -0.001293109254 0.000041333453 -7.847461160557 +1.270136092369 0.000029744008 -0.001263365748 0.000089786031 -7.934787659220 +1.276272015521 0.000586976621 -0.000676389502 0.000099710876 -8.018721885192 +1.282407938672 0.000766831086 0.000090441529 0.000086746582 -8.099482782335 +1.288543861824 0.000689182850 0.000779624700 0.000061585011 -8.177269063916 +1.294679784975 0.000452540306 0.001232165556 0.000031376864 -8.252261715154 +1.300815708127 0.000038474942 0.001270640987 0.000000754910 -8.324626123252 +1.306951631279 -0.000510904974 0.000759736175 0.000027422349 -5.252921081941 +1.313087554430 -0.000932728265 -0.000172992331 0.000051531546 -5.320471204796 +1.319223477582 -0.000881051111 -0.001054043935 0.000070795031 -5.385812044612 +1.325359400733 -0.000270809141 -0.001324853547 0.000085000951 -5.449061987703 +1.331495323885 0.000549643728 -0.000775210046 0.000094303394 -5.510330562261 +1.337631247036 0.001029911707 0.000254701753 0.000099080933 -5.569719303771 +1.343767170188 0.000862505371 0.001117207454 0.000099837705 -5.627322516032 +1.349903093339 0.000219186904 0.001336394767 0.000097135323 -5.683227941368 +1.356039016491 -0.000432430122 0.000903964964 0.000091547070 -5.737517353278 +1.362174939642 -0.000725972263 0.000177992802 0.000083628062 -5.790267082181 +1.368310862794 -0.000623807361 -0.000445814724 0.000073896784 -5.841548484993 +1.374446785946 -0.000315682409 -0.000761497504 0.000062824629 -5.891428363333 +1.380582709097 0.000022591352 -0.000738906559 0.000050830976 -5.939969338772 +1.386718632249 0.000329649818 -0.000409256980 0.000038282037 -5.987230189465 +1.392854555400 0.000563626392 0.000154369469 0.000025492186 -6.033266153749 +1.398990478552 0.000605867146 0.000760236938 0.000012726845 -6.078129204285 +1.405126401703 0.000337916833 0.001098154186 0.000000206287 -6.121868290928 +1.411262324855 -0.000178473723 0.000919680754 0.000011890103 -3.022936935341 +1.417398248006 -0.000651933817 0.000267746970 0.000023419432 -3.064564001310 +1.423534171158 -0.000754997310 -0.000487250557 0.000034270956 -3.105198008812 +1.429670094309 -0.000400748130 -0.000887999031 0.000044361940 -3.144877891521 +1.435806017461 0.000169483550 -0.000718515789 0.000053633799 -3.183640504254 +1.441941940613 0.000580499911 -0.000138016020 0.000062048553 -3.221520764279 +1.448077863764 0.000615225913 0.000477209972 0.000069585634 -3.258551781041 +1.454213786916 0.000338756009 0.000815966242 0.000076239020 -3.294764975628 +1.460349710067 -0.000023467214 0.000792499354 0.000082014705 -3.330190190295 +1.466485633219 -0.000290881842 0.000501617747 0.000086928477 -3.364855789434 +1.472621556370 -0.000412740923 0.000088876851 0.000091003976 -3.398788752595 +1.478757479522 -0.000401376214 -0.000312499559 0.000094271022 -3.432014760489 +1.484893402673 -0.000252116758 -0.000564616629 0.000096764173 -3.464558274387 +1.491029325825 0.000032202166 -0.000532414727 0.000098521492 -3.496442609600 +1.497165248976 0.000357234882 -0.000175179929 0.000099583509 -3.527690003661 +1.503301172128 0.000535167663 0.000359987852 0.000099992338 -3.558321679502 +1.509437095279 0.000417030125 0.000777018215 0.000099790947 -3.588357904142 +1.515573018431 0.000042395389 0.000819413835 0.000099022548 -3.617818043262 +1.521708941583 -0.000357360086 0.000462053875 0.000097730101 -3.646720611996 +1.527844864734 -0.000528280479 -0.000066226616 0.000095955909 -3.675083322237 +1.533980787886 -0.000386393944 -0.000452620688 0.000093741296 -3.702923126763 +1.540116711037 -0.000061106020 -0.000513726892 0.000091126353 -3.730256260420 +1.546252634189 0.000233297081 -0.000280429983 0.000088149744 -3.757098278583 +1.552388557340 0.000361149112 0.000080719039 0.000084848561 -3.783464093142 +1.558524480492 0.000319965990 0.000400685062 0.000081258224 -3.809368006162 +1.564660403643 0.000175794819 0.000576480028 0.000077412413 -3.834823741419 +1.570796326795 -0.000014590598 0.000561889625 0.000073343030 -3.859844473962 +1.576932249946 -0.000209343126 0.000352546645 0.000069080184 -3.884442857834 +1.583068173098 -0.000342281434 0.000010265237 0.000064652203 -3.908631052125 +1.589204096250 -0.000326718981 -0.000316453845 0.000060085651 -3.932420745413 +1.595340019401 -0.000129236414 -0.000445690429 0.000055405365 -3.955823178779 +1.601475942553 0.000163152621 -0.000282537960 0.000050634504 -3.978849167446 +1.607611865704 0.000374939964 0.000092401934 0.000045794597 -4.001509121144 +1.613747788856 0.000367887347 0.000460289314 0.000040905606 -4.023813063325 +1.619883712007 0.000151024049 0.000611313474 0.000035985988 -4.045770649248 +1.626019635159 -0.000128154805 0.000483158807 0.000031052761 -4.067391183064 +1.632155558310 -0.000301473819 0.000181685097 0.000026121573 -4.088683633932 +1.638291481462 -0.000297200887 -0.000115515753 0.000021206768 -4.109656651248 +1.644427404613 -0.000160750413 -0.000276266218 0.000016321460 -4.130318579033 +1.650563327765 0.000013761084 -0.000262505253 0.000011477593 -4.150677469542 +1.656699250916 0.000156146684 -0.000106358702 0.000006686013 -4.170741096149 +1.662835174068 0.000234283624 0.000127924838 0.000001956533 -4.190516965526 +1.668971097220 0.000228297241 0.000356222084 0.000002702005 -1.068419675637 +1.675107020371 0.000124078848 0.000480301020 0.000007281671 -1.087641540963 +1.681242943523 -0.000055602411 0.000424698734 0.000011775385 -1.106596681462 +1.687378866674 -0.000228398774 0.000196300063 0.000016176862 -1.125291646672 +1.693514789826 -0.000288254359 -0.000091954260 0.000020480557 -1.143732771525 +1.699650712977 -0.000185261050 -0.000277215350 0.000024681617 -1.161926185209 +1.705786636129 0.000023809564 -0.000253405880 0.000028775828 -1.179877819605 +1.711922559280 0.000209585615 -0.000043820375 0.000032759572 -1.197593417308 +1.718058482432 0.000264362669 0.000220542216 0.000036629781 -1.215078539255 +1.724194405583 0.000174635768 0.000395177971 0.000040383895 -1.232338571977 +1.730330328735 0.000014023953 0.000409201986 0.000044019828 -1.249378734513 +1.736466251887 -0.000124229507 0.000284972589 0.000047535924 -1.266204084983 +1.742602175038 -0.000187278602 0.000097694094 0.000050930928 -1.282819526855 +1.748738098190 -0.000171204016 -0.000073509874 0.000054203951 -1.299229814926 +1.754874021341 -0.000094490575 -0.000168000484 0.000057354439 -1.315439561009 +1.761009944493 0.000019373022 -0.000148627561 0.000060382148 -1.331453239370 +1.767145867644 0.000134690899 -0.000013936773 0.000063287111 -1.347275191915 +1.773281790796 0.000198381026 0.000184444187 0.000066069622 -1.362909633136 +1.779417713947 0.000164760214 0.000349204408 0.000068730203 -1.378360654842 +1.785553637099 0.000037473018 0.000386677496 0.000071269589 -1.393632230671 +1.791689560250 -0.000116105354 0.000270572238 0.000073688708 -1.408728220410 +1.797825483402 -0.000203846211 0.000066726104 0.000075988655 -1.423652374121 +1.803961406554 -0.000174488092 -0.000107761962 0.000078170685 -1.438408336085 +1.810097329705 -0.000053563894 -0.000161325890 0.000080236188 -1.452999648583 +1.816233252857 0.000080521820 -0.000080804148 0.000082186678 -1.467429755507 +1.822369176008 0.000155591352 0.000074787118 0.000084023779 -1.481702005822 +1.828505099160 0.000147928023 0.000222715086 0.000085749211 -1.495819656878 +1.834641022311 0.000079828297 0.000302543389 0.000087364779 -1.509785877589 +1.840776945463 -0.000010288292 0.000292255159 0.000088872360 -1.523603751471 +1.846912868614 -0.000090120801 0.000202134445 0.000090273898 -1.537276279563 +1.853048791766 -0.000134907662 0.000067226850 0.000091571387 -1.550806383224 +1.859184714917 -0.000124452182 -0.000057225317 0.000092766868 -1.564196906813 +1.865320638069 -0.000053552307 -0.000110777666 0.000093862421 -1.577450620270 +1.871456561220 0.000051614665 -0.000059163074 0.000094860153 -1.590570221581 +1.877592484372 0.000136130213 0.000076967070 0.000095762196 -1.603558339157 +1.883728407524 0.000148181784 0.000225148822 0.000096570701 -1.616417534110 +1.889864330675 0.000077886369 0.000303035206 0.000097287827 -1.629150302442 +1.896000253827 -0.000032117225 0.000270918034 0.000097915744 -1.641759077151 +1.902136176978 -0.000116293048 0.000154625053 0.000098456620 -1.654246230254 +1.908272100130 -0.000131488308 0.000023136794 0.000098912622 -1.666614074728 +1.914408023281 -0.000080705413 -0.000057568608 0.000099285912 -1.678864866383 +1.920543946433 -0.000000830284 -0.000058398926 0.000099578641 -1.691000805663 +1.926679869584 0.000067635418 0.000009236428 0.000099792949 -1.703024039372 +1.932815792736 0.000100928412 0.000110164778 0.000099930957 -1.714936662344 +1.938951715887 0.000092735209 0.000202899957 0.000099994770 -1.726740719050 +1.945087639039 0.000047411774 0.000250311750 0.000099986474 -1.738438205135 +1.951223562191 -0.000020654158 0.000229657649 0.000099908129 -1.750031068915 +1.957359485342 -0.000084164604 0.000145493111 0.000099761773 -1.761521212803 +1.963495408494 -0.000109803230 0.000035689923 0.000099549418 -1.772910494697 +1.969631331645 -0.000078445565 -0.000042755644 0.000099273047 -1.784200729310 +1.975767254797 -0.000003379906 -0.000046135594 0.000098934616 -1.795393689452 +1.981903177948 0.000073162944 0.000027027287 0.000098536052 -1.806491107272 +1.988039101100 0.000106994545 0.000134021781 0.000098079248 -1.817494675449 +1.994175024251 0.000081778772 0.000215800539 0.000097566070 -1.828406048350 +2.000310947403 0.000017520418 0.000233320985 0.000096998350 -1.839226843136 +2.006446870554 -0.000047106281 0.000186214761 0.000096377887 -1.849958640842 +2.012582793706 -0.000081201227 0.000105013591 0.000095706447 -1.860602987408 +2.018718716858 -0.000075773658 0.000029239962 0.000094985765 -1.871161394686 +2.024854640009 -0.000040063222 -0.000010823274 0.000094217541 -1.881635341401 +2.030990563161 0.000009199202 -0.000001624121 0.000093403441 -1.892026274090 +2.037126486312 0.000054017108 0.000052392927 0.000092545097 -1.902335608004 +2.043262409464 0.000076765884 0.000129158772 0.000091644110 -1.912564727978 +2.049398332615 0.000064725601 0.000193884375 0.000090702045 -1.922714989277 +2.055534255767 0.000019366995 0.000213251409 0.000089720434 -1.932787718410 +2.061670178918 -0.000038436847 0.000174814619 0.000088700777 -1.942784213919 +2.067806102070 -0.000076995742 0.000097818921 0.000087644539 -1.952705747145 +2.073942025221 -0.000073697884 0.000024121047 0.000086553154 -1.962553562961 +2.080077948373 -0.000031070094 -0.000006949075 0.000085428022 -1.972328880488 +2.086213871524 0.000024863178 0.000017914053 0.000084270511 -1.982032893790 +2.092349794676 0.000062789160 0.000080703168 0.000083081959 -1.991666772537 +2.098485717828 0.000065822729 0.000146525878 0.000081863671 -2.001231662658 +2.104621640979 0.000038186168 0.000184712061 0.000080616921 -2.010728686966 +2.110757564131 -0.000002626055 0.000182086046 0.000079342953 -2.020158945765 +2.116893487282 -0.000038097254 0.000143988836 0.000078042980 -2.029523517442 +2.123029410434 -0.000055658238 0.000088330625 0.000076718187 -2.038823459031 +2.129165333585 -0.000049679128 0.000038651494 0.000075369727 -2.048059806775 +2.135301256737 -0.000021725420 0.000016926046 0.000073998727 -2.057233576653 +2.141437179888 0.000017756219 0.000034682226 0.000072606285 -2.066345764904 +2.147573103040 0.000050486588 0.000085168782 0.000071193470 -2.075397348530 +2.153709026191 0.000058401052 0.000143569825 0.000069761325 -2.084389285784 +2.159844949343 0.000035496804 0.000179066646 0.000068310866 -2.093322516642 +2.165980872495 -0.000006166811 0.000172899867 0.000066843084 -2.102197963265 +2.172116795646 -0.000043001915 0.000129897986 0.000065358941 -2.111016530445 +2.178252718798 -0.000055075489 0.000074822515 0.000063859378 -2.119779106034 +2.184388641949 -0.000038296578 0.000036525933 0.000062345307 -2.128486561368 +2.190524565101 -0.000004798942 0.000031726965 0.000060817621 -2.137139751672 +2.196660488252 0.000026940961 0.000058667892 0.000059277184 -2.145739516458 +2.202796411404 0.000043145654 0.000101813522 0.000057724840 -2.154286679905 +2.208932334555 0.000039504014 0.000141317532 0.000056161410 -2.162782051238 +2.215068257707 0.000019643577 0.000160961127 0.000054587692 -2.171226425085 +2.221204180858 -0.000008047355 0.000152913803 0.000053004464 -2.179620581833 +2.227340104010 -0.000032519322 0.000120394508 0.000051412481 -2.187965287967 +2.233476027161 -0.000042636631 0.000077757886 0.000049812477 -2.196261296407 +2.239611950313 -0.000032147103 0.000045610773 0.000048205169 -2.204509346824 +2.245747873465 -0.000004832087 0.000040778661 0.000046591251 -2.212710165962 +2.251883796616 0.000025411637 0.000066190272 0.000044971399 -2.220864467938 +2.258019719768 0.000041942366 0.000108132624 0.000043346270 -2.228972954542 +2.264155642919 0.000035863847 0.000143996476 0.000041716502 -2.237036315521 +2.270291566071 0.000011667750 0.000155664244 0.000040082718 -2.245055228868 +2.276427489222 -0.000016334677 0.000139329589 0.000038445520 -2.253030361086 +2.282563412374 -0.000033585627 0.000105743977 0.000036805494 -2.260962367462 +2.288699335525 -0.000033346760 0.000072397218 0.000035163210 -2.268851892319 +2.294835258677 -0.000018299875 0.000054097333 0.000033519223 -2.276699569272 +2.300971181828 0.000003238137 0.000057335454 0.000031874068 -2.284506021472 +2.307107104980 0.000022044387 0.000079379826 0.000030228270 -2.292271861843 +2.313243028132 0.000030859177 0.000110238996 0.000028582335 -2.299997693317 +2.319378951283 0.000025965237 0.000136204236 0.000026936755 -2.307684109056 +2.325514874435 0.000008803336 0.000145007581 0.000025292010 -2.315331692677 +2.331650797586 -0.000013227920 0.000131779675 0.000023648564 -2.322941018463 +2.337786720738 -0.000029120358 0.000102659328 0.000022006868 -2.330512651573 +2.343922643889 -0.000030075765 0.000072583568 0.000020367359 -2.338047148245 +2.350058567041 -0.000015308545 0.000057275019 0.000018730463 -2.345545055998 +2.356194490192 0.000006894911 0.000064169917 0.000017096593 -2.353006913817 +2.362330413344 0.000024259327 0.000088429229 0.000015466148 -2.360433252352 +2.368466336495 0.000028122834 0.000116552053 0.000013839518 -2.367824594091 +2.374602259647 0.000018016464 0.000134568517 0.000012217079 -2.375181453550 +2.380738182799 0.000000551999 0.000135120527 0.000010599197 -2.382504337436 +2.386874105950 -0.000015410866 0.000119709677 0.000008986227 -2.389793744826 +2.393010029102 -0.000023285938 0.000096423750 0.000007378513 -2.397050167330 +2.399145952253 -0.000020663329 0.000075760423 0.000005776389 -2.404274089253 +2.405281875405 -0.000009146524 0.000066613892 0.000004180180 -2.411465987752 +2.411417798556 0.000006437742 0.000073051621 0.000002590198 -2.418626332991 +2.417553721708 0.000019276195 0.000092327805 0.000001006749 -2.425755588292 +2.423689644859 0.000023036087 0.000115363887 0.000000569873 0.708738443307 +2.429825568011 0.000015281278 0.000130645167 0.000002139380 0.701670004556 +2.435961491162 -0.000000362056 0.000130283120 0.000003701495 0.694631305383 +2.442097414314 -0.000015607518 0.000114675614 0.000005255950 0.687621908402 +2.448233337465 -0.000022270991 0.000092404632 0.000006802483 0.680641382373 +2.454369260617 -0.000017227102 0.000075177532 0.000008340843 0.673689302065 +2.460505183769 -0.000003985683 0.000071191843 0.000009870783 0.666765248136 +2.466641106920 0.000010007356 0.000081199189 0.000011392068 0.659868807003 +2.472777030072 0.000017981610 0.000099180788 0.000012904466 0.652999570723 +2.478912953223 0.000017075989 0.000116256772 0.000014407756 0.646157136877 +2.485048876375 0.000008720913 0.000124977688 0.000015901721 0.639341108448 +2.491184799526 -0.000002930126 0.000122047572 0.000017386153 0.632551093714 +2.497320722678 -0.000012902521 0.000109145062 0.000018860850 0.625786706133 +2.503456645829 -0.000016975390 0.000092169679 0.000020325615 0.619047564238 +2.509592568981 -0.000013154105 0.000079015574 0.000021780259 0.612333291529 +2.515728492132 -0.000002894903 0.000076120665 0.000023224599 0.605643516370 +2.521864415284 0.000008944468 0.000085065124 0.000024658456 0.598977871889 +2.528000338436 0.000016250837 0.000101315952 0.000026081659 0.592335995878 +2.534136261587 0.000015107928 0.000116423877 0.000027494041 0.585717530698 +2.540272184739 0.000006270626 0.000122694506 0.000028895441 0.579122123180 +2.546408107890 -0.000005265343 0.000117429170 0.000030285703 0.572549424538 +2.552544031042 -0.000013375340 0.000104053840 0.000031664677 0.565999090275 +2.558679954193 -0.000014347022 0.000089706824 0.000033032217 0.559470780095 +2.564815877345 -0.000008503185 0.000081203639 0.000034388180 0.552964157815 +2.570951800496 0.000000698938 0.000081902572 0.000035732432 0.546478891283 +2.577087723648 0.000008878957 0.000090781519 0.000037064840 0.540014652293 +2.583223646799 0.000012669107 0.000103450618 0.000038385277 0.533571116502 +2.589359569951 0.000010709739 0.000114160356 0.000039693619 0.527147963355 +2.595495493103 0.000003924983 0.000118085345 0.000040989747 0.520744875999 +2.601631416254 -0.000004712760 0.000113372594 0.000042273546 0.514361541216 +2.607767339406 -0.000011160142 0.000102212459 0.000043544905 0.507997649340 +2.613903262557 -0.000012121789 0.000090090672 0.000044803716 0.501652894187 +2.620039185709 -0.000006959929 0.000083130739 0.000046049875 0.495326972984 +2.626175108860 0.000001658199 0.000084788931 0.000047283281 0.489019586295 +2.632311032012 0.000009139443 0.000093928369 0.000048503839 0.482730437957 +2.638446955163 0.000011636760 0.000105565127 0.000049711455 0.476459235005 +2.644582878315 0.000008213967 0.000113779095 0.000050906037 0.470205687612 +2.650718801466 0.000001092605 0.000114871704 0.000052087499 0.463969509021 +2.656854724618 -0.000005942805 0.000108928902 0.000053255757 0.457750415481 +2.662990647769 -0.000009673024 0.000099255881 0.000054410730 0.451548126184 +2.669126570921 -0.000008787194 0.000090468688 0.000055552338 0.445362363205 +2.675262494073 -0.000004045031 0.000086423657 0.000056680507 0.439192851438 +2.681398417224 0.000002328431 0.000088752086 0.000057795164 0.433039318544 +2.687534340376 0.000007530059 0.000096282141 0.000058896237 0.426901494882 +2.693670263527 0.000009194806 0.000105476944 0.000059983660 0.420779113462 +2.699806186679 0.000006441250 0.000111918194 0.000061057368 0.414671909883 +2.705942109830 0.000000504156 0.000112422351 0.000062117296 0.408579622281 +2.712078032982 -0.000005652437 0.000106769919 0.000063163384 0.402501991270 +2.718213956133 -0.000008837126 0.000097932797 0.000064195574 0.396438759897 +2.724349879285 -0.000007449517 0.000090483282 0.000065213810 0.390389673582 +2.730485802436 -0.000002400451 0.000088082830 0.000066218036 0.384354480071 +2.736621725588 0.000003511113 0.000091593939 0.000067208202 0.378332929383 +2.742757648740 0.000007290330 0.000098884264 0.000068184255 0.372324773762 +2.748893571891 0.000007333328 0.000106217588 0.000069146149 0.366329767630 +2.755029495043 0.000003995587 0.000110213175 0.000070093836 0.360347667535 +2.761165418194 -0.000000915004 0.000109298176 0.000071027272 0.354378232106 +2.767301341346 -0.000005140137 0.000104158047 0.000071946412 0.348421222006 +2.773437264497 -0.000006889331 0.000097268721 0.000072851217 0.342476399890 +2.779573187649 -0.000005451685 0.000091817037 0.000073741645 0.336543530354 +2.785709110800 -0.000001473831 0.000090343201 0.000074617659 0.330622379893 +2.791845033952 0.000003206301 0.000093549494 0.000075479221 0.324712716862 +2.797980957103 0.000006303939 0.000099853425 0.000076326297 0.318814311427 +2.804116880255 0.000006231915 0.000106085338 0.000077158851 0.312926935525 +2.810252803406 0.000003030566 0.000109115910 0.000077976852 0.307050362824 +2.816388726558 -0.000001584682 0.000107531238 0.000078780268 0.301184368681 +2.822524649710 -0.000005188874 0.000102342372 0.000079569068 0.295328730100 +2.828660572861 -0.000006024066 0.000096318308 0.000080343224 0.289483225696 +2.834796496013 -0.000003894326 0.000092423977 0.000081102708 0.283647635652 +2.840932419164 -0.000000084918 0.000092339050 0.000081847494 0.277821741684 +2.847068342316 0.000003481287 0.000095820330 0.000082577555 0.272005326998 +2.853204265467 0.000005223031 0.000101043358 0.000083292868 0.266198176259 +2.859340188619 0.000004509875 0.000105553235 0.000083993408 0.260400075548 +2.865476111770 0.000001781588 0.000107334830 0.000084679154 0.254610812328 +2.871612034922 -0.000001699012 0.000105635826 0.000085350084 0.248830175410 +2.877747958073 -0.000004341462 0.000101294369 0.000086006177 0.243057954913 +2.883883881225 -0.000004888657 0.000096405713 0.000086647414 0.237293942232 +2.890019804377 -0.000003043676 0.000093362033 0.000087273775 0.231537930003 +2.896155727528 0.000000288570 0.000093650596 0.000087885243 0.225789712066 +2.902291650680 0.000003404515 0.000097055103 0.000088481800 0.220049083434 +2.908427573831 0.000004713933 0.000101769032 0.000089063430 0.214315840261 +2.914563496983 0.000003622390 0.000105391425 0.000089630117 0.208589779804 +2.920699420134 0.000000817917 0.000106209349 0.000090181845 0.202870700392 +2.926835343286 -0.000002194185 0.000104015172 0.000090718602 0.197158401397 +2.932971266437 -0.000003953815 0.000100061363 0.000091240372 0.191452683199 +2.939107189589 -0.000003752553 0.000096308811 0.000091747143 0.185753347153 +2.945243112740 -0.000001845871 0.000094462934 0.000092238903 0.180060195560 +2.951379035892 0.000000797703 0.000095260629 0.000092715639 0.174373031637 +2.957514959044 0.000002971711 0.000098232333 0.000093177340 0.168691659482 +2.963650882195 0.000003718641 0.000101950973 0.000093623996 0.163015884047 +2.969786805347 0.000002710008 0.000104660985 0.000094055597 0.157345511109 +2.975922728498 0.000000415400 0.000105076391 0.000094472131 0.151680347234 +2.982058651650 -0.000002059239 0.000103017159 0.000094873592 0.146020199754 +2.988194574801 -0.000003481991 0.000099535171 0.000095259969 0.140364876734 +2.994330497953 -0.000003141432 0.000096393738 0.000095631254 0.134714186946 +3.000466421104 -0.000001250191 0.000095143543 0.000095987440 0.129067939834 +3.006602344256 0.000001173693 0.000096317229 0.000096328520 0.123425945491 +3.012738267407 0.000002888601 0.000099205825 0.000096654485 0.117788014629 +3.018874190559 0.000003102376 0.000102308200 0.000096965331 0.112153958551 +3.025010113710 0.000001831427 0.000104139630 0.000097261050 0.106523589120 +3.031146036862 -0.000000207901 0.000103931734 0.000097541637 0.100896718735 +3.037281960014 -0.000002025060 0.000101906679 0.000097807086 0.095273160300 +3.043417883165 -0.000002820601 0.000099086081 0.000098057393 0.089652727200 +3.049553806317 -0.000002291956 0.000096794126 0.000098292552 0.084035233270 +3.055689729468 -0.000000718810 0.000096075314 0.000098512560 0.078420492769 +3.061825652620 0.000001161782 0.000097237091 0.000098717412 0.072808320353 +3.067961575771 0.000002461974 0.000099699060 0.000098907104 0.067198531050 +3.074097498923 0.000002550324 0.000102249380 0.000099081633 0.061590940228 +3.080233422074 0.000001384117 0.000103633498 0.000099240996 0.055985363574 +3.086369345226 -0.000000438297 0.000103195205 0.000099385190 0.050381617062 +3.092505268377 -0.000001981637 0.000101213574 0.000099514212 0.044779516932 +3.098641191529 -0.000002480070 0.000098733510 0.000099628061 0.039178879656 +3.104777114681 -0.000001741175 0.000096992336 0.000099726733 0.033579521921 +3.110913037832 -0.000000208355 0.000096783977 0.000099810228 0.027981260594 +3.117048960984 0.000001324367 0.000098108337 0.000099878545 0.022383912700 +3.123184884135 0.000002139106 0.000100247436 0.000099931681 0.016787295397 +3.129320807287 0.000001916150 0.000102163583 0.000099969636 0.011191225944 +3.135456730438 0.000000824108 0.000102987693 0.000099992409 0.005595521681 diff --git a/test/filter_response.jl b/test/filter_response.jl index 6f565220b..a35108793 100644 --- a/test/filter_response.jl +++ b/test/filter_response.jl @@ -113,6 +113,44 @@ matlab_phasedeg = freqs_eg1_w_mag_phasedeg[:,3] #=xlabel("Frequency (rad/s)")=# #=file(figure, "MATLAB-freqs-phase.png", width=1200, height=800)=# +####################################### +# +# Test frequency, phase, impulse and step response +# +# Data from Matlab: +# [b,a]=cheby2(10, 80, [0.2 0.4]); +# ir = impz(b,a, 512); +# stepr = stepz(b,a, 512); +# h = abs(freqz(b,a)); +# [phi,f] = phasez(b, a); +# all = [f, ir, stepr, h, phi]; +# dlmwrite('responses-eg1.txt',all, 'delimiter', '\t', 'precision', '%.12f') +# +####################################### + +cheby2_matlab = readdlm(joinpath(dirname(@__FILE__), "data", "responses-eg1.txt"),'\t') +df = digitalfilter(Bandpass(0.2, 0.4), Chebyshev2(10, 80)) +w = cheby2_matlab[:,1] + +#Impulse response +impz_matlab = cheby2_matlab[:,2] +@test_approx_eq_eps(impz(df, 512), impz_matlab, 1e-7) + +#Step response +stepz_matlab = cheby2_matlab[:,3] +@test_approx_eq_eps(stepz(df, 512), stepz_matlab, 1e-7) + +h_matlab = cheby2_matlab[:,4] +@test_approx_eq_eps(abs(freqz(df, w)), h_matlab, 1e-5) + +phi_matlab = cheby2_matlab[:,5] +@test_approx_eq_eps(phasez(df, w), phi_matlab, 1e-5) + + +#Test if we get same results with summing impz and stepz +@test_approx_eq(cumsum(impz(df)), stepz(df)) + + ####################################### # From 1f620090aa7f54543d388b0865ade4b80a1aa02e Mon Sep 17 00:00:00 2001 From: Matti Pastell Date: Wed, 31 Dec 2014 16:33:46 +0200 Subject: [PATCH 10/26] Few more tests --- src/Filters/response.jl | 4 +--- test/filter_response.jl | 5 ++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Filters/response.jl b/src/Filters/response.jl index 192d1258c..4e3afa2e6 100644 --- a/src/Filters/response.jl +++ b/src/Filters/response.jl @@ -21,9 +21,7 @@ function freqz(filter::Filter, hz::Union(Number, AbstractVector), fs::Number) end function freqz(filter::Filter) - filter = convert(TFFilter, filter) - w = linspace(0, π, 250) - [freqz(filter, i) for i = w] + freqz(filter, linspace(0, π, 250)) end diff --git a/test/filter_response.jl b/test/filter_response.jl index a35108793..ad56fdf7a 100644 --- a/test/filter_response.jl +++ b/test/filter_response.jl @@ -147,11 +147,14 @@ phi_matlab = cheby2_matlab[:,5] @test_approx_eq_eps(phasez(df, w), phi_matlab, 1e-5) -#Test if we get same results with summing impz and stepz +# Test diffent versions of the functions +@test freqz(df) == freqz(df, linspace(0, pi, 250)) +@test phasez(df) == phasez(df, linspace(0, pi, 250)) @test_approx_eq(cumsum(impz(df)), stepz(df)) + ####################################### # # Test analog filter with frequency specified in hz From 621167a1c9c107d7db7326096c59f52b3972b544 Mon Sep 17 00:00:00 2001 From: Matti Pastell Date: Thu, 1 Jan 2015 01:27:21 +0200 Subject: [PATCH 11/26] Fixed response tests to use same b and a as Matlab --- test/data/responses-eg1.txt | 1024 +++++++++++++++++------------------ test/filter_response.jl | 76 +-- 2 files changed, 550 insertions(+), 550 deletions(-) diff --git a/test/data/responses-eg1.txt b/test/data/responses-eg1.txt index 9bedf225b..f8e6067d8 100644 --- a/test/data/responses-eg1.txt +++ b/test/data/responses-eg1.txt @@ -1,512 +1,512 @@ -0.000000000000 0.000281660753 0.000281660753 0.000100000000 0.000000000000 -0.006135923152 0.000566736519 0.000848397272 0.000099863801 -0.023703934294 -0.012271846303 0.000314032076 0.001162429349 0.000099455418 -0.047414187682 -0.018407769455 -0.000988512411 0.000173916937 0.000098775501 -0.071137085527 -0.024543692606 -0.002498455836 -0.002324538899 0.000097825131 -0.094878965380 -0.030679615758 -0.002261680062 -0.004586218961 0.000096605830 -0.118646183399 -0.036815538909 0.001384751168 -0.003201467793 0.000095119561 -0.142445120628 -0.042951462061 0.006633284926 0.003431817132 0.000093368739 -0.166282189022 -0.049087385212 0.008023410369 0.011455227501 0.000091356237 -0.190163838152 -0.055223308364 0.000948538865 0.012403766366 0.000089085393 -0.214096561252 -0.061359231515 -0.011969914825 0.000433851542 0.000086560028 -0.238086902027 -0.067495154667 -0.019497372317 -0.019063520775 0.000083784450 -0.262141461463 -0.073631077819 -0.010139304084 -0.029202824859 0.000080763477 -0.286266904207 -0.079767000970 0.014645240742 -0.014557584117 0.000077502445 -0.310469965856 -0.085902924122 0.035754122487 0.021196538369 0.000074007227 -0.334757458766 -0.092038847273 0.029648093937 0.050844632305 0.000070284254 -0.359136281965 -0.098174770425 -0.008072771833 0.042771860472 0.000066340532 -0.383613425133 -0.104310693576 -0.050922194708 -0.008150334237 0.000062183664 -0.408195980052 -0.110446616728 -0.058513231117 -0.066663565353 0.000057821872 -0.432891143980 -0.116582539879 -0.013354674570 -0.080018239921 0.000053264021 -0.457706232129 -0.122718463031 0.055330963043 -0.024687276879 0.000048519644 -0.482648683126 -0.128854386182 0.088767108753 0.064079831869 0.000043598967 -0.507726068472 -0.134990309334 0.049080043099 0.113159874961 0.000038512939 -0.532946102274 -0.141126232485 -0.040435120260 0.072724754700 0.000033273255 -0.558316649195 -0.147262155637 -0.106986392723 -0.034261638002 0.000027892390 -0.583845733930 -0.153398078789 -0.088995705367 -0.123257343326 0.000022383627 -0.609541554637 -0.159534001940 0.005915721323 -0.117341621961 0.000016761083 -0.635412488092 -0.165669925092 0.101381453655 -0.015960168308 0.000011039745 -0.661467104323 -0.171805848243 0.116243987182 0.100283818796 0.000005235497 -0.687714176564 -0.177941771395 0.036613243378 0.136897062042 0.000000634849 2.427429969522 -0.184077694546 -0.070530781416 0.066366280518 0.000006553528 2.400770785512 -0.190213617698 -0.116294447662 -0.049928167134 0.000012501786 2.373891490944 -0.196349540849 -0.067655774847 -0.117583941822 0.000018459860 2.346782366498 -0.202485464001 0.027229464813 -0.090354476776 0.000024406954 2.319433431886 -0.208621387152 0.087116359976 -0.003238116634 0.000030321211 2.291834423487 -0.214757310304 0.070874383323 0.067636266672 0.000036179702 2.263974778292 -0.220893233456 0.007027752749 0.074664019217 0.000041958410 2.235843616208 -0.227029156607 -0.042794986185 0.031869032748 0.000047632219 2.207429724186 -0.233165079759 -0.044358898820 -0.012489866284 0.000053174916 2.178721536608 -0.239301002910 -0.014956865882 -0.027446732191 0.000058559193 2.149707116678 -0.245436926062 0.006274650860 -0.021172081143 0.000063756666 2.120374135119 -0.251572849213 0.003449787415 -0.017722293409 0.000068737894 2.090709847698 -0.257708772365 -0.004731018396 -0.022453311529 0.000073472422 2.060701073498 -0.263844695516 0.005127935701 -0.017325375781 0.000077928832 2.030334170332 -0.269980618668 0.028422417730 0.011097041705 0.000082074810 1.999595008009 -0.276116541819 0.035862815564 0.046959856900 0.000085877233 1.968468940920 -0.282252464971 0.008685906060 0.055645762783 0.000089302284 1.936940778896 -0.288388388123 -0.035282064679 0.020363698321 0.000092315582 1.904994756526 -0.294524311274 -0.055814842219 -0.035451143446 0.000094882346 1.872614499160 -0.300660234426 -0.030965419310 -0.066416562518 0.000096967597 1.839782988773 -0.306796157577 0.019206510081 -0.047210052748 0.000098536384 1.806482522961 -0.312932080729 0.051413655388 0.004203601943 0.000099554063 1.772694681834 -0.319068003880 0.040759013193 0.044962614662 0.000099986616 1.738400276716 -0.325203927032 0.002279238033 0.047241852959 0.000099801025 1.703579309576 -0.331339850183 -0.027751841161 0.019490012694 0.000098965705 1.668210921885 -0.337475773335 -0.028427336052 -0.008937322534 0.000097450993 1.632273342902 -0.343611696486 -0.010170183527 -0.019107505988 0.000095229719 1.595743831857 -0.349747619638 0.003114120654 -0.015993386044 0.000092277849 1.558598618888 -0.355883542789 0.002048114114 -0.013945272798 0.000088575206 1.520812837423 -0.362019465941 -0.001606505716 -0.015551778881 0.000084106295 1.482360456679 -0.368155389093 0.005829409235 -0.009722369419 0.000078861218 1.443214204715 -0.374291312244 0.020084960764 0.010362591723 0.000072836688 1.403345484459 -0.380427235396 0.022618110061 0.032980701922 0.000066037161 1.362724291493 -0.386563158547 0.003368818393 0.036349520321 0.000058476075 1.321319110508 -0.392699081699 -0.024447147243 0.011902373360 0.000050177197 1.279096820558 -0.398835004850 -0.035564187394 -0.023661813396 0.000041176084 1.236022579263 -0.404970928002 -0.018428131663 -0.042089944602 0.000031521644 1.192059699165 -0.411106851153 0.012435705992 -0.029654239018 0.000021277783 1.147169515015 -0.417242774305 0.030700082137 0.001045841804 0.000010525122 1.101311247529 -0.423378697456 0.023646797102 0.024692637542 0.000000637255 4.196034338783 -0.429514620608 0.002208942322 0.026901579559 0.000012090069 4.148108462493 -0.435650543760 -0.013058391991 0.013843188694 0.000023692184 4.099077653395 -0.441786466911 -0.013053648253 0.000789542263 0.000035279113 4.048891098452 -0.447922390063 -0.005752848590 -0.004963305053 0.000046661799 3.997494761290 -0.454058313214 -0.002951337801 -0.007914642887 0.000057625818 3.944831310550 -0.460194236366 -0.005534831269 -0.013449475292 0.000067931207 3.890839795978 -0.466330159517 -0.004296563760 -0.017746040489 0.000077313131 3.835455417936 -0.472466082669 0.006165618170 -0.011580423357 0.000085483729 3.778609156125 -0.478602005820 0.018218070741 0.006637647012 0.000092135484 3.720227393501 -0.484737928972 0.018304708487 0.024942355815 0.000096946585 3.660231538504 -0.490873852123 0.002561001140 0.027503357962 0.000099588846 3.598537530540 -0.497009775275 -0.017091665233 0.010411694266 0.000099738814 3.535055374390 -0.503145698426 -0.023843486565 -0.013431790866 0.000097092832 3.469688548303 -0.509281621578 -0.012445596896 -0.025877387433 0.000091386905 3.402333334953 -0.515417544730 0.006189898092 -0.019687490727 0.000082422246 3.332878186290 -0.521553467881 0.016492646263 -0.003194847023 0.000070097410 3.261202820554 -0.527689391033 0.012994323067 0.009799473944 0.000054447741 3.187177326402 -0.533825314184 0.003172613209 0.012972087113 0.000035692529 3.110661150816 -0.539961237336 -0.002835484747 0.010136604620 0.000014289519 3.031501914639 -0.546097160487 -0.002940386618 0.007196221087 0.000009004867 6.091126656143 -0.552233083639 -0.002724367778 0.004471855094 0.000033073526 6.006169458190 -0.558369006790 -0.006168423699 -0.001696569312 0.000056382546 5.918025995105 -0.564504929942 -0.009580887776 -0.011277459694 0.000076944658 5.826480350062 -0.570640853093 -0.006104238874 -0.017381701252 0.000092325709 5.731295330682 -0.576776776245 0.004859160113 -0.012522542237 0.000099732742 5.632209683832 -0.582912699397 0.014915538358 0.002392997051 0.000096246269 5.528934292570 -0.589048622548 0.014510306290 0.016903305479 0.000079296477 5.421148298277 -0.595184545700 0.002971809514 0.019875117022 0.000047540886 5.308493977503 -0.601320468851 -0.010277116642 0.009598001305 0.000002390605 5.190571732973 -0.607456392003 -0.014728833637 -0.005130832811 0.000049428709 8.208519429978 -0.613592315154 -0.008451628485 -0.013582462845 0.000091679554 8.078644516401 -0.619728238306 0.001381136900 -0.012201327803 0.000091842297 7.941955540852 -0.625864161457 0.006666448773 -0.005534880267 0.000009686955 10.939375974288 -0.632000084609 0.005877748872 0.000342868686 0.000316705204 10.786942955014 -0.638136007760 0.003383475695 0.003726345803 0.001004174258 10.625340363317 -0.644271930912 0.002777315891 0.006503663653 0.002360630138 10.453486736999 -0.650407854064 0.002669369068 0.009173034017 0.004854790848 10.270077195464 -0.656543777215 -0.000439193994 0.008733839874 0.009240143197 10.073504358346 -0.662679700367 -0.006349843399 0.002383995081 0.016719049047 9.861737383177 -0.668815623518 -0.009951315209 -0.007567321768 0.029199189822 9.632130813850 -0.674951546670 -0.006477875576 -0.014045198219 0.049687936250 9.381121510422 -0.681087469821 0.002674222642 -0.011370975376 0.082869030906 9.103747577307 -0.687223392973 0.010387939742 -0.000983034780 0.135817156998 8.792968541338 -0.693359316124 0.010423578514 0.009440544613 0.218348112605 8.439026632227 -0.699495239276 0.003278674209 0.012719219402 0.340920353819 8.030191003000 -0.705631162427 -0.004705013011 0.008014206683 0.505043793904 7.558888121791 -0.711767085579 -0.007679883354 0.000334323351 0.685691294646 7.037247059460 -0.717903008730 -0.005256231418 -0.004921908451 0.834747411542 6.507224396590 -0.724038931882 -0.001384213902 -0.006306123205 0.925468371634 6.015797968184 -0.730174855034 0.000676268214 -0.005629855985 0.969399793670 5.582754977991 -0.736310778185 0.001323713965 -0.004306142507 0.988058862011 5.203852340571 -0.742446701337 0.002667267633 -0.001638874392 0.995477131347 4.867655788684 -0.748582624488 0.004756126217 0.003117253057 0.998325321942 4.563915900623 -0.754718547640 0.004926020221 0.008043274450 0.999393457665 4.285138691654 -0.760854470791 0.001136020394 0.009179295179 0.999785160931 4.026085730868 -0.766990393943 -0.004786167199 0.004393127350 0.999925544613 3.783057581000 -0.773126317094 -0.008116661602 -0.003723535298 0.999974999782 3.553359390411 -0.779262240246 -0.005732022303 -0.009455558365 0.999992056423 3.334958821463 -0.785398163397 0.000647407643 -0.008808150899 0.999997688120 3.126272618113 -0.791534086549 0.005974530330 -0.002833620320 0.999999278773 2.926033550063 -0.797670009701 0.006551876168 0.003718256241 0.999999577516 2.733203816464 -0.803805932852 0.003039937052 0.006758193729 0.999999781231 2.546917382004 -0.809941856004 -0.000972050924 0.005786143302 1.000000230395 2.366439681304 -0.816077779155 -0.002802064305 0.002984079426 0.999999820565 2.191140909765 -0.822213702307 -0.002695687080 0.000288392389 0.999999905450 2.020473030416 -0.828349625458 -0.002341489493 -0.002053097669 0.999999851340 1.853956462748 -0.834485548610 -0.002236946709 -0.004290045341 0.999999906728 1.691165640408 -0.840621471761 -0.001211776959 -0.005501823057 1.000000061058 1.531721740792 -0.846757394913 0.001511842480 -0.003989980591 0.999999864689 1.375283303780 -0.852893318064 0.004502768220 0.000512788383 0.999999802450 1.221541445054 -0.859029241216 0.005037050922 0.005549840313 1.000000076089 1.070214123700 -0.865165164368 0.001950914236 0.007500755183 1.000000050775 0.921041978904 -0.871301087519 -0.002757643847 0.004743111315 0.999999882019 0.773785481501 -0.877437010671 -0.005508350864 -0.000765240067 0.999999980589 0.628221493219 -0.883572933822 -0.004373205957 -0.005138446692 0.999999974864 0.484140759515 -0.889708856974 -0.000672187079 -0.005810634330 1.000000051328 0.341346161488 -0.895844780125 0.002553482021 -0.003257152637 1.000000095484 0.199650028020 -0.901980703277 0.003398852392 0.000141699766 1.000000087704 0.058873296864 -0.908116626428 0.002343870438 0.002485570653 1.000000074302 -0.081156556736 -0.914252549580 0.000984793766 0.003470365235 1.000000021291 -0.220606710691 -0.920388472731 0.000080910436 0.003551276482 1.000000039752 -0.359640535777 -0.926524395883 -0.000833444450 0.002717832314 1.000000036542 -0.498418338026 -0.932660319034 -0.002143056975 0.000574774809 0.999999896947 -0.637098903432 -0.938796242186 -0.003057620810 -0.002482847090 1.000000066268 -0.775840766373 -0.944932165338 -0.002255848695 -0.004738696770 1.000000009448 -0.914802833544 -0.951068088489 0.000416603599 -0.004322093444 0.999999955781 -1.054146101156 -0.957204011641 0.003260363204 -0.001061729674 1.000000007038 -1.194034586751 -0.963339934792 0.004049051476 0.002987322809 1.000000016241 -1.334636504717 -0.969475857944 0.002102893451 0.005090217116 1.000000036730 -1.476126088159 -0.975611781095 -0.001044735267 0.004045482158 1.000000005334 -1.618684536728 -0.981747704247 -0.003068201904 0.000977279964 1.000000008575 -1.762502206988 -0.987883627398 -0.002871319779 -0.001894040497 1.000000051270 -1.907780269151 -0.994019550550 -0.001223924023 -0.003117965295 1.000000035972 -2.054732935271 -1.000155473701 0.000377000503 -0.002740965353 1.000000003628 -2.203590059968 -1.006291396853 0.001182539154 -0.001558426294 0.999999934072 -2.354600413417 -1.012427320005 0.001467793882 -0.000090631947 0.999999939881 -2.508034906893 -1.018563243156 0.001625438632 0.001534807526 0.999999864186 -2.664191634665 -1.024699166308 0.001413390319 0.002948198626 0.999999682396 -2.823401115585 -1.030835089459 0.000324929231 0.003273128129 0.999998872379 -2.986033446068 -1.036971012611 -0.001439334271 0.001833793467 0.999997071437 -3.152507732041 -1.043106935762 -0.002715304252 -0.000881511582 0.999992404305 -3.323303706454 -1.049242858914 -0.002334239209 -0.003215751516 0.999981057407 -3.498978547845 -1.055378782065 -0.000342610456 -0.003558362255 0.999954027746 -3.680188786308 -1.061514705217 0.001864373103 -0.001693988942 0.999891417064 -3.867722135240 -1.067650628368 0.002718693243 0.001024704794 0.999749738247 -4.062541484279 -1.073786551520 0.001806252307 0.002830957618 0.999436262143 -4.265848422637 -1.079922474671 0.000061332604 0.002892290595 0.998756283381 -4.479172677090 -1.086058397823 -0.001237675112 0.001654615631 0.997309466139 -4.704493486107 -1.092194320975 -0.001551233263 0.000103382240 0.994288627906 -4.944390865840 -1.098330244126 -0.001210673104 -0.001107291271 0.988111373044 -5.202191514912 -1.104466167278 -0.000711798408 -0.001819090240 0.975806418062 -5.481986072707 -1.110602090429 -0.000136458056 -0.001955548745 0.952204895679 -5.788189859525 -1.116738013581 0.000662785776 -0.001292763037 0.909527730576 -6.124018535120 -1.122873936732 0.001494464927 0.000201702268 0.839128029286 -6.488277906342 -1.129009859884 0.001723615371 0.001925318255 0.737337484185 -6.871523345276 -1.135145783035 0.000880590307 0.002805909071 0.612318830384 -7.255929111892 -1.141281706187 -0.000684472981 0.002121436243 0.482409400222 -7.622128594011 -1.147417629338 -0.001911343744 0.000210092278 0.365099567399 -7.957613559286 -1.153553552490 -0.001902234317 -0.001692142472 0.269133826799 -8.258934259497 -1.159689475642 -0.000709504318 -0.002401647237 0.195255611444 -8.528482729646 -1.165825398793 0.000743544107 -0.001658103445 0.140289836859 -8.770774508550 -1.171961321945 0.001497257527 -0.000160846011 0.100135047758 -8.990366817072 -1.178097245096 0.001297635498 0.001136789674 0.071084270101 -9.191120619780 -1.184233168248 0.000584303344 0.001721093464 0.050183291041 -9.376102277400 -1.190369091399 -0.000101210447 0.001619883560 0.035203119764 -9.547700383432 -1.196505014551 -0.000572517242 0.001047366681 0.024503456511 -9.707778912660 -1.202640937702 -0.000899744181 0.000147622449 0.016890702126 -9.857809945964 -1.208776860854 -0.001038145061 -0.000890523091 0.011500375562 -9.998974933973 -1.214912784005 -0.000746108875 -0.001636632615 0.007707406217 -10.132238425190 -1.221048707157 0.000071523812 -0.001565109258 0.005060009805 -10.258400927154 -1.227184630309 0.001039290675 -0.000525818607 0.003231670331 -10.378136737189 -1.233320553460 0.001481082730 0.000955264508 0.001986462452 -10.492021358113 -1.239456476612 0.001000566223 0.001955831292 0.001154040025 -10.600551568958 -1.245592399763 -0.000110542575 0.001845289178 0.000611581534 -10.704160402510 -1.251728322915 -0.001080414876 0.000764874476 0.000270735245 -10.803228498255 -1.257864246066 -0.001296506741 -0.000531632423 0.000068161259 -10.898092877256 -1.264000169218 -0.000761476417 -0.001293109254 0.000041333453 -7.847461160557 -1.270136092369 0.000029744008 -0.001263365748 0.000089786031 -7.934787659220 -1.276272015521 0.000586976621 -0.000676389502 0.000099710876 -8.018721885192 -1.282407938672 0.000766831086 0.000090441529 0.000086746582 -8.099482782335 -1.288543861824 0.000689182850 0.000779624700 0.000061585011 -8.177269063916 -1.294679784975 0.000452540306 0.001232165556 0.000031376864 -8.252261715154 -1.300815708127 0.000038474942 0.001270640987 0.000000754910 -8.324626123252 -1.306951631279 -0.000510904974 0.000759736175 0.000027422349 -5.252921081941 -1.313087554430 -0.000932728265 -0.000172992331 0.000051531546 -5.320471204796 -1.319223477582 -0.000881051111 -0.001054043935 0.000070795031 -5.385812044612 -1.325359400733 -0.000270809141 -0.001324853547 0.000085000951 -5.449061987703 -1.331495323885 0.000549643728 -0.000775210046 0.000094303394 -5.510330562261 -1.337631247036 0.001029911707 0.000254701753 0.000099080933 -5.569719303771 -1.343767170188 0.000862505371 0.001117207454 0.000099837705 -5.627322516032 -1.349903093339 0.000219186904 0.001336394767 0.000097135323 -5.683227941368 -1.356039016491 -0.000432430122 0.000903964964 0.000091547070 -5.737517353278 -1.362174939642 -0.000725972263 0.000177992802 0.000083628062 -5.790267082181 -1.368310862794 -0.000623807361 -0.000445814724 0.000073896784 -5.841548484993 -1.374446785946 -0.000315682409 -0.000761497504 0.000062824629 -5.891428363333 -1.380582709097 0.000022591352 -0.000738906559 0.000050830976 -5.939969338772 -1.386718632249 0.000329649818 -0.000409256980 0.000038282037 -5.987230189465 -1.392854555400 0.000563626392 0.000154369469 0.000025492186 -6.033266153749 -1.398990478552 0.000605867146 0.000760236938 0.000012726845 -6.078129204285 -1.405126401703 0.000337916833 0.001098154186 0.000000206287 -6.121868290928 -1.411262324855 -0.000178473723 0.000919680754 0.000011890103 -3.022936935341 -1.417398248006 -0.000651933817 0.000267746970 0.000023419432 -3.064564001310 -1.423534171158 -0.000754997310 -0.000487250557 0.000034270956 -3.105198008812 -1.429670094309 -0.000400748130 -0.000887999031 0.000044361940 -3.144877891521 -1.435806017461 0.000169483550 -0.000718515789 0.000053633799 -3.183640504254 -1.441941940613 0.000580499911 -0.000138016020 0.000062048553 -3.221520764279 -1.448077863764 0.000615225913 0.000477209972 0.000069585634 -3.258551781041 -1.454213786916 0.000338756009 0.000815966242 0.000076239020 -3.294764975628 -1.460349710067 -0.000023467214 0.000792499354 0.000082014705 -3.330190190295 -1.466485633219 -0.000290881842 0.000501617747 0.000086928477 -3.364855789434 -1.472621556370 -0.000412740923 0.000088876851 0.000091003976 -3.398788752595 -1.478757479522 -0.000401376214 -0.000312499559 0.000094271022 -3.432014760489 -1.484893402673 -0.000252116758 -0.000564616629 0.000096764173 -3.464558274387 -1.491029325825 0.000032202166 -0.000532414727 0.000098521492 -3.496442609600 -1.497165248976 0.000357234882 -0.000175179929 0.000099583509 -3.527690003661 -1.503301172128 0.000535167663 0.000359987852 0.000099992338 -3.558321679502 -1.509437095279 0.000417030125 0.000777018215 0.000099790947 -3.588357904142 -1.515573018431 0.000042395389 0.000819413835 0.000099022548 -3.617818043262 -1.521708941583 -0.000357360086 0.000462053875 0.000097730101 -3.646720611996 -1.527844864734 -0.000528280479 -0.000066226616 0.000095955909 -3.675083322237 -1.533980787886 -0.000386393944 -0.000452620688 0.000093741296 -3.702923126763 -1.540116711037 -0.000061106020 -0.000513726892 0.000091126353 -3.730256260420 -1.546252634189 0.000233297081 -0.000280429983 0.000088149744 -3.757098278583 -1.552388557340 0.000361149112 0.000080719039 0.000084848561 -3.783464093142 -1.558524480492 0.000319965990 0.000400685062 0.000081258224 -3.809368006162 -1.564660403643 0.000175794819 0.000576480028 0.000077412413 -3.834823741419 -1.570796326795 -0.000014590598 0.000561889625 0.000073343030 -3.859844473962 -1.576932249946 -0.000209343126 0.000352546645 0.000069080184 -3.884442857834 -1.583068173098 -0.000342281434 0.000010265237 0.000064652203 -3.908631052125 -1.589204096250 -0.000326718981 -0.000316453845 0.000060085651 -3.932420745413 -1.595340019401 -0.000129236414 -0.000445690429 0.000055405365 -3.955823178779 -1.601475942553 0.000163152621 -0.000282537960 0.000050634504 -3.978849167446 -1.607611865704 0.000374939964 0.000092401934 0.000045794597 -4.001509121144 -1.613747788856 0.000367887347 0.000460289314 0.000040905606 -4.023813063325 -1.619883712007 0.000151024049 0.000611313474 0.000035985988 -4.045770649248 -1.626019635159 -0.000128154805 0.000483158807 0.000031052761 -4.067391183064 -1.632155558310 -0.000301473819 0.000181685097 0.000026121573 -4.088683633932 -1.638291481462 -0.000297200887 -0.000115515753 0.000021206768 -4.109656651248 -1.644427404613 -0.000160750413 -0.000276266218 0.000016321460 -4.130318579033 -1.650563327765 0.000013761084 -0.000262505253 0.000011477593 -4.150677469542 -1.656699250916 0.000156146684 -0.000106358702 0.000006686013 -4.170741096149 -1.662835174068 0.000234283624 0.000127924838 0.000001956533 -4.190516965526 -1.668971097220 0.000228297241 0.000356222084 0.000002702005 -1.068419675637 -1.675107020371 0.000124078848 0.000480301020 0.000007281671 -1.087641540963 -1.681242943523 -0.000055602411 0.000424698734 0.000011775385 -1.106596681462 -1.687378866674 -0.000228398774 0.000196300063 0.000016176862 -1.125291646672 -1.693514789826 -0.000288254359 -0.000091954260 0.000020480557 -1.143732771525 -1.699650712977 -0.000185261050 -0.000277215350 0.000024681617 -1.161926185209 -1.705786636129 0.000023809564 -0.000253405880 0.000028775828 -1.179877819605 -1.711922559280 0.000209585615 -0.000043820375 0.000032759572 -1.197593417308 -1.718058482432 0.000264362669 0.000220542216 0.000036629781 -1.215078539255 -1.724194405583 0.000174635768 0.000395177971 0.000040383895 -1.232338571977 -1.730330328735 0.000014023953 0.000409201986 0.000044019828 -1.249378734513 -1.736466251887 -0.000124229507 0.000284972589 0.000047535924 -1.266204084983 -1.742602175038 -0.000187278602 0.000097694094 0.000050930928 -1.282819526855 -1.748738098190 -0.000171204016 -0.000073509874 0.000054203951 -1.299229814926 -1.754874021341 -0.000094490575 -0.000168000484 0.000057354439 -1.315439561009 -1.761009944493 0.000019373022 -0.000148627561 0.000060382148 -1.331453239370 -1.767145867644 0.000134690899 -0.000013936773 0.000063287111 -1.347275191915 -1.773281790796 0.000198381026 0.000184444187 0.000066069622 -1.362909633136 -1.779417713947 0.000164760214 0.000349204408 0.000068730203 -1.378360654842 -1.785553637099 0.000037473018 0.000386677496 0.000071269589 -1.393632230671 -1.791689560250 -0.000116105354 0.000270572238 0.000073688708 -1.408728220410 -1.797825483402 -0.000203846211 0.000066726104 0.000075988655 -1.423652374121 -1.803961406554 -0.000174488092 -0.000107761962 0.000078170685 -1.438408336085 -1.810097329705 -0.000053563894 -0.000161325890 0.000080236188 -1.452999648583 -1.816233252857 0.000080521820 -0.000080804148 0.000082186678 -1.467429755507 -1.822369176008 0.000155591352 0.000074787118 0.000084023779 -1.481702005822 -1.828505099160 0.000147928023 0.000222715086 0.000085749211 -1.495819656878 -1.834641022311 0.000079828297 0.000302543389 0.000087364779 -1.509785877589 -1.840776945463 -0.000010288292 0.000292255159 0.000088872360 -1.523603751471 -1.846912868614 -0.000090120801 0.000202134445 0.000090273898 -1.537276279563 -1.853048791766 -0.000134907662 0.000067226850 0.000091571387 -1.550806383224 -1.859184714917 -0.000124452182 -0.000057225317 0.000092766868 -1.564196906813 -1.865320638069 -0.000053552307 -0.000110777666 0.000093862421 -1.577450620270 -1.871456561220 0.000051614665 -0.000059163074 0.000094860153 -1.590570221581 -1.877592484372 0.000136130213 0.000076967070 0.000095762196 -1.603558339157 -1.883728407524 0.000148181784 0.000225148822 0.000096570701 -1.616417534110 -1.889864330675 0.000077886369 0.000303035206 0.000097287827 -1.629150302442 -1.896000253827 -0.000032117225 0.000270918034 0.000097915744 -1.641759077151 -1.902136176978 -0.000116293048 0.000154625053 0.000098456620 -1.654246230254 -1.908272100130 -0.000131488308 0.000023136794 0.000098912622 -1.666614074728 -1.914408023281 -0.000080705413 -0.000057568608 0.000099285912 -1.678864866383 -1.920543946433 -0.000000830284 -0.000058398926 0.000099578641 -1.691000805663 -1.926679869584 0.000067635418 0.000009236428 0.000099792949 -1.703024039372 -1.932815792736 0.000100928412 0.000110164778 0.000099930957 -1.714936662344 -1.938951715887 0.000092735209 0.000202899957 0.000099994770 -1.726740719050 -1.945087639039 0.000047411774 0.000250311750 0.000099986474 -1.738438205135 -1.951223562191 -0.000020654158 0.000229657649 0.000099908129 -1.750031068915 -1.957359485342 -0.000084164604 0.000145493111 0.000099761773 -1.761521212803 -1.963495408494 -0.000109803230 0.000035689923 0.000099549418 -1.772910494697 -1.969631331645 -0.000078445565 -0.000042755644 0.000099273047 -1.784200729310 -1.975767254797 -0.000003379906 -0.000046135594 0.000098934616 -1.795393689452 -1.981903177948 0.000073162944 0.000027027287 0.000098536052 -1.806491107272 -1.988039101100 0.000106994545 0.000134021781 0.000098079248 -1.817494675449 -1.994175024251 0.000081778772 0.000215800539 0.000097566070 -1.828406048350 -2.000310947403 0.000017520418 0.000233320985 0.000096998350 -1.839226843136 -2.006446870554 -0.000047106281 0.000186214761 0.000096377887 -1.849958640842 -2.012582793706 -0.000081201227 0.000105013591 0.000095706447 -1.860602987408 -2.018718716858 -0.000075773658 0.000029239962 0.000094985765 -1.871161394686 -2.024854640009 -0.000040063222 -0.000010823274 0.000094217541 -1.881635341401 -2.030990563161 0.000009199202 -0.000001624121 0.000093403441 -1.892026274090 -2.037126486312 0.000054017108 0.000052392927 0.000092545097 -1.902335608004 -2.043262409464 0.000076765884 0.000129158772 0.000091644110 -1.912564727978 -2.049398332615 0.000064725601 0.000193884375 0.000090702045 -1.922714989277 -2.055534255767 0.000019366995 0.000213251409 0.000089720434 -1.932787718410 -2.061670178918 -0.000038436847 0.000174814619 0.000088700777 -1.942784213919 -2.067806102070 -0.000076995742 0.000097818921 0.000087644539 -1.952705747145 -2.073942025221 -0.000073697884 0.000024121047 0.000086553154 -1.962553562961 -2.080077948373 -0.000031070094 -0.000006949075 0.000085428022 -1.972328880488 -2.086213871524 0.000024863178 0.000017914053 0.000084270511 -1.982032893790 -2.092349794676 0.000062789160 0.000080703168 0.000083081959 -1.991666772537 -2.098485717828 0.000065822729 0.000146525878 0.000081863671 -2.001231662658 -2.104621640979 0.000038186168 0.000184712061 0.000080616921 -2.010728686966 -2.110757564131 -0.000002626055 0.000182086046 0.000079342953 -2.020158945765 -2.116893487282 -0.000038097254 0.000143988836 0.000078042980 -2.029523517442 -2.123029410434 -0.000055658238 0.000088330625 0.000076718187 -2.038823459031 -2.129165333585 -0.000049679128 0.000038651494 0.000075369727 -2.048059806775 -2.135301256737 -0.000021725420 0.000016926046 0.000073998727 -2.057233576653 -2.141437179888 0.000017756219 0.000034682226 0.000072606285 -2.066345764904 -2.147573103040 0.000050486588 0.000085168782 0.000071193470 -2.075397348530 -2.153709026191 0.000058401052 0.000143569825 0.000069761325 -2.084389285784 -2.159844949343 0.000035496804 0.000179066646 0.000068310866 -2.093322516642 -2.165980872495 -0.000006166811 0.000172899867 0.000066843084 -2.102197963265 -2.172116795646 -0.000043001915 0.000129897986 0.000065358941 -2.111016530445 -2.178252718798 -0.000055075489 0.000074822515 0.000063859378 -2.119779106034 -2.184388641949 -0.000038296578 0.000036525933 0.000062345307 -2.128486561368 -2.190524565101 -0.000004798942 0.000031726965 0.000060817621 -2.137139751672 -2.196660488252 0.000026940961 0.000058667892 0.000059277184 -2.145739516458 -2.202796411404 0.000043145654 0.000101813522 0.000057724840 -2.154286679905 -2.208932334555 0.000039504014 0.000141317532 0.000056161410 -2.162782051238 -2.215068257707 0.000019643577 0.000160961127 0.000054587692 -2.171226425085 -2.221204180858 -0.000008047355 0.000152913803 0.000053004464 -2.179620581833 -2.227340104010 -0.000032519322 0.000120394508 0.000051412481 -2.187965287967 -2.233476027161 -0.000042636631 0.000077757886 0.000049812477 -2.196261296407 -2.239611950313 -0.000032147103 0.000045610773 0.000048205169 -2.204509346824 -2.245747873465 -0.000004832087 0.000040778661 0.000046591251 -2.212710165962 -2.251883796616 0.000025411637 0.000066190272 0.000044971399 -2.220864467938 -2.258019719768 0.000041942366 0.000108132624 0.000043346270 -2.228972954542 -2.264155642919 0.000035863847 0.000143996476 0.000041716502 -2.237036315521 -2.270291566071 0.000011667750 0.000155664244 0.000040082718 -2.245055228868 -2.276427489222 -0.000016334677 0.000139329589 0.000038445520 -2.253030361086 -2.282563412374 -0.000033585627 0.000105743977 0.000036805494 -2.260962367462 -2.288699335525 -0.000033346760 0.000072397218 0.000035163210 -2.268851892319 -2.294835258677 -0.000018299875 0.000054097333 0.000033519223 -2.276699569272 -2.300971181828 0.000003238137 0.000057335454 0.000031874068 -2.284506021472 -2.307107104980 0.000022044387 0.000079379826 0.000030228270 -2.292271861843 -2.313243028132 0.000030859177 0.000110238996 0.000028582335 -2.299997693317 -2.319378951283 0.000025965237 0.000136204236 0.000026936755 -2.307684109056 -2.325514874435 0.000008803336 0.000145007581 0.000025292010 -2.315331692677 -2.331650797586 -0.000013227920 0.000131779675 0.000023648564 -2.322941018463 -2.337786720738 -0.000029120358 0.000102659328 0.000022006868 -2.330512651573 -2.343922643889 -0.000030075765 0.000072583568 0.000020367359 -2.338047148245 -2.350058567041 -0.000015308545 0.000057275019 0.000018730463 -2.345545055998 -2.356194490192 0.000006894911 0.000064169917 0.000017096593 -2.353006913817 -2.362330413344 0.000024259327 0.000088429229 0.000015466148 -2.360433252352 -2.368466336495 0.000028122834 0.000116552053 0.000013839518 -2.367824594091 -2.374602259647 0.000018016464 0.000134568517 0.000012217079 -2.375181453550 -2.380738182799 0.000000551999 0.000135120527 0.000010599197 -2.382504337436 -2.386874105950 -0.000015410866 0.000119709677 0.000008986227 -2.389793744826 -2.393010029102 -0.000023285938 0.000096423750 0.000007378513 -2.397050167330 -2.399145952253 -0.000020663329 0.000075760423 0.000005776389 -2.404274089253 -2.405281875405 -0.000009146524 0.000066613892 0.000004180180 -2.411465987752 -2.411417798556 0.000006437742 0.000073051621 0.000002590198 -2.418626332991 -2.417553721708 0.000019276195 0.000092327805 0.000001006749 -2.425755588292 -2.423689644859 0.000023036087 0.000115363887 0.000000569873 0.708738443307 -2.429825568011 0.000015281278 0.000130645167 0.000002139380 0.701670004556 -2.435961491162 -0.000000362056 0.000130283120 0.000003701495 0.694631305383 -2.442097414314 -0.000015607518 0.000114675614 0.000005255950 0.687621908402 -2.448233337465 -0.000022270991 0.000092404632 0.000006802483 0.680641382373 -2.454369260617 -0.000017227102 0.000075177532 0.000008340843 0.673689302065 -2.460505183769 -0.000003985683 0.000071191843 0.000009870783 0.666765248136 -2.466641106920 0.000010007356 0.000081199189 0.000011392068 0.659868807003 -2.472777030072 0.000017981610 0.000099180788 0.000012904466 0.652999570723 -2.478912953223 0.000017075989 0.000116256772 0.000014407756 0.646157136877 -2.485048876375 0.000008720913 0.000124977688 0.000015901721 0.639341108448 -2.491184799526 -0.000002930126 0.000122047572 0.000017386153 0.632551093714 -2.497320722678 -0.000012902521 0.000109145062 0.000018860850 0.625786706133 -2.503456645829 -0.000016975390 0.000092169679 0.000020325615 0.619047564238 -2.509592568981 -0.000013154105 0.000079015574 0.000021780259 0.612333291529 -2.515728492132 -0.000002894903 0.000076120665 0.000023224599 0.605643516370 -2.521864415284 0.000008944468 0.000085065124 0.000024658456 0.598977871889 -2.528000338436 0.000016250837 0.000101315952 0.000026081659 0.592335995878 -2.534136261587 0.000015107928 0.000116423877 0.000027494041 0.585717530698 -2.540272184739 0.000006270626 0.000122694506 0.000028895441 0.579122123180 -2.546408107890 -0.000005265343 0.000117429170 0.000030285703 0.572549424538 -2.552544031042 -0.000013375340 0.000104053840 0.000031664677 0.565999090275 -2.558679954193 -0.000014347022 0.000089706824 0.000033032217 0.559470780095 -2.564815877345 -0.000008503185 0.000081203639 0.000034388180 0.552964157815 -2.570951800496 0.000000698938 0.000081902572 0.000035732432 0.546478891283 -2.577087723648 0.000008878957 0.000090781519 0.000037064840 0.540014652293 -2.583223646799 0.000012669107 0.000103450618 0.000038385277 0.533571116502 -2.589359569951 0.000010709739 0.000114160356 0.000039693619 0.527147963355 -2.595495493103 0.000003924983 0.000118085345 0.000040989747 0.520744875999 -2.601631416254 -0.000004712760 0.000113372594 0.000042273546 0.514361541216 -2.607767339406 -0.000011160142 0.000102212459 0.000043544905 0.507997649340 -2.613903262557 -0.000012121789 0.000090090672 0.000044803716 0.501652894187 -2.620039185709 -0.000006959929 0.000083130739 0.000046049875 0.495326972984 -2.626175108860 0.000001658199 0.000084788931 0.000047283281 0.489019586295 -2.632311032012 0.000009139443 0.000093928369 0.000048503839 0.482730437957 -2.638446955163 0.000011636760 0.000105565127 0.000049711455 0.476459235005 -2.644582878315 0.000008213967 0.000113779095 0.000050906037 0.470205687612 -2.650718801466 0.000001092605 0.000114871704 0.000052087499 0.463969509021 -2.656854724618 -0.000005942805 0.000108928902 0.000053255757 0.457750415481 -2.662990647769 -0.000009673024 0.000099255881 0.000054410730 0.451548126184 -2.669126570921 -0.000008787194 0.000090468688 0.000055552338 0.445362363205 -2.675262494073 -0.000004045031 0.000086423657 0.000056680507 0.439192851438 -2.681398417224 0.000002328431 0.000088752086 0.000057795164 0.433039318544 -2.687534340376 0.000007530059 0.000096282141 0.000058896237 0.426901494882 -2.693670263527 0.000009194806 0.000105476944 0.000059983660 0.420779113462 -2.699806186679 0.000006441250 0.000111918194 0.000061057368 0.414671909883 -2.705942109830 0.000000504156 0.000112422351 0.000062117296 0.408579622281 -2.712078032982 -0.000005652437 0.000106769919 0.000063163384 0.402501991270 -2.718213956133 -0.000008837126 0.000097932797 0.000064195574 0.396438759897 -2.724349879285 -0.000007449517 0.000090483282 0.000065213810 0.390389673582 -2.730485802436 -0.000002400451 0.000088082830 0.000066218036 0.384354480071 -2.736621725588 0.000003511113 0.000091593939 0.000067208202 0.378332929383 -2.742757648740 0.000007290330 0.000098884264 0.000068184255 0.372324773762 -2.748893571891 0.000007333328 0.000106217588 0.000069146149 0.366329767630 -2.755029495043 0.000003995587 0.000110213175 0.000070093836 0.360347667535 -2.761165418194 -0.000000915004 0.000109298176 0.000071027272 0.354378232106 -2.767301341346 -0.000005140137 0.000104158047 0.000071946412 0.348421222006 -2.773437264497 -0.000006889331 0.000097268721 0.000072851217 0.342476399890 -2.779573187649 -0.000005451685 0.000091817037 0.000073741645 0.336543530354 -2.785709110800 -0.000001473831 0.000090343201 0.000074617659 0.330622379893 -2.791845033952 0.000003206301 0.000093549494 0.000075479221 0.324712716862 -2.797980957103 0.000006303939 0.000099853425 0.000076326297 0.318814311427 -2.804116880255 0.000006231915 0.000106085338 0.000077158851 0.312926935525 -2.810252803406 0.000003030566 0.000109115910 0.000077976852 0.307050362824 -2.816388726558 -0.000001584682 0.000107531238 0.000078780268 0.301184368681 -2.822524649710 -0.000005188874 0.000102342372 0.000079569068 0.295328730100 -2.828660572861 -0.000006024066 0.000096318308 0.000080343224 0.289483225696 -2.834796496013 -0.000003894326 0.000092423977 0.000081102708 0.283647635652 -2.840932419164 -0.000000084918 0.000092339050 0.000081847494 0.277821741684 -2.847068342316 0.000003481287 0.000095820330 0.000082577555 0.272005326998 -2.853204265467 0.000005223031 0.000101043358 0.000083292868 0.266198176259 -2.859340188619 0.000004509875 0.000105553235 0.000083993408 0.260400075548 -2.865476111770 0.000001781588 0.000107334830 0.000084679154 0.254610812328 -2.871612034922 -0.000001699012 0.000105635826 0.000085350084 0.248830175410 -2.877747958073 -0.000004341462 0.000101294369 0.000086006177 0.243057954913 -2.883883881225 -0.000004888657 0.000096405713 0.000086647414 0.237293942232 -2.890019804377 -0.000003043676 0.000093362033 0.000087273775 0.231537930003 -2.896155727528 0.000000288570 0.000093650596 0.000087885243 0.225789712066 -2.902291650680 0.000003404515 0.000097055103 0.000088481800 0.220049083434 -2.908427573831 0.000004713933 0.000101769032 0.000089063430 0.214315840261 -2.914563496983 0.000003622390 0.000105391425 0.000089630117 0.208589779804 -2.920699420134 0.000000817917 0.000106209349 0.000090181845 0.202870700392 -2.926835343286 -0.000002194185 0.000104015172 0.000090718602 0.197158401397 -2.932971266437 -0.000003953815 0.000100061363 0.000091240372 0.191452683199 -2.939107189589 -0.000003752553 0.000096308811 0.000091747143 0.185753347153 -2.945243112740 -0.000001845871 0.000094462934 0.000092238903 0.180060195560 -2.951379035892 0.000000797703 0.000095260629 0.000092715639 0.174373031637 -2.957514959044 0.000002971711 0.000098232333 0.000093177340 0.168691659482 -2.963650882195 0.000003718641 0.000101950973 0.000093623996 0.163015884047 -2.969786805347 0.000002710008 0.000104660985 0.000094055597 0.157345511109 -2.975922728498 0.000000415400 0.000105076391 0.000094472131 0.151680347234 -2.982058651650 -0.000002059239 0.000103017159 0.000094873592 0.146020199754 -2.988194574801 -0.000003481991 0.000099535171 0.000095259969 0.140364876734 -2.994330497953 -0.000003141432 0.000096393738 0.000095631254 0.134714186946 -3.000466421104 -0.000001250191 0.000095143543 0.000095987440 0.129067939834 -3.006602344256 0.000001173693 0.000096317229 0.000096328520 0.123425945491 -3.012738267407 0.000002888601 0.000099205825 0.000096654485 0.117788014629 -3.018874190559 0.000003102376 0.000102308200 0.000096965331 0.112153958551 -3.025010113710 0.000001831427 0.000104139630 0.000097261050 0.106523589120 -3.031146036862 -0.000000207901 0.000103931734 0.000097541637 0.100896718735 -3.037281960014 -0.000002025060 0.000101906679 0.000097807086 0.095273160300 -3.043417883165 -0.000002820601 0.000099086081 0.000098057393 0.089652727200 -3.049553806317 -0.000002291956 0.000096794126 0.000098292552 0.084035233270 -3.055689729468 -0.000000718810 0.000096075314 0.000098512560 0.078420492769 -3.061825652620 0.000001161782 0.000097237091 0.000098717412 0.072808320353 -3.067961575771 0.000002461974 0.000099699060 0.000098907104 0.067198531050 -3.074097498923 0.000002550324 0.000102249380 0.000099081633 0.061590940228 -3.080233422074 0.000001384117 0.000103633498 0.000099240996 0.055985363574 -3.086369345226 -0.000000438297 0.000103195205 0.000099385190 0.050381617062 -3.092505268377 -0.000001981637 0.000101213574 0.000099514212 0.044779516932 -3.098641191529 -0.000002480070 0.000098733510 0.000099628061 0.039178879656 -3.104777114681 -0.000001741175 0.000096992336 0.000099726733 0.033579521921 -3.110913037832 -0.000000208355 0.000096783977 0.000099810228 0.027981260594 -3.117048960984 0.000001324367 0.000098108337 0.000099878545 0.022383912700 -3.123184884135 0.000002139106 0.000100247436 0.000099931681 0.016787295397 -3.129320807287 0.000001916150 0.000102163583 0.000099969636 0.011191225944 -3.135456730438 0.000000824108 0.000102987693 0.000099992409 0.005595521681 +0.000000000000 0.056340000000 0.056340000000 0.999876487956 0.000000000000 +0.006135923152 0.119018250000 0.175358250000 0.999795845387 -0.019872906571 +0.012271846303 0.151990527933 0.327348777933 0.999554189259 -0.039739337295 +0.018407769455 0.198306227576 0.525655005509 0.999152332703 -0.059592845322 +0.024543692606 0.215837990989 0.741492996498 0.998591625659 -0.079427041614 +0.030679615758 0.188485300631 0.929978297128 0.997873947012 -0.099235623374 +0.036815538909 0.124153654612 1.054131951741 0.997001693741 -0.119012401923 +0.042951462061 0.045493426819 1.099625378560 0.995977767203 -0.138751329853 +0.049087385212 -0.022119065905 1.077506312655 0.994805556740 -0.158446527281 +0.055223308364 -0.060753127335 1.016753185321 0.993488920799 -0.178092307074 +0.061359231515 -0.065178645537 0.951574539784 0.992032165820 -0.197683198900 +0.067495154667 -0.042446455367 0.909128084417 0.990440023132 -0.217213971997 +0.073631077819 -0.007151127535 0.901976956882 0.988717624138 -0.236679656562 +0.079767000970 0.025050772593 0.927027729475 0.986870474081 -0.256075563681 +0.085902924122 0.043020740586 0.970048470060 0.984904424681 -0.275397303746 +0.092038847273 0.043033880195 1.013082350256 0.982825645948 -0.294640803324 +0.098174770425 0.028515005478 1.041597355734 0.980640597463 -0.313802320457 +0.104310693576 0.007345450831 1.048942806565 0.978355999421 -0.332878458398 +0.110446616728 -0.011826744815 1.037116061750 0.975978803724 -0.351866177818 +0.116582539879 -0.022783245490 1.014332816260 0.973516165377 -0.370762807501 +0.122718463031 -0.023424171818 0.990908644442 0.970975414449 -0.389566053609 +0.128854386182 -0.015668475740 0.975240168702 0.968364028824 -0.408274007580 +0.134990309334 -0.003967257812 0.971272910890 0.965689607957 -0.426885152748 +0.141126232485 0.006766083338 0.978038994229 0.962959847810 -0.445398369788 +0.147262155637 0.012965582868 0.991004577097 0.960182517139 -0.463812941094 +0.153398078789 0.013382423925 1.004387001022 0.957365435271 -0.482128554221 +0.159534001940 0.009046992547 1.013433993569 0.954516451470 -0.500345304512 +0.165669925092 0.002442236201 1.015876229770 0.951643425997 -0.518463697048 +0.171805848243 -0.003661663877 1.012214565893 0.948754212921 -0.536484648063 +0.177941771395 -0.007234792527 1.004979773366 0.945856644725 -0.554409485981 +0.184077694546 -0.007546170319 0.997433603046 0.942958518733 -0.572239952200 +0.190213617698 -0.005154100553 0.992279502494 0.940067585353 -0.589978201797 +0.196349540849 -0.001447701496 0.990831800997 0.937191538141 -0.607626804298 +0.202485464001 0.002008385944 0.992840186941 0.934338005630 -0.625188744659 +0.208621387152 0.004056802064 0.996896989005 0.931514544900 -0.642667424627 +0.214757310304 0.004268836954 1.001165825959 0.928728636823 -0.660066664621 +0.220893233456 0.002945419187 1.004111245146 0.925987682923 -0.677390706294 +0.227029156607 0.000862828876 1.004974074022 0.923299003751 -0.694644215939 +0.233165079759 -0.001095815901 1.003878258121 0.920669838724 -0.711832288872 +0.239301002910 -0.002271132190 1.001607125931 0.918107347302 -0.728960454984 +0.245436926062 -0.002412288825 0.999194837107 0.915618611413 -0.746034685585 +0.251572849213 -0.001681233610 0.997513603497 0.913210639027 -0.763061401730 +0.257708772365 -0.000511748178 0.997001855319 0.910890368753 -0.780047484186 +0.263844695516 0.000597735979 0.997599591298 0.908664675338 -0.797000285201 +0.269980618668 0.001271595932 0.998871187230 0.906540375954 -0.813927642272 +0.276116541819 0.001363244493 1.000234431723 0.904524237119 -0.830837894083 +0.282252464971 0.000959584533 1.001194016256 0.902622982117 -0.847739898810 +0.288388388123 0.000302925344 1.001496941600 0.900843298755 -0.864643055006 +0.294524311274 -0.000325478481 1.001171463119 0.899191847285 -0.881557325271 +0.300660234426 -0.000711710358 1.000459752761 0.897675268303 -0.898493262948 +0.306796157577 -0.000770219912 0.999689532849 0.896300190398 -0.915462042080 +0.312932080729 -0.000547506258 0.999142026591 0.895073237332 -0.932475490899 +0.319068003880 -0.000178884251 0.998963142339 0.894001034457 -0.949546129118 +0.325203927032 0.000176966599 0.999140108938 0.893090214062 -0.966687209333 +0.331339850183 0.000398249860 0.999538358799 0.892347419279 -0.983912762839 +0.337475773335 0.000435096980 0.999973455779 0.891779306121 -1.001237650214 +0.343611696486 0.000312306452 1.000285762230 0.891392543154 -1.018677617016 +0.349747619638 0.000105419777 1.000391182007 0.891193808198 -1.036249354975 +0.355883542789 -0.000096054647 1.000295127359 0.891189781368 -1.053970569073 +0.362019465941 -0.000222787103 1.000072340257 0.891387133621 -1.071860050911 +0.368155389093 -0.000245741720 0.999826598537 0.891792509815 -1.089937758787 +0.374291312244 -0.000178095385 0.999648503152 0.892412505118 -1.108224904881 +0.380427235396 -0.000062007037 0.999586496115 0.893253633365 -1.126744049957 +0.386563158547 0.000052042130 0.999638538244 0.894322285712 -1.145519205939 +0.392699081699 0.000124597129 0.999763135374 0.895624677608 -1.164575946676 +0.398835004850 0.000138769990 0.999901905363 0.897166781761 -1.183941527130 +0.404970928002 0.000101533349 1.000003438713 0.898954244319 -1.203645011078 +0.411106851153 0.000036408097 1.000039846810 0.900992281000 -1.223717407274 +0.417242774305 -0.000028140335 1.000011706475 0.903285549317 -1.244191813740 +0.423378697456 -0.000069663661 0.999942042814 0.905837992357 -1.265103569542 +0.429514620608 -0.000078349355 0.999863693459 0.908652648845 -1.286490412942 +0.435650543760 -0.000057869627 0.999805823833 0.911731423323 -1.308392644249 +0.441786466911 -0.000021342685 0.999784481148 0.915074809365 -1.330853290885 +0.447922390063 0.000015183205 0.999799664353 0.918681557718 -1.353918271205 +0.454058313214 0.000038938808 0.999838603160 0.922548280233 -1.377636552322 +0.460194236366 0.000044228133 0.999882831294 0.926668979402 -1.402060295523 +0.466330159517 0.000032974695 0.999915805988 0.931034492448 -1.427244980858 +0.472466082669 0.000012492380 0.999928298368 0.935631838276 -1.453249499900 +0.478602005820 -0.000008172734 0.999920125635 0.940443455440 -1.480136202548 +0.484737928972 -0.000021758777 0.999898366858 0.945446319920 -1.507970879997 +0.490873852123 -0.000024962323 0.999873404535 0.950610933382 -1.536822661469 +0.497009775275 -0.000018784557 0.999854619978 0.955900176164 -1.566763797170 +0.503145698426 -0.000007301827 0.999847318151 0.961268025405 -1.597869294066 +0.509281621578 0.000004387700 0.999851705851 0.966658148225 -1.630216364843 +0.515417544730 0.000012155116 0.999863860968 0.972002393882 -1.663883644114 +0.521553467881 0.000014086221 0.999877947189 0.977219228406 -1.698950120260 +0.527689391033 0.000010698258 0.999888645447 0.982212181464 -1.735493727324 +0.533825314184 0.000004262345 0.999892907792 0.986868408844 -1.773589540556 +0.539961237336 -0.000002348827 0.999890558965 0.991057514777 -1.813307523682 +0.546097160487 -0.000006788186 0.999883770779 0.994630824748 -1.854709788295 +0.552233083639 -0.000007947435 0.999875823344 0.997421347586 -1.897847348937 +0.558369006790 -0.000006091426 0.999869731918 0.999244708080 -1.942756394509 +0.564504929942 -0.000002485037 0.999867246881 0.999901357135 -1.989454149993 +0.570640853093 0.000001253336 0.999868500217 0.999180360172 -2.037934472497 +0.576776776245 0.000003789793 0.999872290010 0.996865008252 -2.088163409801 +0.582912699397 0.000004483140 0.999876773150 0.992740373136 -2.140075040240 +0.589048622548 0.000003467531 0.999880240680 0.986602726575 -2.193567996508 +0.595184545700 0.000001447161 0.999881687842 0.978270469825 -2.248503133544 +0.601320468851 -0.000000666374 0.999881021468 0.967595898048 -2.304702809369 +0.607456392003 -0.000002115150 0.999878906318 0.954476809042 -2.361952186318 +0.613592315154 -0.000002528484 0.999876377834 0.938866731395 -2.420002816447 +0.619728238306 -0.000001973416 0.999874404418 0.920782474972 -2.478578553070 +0.625864161457 -0.000000841843 0.999873562575 0.900307857839 -2.537383556575 +0.632000084609 0.000000352859 0.999873915434 0.877592852260 -2.596111882428 +0.638136007760 0.000001180123 0.999875095557 0.852847967166 -2.654457909527 +0.644271930912 0.000001425807 0.999876521364 0.826334334468 -2.712126739152 +0.650407854064 0.000001122835 0.999877644199 0.798350550201 -2.768843699338 +0.656543777215 0.000000489217 0.999878133416 0.769217710919 -2.824362225296 +0.662679700367 -0.000000185983 0.999877947433 0.739264207712 -2.878469621428 +0.668815623518 -0.000000658220 0.999877289213 0.708811695120 -2.930990491887 +0.674951546670 -0.000000803865 0.999876485348 0.678163305832 -2.981787898348 +0.681087469821 -0.000000638724 0.999875846624 0.647594736350 -3.030762520762 +0.687223392973 -0.000000284023 0.999875562601 0.617348386200 -3.077850235122 +0.693359316124 0.000000097507 0.999875660108 0.587630370419 -3.123018578455 +0.699495239276 0.000000367002 0.999876027110 0.558609980436 -3.166262558676 +0.705631162427 0.000000453135 0.999876480245 0.530421045865 -3.207600206924 +0.711767085579 0.000000363255 0.999876843500 0.503164628812 -3.247068185273 +0.717903008730 0.000000164744 0.999877008244 0.476912532055 -3.284717672105 +0.724038931882 -0.000000050806 0.999876957438 0.451711191451 -3.320610664092 +0.730174855034 -0.000000204557 0.999876752881 0.427585625499 -3.354816764689 +0.736310778185 -0.000000255384 0.999876497496 0.404543213681 -3.387410476862 +0.742446701337 -0.000000206545 0.999876290952 0.382577160056 -3.418468981715 +0.748582624488 -0.000000095475 0.999876195477 0.361669565639 -3.448070362281 +0.754718547640 0.000000026281 0.999876221758 0.341794082414 -3.476292220050 +0.760854470791 0.000000113975 0.999876335733 0.322918155391 -3.503210627773 +0.766990393943 0.000000143907 0.999876479639 0.305004880151 -3.528899363133 +0.773126317094 0.000000117414 0.999876597053 0.288014514778 -3.553429372014 +0.779262240246 0.000000055286 0.999876652339 0.271905689876 -3.576868415858 +0.785398163397 -0.000000013478 0.999876638861 0.256636360636 -3.599280863868 +0.791534086549 -0.000000063481 0.999876575381 0.242164542566 -3.620727597106 +0.797670009701 -0.000000081075 0.999876494305 0.228448868493 -3.641265997270 +0.803805932852 -0.000000066732 0.999876427574 0.215448999950 -3.660949998113 +0.809941856004 -0.000000031989 0.999876395585 0.203125921349 -3.679830181881 +0.816077779155 0.000000006839 0.999876402424 0.191442140902 -3.697953906882 +0.822213702307 0.000000035344 0.999876437768 0.180361818221 -3.715365455393 +0.828349625458 0.000000045669 0.999876483437 0.169850834969 -3.732106193617 +0.834485548610 0.000000037918 0.999876521355 0.159876821854 -3.748214737434 +0.840621471761 0.000000018495 0.999876539850 0.150409152696 -3.763727119298 +0.846757394913 -0.000000003426 0.999876536424 0.141418914123 -3.778676952878 +0.852893318064 -0.000000019671 0.999876516754 0.132878857665 -3.793095593071 +0.859029241216 -0.000000025720 0.999876491034 0.124763339588 -3.807012289725 +0.865165164368 -0.000000021541 0.999876469493 0.117048252605 -3.820454334036 +0.871301087519 -0.000000010686 0.999876458807 0.109710952667 -3.833447196993 +0.877437010671 0.000000001688 0.999876460494 0.102730183288 -3.846014659595 +0.883572933822 0.000000010943 0.999876471438 0.096085999227 -3.858178934782 +0.889708856974 0.000000014482 0.999876485920 0.089759690912 -3.869960781218 +0.895844780125 0.000000012235 0.999876498155 0.083733710595 -3.881379609169 +0.901980703277 0.000000006170 0.999876504325 0.077991600923 -3.892453578804 +0.908116626428 -0.000000000813 0.999876503511 0.072517926425 -3.903199691296 +0.914252549580 -0.000000006086 0.999876497426 0.067298208199 -3.913633873154 +0.920388472731 -0.000000008153 0.999876489273 0.062318861965 -3.923771054169 +0.926524395883 -0.000000006948 0.999876482325 0.057567139574 -3.933625239442 +0.932660319034 -0.000000003560 0.999876478765 0.053031073933 -3.943209575869 +0.938796242186 0.000000000380 0.999876479145 0.048699427320 -3.952536413507 +0.944932165338 0.000000003383 0.999876482528 0.044561642961 -3.961617362197 +0.951068088489 0.000000004589 0.999876487117 0.040607799760 -3.970463343802 +0.957204011641 0.000000003945 0.999876491062 0.036828570037 -3.979084640405 +0.963339934792 0.000000002053 0.999876493115 0.033215180106 -3.987490938784 +0.969475857944 -0.000000000170 0.999876492945 0.029759373556 -3.995691371457 +0.975611781095 -0.000000001880 0.999876491065 0.026453377058 -4.003694554578 +0.981747704247 -0.000000002583 0.999876488482 0.023289868545 -4.011508622931 +0.987883627398 -0.000000002239 0.999876486243 0.020261947619 -4.019141262262 +0.994019550550 -0.000000001183 0.999876485060 0.017363108024 -4.026599739162 +1.000155473701 0.000000000071 0.999876485131 0.014587212057 -4.033890928700 +1.006291396853 0.000000001044 0.999876486175 0.011928466769 -4.041021339990 +1.012427320005 0.000000001453 0.999876487628 0.009381401840 -4.047997139854 +1.018563243156 0.000000001271 0.999876488899 0.006940849009 -4.054824174740 +1.024699166308 0.000000000681 0.999876489580 0.004601922935 -4.061507991042 +1.030835089459 -0.000000000026 0.999876489554 0.002360003399 -4.068053853925 +1.036971012611 -0.000000000579 0.999876488975 0.000210718739 -4.074466764809 +1.043106935762 -0.000000000817 0.999876488158 0.001850069561 -0.939158824001 +1.049242858914 -0.000000000721 0.999876487436 0.003826281228 -0.945319860128 +1.055378782065 -0.000000000392 0.999876487044 0.005721630566 -0.951361522607 +1.061514705217 0.000000000007 0.999876487051 0.007539638914 -0.957287909038 +1.067650628368 0.000000000322 0.999876487372 0.009283646251 -0.963102923744 +1.073786551520 0.000000000460 0.999876487832 0.010956822027 -0.968810289068 +1.079922474671 0.000000000409 0.999876488241 0.012562175260 -0.974413555898 +1.086058397823 0.000000000226 0.999876488467 0.014102563963 -0.979916113489 +1.092194320975 0.000000000001 0.999876488468 0.015580703950 -0.985321198619 +1.098330244126 -0.000000000178 0.999876488289 0.016999177050 -0.990631904145 +1.104466167278 -0.000000000259 0.999876488031 0.018360438801 -0.995851186992 +1.110602090429 -0.000000000232 0.999876487799 0.019666825629 -1.000981875625 +1.116738013581 -0.000000000130 0.999876487669 0.020920561578 -1.006026677038 +1.122873936732 -0.000000000003 0.999876487666 0.022123764593 -1.010988183294 +1.129009859884 0.000000000099 0.999876487765 0.023278452421 -1.015868877651 +1.135145783035 0.000000000145 0.999876487910 0.024386548126 -1.020671140306 +1.141281706187 0.000000000132 0.999876488042 0.025449885263 -1.025397253775 +1.147417629338 0.000000000075 0.999876488116 0.026470212736 -1.030049407949 +1.153553552490 0.000000000003 0.999876488119 0.027449199343 -1.034629704834 +1.159689475642 -0.000000000055 0.999876488065 0.028388438056 -1.039140163007 +1.165825398793 -0.000000000082 0.999876487983 0.029289450033 -1.043582721803 +1.171961321945 -0.000000000075 0.999876487908 0.030153688386 -1.047959245253 +1.178097245096 -0.000000000043 0.999876487866 0.030982541731 -1.052271525793 +1.184233168248 -0.000000000003 0.999876487863 0.031777337519 -1.056521287747 +1.190369091399 0.000000000030 0.999876487893 0.032539345173 -1.060710190620 +1.196505014551 0.000000000046 0.999876487939 0.033269779045 -1.064839832190 +1.202640937702 0.000000000042 0.999876487981 0.033969801193 -1.068911751435 +1.208776860854 0.000000000025 0.999876488006 0.034640524004 -1.072927431286 +1.214912784005 0.000000000002 0.999876488008 0.035283012664 -1.076888301230 +1.221048707157 -0.000000000017 0.999876487991 0.035898287488 -1.080795739768 +1.227184630309 -0.000000000026 0.999876487965 0.036487326119 -1.084651076737 +1.233320553460 -0.000000000024 0.999876487941 0.037051065601 -1.088455595510 +1.239456476612 -0.000000000014 0.999876487927 0.037590404340 -1.092210535067 +1.245592399763 -0.000000000001 0.999876487926 0.038106203955 -1.095917091966 +1.251728322915 0.000000000009 0.999876487935 0.038599291027 -1.099576422202 +1.257864246066 0.000000000014 0.999876487950 0.039070458753 -1.103189642974 +1.264000169218 0.000000000014 0.999876487963 0.039520468511 -1.106757834352 +1.270136092369 0.000000000008 0.999876487971 0.039950051344 -1.110282040865 +1.276272015521 0.000000000001 0.999876487972 0.040359909353 -1.113763273003 +1.282407938672 -0.000000000005 0.999876487967 0.040750717036 -1.117202508646 +1.288543861824 -0.000000000008 0.999876487959 0.041123122537 -1.120600694419 +1.294679784975 -0.000000000008 0.999876487951 0.041477748842 -1.123958746973 +1.300815708127 -0.000000000005 0.999876487947 0.041815194908 -1.127277554219 +1.306951631279 -0.000000000001 0.999876487946 0.042136036737 -1.130557976481 +1.313087554430 0.000000000003 0.999876487949 0.042440828391 -1.133800847609 +1.319223477582 0.000000000005 0.999876487954 0.042730102960 -1.137006976026 +1.325359400733 0.000000000004 0.999876487958 0.043004373476 -1.140177145735 +1.331495323885 0.000000000003 0.999876487961 0.043264133790 -1.143312117272 +1.337631247036 0.000000000000 0.999876487961 0.043509859391 -1.146412628610 +1.343767170188 -0.000000000002 0.999876487959 0.043742008200 -1.149479396035 +1.349903093339 -0.000000000003 0.999876487957 0.043961021317 -1.152513114964 +1.356039016491 -0.000000000002 0.999876487954 0.044167323729 -1.155514460736 +1.362174939642 -0.000000000002 0.999876487953 0.044361324993 -1.158484089365 +1.368310862794 -0.000000000000 0.999876487953 0.044543419877 -1.161422638255 +1.374446785946 0.000000000001 0.999876487953 0.044713988972 -1.164330726889 +1.380582709097 0.000000000001 0.999876487955 0.044873399283 -1.167208957481 +1.386718632249 0.000000000001 0.999876487956 0.045022004781 -1.170057915603 +1.392854555400 0.000000000001 0.999876487957 0.045160146936 -1.172878170781 +1.398990478552 0.000000000000 0.999876487957 0.045288155223 -1.175670277073 +1.405126401703 -0.000000000000 0.999876487957 0.045406347603 -1.178434773607 +1.411262324855 -0.000000000001 0.999876487956 0.045515030989 -1.181172185112 +1.417398248006 -0.000000000001 0.999876487955 0.045614501679 -1.183883022418 +1.423534171158 -0.000000000001 0.999876487955 0.045705045779 -1.186567782932 +1.429670094309 -0.000000000000 0.999876487955 0.045786939605 -1.189226951104 +1.435806017461 0.000000000000 0.999876487955 0.045860450062 -1.191860998862 +1.441941940613 0.000000000000 0.999876487955 0.045925835014 -1.194470386039 +1.448077863764 0.000000000000 0.999876487956 0.045983343627 -1.197055560772 +1.454213786916 0.000000000000 0.999876487956 0.046033216710 -1.199616959898 +1.460349710067 0.000000000000 0.999876487956 0.046075687031 -1.202155009322 +1.466485633219 -0.000000000000 0.999876487956 0.046110979621 -1.204670124373 +1.472621556370 -0.000000000000 0.999876487956 0.046139312071 -1.207162710153 +1.478757479522 -0.000000000000 0.999876487955 0.046160894804 -1.209633161862 +1.484893402673 -0.000000000000 0.999876487955 0.046175931351 -1.212081865117 +1.491029325825 -0.000000000000 0.999876487955 0.046184618603 -1.214509196257 +1.497165248976 0.000000000000 0.999876487955 0.046187147054 -1.216915522631 +1.503301172128 0.000000000000 0.999876487956 0.046183701043 -1.219301202886 +1.509437095279 0.000000000000 0.999876487956 0.046174458971 -1.221666587232 +1.515573018431 0.000000000000 0.999876487956 0.046159593526 -1.224012017707 +1.521708941583 0.000000000000 0.999876487956 0.046139271880 -1.226337828421 +1.527844864734 -0.000000000000 0.999876487956 0.046113655895 -1.228644345805 +1.533980787886 -0.000000000000 0.999876487956 0.046082902312 -1.230931888835 +1.540116711037 -0.000000000000 0.999876487956 0.046047162930 -1.233200769261 +1.546252634189 -0.000000000000 0.999876487956 0.046006584785 -1.235451291821 +1.552388557340 -0.000000000000 0.999876487955 0.045961310316 -1.237683754446 +1.558524480492 0.000000000000 0.999876487956 0.045911477526 -1.239898448465 +1.564660403643 0.000000000000 0.999876487956 0.045857220140 -1.242095658790 +1.570796326795 0.000000000000 0.999876487956 0.045798667751 -1.244275664110 +1.576932249946 0.000000000000 0.999876487956 0.045735945963 -1.246438737064 +1.583068173098 0.000000000000 0.999876487956 0.045669176530 -1.248585144417 +1.589204096250 -0.000000000000 0.999876487956 0.045598477486 -1.250715147226 +1.595340019401 -0.000000000000 0.999876487956 0.045523963275 -1.252829001000 +1.601475942553 -0.000000000000 0.999876487956 0.045445744868 -1.254926955859 +1.607611865704 -0.000000000000 0.999876487956 0.045363929885 -1.257009256680 +1.613747788856 -0.000000000000 0.999876487956 0.045278622706 -1.259076143241 +1.619883712007 0.000000000000 0.999876487956 0.045189924578 -1.261127850367 +1.626019635159 0.000000000000 0.999876487956 0.045097933722 -1.263164608061 +1.632155558310 0.000000000000 0.999876487956 0.045002745431 -1.265186641633 +1.638291481462 0.000000000000 0.999876487956 0.044904452169 -1.267194171833 +1.644427404613 0.000000000000 0.999876487956 0.044803143663 -1.269187414967 +1.650563327765 -0.000000000000 0.999876487956 0.044698906992 -1.271166583016 +1.656699250916 -0.000000000000 0.999876487956 0.044591826674 -1.273131883755 +1.662835174068 -0.000000000000 0.999876487956 0.044481984748 -1.275083520857 +1.668971097220 -0.000000000000 0.999876487956 0.044369460859 -1.277021694007 +1.675107020371 -0.000000000000 0.999876487956 0.044254332326 -1.278946598999 +1.681242943523 0.000000000000 0.999876487956 0.044136674225 -1.280858427842 +1.687378866674 0.000000000000 0.999876487956 0.044016559456 -1.282757368854 +1.693514789826 0.000000000000 0.999876487956 0.043894058815 -1.284643606755 +1.699650712977 0.000000000000 0.999876487956 0.043769241057 -1.286517322761 +1.705786636129 0.000000000000 0.999876487956 0.043642172965 -1.288378694673 +1.711922559280 -0.000000000000 0.999876487956 0.043512919405 -1.290227896959 +1.718058482432 -0.000000000000 0.999876487956 0.043381543396 -1.292065100838 +1.724194405583 -0.000000000000 0.999876487956 0.043248106156 -1.293890474364 +1.730330328735 -0.000000000000 0.999876487956 0.043112667168 -1.295704182497 +1.736466251887 -0.000000000000 0.999876487956 0.042975284227 -1.297506387188 +1.742602175038 0.000000000000 0.999876487956 0.042836013495 -1.299297247443 +1.748738098190 0.000000000000 0.999876487956 0.042694909549 -1.301076919400 +1.754874021341 0.000000000000 0.999876487956 0.042552025433 -1.302845556396 +1.761009944493 0.000000000000 0.999876487956 0.042407412699 -1.304603309036 +1.767145867644 0.000000000000 0.999876487956 0.042261121458 -1.306350325254 +1.773281790796 -0.000000000000 0.999876487956 0.042113200421 -1.308086750379 +1.779417713947 -0.000000000000 0.999876487956 0.041963696939 -1.309812727199 +1.785553637099 -0.000000000000 0.999876487956 0.041812657048 -1.311528396014 +1.791689560250 -0.000000000000 0.999876487956 0.041660125505 -1.313233894698 +1.797825483402 -0.000000000000 0.999876487956 0.041506145828 -1.314929358756 +1.803961406554 0.000000000000 0.999876487956 0.041350760330 -1.316614921376 +1.810097329705 0.000000000000 0.999876487956 0.041194010159 -1.318290713484 +1.816233252857 0.000000000000 0.999876487956 0.041035935329 -1.319956863794 +1.822369176008 0.000000000000 0.999876487956 0.040876574752 -1.321613498860 +1.828505099160 0.000000000000 0.999876487956 0.040715966275 -1.323260743122 +1.834641022311 -0.000000000000 0.999876487956 0.040554146707 -1.324898718957 +1.840776945463 -0.000000000000 0.999876487956 0.040391151851 -1.326527546722 +1.846912868614 -0.000000000000 0.999876487956 0.040227016531 -1.328147344800 +1.853048791766 -0.000000000000 0.999876487956 0.040061774624 -1.329758229645 +1.859184714917 -0.000000000000 0.999876487956 0.039895459083 -1.331360315822 +1.865320638069 0.000000000000 0.999876487956 0.039728101966 -1.332953716049 +1.871456561220 0.000000000000 0.999876487956 0.039559734461 -1.334538541240 +1.877592484372 0.000000000000 0.999876487956 0.039390386911 -1.336114900539 +1.883728407524 0.000000000000 0.999876487956 0.039220088838 -1.337682901363 +1.889864330675 0.000000000000 0.999876487956 0.039048868964 -1.339242649436 +1.896000253827 -0.000000000000 0.999876487956 0.038876755237 -1.340794248825 +1.902136176978 -0.000000000000 0.999876487956 0.038703774850 -1.342337801980 +1.908272100130 -0.000000000000 0.999876487956 0.038529954266 -1.343873409761 +1.914408023281 -0.000000000000 0.999876487956 0.038355319232 -1.345401171478 +1.920543946433 -0.000000000000 0.999876487956 0.038179894804 -1.346921184917 +1.926679869584 0.000000000000 0.999876487956 0.038003705366 -1.348433546379 +1.932815792736 0.000000000000 0.999876487956 0.037826774646 -1.349938350705 +1.938951715887 0.000000000000 0.999876487956 0.037649125735 -1.351435691311 +1.945087639039 0.000000000000 0.999876487956 0.037470781105 -1.352925660210 +1.951223562191 0.000000000000 0.999876487956 0.037291762628 -1.354408348051 +1.957359485342 -0.000000000000 0.999876487956 0.037112091588 -1.355883844138 +1.963495408494 -0.000000000000 0.999876487956 0.036931788700 -1.357352236461 +1.969631331645 -0.000000000000 0.999876487956 0.036750874124 -1.358813611722 +1.975767254797 -0.000000000000 0.999876487956 0.036569367482 -1.360268055364 +1.981903177948 -0.000000000000 0.999876487956 0.036387287871 -1.361715651590 +1.988039101100 0.000000000000 0.999876487956 0.036204653876 -1.363156483392 +1.994175024251 0.000000000000 0.999876487956 0.036021483589 -1.364590632576 +2.000310947403 0.000000000000 0.999876487956 0.035837794613 -1.366018179780 +2.006446870554 0.000000000000 0.999876487956 0.035653604085 -1.367439204506 +2.012582793706 0.000000000000 0.999876487956 0.035468928682 -1.368853785132 +2.018718716858 -0.000000000000 0.999876487956 0.035283784635 -1.370261998942 +2.024854640009 -0.000000000000 0.999876487956 0.035098187741 -1.371663922144 +2.030990563161 -0.000000000000 0.999876487956 0.034912153376 -1.373059629891 +2.037126486312 -0.000000000000 0.999876487956 0.034725696501 -1.374449196300 +2.043262409464 -0.000000000000 0.999876487956 0.034538831681 -1.375832694476 +2.049398332615 0.000000000000 0.999876487956 0.034351573086 -1.377210196527 +2.055534255767 0.000000000000 0.999876487956 0.034163934510 -1.378581773588 +2.061670178918 0.000000000000 0.999876487956 0.033975929374 -1.379947495832 +2.067806102070 0.000000000000 0.999876487956 0.033787570741 -1.381307432497 +2.073942025221 0.000000000000 0.999876487956 0.033598871322 -1.382661651897 +2.080077948373 -0.000000000000 0.999876487956 0.033409843486 -1.384010221442 +2.086213871524 -0.000000000000 0.999876487956 0.033220499269 -1.385353207656 +2.092349794676 -0.000000000000 0.999876487956 0.033030850381 -1.386690676191 +2.098485717828 -0.000000000000 0.999876487956 0.032840908218 -1.388022691846 +2.104621640979 -0.000000000000 0.999876487956 0.032650683867 -1.389349318579 +2.110757564131 0.000000000000 0.999876487956 0.032460188115 -1.390670619527 +2.116893487282 0.000000000000 0.999876487956 0.032269431455 -1.391986657019 +2.123029410434 0.000000000000 0.999876487956 0.032078424098 -1.393297492589 +2.129165333585 0.000000000000 0.999876487956 0.031887175975 -1.394603186996 +2.135301256737 0.000000000000 0.999876487956 0.031695696745 -1.395903800230 +2.141437179888 -0.000000000000 0.999876487956 0.031503995806 -1.397199391533 +2.147573103040 -0.000000000000 0.999876487956 0.031312082296 -1.398490019412 +2.153709026191 -0.000000000000 0.999876487956 0.031119965105 -1.399775741646 +2.159844949343 -0.000000000000 0.999876487956 0.030927652875 -1.401056615308 +2.165980872495 -0.000000000000 0.999876487956 0.030735154013 -1.402332696769 +2.172116795646 0.000000000000 0.999876487956 0.030542476692 -1.403604041718 +2.178252718798 0.000000000000 0.999876487956 0.030349628858 -1.404870705169 +2.184388641949 0.000000000000 0.999876487956 0.030156618237 -1.406132741475 +2.190524565101 0.000000000000 0.999876487956 0.029963452338 -1.407390204342 +2.196660488252 0.000000000000 0.999876487956 0.029770138462 -1.408643146836 +2.202796411404 -0.000000000000 0.999876487956 0.029576683703 -1.409891621395 +2.208932334555 -0.000000000000 0.999876487956 0.029383094958 -1.411135679844 +2.215068257707 -0.000000000000 0.999876487956 0.029189378925 -1.412375373403 +2.221204180858 -0.000000000000 0.999876487956 0.028995542115 -1.413610752696 +2.227340104010 -0.000000000000 0.999876487956 0.028801590853 -1.414841867765 +2.233476027161 0.000000000000 0.999876487956 0.028607531282 -1.416068768077 +2.239611950313 0.000000000000 0.999876487956 0.028413369370 -1.417291502536 +2.245747873465 0.000000000000 0.999876487956 0.028219110912 -1.418510119492 +2.251883796616 0.000000000000 0.999876487956 0.028024761534 -1.419724666750 +2.258019719768 0.000000000000 0.999876487956 0.027830326700 -1.420935191581 +2.264155642919 -0.000000000000 0.999876487956 0.027635811714 -1.422141740729 +2.270291566071 -0.000000000000 0.999876487956 0.027441221723 -1.423344360423 +2.276427489222 -0.000000000000 0.999876487956 0.027246561721 -1.424543096383 +2.282563412374 -0.000000000000 0.999876487956 0.027051836556 -1.425737993828 +2.288699335525 -0.000000000000 0.999876487956 0.026857050929 -1.426929097490 +2.294835258677 0.000000000000 0.999876487956 0.026662209400 -1.428116451615 +2.300971181828 0.000000000000 0.999876487956 0.026467316391 -1.429300099978 +2.307107104980 0.000000000000 0.999876487956 0.026272376189 -1.430480085885 +2.313243028132 0.000000000000 0.999876487956 0.026077392951 -1.431656452185 +2.319378951283 0.000000000000 0.999876487956 0.025882370703 -1.432829241278 +2.325514874435 -0.000000000000 0.999876487956 0.025687313348 -1.433998495119 +2.331650797586 -0.000000000000 0.999876487956 0.025492224666 -1.435164255228 +2.337786720738 -0.000000000000 0.999876487956 0.025297108316 -1.436326562696 +2.343922643889 -0.000000000000 0.999876487956 0.025101967844 -1.437485458196 +2.350058567041 -0.000000000000 0.999876487956 0.024906806678 -1.438640981983 +2.356194490192 0.000000000000 0.999876487956 0.024711628139 -1.439793173909 +2.362330413344 0.000000000000 0.999876487956 0.024516435436 -1.440942073424 +2.368466336495 0.000000000000 0.999876487956 0.024321231675 -1.442087719583 +2.374602259647 0.000000000000 0.999876487956 0.024126019857 -1.443230151057 +2.380738182799 0.000000000000 0.999876487956 0.023930802882 -1.444369406135 +2.386874105950 -0.000000000000 0.999876487956 0.023735583552 -1.445505522732 +2.393010029102 -0.000000000000 0.999876487956 0.023540364573 -1.446638538394 +2.399145952253 -0.000000000000 0.999876487956 0.023345148556 -1.447768490307 +2.405281875405 -0.000000000000 0.999876487956 0.023149938023 -1.448895415301 +2.411417798556 -0.000000000000 0.999876487956 0.022954735402 -1.450019349855 +2.417553721708 0.000000000000 0.999876487956 0.022759543038 -1.451140330104 +2.423689644859 0.000000000000 0.999876487956 0.022564363187 -1.452258391845 +2.429825568011 0.000000000000 0.999876487956 0.022369198024 -1.453373570543 +2.435961491162 0.000000000000 0.999876487956 0.022174049641 -1.454485901335 +2.442097414314 0.000000000000 0.999876487956 0.021978920051 -1.455595419035 +2.448233337465 -0.000000000000 0.999876487956 0.021783811190 -1.456702158142 +2.454369260617 -0.000000000000 0.999876487956 0.021588724918 -1.457806152844 +2.460505183769 -0.000000000000 0.999876487956 0.021393663018 -1.458907437020 +2.466641106920 -0.000000000000 0.999876487956 0.021198627205 -1.460006044252 +2.472777030072 -0.000000000000 0.999876487956 0.021003619120 -1.461102007823 +2.478912953223 0.000000000000 0.999876487956 0.020808640337 -1.462195360725 +2.485048876375 0.000000000000 0.999876487956 0.020613692361 -1.463286135665 +2.491184799526 0.000000000000 0.999876487956 0.020418776632 -1.464374365067 +2.497320722678 0.000000000000 0.999876487956 0.020223894526 -1.465460081078 +2.503456645829 0.000000000000 0.999876487956 0.020029047354 -1.466543315575 +2.509592568981 -0.000000000000 0.999876487956 0.019834236368 -1.467624100164 +2.515728492132 -0.000000000000 0.999876487956 0.019639462760 -1.468702466189 +2.521864415284 -0.000000000000 0.999876487956 0.019444727661 -1.469778444735 +2.528000338436 -0.000000000000 0.999876487956 0.019250032148 -1.470852066632 +2.534136261587 -0.000000000000 0.999876487956 0.019055377238 -1.471923362461 +2.540272184739 -0.000000000000 0.999876487956 0.018860763899 -1.472992362554 +2.546408107890 0.000000000000 0.999876487956 0.018666193040 -1.474059097002 +2.552544031042 0.000000000000 0.999876487956 0.018471665521 -1.475123595660 +2.558679954193 0.000000000000 0.999876487956 0.018277182151 -1.476185888146 +2.564815877345 0.000000000000 0.999876487956 0.018082743689 -1.477246003848 +2.570951800496 0.000000000000 0.999876487956 0.017888350845 -1.478303971931 +2.577087723648 -0.000000000000 0.999876487956 0.017694004281 -1.479359821333 +2.583223646799 -0.000000000000 0.999876487956 0.017499704614 -1.480413580776 +2.589359569951 -0.000000000000 0.999876487956 0.017305452416 -1.481465278768 +2.595495493103 -0.000000000000 0.999876487956 0.017111248212 -1.482514943602 +2.601631416254 -0.000000000000 0.999876487956 0.016917092489 -1.483562603366 +2.607767339406 0.000000000000 0.999876487956 0.016722985686 -1.484608285945 +2.613903262557 0.000000000000 0.999876487956 0.016528928204 -1.485652019019 +2.620039185709 0.000000000000 0.999876487956 0.016334920405 -1.486693830076 +2.626175108860 0.000000000000 0.999876487956 0.016140962608 -1.487733746405 +2.632311032012 0.000000000000 0.999876487956 0.015947055097 -1.488771795110 +2.638446955163 -0.000000000000 0.999876487956 0.015753198116 -1.489808003103 +2.644582878315 -0.000000000000 0.999876487956 0.015559391875 -1.490842397115 +2.650718801466 -0.000000000000 0.999876487956 0.015365636546 -1.491875003695 +2.656854724618 -0.000000000000 0.999876487956 0.015171932267 -1.492905849216 +2.662990647769 -0.000000000000 0.999876487956 0.014978279142 -1.493934959875 +2.669126570921 0.000000000000 0.999876487956 0.014784677242 -1.494962361699 +2.675262494073 0.000000000000 0.999876487956 0.014591126605 -1.495988080547 +2.681398417224 0.000000000000 0.999876487956 0.014397627237 -1.497012142113 +2.687534340376 0.000000000000 0.999876487956 0.014204179114 -1.498034571927 +2.693670263527 0.000000000000 0.999876487956 0.014010782181 -1.499055395361 +2.699806186679 -0.000000000000 0.999876487956 0.013817436354 -1.500074637632 +2.705942109830 -0.000000000000 0.999876487956 0.013624141520 -1.501092323802 +2.712078032982 -0.000000000000 0.999876487956 0.013430897537 -1.502108478782 +2.718213956133 -0.000000000000 0.999876487956 0.013237704238 -1.503123127338 +2.724349879285 -0.000000000000 0.999876487956 0.013044561427 -1.504136294088 +2.730485802436 0.000000000000 0.999876487956 0.012851468883 -1.505148003509 +2.736621725588 0.000000000000 0.999876487956 0.012658426358 -1.506158279938 +2.742757648740 0.000000000000 0.999876487956 0.012465433581 -1.507167147577 +2.748893571891 0.000000000000 0.999876487956 0.012272490256 -1.508174630491 +2.755029495043 0.000000000000 0.999876487956 0.012079596063 -1.509180752615 +2.761165418194 -0.000000000000 0.999876487956 0.011886750659 -1.510185537755 +2.767301341346 -0.000000000000 0.999876487956 0.011693953680 -1.511189009590 +2.773437264497 -0.000000000000 0.999876487956 0.011501204737 -1.512191191675 +2.779573187649 -0.000000000000 0.999876487956 0.011308503423 -1.513192107445 +2.785709110800 -0.000000000000 0.999876487956 0.011115849308 -1.514191780213 +2.791845033952 0.000000000000 0.999876487956 0.010923241942 -1.515190233179 +2.797980957103 0.000000000000 0.999876487956 0.010730680855 -1.516187489426 +2.804116880255 0.000000000000 0.999876487956 0.010538165559 -1.517183571927 +2.810252803406 0.000000000000 0.999876487956 0.010345695546 -1.518178503546 +2.816388726558 0.000000000000 0.999876487956 0.010153270290 -1.519172307039 +2.822524649710 -0.000000000000 0.999876487956 0.009960889248 -1.520165005057 +2.828660572861 -0.000000000000 0.999876487956 0.009768551858 -1.521156620150 +2.834796496013 -0.000000000000 0.999876487956 0.009576257542 -1.522147174767 +2.840932419164 -0.000000000000 0.999876487956 0.009384005705 -1.523136691259 +2.847068342316 -0.000000000000 0.999876487956 0.009191795738 -1.524125191882 +2.853204265467 0.000000000000 0.999876487956 0.008999627014 -1.525112698799 +2.859340188619 0.000000000000 0.999876487956 0.008807498891 -1.526099234081 +2.865476111770 0.000000000000 0.999876487956 0.008615410715 -1.527084819711 +2.871612034922 0.000000000000 0.999876487956 0.008423361815 -1.528069477584 +2.877747958073 0.000000000000 0.999876487956 0.008231351507 -1.529053229511 +2.883883881225 -0.000000000000 0.999876487956 0.008039379093 -1.530036097221 +2.890019804377 -0.000000000000 0.999876487956 0.007847443864 -1.531018102362 +2.896155727528 -0.000000000000 0.999876487956 0.007655545094 -1.531999266504 +2.902291650680 -0.000000000000 0.999876487956 0.007463682050 -1.532979611139 +2.908427573831 -0.000000000000 0.999876487956 0.007271853983 -1.533959157688 +2.914563496983 0.000000000000 0.999876487956 0.007080060134 -1.534937927498 +2.920699420134 0.000000000000 0.999876487956 0.006888299734 -1.535915941845 +2.926835343286 0.000000000000 0.999876487956 0.006696572000 -1.536893221939 +2.932971266437 0.000000000000 0.999876487956 0.006504876141 -1.537869788922 +2.939107189589 0.000000000000 0.999876487956 0.006313211355 -1.538845663874 +2.945243112740 -0.000000000000 0.999876487956 0.006121576832 -1.539820867810 +2.951379035892 -0.000000000000 0.999876487956 0.005929971748 -1.540795421688 +2.957514959044 -0.000000000000 0.999876487956 0.005738395276 -1.541769346405 +2.963650882195 -0.000000000000 0.999876487956 0.005546846574 -1.542742662804 +2.969786805347 -0.000000000000 0.999876487956 0.005355324796 -1.543715391672 +2.975922728498 0.000000000000 0.999876487956 0.005163829087 -1.544687553744 +2.982058651650 0.000000000000 0.999876487956 0.004972358582 -1.545659169704 +2.988194574801 0.000000000000 0.999876487956 0.004780912411 -1.546630260190 +2.994330497953 0.000000000000 0.999876487956 0.004589489696 -1.547600845789 +3.000466421104 0.000000000000 0.999876487956 0.004398089551 -1.548570947046 +3.006602344256 -0.000000000000 0.999876487956 0.004206711084 -1.549540584463 +3.012738267407 -0.000000000000 0.999876487956 0.004015353398 -1.550509778500 +3.018874190559 -0.000000000000 0.999876487956 0.003824015588 -1.551478549577 +3.025010113710 -0.000000000000 0.999876487956 0.003632696745 -1.552446918078 +3.031146036862 -0.000000000000 0.999876487956 0.003441395953 -1.553414904349 +3.037281960014 0.000000000000 0.999876487956 0.003250112292 -1.554382528707 +3.043417883165 0.000000000000 0.999876487956 0.003058844837 -1.555349811431 +3.049553806317 0.000000000000 0.999876487956 0.002867592658 -1.556316772774 +3.055689729468 0.000000000000 0.999876487956 0.002676354820 -1.557283432958 +3.061825652620 0.000000000000 0.999876487956 0.002485130386 -1.558249812182 +3.067961575771 -0.000000000000 0.999876487956 0.002293918414 -1.559215930616 +3.074097498923 -0.000000000000 0.999876487956 0.002102717958 -1.560181808410 +3.080233422074 -0.000000000000 0.999876487956 0.001911528070 -1.561147465691 +3.086369345226 -0.000000000000 0.999876487956 0.001720347798 -1.562112922567 +3.092505268377 -0.000000000000 0.999876487956 0.001529176189 -1.563078199130 +3.098641191529 0.000000000000 0.999876487956 0.001338012285 -1.564043315454 +3.104777114681 0.000000000000 0.999876487956 0.001146855129 -1.565008291599 +3.110913037832 0.000000000000 0.999876487956 0.000955703759 -1.565973147615 +3.117048960984 0.000000000000 0.999876487956 0.000764557214 -1.566937903538 +3.123184884135 0.000000000000 0.999876487956 0.000573414531 -1.567902579398 +3.129320807287 -0.000000000000 0.999876487956 0.000382274744 -1.568867195217 +3.135456730438 -0.000000000000 0.999876487956 0.000191136889 -1.569831771012 diff --git a/test/filter_response.jl b/test/filter_response.jl index ad56fdf7a..397e15edb 100644 --- a/test/filter_response.jl +++ b/test/filter_response.jl @@ -40,6 +40,44 @@ h_abs = convert(Array{Float64}, abs(h)) #=file(figure, "MATLAB-freqz.png", width=1200, height=800)=# +####################################### +# +# Test frequency, phase, impulse and step response +# +# Data from Matlab using b,a and a from above: +# ir = impz(b,a, 512); +# stepr = stepz(b,a, 512); +# h = abs(freqz(b,a)); +# [phi,f] = phasez(b, a); +# all = [f, ir, stepr, h, phi]; +# dlmwrite('responses-eg1.txt',all, 'delimiter', '\t', 'precision', '%.12f') +# +####################################### + +matlab_resp = readdlm(joinpath(dirname(@__FILE__), "data", "responses-eg1.txt"),'\t') +df = TFFilter(b, a) +w = matlab_resp[:,1] + +#Impulse response +impz_matlab = matlab_resp[:,2] +@test_approx_eq impz(df, 512) impz_matlab + +#Step response +stepz_matlab = matlab_resp[:,3] +@test_approx_eq stepz(df, 512) stepz_matlab + +h_matlab = matlab_resp[:,4] +@test_approx_eq abs(freqz(df, w)) h_matlab + +phi_matlab = matlab_resp[:,5] +@test_approx_eq phasez(df, w) phi_matlab + + +# Test diffent versions of the functions +@test freqz(df) == freqz(df, linspace(0, pi, 250)) +@test phasez(df) == phasez(df, linspace(0, pi, 250)) +@test_approx_eq(cumsum(impz(df)), stepz(df)) + ####################################### # # Test digital filter with frequency specified in hz @@ -113,44 +151,6 @@ matlab_phasedeg = freqs_eg1_w_mag_phasedeg[:,3] #=xlabel("Frequency (rad/s)")=# #=file(figure, "MATLAB-freqs-phase.png", width=1200, height=800)=# -####################################### -# -# Test frequency, phase, impulse and step response -# -# Data from Matlab: -# [b,a]=cheby2(10, 80, [0.2 0.4]); -# ir = impz(b,a, 512); -# stepr = stepz(b,a, 512); -# h = abs(freqz(b,a)); -# [phi,f] = phasez(b, a); -# all = [f, ir, stepr, h, phi]; -# dlmwrite('responses-eg1.txt',all, 'delimiter', '\t', 'precision', '%.12f') -# -####################################### - -cheby2_matlab = readdlm(joinpath(dirname(@__FILE__), "data", "responses-eg1.txt"),'\t') -df = digitalfilter(Bandpass(0.2, 0.4), Chebyshev2(10, 80)) -w = cheby2_matlab[:,1] - -#Impulse response -impz_matlab = cheby2_matlab[:,2] -@test_approx_eq_eps(impz(df, 512), impz_matlab, 1e-7) - -#Step response -stepz_matlab = cheby2_matlab[:,3] -@test_approx_eq_eps(stepz(df, 512), stepz_matlab, 1e-7) - -h_matlab = cheby2_matlab[:,4] -@test_approx_eq_eps(abs(freqz(df, w)), h_matlab, 1e-5) - -phi_matlab = cheby2_matlab[:,5] -@test_approx_eq_eps(phasez(df, w), phi_matlab, 1e-5) - - -# Test diffent versions of the functions -@test freqz(df) == freqz(df, linspace(0, pi, 250)) -@test phasez(df) == phasez(df, linspace(0, pi, 250)) -@test_approx_eq(cumsum(impz(df)), stepz(df)) From 6de1fe81e4efaa865552848468d37e5db5738ad6 Mon Sep 17 00:00:00 2001 From: Matti Pastell Date: Thu, 1 Jan 2015 16:02:54 +0200 Subject: [PATCH 12/26] Added docs to new functions --- .gitignore | 1 + doc/filters.rst | 17 +++++++++++++++-- src/Filters/response.jl | 12 ++---------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 77203ce23..97416eab6 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ *.orig /usr +/doc/_build diff --git a/doc/filters.rst b/doc/filters.rst index a6f951f12..d1ae85304 100644 --- a/doc/filters.rst +++ b/doc/filters.rst @@ -140,7 +140,7 @@ Filter prototypes ``n`` pole Chebyshev type II filter with ``ripple`` dB ripple in the stopband. -.. function:: Elliptic(n, rp, rs) +.. function:: Elliptic(n, rp, rs) ``n`` pole elliptic (Cauer) filter with ``rp`` dB ripple in the passband and ``rs`` dB attentuation in the stopband. @@ -149,7 +149,7 @@ Filter prototypes Filter response --------------- -.. function:: freqz(filter, w) +.. function:: freqz(filter, w = linspace(0, π, 250)) Frequency response of a digital ``filter`` at normalised frequency or frequencies ``w`` in radians/sample. @@ -159,6 +159,19 @@ Filter response Frequency response of a digital ``filter`` at frequency or frequencies ``hz`` with sampling rate ``fs``. +.. function:: phasez(filter, w = linspace(0, π, 250)) + + Phase response of a digital ``filter`` at normalised frequency + or frequencies ``w`` in radians/sample. + +.. function:: impz(filter, n=100) + + Impulse response of a digital ``filter`` with ``n`` points. + +.. function:: stepz(filter, n=100) + + Step response of a digital ``filter`` with ``n`` points. + .. function:: freqs(filter, w) Frequency response of an analog ``filter`` at normalised frequency diff --git a/src/Filters/response.jl b/src/Filters/response.jl index 4e3afa2e6..c85f546a5 100644 --- a/src/Filters/response.jl +++ b/src/Filters/response.jl @@ -10,7 +10,7 @@ function freqz(filter::Filter, w::Number) polyval(filter.b, ejw) ./ polyval(filter.a, ejw) end -function freqz(filter::Filter, w::AbstractVector) +function freqz(filter::Filter, w = linspace(0, π, 250)) filter = convert(TFFilter, filter) [freqz(filter, i) for i = w] end @@ -20,24 +20,16 @@ function freqz(filter::Filter, hz::Union(Number, AbstractVector), fs::Number) freqz(filter, hz_to_radians_per_second(hz, fs)) end -function freqz(filter::Filter) - freqz(filter, linspace(0, π, 250)) -end - # # Phase response of a digital filter # -function phasez(filter::Filter, w::AbstractVector) +function phasez(filter::Filter, w = linspace(0, π, 250)) h = freqz(filter, w) unwrap(-atan2(imag(h), real(h))) end -function phasez(filter::Filter) - h = freqz(filter) - unwrap(-atan2(imag(h), real(h))) -end # # Impulse response of a digital filter From 887e1c39e18827763188e7bd3c751bef058c56a6 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Sat, 21 Feb 2015 15:56:08 -0500 Subject: [PATCH 13/26] Fix deprecation warnings --- REQUIRE | 1 + src/Filters/Filters.jl | 2 +- src/Filters/filt.jl | 4 ++-- src/Filters/response.jl | 2 +- src/Filters/types.jl | 4 ++-- src/periodograms.jl | 16 ++++++++-------- src/windows.jl | 4 ++-- test/filter_conversion.jl | 2 +- test/periodograms.jl | 13 ++++++------- test/util.jl | 16 ++++++++-------- 10 files changed, 32 insertions(+), 32 deletions(-) diff --git a/REQUIRE b/REQUIRE index c0bf8da63..22e333384 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,3 +1,4 @@ julia 0.3- Polynomials Reexport +Compat diff --git a/src/Filters/Filters.jl b/src/Filters/Filters.jl index 018029380..774d973fc 100644 --- a/src/Filters/Filters.jl +++ b/src/Filters/Filters.jl @@ -1,5 +1,5 @@ module Filters -using Polynomials, ..Util +using Polynomials, Compat, ..Util include("types.jl") export Filter, ZPKFilter, TFFilter, BiquadFilter, SOSFilter, coefa, coefb diff --git a/src/Filters/filt.jl b/src/Filters/filt.jl index 7dbea4fa7..232f2b441 100644 --- a/src/Filters/filt.jl +++ b/src/Filters/filt.jl @@ -284,7 +284,7 @@ function optimalfftfiltlength(nb, nx) L = 0 for i = firsti:lasti curL = FFT_LENGTHS[i] - (nb - 1) - estimate = iceil(nx/curL)*FFT_TIMES[i] + estimate = ceil(Int, nx/curL)*FFT_TIMES[i] if estimate < fastestestimate nfft = FFT_LENGTHS[i] fastestestimate = estimate @@ -367,7 +367,7 @@ function firfilt{T<:Number}(b::AbstractVector{T}, x::AbstractArray{T}) # and filt() nfft = optimalfftfiltlength(nb, nx) L = min(nx, nfft - (nb - 1)) - nchunk = iceil(nx/L)*div(length(x), nx) + nchunk = ceil(Int, nx/L)*div(length(x), nx) fftops = (2*nchunk + 1) * nfft * log2(nfft)/2 + nchunk * nfft + 100000 filtops > fftops ? fftfilt(b, x, nfft) : filt(b, [one(T)], x) diff --git a/src/Filters/response.jl b/src/Filters/response.jl index c85f546a5..21d072ad1 100644 --- a/src/Filters/response.jl +++ b/src/Filters/response.jl @@ -36,7 +36,7 @@ end # function impz(filter::Filter, n=100) - i = [1, zeros(n-1)] + i = [1; zeros(n-1)] filt(filter, i) end diff --git a/src/Filters/types.jl b/src/Filters/types.jl index 9f1660962..fe71f0bb8 100644 --- a/src/Filters/types.jl +++ b/src/Filters/types.jl @@ -216,8 +216,8 @@ function Base.convert{Z,P}(::Type{SOSFilter}, f::ZPKFilter{Z,P}) # necessarily paired with a zero @assert isempty(complexz) @assert isempty(realz) - groupedz = [z1, z2, z3, z4]::Vector{Z} - groupedp = [p1, p2, p3, p4, complexp, realp]::Vector{P} + groupedz = [z1; z2; z3; z4]::Vector{Z} + groupedp = [p1; p2; p3; p4; complexp; realp]::Vector{P} @assert length(groupedz) == nz @assert length(groupedp) == n diff --git a/src/periodograms.jl b/src/periodograms.jl index 98b44790f..5e878560e 100644 --- a/src/periodograms.jl +++ b/src/periodograms.jl @@ -3,7 +3,7 @@ # of the methods is available at: # http://www.ee.lamar.edu/gleb/adsp/Lecture%2008%20-%20Nonparametric%20SE.pdf module Periodograms -using ..Util, ..Windows +using Compat, ..Util, ..Windows export arraysplit, nextfastfft, periodogram, welch_pgram, mt_pgram, spectrogram, power, freq, stft @@ -246,13 +246,13 @@ end # DTFT of the signal S if radialsum and radialavg are both false (default), # a radial sum if radialsum=true, or a radial averave if radialavg=true function periodogram{T<:Real}(s::AbstractMatrix{T}; - nfft::NTuple{2,Int}=nextfastfft(size(s)), - fs::Real=1, - radialsum::Bool=false, radialavg::Bool=false) - @assert size(s,1)<=nfft[1] && size(s,2)<=nfft[2] - @assert size(s,1)!=1 && size(s,2)!=1 + nfft::NTuple{2,Int}=nextfastfft(size(s)), + fs::Real=1, + radialsum::Bool=false, radialavg::Bool=false) + size(s,1)<=nfft[1] && size(s,2)<=nfft[2] || throw(ArgumentError("nfft must be >= size(s)")) + size(s,1)>1 && size(s,2)>1 || throw(ArgumentError("dimensions of s must be > 1")) if radialsum && radialavg - error("radialsum and radialavg both true") + throw(ArgumentError("radialsum and radialavg are mutually exclusive")) elseif !radialsum && !radialavg ptype = 0 elseif radialsum @@ -318,7 +318,7 @@ end function mt_pgram{T<:Number}(s::AbstractVector{T}; onesided::Bool=eltype(s)<:Real, nfft::Int=nextfastfft(length(s)), fs::Real=1, - nw::Int=4, ntapers::Int=iceil(2nw)-1, + nw::Int=4, ntapers::Int=ceil(Int, 2nw)-1, window::Union(AbstractMatrix, Nothing)=nothing) onesided && T <: Complex && error("cannot compute one-sided FFT of a complex signal") nfft >= length(s) || error("nfft must be >= n") diff --git a/src/windows.jl b/src/windows.jl index 514e3e9fe..05b9d0c6d 100644 --- a/src/windows.jl +++ b/src/windows.jl @@ -1,5 +1,5 @@ module Windows -using ..Util +using Compat, ..Util export rect, hanning, hamming, tukey, cosine, lanczos, triang, bartlett, gaussian, bartlett_hann, blackman, kaiser, dpss, dpsseig @@ -105,7 +105,7 @@ end # See Gruenbacher, D. M., & Hummels, D. R. (1994). A simple algorithm # for generating discrete prolate spheroidal sequences. IEEE # Transactions on Signal Processing, 42(11), 3276-3278. -function dpss(n::Int, nw::Real, ntapers::Int=iceil(2*nw)-1) +function dpss(n::Int, nw::Real, ntapers::Int=ceil(Int, 2*nw)-1) 0 < ntapers <= n || error("ntapers must be in interval (0, n]") 0 <= nw < n/2 || error("nw must be in interval [0, n/2)") diff --git a/test/filter_conversion.jl b/test/filter_conversion.jl index 12e84ee81..76354e6ca 100644 --- a/test/filter_conversion.jl +++ b/test/filter_conversion.jl @@ -40,7 +40,7 @@ m_sos_full = [ # And with half of the zeros removed # MATLAB: # [sos, g] = zp2sos(z([1:5, 11:15]), p, k) -zp = z[[1:5, 11:15]] +zp = z[[1:5; 11:15]] m_sos_half = [ 0.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 1.8634035480499262e-02 2.5995031728136877e-04 0.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 6.5784934880398133e-02 1.6684559930728524e-03 diff --git a/test/periodograms.jl b/test/periodograms.jl index 93042785d..d0fa54b62 100644 --- a/test/periodograms.jl +++ b/test/periodograms.jl @@ -41,9 +41,9 @@ data0 = Float64[98.0, @test_approx_eq power(periodogram(data, onesided=false)) data0 @test_approx_eq power(welch_pgram(data, length(data), 0, onesided=false)) data0 @test_approx_eq power(spectrogram(data, length(data), 0, onesided=false)) data0 -@test_approx_eq power(periodogram(complex([data], [data]), onesided=false)) data0*2 -@test_approx_eq power(welch_pgram(complex([data], [data]), length(data), 0, onesided=false)) data0*2 -@test_approx_eq power(spectrogram(complex([data], [data]), length(data), 0, onesided=false)) data0*2 +@test_approx_eq power(periodogram(complex([data;], [data;]), onesided=false)) data0*2 +@test_approx_eq power(welch_pgram(complex([data;], [data;]), length(data), 0, onesided=false)) data0*2 +@test_approx_eq power(spectrogram(complex([data;], [data;]), length(data), 0, onesided=false)) data0*2 # # ~~~~~~~~ Tests with no window ~~~~~~~~~~~~~~~~~~~ # Matlab: p = pwelch(0:7, [1, 1], 0, 2, 1, 'twosided') @@ -288,7 +288,6 @@ mtdata = vec(readdlm(joinpath(dirname(@__FILE__), "data", "mt_pgram.txt"))) @test_approx_eq power(mt_pgram(s; fs=16000, window=dpss(length(s), 4))) mtdata # error tests -EE = ErrorException -@test_throws EE periodogram([1 2 3]) -@test_throws EE periodogram(rand(2,3), nfft=(3,2)) -@test_throws EE periodogram([1 2;3 4],radialsum=true, radialavg=true) +@test_throws ArgumentError periodogram([1 2 3]) +@test_throws ArgumentError periodogram(rand(2,3), nfft=(3,2)) +@test_throws ArgumentError periodogram([1 2;3 4],radialsum=true, radialavg=true) diff --git a/test/util.jl b/test/util.jl index 3f438f289..c07083567 100644 --- a/test/util.jl +++ b/test/util.jl @@ -23,7 +23,7 @@ unwrapped = hcat(unwrapped, unwrapped) @test_approx_eq(unwrap(wrapped, 1), unwrapped) # test unwrapping with other ranges -unwrapped = [1.0:100] +unwrapped = [1.0:100;] wrapped = unwrapped % 10 @test_approx_eq(unwrap(wrapped, range=10), unwrapped) @@ -48,24 +48,24 @@ h_real = real(h) #For the 'slow' sine - the phase should go from -pi/2 to pi/2 in #the first 256 bins: -@test_approx_eq h_angle[1:256,1] [-pi/2:pi/256:pi/2-pi/256] +@test_approx_eq h_angle[1:256,1] -pi/2:pi/256:pi/2-pi/256 #For the 'slow' cosine - the phase should go from 0 to pi in the #same interval: -@test_approx_eq h_angle[1:256,2] [0:pi/256:pi-pi/256] +@test_approx_eq h_angle[1:256,2] 0:pi/256:pi-pi/256 #The 'fast' sine should make this phase transition in half the time: -@test_approx_eq h_angle[1:128,3] [-pi/2:pi/128:pi/2-pi/128] +@test_approx_eq h_angle[1:128,3] -pi/2:pi/128:pi/2-pi/128 #Ditto for the 'fast' cosine: -@test_approx_eq h_angle[1:128,4] [0:pi/128:pi-pi/128] +@test_approx_eq h_angle[1:128,4] 0:pi/128:pi-pi/128 #The imaginary part of hilbert(cos(t)) = sin(t) Wikipedia @test_approx_eq imag(h[:,2]) a0 #Sanity check with odd number of samples -h2 = hilbert([ones(10), zeros(9)]) -@test_approx_eq real(h2) [ones(10), zeros(9)] +h2 = hilbert([ones(10); zeros(9)]) +@test_approx_eq real(h2) [ones(10); zeros(9)] #Sanity check with integer arguments r = int(rand(128)*20) @@ -93,7 +93,7 @@ r = int(rand(128)*20) @test_approx_eq rfftfreq(7) [0., 1/7, 2/7, 3/7] for n = 1:7 - @test_approx_eq fftshift(fftfreq(n)) fftshift([fftfreq(n)]) + @test_approx_eq fftshift(fftfreq(n)) fftshift([fftfreq(n);]) end # nextfastfft From 937d7ab27553be092709c50b138210e9da48bfa9 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Sat, 21 Feb 2015 18:59:27 -0500 Subject: [PATCH 14/26] Use new-style .travis.yml --- .travis.yml | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4f283bd3f..6a6fff8c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,13 @@ -language: cpp -compiler: - - clang +language: julia +os: + - linux +julia: + - release + - nightly notifications: email: false -env: - matrix: - - JULIAVERSION="juliareleases" - - JULIAVERSION="julianightlies" -before_install: - - sudo add-apt-repository ppa:staticfloat/julia-deps -y - - sudo add-apt-repository ppa:staticfloat/${JULIAVERSION} -y - - sudo apt-get update -qq -y - - sudo apt-get install libpcre3-dev julia -y script: - - julia -e 'Pkg.init(); run(`ln -s $(pwd()) $(Pkg.dir("DSP"))`); Pkg.pin("DSP"); Pkg.resolve()' - - if [ $JULIAVERSION = "julianightlies" ]; then julia --code-coverage test/runtests.jl; fi - - if [ $JULIAVERSION = "juliareleases" ]; then julia test/runtests.jl; fi + - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi + - julia --check-bounds=yes -e 'Pkg.clone(pwd()); Pkg.build("DSP"); Pkg.test("DSP"; coverage=true)' after_success: - - if [ $JULIAVERSION = "julianightlies" ]; then julia -e 'cd(Pkg.dir("DSP")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'; fi + - if [ $TRAVIS_JULIA_VERSION = "nightly" ]; julia -e 'cd(Pkg.dir("DSP")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'; fi From 123c761b73f36a10534bd2cb887369d6074c0253 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Sat, 21 Feb 2015 19:03:01 -0500 Subject: [PATCH 15/26] Travis tweak --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6a6fff8c9..9c4381e4e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,4 +10,4 @@ script: - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi - julia --check-bounds=yes -e 'Pkg.clone(pwd()); Pkg.build("DSP"); Pkg.test("DSP"; coverage=true)' after_success: - - if [ $TRAVIS_JULIA_VERSION = "nightly" ]; julia -e 'cd(Pkg.dir("DSP")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'; fi + - if [ $TRAVIS_JULIA_VERSION = "nightly" ]; then julia -e 'cd(Pkg.dir("DSP")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'; fi From 5c016833c48cd622f949ea458a4a886c9f590741 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Sat, 21 Feb 2015 19:08:21 -0500 Subject: [PATCH 16/26] Remove unneeded sumabs2 implementation --- src/periodograms.jl | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/periodograms.jl b/src/periodograms.jl index 5e878560e..5d0be9542 100644 --- a/src/periodograms.jl +++ b/src/periodograms.jl @@ -162,21 +162,6 @@ function fft2oneortwosided!{T}(out::Array{Complex{T}}, s_fft::Vector{Complex{T}} out end - -# Calculate sum of abs2 -# Remove this once we drop support for Julia 0.2 -if isdefined(Base, :sumabs2) - sumabs2(x) = Base.sumabs2(x) -else - function sumabs2(s) - x = zero(eltype(s)) - for i = 1:length(s) - @inbounds x += abs2(s[i]) - end - x - end -end - # Evaluate a window function at n points, returning both the window # (or nothing if no window) and the squared L2 norm of the window compute_window(::Nothing, n::Int) = (nothing, n) From af0512fc26816a23a66e0b8ee6a878ef0658bf5d Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Sat, 21 Feb 2015 16:14:34 -0500 Subject: [PATCH 17/26] Fix variables in filter docs --- doc/filters.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/filters.rst b/doc/filters.rst index d1ae85304..76a5ffff6 100644 --- a/doc/filters.rst +++ b/doc/filters.rst @@ -12,18 +12,18 @@ from one type to another using ``convert``. Filter representation in terms of zeros ``z``, poles ``p``, and gain ``k``: - .. math:: H(z) = k\frac{(s - \verb!z[1]!) \ldots (s - \verb!z[end]!)}{(s - \verb!p[1]!) \ldots (s - \verb!p[end]!)} + .. math:: H(x) = k\frac{(x - \verb!z[1]!) \ldots (x - \verb!z[end]!)}{(x - \verb!p[1]!) \ldots (x - \verb!p[end]!)} .. function:: TFFilter(b, a) Filter representation in terms of the coefficients of the numerator ``b`` and denominator ``a`` of the transfer function: - .. math:: H(z) = \frac{\verb!b[1]! s^{n-1} + \ldots + \verb!b[n]!}{\verb!a[1]! s^{n-1} + \ldots + \verb!a[n]!} + .. math:: H(s) = \frac{\verb!b[1]! s^{n-1} + \ldots + \verb!b[n]!}{\verb!a[1]! s^{n-1} + \ldots + \verb!a[n]!} or equivalently: - .. math:: H(z) = \frac{\verb!b[1]! + \ldots + \verb!b[n]! s^{-n+1}}{\verb!a[1]! + \ldots + \verb!b[n]! s^{-n+1}} + .. math:: H(z) = \frac{\verb!b[1]! + \ldots + \verb!b[n]! z^{-n+1}}{\verb!a[1]! + \ldots + \verb!a[n]! z^{-n+1}} ``b`` and ``a`` may be specified as ``Polynomial`` objects or vectors ordered from highest power to lowest. @@ -33,7 +33,7 @@ from one type to another using ``convert``. Filter representation in terms of the transfer function of a single second-order section given by: - .. math:: H(z) = \frac{\verb!b0! s^2+\verb!b1! s+\verb!b2!}{s^2+\verb!a1! s + \verb!a2!} + .. math:: H(s) = \frac{\verb!b0! s^2+\verb!b1! s+\verb!b2!}{s^2+\verb!a1! s + \verb!a2!} or equivalently: From 781e55e066009dce9aec10a46ebf40051cce970d Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Sat, 28 Mar 2015 10:47:27 -0400 Subject: [PATCH 18/26] Close #98 --- doc/periodograms.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/periodograms.rst b/doc/periodograms.rst index c176abd9f..206185803 100644 --- a/doc/periodograms.rst +++ b/doc/periodograms.rst @@ -25,7 +25,8 @@ an optional window function or vector to be applied to the original signal before computing the Fourier transform. The computed periodogram is normalized so that the area under the periodogram is - equal to the uncentered variance of the original signal. + equal to the uncentered variance (or average power) of the original + signal. .. function:: welch_pgram(s, n=div(length(s), 8), noverlap=div(n, 2); onesided=eltype(s)<:Real, nfft=nextfastfft(n), fs=1, window=nothing) From c1da1b29fc49a71d1442af8a889d7a7bfbcf21cc Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Sat, 21 Feb 2015 16:02:51 -0500 Subject: [PATCH 19/26] Rename filter types to distinguish coefficients from implementations ZPKFilter -> ZeroPoleGain TFFilter -> PolynomialRatio BiquadFilter -> Biquad SOSFilter -> SecondOrderSections --- doc/filters.rst | 22 +++++----- src/DSP.jl | 2 + src/Filters/Filters.jl | 2 +- src/Filters/design.jl | 32 +++++++-------- src/Filters/filt.jl | 38 +++++++++--------- src/Filters/response.jl | 12 +++--- src/Filters/types.jl | 82 +++++++++++++++++++------------------- src/deprecated.jl | 5 +++ test/FilterTestHelpers.jl | 12 +++--- test/filt.jl | 12 +++--- test/filter_conversion.jl | 26 ++++++------ test/filter_design.jl | 84 +++++++++++++++++++-------------------- test/filter_response.jl | 10 ++--- 13 files changed, 173 insertions(+), 166 deletions(-) create mode 100644 src/deprecated.jl diff --git a/doc/filters.rst b/doc/filters.rst index 76a5ffff6..9a45ea390 100644 --- a/doc/filters.rst +++ b/doc/filters.rst @@ -7,14 +7,14 @@ Linear time-invariant filter representations DSP.jl supports common filter representations. Filters can be converted from one type to another using ``convert``. -.. function:: ZPKFilter(z, p, k) +.. function:: ZeroPoleGain(z, p, k) Filter representation in terms of zeros ``z``, poles ``p``, and gain ``k``: .. math:: H(x) = k\frac{(x - \verb!z[1]!) \ldots (x - \verb!z[end]!)}{(x - \verb!p[1]!) \ldots (x - \verb!p[end]!)} -.. function:: TFFilter(b, a) +.. function:: PolynomialRatio(b, a) Filter representation in terms of the coefficients of the numerator ``b`` and denominator ``a`` of the transfer function: @@ -28,7 +28,7 @@ from one type to another using ``convert``. ``b`` and ``a`` may be specified as ``Polynomial`` objects or vectors ordered from highest power to lowest. -.. function:: BiquadFilter(b0, b1, b2, a1, a2) +.. function:: Biquad(b0, b1, b2, a1, a2) Filter representation in terms of the transfer function of a single second-order section given by: @@ -39,11 +39,11 @@ from one type to another using ``convert``. .. math:: H(z) = \frac{\verb!b0!+\verb!b1! z^{-1}+\verb!b2! z^{-2}}{1+\verb!a1! z^{-1} + \verb!a2! z^{-2}} -.. function:: SOSFilter(biquads, gain) +.. function:: SecondOrderSections(biquads, gain) Filter representation in terms of a cascade of second-order sections and gain. ``biquads`` must be specified as a vector of - ``BiquadFilters``. + ``Biquads``. Filter application ------------------ @@ -52,9 +52,9 @@ Filter application Apply filter ``f`` along the first dimension of array ``x``. ``si`` is an optional array representing the initial filter state - (defaults to zeros). If ``f`` is a ``TFFilter``, ``BiquadFilter``, - or ``SOSFilter``, filtering is implemented directly. If ``f`` is a - ``ZPKFilter``, it is first converted to an ``SOSFilter``. + (defaults to zeros). If ``f`` is a ``PolynomialRatio``, ``Biquad``, + or ``SecondOrderSections``, filtering is implemented directly. If ``f`` is a + ``ZeroPoleGain``, it is first converted to an ``SecondOrderSections``. .. function:: filt!(out, f, x[, si]) @@ -188,12 +188,12 @@ Miscellaneous .. function:: coefb(f) - Coefficients of the numerator of a TFFilter object, highest power + Coefficients of the numerator of a PolynomialRatio object, highest power first, i.e., the ``b`` passed to ``Base.filt()`` .. function:: coefa(f) - Coefficients of the denominator of a TFFilter object, highest power + Coefficients of the denominator of a PolynomialRatio object, highest power first, i.e., the ``a`` passed to ``Base.filt()`` @@ -207,7 +207,7 @@ denominator of the transfer function:: responsetype = Lowpass(0.2) prototype = Elliptic(4, 0.5, 30) - tf = convert(TFFilter, digitalfilter(responsetype, prototype)) + tf = convert(PolynomialRatio, digitalfilter(responsetype, prototype)) numerator_coefs = coefb(tf) denominator_coefs = coefa(tf) diff --git a/src/DSP.jl b/src/DSP.jl index 1d1646e9c..7b6b0e9bb 100644 --- a/src/DSP.jl +++ b/src/DSP.jl @@ -7,4 +7,6 @@ include("Filters/Filters.jl") using Reexport @reexport using .Util, .Windows, .Periodograms, .Filters + +include("deprecated.jl") end diff --git a/src/Filters/Filters.jl b/src/Filters/Filters.jl index 774d973fc..5ee984a88 100644 --- a/src/Filters/Filters.jl +++ b/src/Filters/Filters.jl @@ -2,7 +2,7 @@ module Filters using Polynomials, Compat, ..Util include("types.jl") -export Filter, ZPKFilter, TFFilter, BiquadFilter, SOSFilter, coefa, coefb +export Filter, ZeroPoleGain, PolynomialRatio, Biquad, SecondOrderSections, coefa, coefb include("filt.jl") export filtfilt, fftfilt, firfilt diff --git a/src/Filters/design.jl b/src/Filters/design.jl index 3cae04e98..e13607ec3 100644 --- a/src/Filters/design.jl +++ b/src/Filters/design.jl @@ -19,7 +19,7 @@ function Butterworth(T::Type, n::Integer) if isodd(n) poles[end] = -1 end - ZPKFilter(T[], poles, 1) + ZeroPoleGain(T[], poles, 1) end Butterworth(n::Integer) = Butterworth(Float64, n) @@ -61,7 +61,7 @@ function Chebyshev1(T::Type, n::Integer, ripple::Real) else k *= real(-p[end]) end - ZPKFilter(Float64[], p, k) + ZeroPoleGain(Float64[], p, k) end Chebyshev1(n::Integer, ripple::Real) = Chebyshev1(Float64, n, ripple) @@ -86,7 +86,7 @@ function Chebyshev2(T::Type, n::Integer, ripple::Real) end isodd(n) && (k *= -real(p[end])) - ZPKFilter(z, p, k) + ZeroPoleGain(z, p, k) end Chebyshev2(n::Integer, ripple::Real) = Chebyshev2(Float64, n, ripple) @@ -197,7 +197,7 @@ function Elliptic(T::Type, n::Integer, rp::Real, rs::Real) gain *= 10^(-convert(T, rp)/20) end - ZPKFilter(z, p, gain) + ZeroPoleGain(z, p, gain) end Elliptic(n::Integer, rp::Real, rs::Real) = Elliptic(Float64, n, rp, rs) @@ -257,12 +257,12 @@ end # The Octave implementation was not consulted in creating this code. # Create a lowpass filter from a lowpass filter prototype -transform_prototype(ftype::Lowpass, proto::ZPKFilter) = - ZPKFilter(ftype.w * proto.z, ftype.w * proto.p, +transform_prototype(ftype::Lowpass, proto::ZeroPoleGain) = + ZeroPoleGain(ftype.w * proto.z, ftype.w * proto.p, proto.k * ftype.w^(length(proto.p)-length(proto.z))) # Create a highpass filter from a lowpass filter prototype -function transform_prototype(ftype::Highpass, proto::ZPKFilter) +function transform_prototype(ftype::Highpass, proto::ZeroPoleGain) z = proto.z p = proto.p nz = length(z) @@ -282,11 +282,11 @@ function transform_prototype(ftype::Highpass, proto::ZPKFilter) abs(real(num) - 1) < np*eps(real(num)) && (num = 1) abs(real(den) - 1) < np*eps(real(den)) && (den = 1) - ZPKFilter(newz, newp, proto.k * real(num)/real(den)) + ZeroPoleGain(newz, newp, proto.k * real(num)/real(den)) end # Create a bandpass filter from a lowpass filter prototype -function transform_prototype(ftype::Bandpass, proto::ZPKFilter) +function transform_prototype(ftype::Bandpass, proto::ZeroPoleGain) z = proto.z p = proto.p nz = length(z) @@ -302,11 +302,11 @@ function transform_prototype(ftype::Bandpass, proto::ZPKFilter) newc[2i] = b - pm end end - ZPKFilter(newz, newp, proto.k * (ftype.w2 - ftype.w1) ^ (np - nz)) + ZeroPoleGain(newz, newp, proto.k * (ftype.w2 - ftype.w1) ^ (np - nz)) end # Create a bandstop filter from a lowpass filter prototype -function transform_prototype(ftype::Bandstop, proto::ZPKFilter) +function transform_prototype(ftype::Bandstop, proto::ZeroPoleGain) z = proto.z p = proto.p nz = length(z) @@ -344,18 +344,18 @@ function transform_prototype(ftype::Bandstop, proto::ZPKFilter) abs(real(num) - 1) < np*eps(real(num)) && (num = 1) abs(real(den) - 1) < np*eps(real(den)) && (den = 1) - ZPKFilter(newz, newp, proto.k * real(num)/real(den)) + ZeroPoleGain(newz, newp, proto.k * real(num)/real(den)) end transform_prototype(ftype, proto::Filter) = - transform_prototype(ftype, convert(ZPKFilter, proto)) + transform_prototype(ftype, convert(ZeroPoleGain, proto)) analogfilter(ftype::FilterType, proto::Filter) = transform_prototype(ftype, proto) # Bilinear transform -bilinear(f::Filter, fs::Real) = bilinear(convert(ZPKFilter, f), fs) -function bilinear{Z,P,K}(f::ZPKFilter{Z,P,K}, fs::Real) +bilinear(f::Filter, fs::Real) = bilinear(convert(ZeroPoleGain, f), fs) +function bilinear{Z,P,K}(f::ZeroPoleGain{Z,P,K}, fs::Real) ztype = typeof(0 + zero(Z)/fs) z = fill(convert(ztype, -1), max(length(f.p), length(f.z))) @@ -374,7 +374,7 @@ function bilinear{Z,P,K}(f::ZPKFilter{Z,P,K}, fs::Real) den *= (2 * fs - f.p[i]) end - ZPKFilter(z, p, f.k * real(num)/real(den)) + ZeroPoleGain(z, p, f.k * real(num)/real(den)) end # Pre-warp filter frequencies for digital filtering diff --git a/src/Filters/filt.jl b/src/Filters/filt.jl index 232f2b441..9362cd5c1 100644 --- a/src/Filters/filt.jl +++ b/src/Filters/filt.jl @@ -4,19 +4,19 @@ # filt and filt! # -## TFFilter -_zerosi{T,S}(f::TFFilter{T}, x::AbstractArray{S}) = +## PolynomialRatio +_zerosi{T,S}(f::PolynomialRatio{T}, x::AbstractArray{S}) = zeros(promote_type(T, S), max(length(f.a), length(f.b))-1) -Base.filt!{T,S}(out, f::TFFilter{T}, x::AbstractArray{S}, si=_zerosi(f, x)) = +Base.filt!{T,S}(out, f::PolynomialRatio{T}, x::AbstractArray{S}, si=_zerosi(f, x)) = filt!(out, coefb(f), coefa(f), x, si) -Base.filt(f::TFFilter, x, si=_zerosi(f, x)) = filt(coefb(f), coefa(f), x, si) +Base.filt(f::PolynomialRatio, x, si=_zerosi(f, x)) = filt(coefb(f), coefa(f), x, si) -## SOSFilter -_zerosi{T,G,S}(f::SOSFilter{T,G}, x::AbstractArray{S}) = +## SecondOrderSections +_zerosi{T,G,S}(f::SecondOrderSections{T,G}, x::AbstractArray{S}) = zeros(promote_type(T, G, S), 2, length(f.biquads)) -function Base.filt!{S,N}(out::AbstractArray, f::SOSFilter, x::AbstractArray, +function Base.filt!{S,N}(out::AbstractArray, f::SecondOrderSections, x::AbstractArray, si::AbstractArray{S,N}=_zerosi(f, x)) biquads = f.biquads ncols = Base.trailingsize(x, 2) @@ -43,14 +43,14 @@ function Base.filt!{S,N}(out::AbstractArray, f::SOSFilter, x::AbstractArray, out end -Base.filt{T,G,S<:Number}(f::SOSFilter{T,G}, x::AbstractArray{S}, si=_zerosi(f, x)) = +Base.filt{T,G,S<:Number}(f::SecondOrderSections{T,G}, x::AbstractArray{S}, si=_zerosi(f, x)) = filt!(Array(promote_type(T, G, S), size(x)), f, x, si) -## BiquadFilter -_zerosi{T,S}(f::BiquadFilter{T}, x::AbstractArray{S}) = +## Biquad +_zerosi{T,S}(f::Biquad{T}, x::AbstractArray{S}) = zeros(promote_type(T, S), 2) -function Base.filt!{S,N}(out::AbstractArray, f::BiquadFilter, x::AbstractArray, +function Base.filt!{S,N}(out::AbstractArray, f::Biquad, x::AbstractArray, si::AbstractArray{S,N}=_zerosi(f, x)) ncols = Base.trailingsize(x, 2) @@ -73,12 +73,12 @@ function Base.filt!{S,N}(out::AbstractArray, f::BiquadFilter, x::AbstractArray, out end -Base.filt{T,S<:Number}(f::BiquadFilter{T}, x::AbstractArray{S}, si=_zerosi(f, x)) = +Base.filt{T,S<:Number}(f::Biquad{T}, x::AbstractArray{S}, si=_zerosi(f, x)) = filt!(Array(promote_type(T, S), size(x)), f, x, si) -## For arbitrary filters, convert to SOSFilter -Base.filt(f::Filter, x) = filt(convert(SOSFilter, f), x) -Base.filt!(out, f::Filter, x) = filt!(out, convert(SOSFilter, f), x) +## For arbitrary filters, convert to SecondOrderSections +Base.filt(f::Filter, x) = filt(convert(SecondOrderSections, f), x) +Base.filt!(out, f::Filter, x) = filt!(out, convert(SecondOrderSections, f), x) # # filtfilt @@ -177,7 +177,7 @@ function biquad_si!(zitmp, zi, i, scal) end # Zero phase digital filtering for second order sections -function filtfilt{T,G,S}(f::SOSFilter{T,G}, x::AbstractArray{S}) +function filtfilt{T,G,S}(f::SecondOrderSections{T,G}, x::AbstractArray{S}) zi = filt_stepstate(f) zi2 = zeros(2) zitmp = zeros(2) @@ -211,8 +211,8 @@ function filtfilt{T,G,S}(f::SOSFilter{T,G}, x::AbstractArray{S}) end # Support for other filter types -filtfilt(f::Filter, x) = filtfilt(convert(SOSFilter, f), x) -filtfilt(f::TFFilter, x) = filtfilt(coefb(f), coefa(f), x) +filtfilt(f::Filter, x) = filtfilt(convert(SecondOrderSections, f), x) +filtfilt(f::PolynomialRatio, x) = filtfilt(coefb(f), coefa(f), x) ## Initial filter state @@ -243,7 +243,7 @@ function filt_stepstate{T<:Number}(b::Union(AbstractVector{T}, T), a::Union(Abst scale_factor \ (I - A) \ B end -function filt_stepstate{T}(f::SOSFilter{T}) +function filt_stepstate{T}(f::SecondOrderSections{T}) biquads = f.biquads si = Array(T, 2, length(biquads)) for i = 1:length(biquads) diff --git a/src/Filters/response.jl b/src/Filters/response.jl index 21d072ad1..231774199 100644 --- a/src/Filters/response.jl +++ b/src/Filters/response.jl @@ -5,18 +5,18 @@ # function freqz(filter::Filter, w::Number) - filter = convert(TFFilter, filter) + filter = convert(PolynomialRatio, filter) ejw = exp(-im * w) polyval(filter.b, ejw) ./ polyval(filter.a, ejw) end function freqz(filter::Filter, w = linspace(0, π, 250)) - filter = convert(TFFilter, filter) + filter = convert(PolynomialRatio, filter) [freqz(filter, i) for i = w] end function freqz(filter::Filter, hz::Union(Number, AbstractVector), fs::Number) - filter = convert(TFFilter, filter) + filter = convert(PolynomialRatio, filter) freqz(filter, hz_to_radians_per_second(hz, fs)) end @@ -55,18 +55,18 @@ end # function freqs(filter::Filter, w::Number) - filter = convert(TFFilter, filter) + filter = convert(PolynomialRatio, filter) s = im * w polyval(filter.b, s) ./ polyval(filter.a, s) end function freqs(filter::Filter, w::AbstractVector) - filter = convert(TFFilter, filter) + filter = convert(PolynomialRatio, filter) [freqs(filter, i) for i = w] end function freqs(filter::Filter, hz::Union(Number, AbstractVector), fs::Number) - filter = convert(TFFilter, filter) + filter = convert(PolynomialRatio, filter) freqs(filter, hz_to_radians_per_second(hz, fs)) end diff --git a/src/Filters/types.jl b/src/Filters/types.jl index fe71f0bb8..cfe35a8c5 100644 --- a/src/Filters/types.jl +++ b/src/Filters/types.jl @@ -6,7 +6,7 @@ abstract Filter # Zero-pole gain form # -immutable ZPKFilter{Z<:Number,P<:Number,K<:Number} <: Filter +immutable ZeroPoleGain{Z<:Number,P<:Number,K<:Number} <: Filter z::Vector{Z} p::Vector{P} k::K @@ -16,59 +16,59 @@ end # Transfer function form # -immutable TFFilter{T<:Number} <: Filter +immutable PolynomialRatio{T<:Number} <: Filter b::Poly{T} a::Poly{T} - TFFilter(b::Poly, a::Poly) = + PolynomialRatio(b::Poly, a::Poly) = new(convert(Poly{T}, b/a[end]), convert(Poly{T}, a/a[end])) end -TFFilter{T<:Number}(b::Poly{T}, a::Poly{T}) = TFFilter{T}(b, a) +PolynomialRatio{T<:Number}(b::Poly{T}, a::Poly{T}) = PolynomialRatio{T}(b, a) # The DSP convention is highest power first. The Polynomials.jl # convention is lowest power first. -function TFFilter{T<:Number,S<:Number}(b::Union(T,Vector{T}), a::Union(S,Vector{S})) +function PolynomialRatio{T<:Number,S<:Number}(b::Union(T,Vector{T}), a::Union(S,Vector{S})) if findfirst(b) == 0 || findfirst(a) == 0 error("filter must have non-zero numerator and denominator") end - TFFilter{promote_type(T,S)}(Poly(b[end:-1:findfirst(b)]), Poly(a[end:-1:findfirst(a)])) + PolynomialRatio{promote_type(T,S)}(Poly(b[end:-1:findfirst(b)]), Poly(a[end:-1:findfirst(a)])) end -function Base.convert(::Type{TFFilter}, f::ZPKFilter) +function Base.convert(::Type{PolynomialRatio}, f::ZeroPoleGain) b = f.k*poly(f.z) a = poly(f.p) - TFFilter(Poly(real(b.a)), Poly(real(a.a))) + PolynomialRatio(Poly(real(b.a)), Poly(real(a.a))) end -function Base.convert{T}(::Type{ZPKFilter}, f::TFFilter{T}) +function Base.convert{T}(::Type{ZeroPoleGain}, f::PolynomialRatio{T}) k = real(f.b[end]) b = f.b / k z = convert(Vector{Complex{T}}, roots(b)) p = convert(Vector{Complex{T}}, roots(f.a)) - ZPKFilter(z, p, k) + ZeroPoleGain(z, p, k) end -coefb(f::TFFilter) = reverse(f.b.a) -coefa(f::TFFilter) = reverse(f.a.a) +coefb(f::PolynomialRatio) = reverse(f.b.a) +coefa(f::PolynomialRatio) = reverse(f.a.a) # # Biquad filter in transfer function form -# A separate immutable to improve efficiency of filtering using SOSFilters +# A separate immutable to improve efficiency of filtering using SecondOrderSectionss # -immutable BiquadFilter{T} <: Filter +immutable Biquad{T} <: Filter b0::T b1::T b2::T a1::T a2::T end -BiquadFilter{T}(b0::T, b1::T, b2::T, a0::T, a1::T, a2::T, g::Real=1) = - BiquadFilter(g*b0/a0, g*b1/a0, g*b2/a0, a1/a0, a2/a0) +Biquad{T}(b0::T, b1::T, b2::T, a0::T, a1::T, a2::T, g::Real=1) = + Biquad(g*b0/a0, g*b1/a0, g*b2/a0, a1/a0, a2/a0) -Base.convert(::Type{ZPKFilter}, f::BiquadFilter) = convert(ZPKFilter, convert(TFFilter, f)) +Base.convert(::Type{ZeroPoleGain}, f::Biquad) = convert(ZeroPoleGain, convert(PolynomialRatio, f)) -function Base.convert{T}(::Type{TFFilter}, f::BiquadFilter{T}) +function Base.convert{T}(::Type{PolynomialRatio}, f::Biquad{T}) if f.b2 == zero(T) && f.a2 == zero(T) if f.b1 == zero(T) && f.a1 == zero(T) b = [f.b0] @@ -82,36 +82,36 @@ function Base.convert{T}(::Type{TFFilter}, f::BiquadFilter{T}) a = [one(T), f.a1, f.a2] end - TFFilter(b, a) + PolynomialRatio(b, a) end -Base.convert(::Type{BiquadFilter}, f::ZPKFilter) = convert(BiquadFilter, convert(TFFilter, f)) +Base.convert(::Type{Biquad}, f::ZeroPoleGain) = convert(Biquad, convert(PolynomialRatio, f)) -function Base.convert{T}(::Type{BiquadFilter}, f::TFFilter{T}) +function Base.convert{T}(::Type{Biquad}, f::PolynomialRatio{T}) a, b = f.a, f.b xs = max(length(b), length(a)) if xs == 3 - BiquadFilter(b[2], b[1], b[0], a[1], a[0]) + Biquad(b[2], b[1], b[0], a[1], a[0]) elseif xs == 2 - BiquadFilter(b[1], b[0], zero(T), a[0], zero(T)) + Biquad(b[1], b[0], zero(T), a[0], zero(T)) elseif xs == 1 - BiquadFilter(b[0], zero(T), zero(T), zero(T), zero(T)) + Biquad(b[0], zero(T), zero(T), zero(T), zero(T)) elseif xs == 0 - error("cannot convert an empty TFFilter to BiquadFilter") + error("cannot convert an empty PolynomialRatio to Biquad") else - error("cannot convert a filter of length > 3 to BiquadFilter") + error("cannot convert a filter of length > 3 to Biquad") end end -*(f::BiquadFilter, g::Number) = BiquadFilter(f.b0*g, f.b1*g, f.b2*g, f.a1, f.a2) +*(f::Biquad, g::Number) = Biquad(f.b0*g, f.b1*g, f.b2*g, f.a1, f.a2) # # Second-order sections (array of biquads) # -immutable SOSFilter{T,G} <: Filter - biquads::Vector{BiquadFilter{T}} +immutable SecondOrderSections{T,G} <: Filter + biquads::Vector{Biquad{T}} g::G end @@ -120,22 +120,22 @@ realtype{T}(::Type{Complex{T}}) = T complextype(T::DataType) = Complex{T} complextype{T}(::Type{Complex{T}}) = Complex{T} -function Base.convert{T}(::Type{ZPKFilter}, f::SOSFilter{T}) +function Base.convert{T}(::Type{ZeroPoleGain}, f::SecondOrderSections{T}) t = complextype(T) z = t[] p = t[] k = f.g for biquad in f.biquads - biquadzpk = convert(ZPKFilter, biquad) + biquadzpk = convert(ZeroPoleGain, biquad) append!(z, biquadzpk.z) append!(p, biquadzpk.p) k *= biquadzpk.k end - ZPKFilter(z, p, k) + ZeroPoleGain(z, p, k) end -Base.convert(to::Union(Type{TFFilter}, Type{BiquadFilter}), f::SOSFilter) = - convert(to, convert(ZPKFilter, f)) +Base.convert(to::Union(Type{PolynomialRatio}, Type{Biquad}), f::SecondOrderSections) = + convert(to, convert(ZeroPoleGain, f)) # Split real and complex values in a vector into separate vectors function split_real_complex{T<:Real}(v::Vector{Complex{T}}) @@ -183,12 +183,12 @@ end # Convert a filter to second-order sections # The returned sections are in ZPK form -function Base.convert{Z,P}(::Type{SOSFilter}, f::ZPKFilter{Z,P}) +function Base.convert{Z,P}(::Type{SecondOrderSections}, f::ZeroPoleGain{Z,P}) z = f.z p = f.p nz = length(z) n = length(p) - nz > n && error("ZPKFilter must not have more zeros than poles") + nz > n && error("ZeroPoleGain must not have more zeros than poles") # Sort poles and zeros lexicographically so that matched values are adjacent z = sort(z, order=Base.Order.Lexicographic) @@ -223,7 +223,7 @@ function Base.convert{Z,P}(::Type{SOSFilter}, f::ZPKFilter{Z,P}) # Allocate memory for biquads T = promote_type(realtype(Z), realtype(P)) - biquads = Array(BiquadFilter{T}, (n >> 1)+(n & 1)) + biquads = Array(Biquad{T}, (n >> 1)+(n & 1)) # Build second-order sections in reverse # First do complete pairs @@ -231,17 +231,17 @@ function Base.convert{Z,P}(::Type{SOSFilter}, f::ZPKFilter{Z,P}) odd = isodd(n) for i = 1:npairs pairidx = 2*(npairs-i) - biquads[odd+i] = convert(BiquadFilter, ZPKFilter(groupedz[pairidx+1:min(pairidx+2, length(groupedz))], + biquads[odd+i] = convert(Biquad, ZeroPoleGain(groupedz[pairidx+1:min(pairidx+2, length(groupedz))], groupedp[pairidx+1:pairidx+2], one(T))) end if odd # Now do remaining pole and (maybe) zero - biquads[1] = convert(BiquadFilter, ZPKFilter(groupedz[length(groupedp):end], + biquads[1] = convert(Biquad, ZeroPoleGain(groupedz[length(groupedp):end], [groupedp[end]], one(T))) end - SOSFilter(biquads, f.k) + SecondOrderSections(biquads, f.k) end -Base.convert(::Type{SOSFilter}, f::Filter) = convert(SOSFilter, convert(ZPKFilter, f)) +Base.convert(::Type{SecondOrderSections}, f::Filter) = convert(SecondOrderSections, convert(ZeroPoleGain, f)) diff --git a/src/deprecated.jl b/src/deprecated.jl new file mode 100644 index 000000000..8961c2311 --- /dev/null +++ b/src/deprecated.jl @@ -0,0 +1,5 @@ +const ZPKFilter = ZeroPoleGain +const TFFilter = PolynomialRatio +const BiquadFilter = Biquad +const SOSFilter = SecondOrderSections +export ZPKFilter, TFFilter, BiquadFilter, SOSFilter diff --git a/test/FilterTestHelpers.jl b/test/FilterTestHelpers.jl index 0b615feb4..edea3e415 100644 --- a/test/FilterTestHelpers.jl +++ b/test/FilterTestHelpers.jl @@ -87,14 +87,14 @@ function zpkfilter_accuracy(f1, f2, accurate_f; relerr=1, eps=nothing) accuracy_check(loss(f1.k, accurate_f.k), loss(f2.k, accurate_f.k), "k", relerr) end -# Convert an SOS matrix, as returned by MATLAB, to an SOSFilter +# Convert an SOS matrix, as returned by MATLAB, to an SecondOrderSections matrix_to_sosfilter(sos::Matrix, g::Number) = - SOSFilter([BiquadFilter(sos[i, 1], sos[i, 2], sos[i, 3], + SecondOrderSections([Biquad(sos[i, 1], sos[i, 2], sos[i, 3], sos[i, 4], sos[i, 5], sos[i, 6]) for i = 1:size(sos, 1)], g) -# Convert an SOSFilter to an SOS matrix as returned by MATLAB -function sosfilter_to_matrix(sos::SOSFilter) +# Convert an SecondOrderSections to an SOS matrix as returned by MATLAB +function sosfilter_to_matrix(sos::SecondOrderSections) A = ones(length(sos.biquads), 6) for (i, biquad) in enumerate(sos.biquads) A[i, 1] = biquad.b0 @@ -108,11 +108,11 @@ end # Show the poles and zeros in each biquad # This is not currently used for testing, but is useful for debugging -function sosfilter_poles_zeros{T}(sos::SOSFilter{T}) +function sosfilter_poles_zeros{T}(sos::SecondOrderSections{T}) z = fill(complex(nan(T)), 2, length(sos.biquads)) p = fill(complex(nan(T)), 2, length(sos.biquads)) for (i, biquad) in enumerate(sos.biquads) - zpk = convert(ZPKFilter, biquad) + zpk = convert(ZeroPoleGain, biquad) z[1:length(zpk.z), i] = zpk.z p[1:length(zpk.p), i] = zpk.p end diff --git a/test/filt.jl b/test/filt.jl index 3ecdd9307..e19ddd361 100644 --- a/test/filt.jl +++ b/test/filt.jl @@ -10,13 +10,13 @@ x = randn(100) for n = 1:6 for proto in (Butterworth(n), Chebyshev1(n, 1), Chebyshev2(n, 1), Elliptic(n, 0.5, 2)) zpk = digitalfilter(Lowpass(0.2), proto) - tf = convert(TFFilter, zpk) + tf = convert(PolynomialRatio, zpk) if n <= 2 - bq = convert(BiquadFilter, zpk) + bq = convert(Biquad, zpk) else - @test_throws ErrorException convert(BiquadFilter, zpk) + @test_throws ErrorException convert(Biquad, zpk) end - sos = convert(SOSFilter, zpk) + sos = convert(SecondOrderSections, zpk) res = filt(sos, x) @@ -209,7 +209,7 @@ x[:,3] = circshift(x[:,3], 128) b = [ 0.00327922, 0.01639608, 0.03279216, 0.03279216, 0.01639608, 0.00327922] a = [ 1. , -2.47441617, 2.81100631, -1.70377224, 0.54443269, -0.07231567] -f = TFFilter(b, a) +f = PolynomialRatio(b, a) # Use 2d data from last test @test_approx_eq x2_output filtfilt(f, x) @@ -217,7 +217,7 @@ f = TFFilter(b, a) ####################################### # -# Test 2d filtfilt with SOSFilter +# Test 2d filtfilt with SecondOrderSections # #= diff --git a/test/filter_conversion.jl b/test/filter_conversion.jl index 76354e6ca..32c6a3198 100644 --- a/test/filter_conversion.jl +++ b/test/filter_conversion.jl @@ -35,7 +35,7 @@ m_sos_full = [ 1.0000000000000000e+00 -1.5349884628162233e-01 3.2015548658469395e-01 1.0000000000000000e+00 3.0103979752048204e-01 9.0127546185805940e-01 1.0000000000000000e+00 7.1961394067477846e-01 1.7609890829003397e-01 1.0000000000000000e+00 1.8923598009282561e+00 9.4902172971582510e-01 ] -@test_approx_eq m_sos_full sosfilter_to_matrix(convert(SOSFilter, ZPKFilter(z, p, k))) +@test_approx_eq m_sos_full sosfilter_to_matrix(convert(SecondOrderSections, ZeroPoleGain(z, p, k))) # And with half of the zeros removed # MATLAB: @@ -53,7 +53,7 @@ m_sos_half = [ 1.0000000000000000e+00 -1.5349884628162233e-01 3.2015548658469395e-01 1.0000000000000000e+00 3.0103979752048204e-01 9.0127546185805940e-01 1.0000000000000000e+00 2.1275529126166826e-01 1.1404343849064294e-02 1.0000000000000000e+00 1.8923598009282561e+00 9.4902172971582510e-01 ] -@test_approx_eq m_sos_half sosfilter_to_matrix(convert(SOSFilter, ZPKFilter(zp, p, k))) +@test_approx_eq m_sos_half sosfilter_to_matrix(convert(SecondOrderSections, ZeroPoleGain(zp, p, k))) # And with an extra real pole pp = [p; 0.7] @@ -75,29 +75,29 @@ m_sos_extra = [ 1.0000000000000000e+00 -1.5349884628162233e-01 3.2015548658469395e-01 1.0000000000000000e+00 3.0103979752048204e-01 9.0127546185805940e-01 1.0000000000000000e+00 7.1961394067477846e-01 1.7609890829003397e-01 1.0000000000000000e+00 1.8923598009282561e+00 9.4902172971582510e-01 ] -@test_approx_eq m_sos_extra sosfilter_to_matrix(convert(SOSFilter, ZPKFilter(z, pp, k))) +@test_approx_eq m_sos_extra sosfilter_to_matrix(convert(SecondOrderSections, ZeroPoleGain(z, pp, k))) # And with only poles (no zeros) m_sos_only_poles = copy(m_sos_full) m_sos_only_poles[:, 1:2] = 0 m_sos_only_poles[:, 3] = 1 -@test_approx_eq m_sos_only_poles sosfilter_to_matrix(convert(SOSFilter, ZPKFilter(Float64[], p, k))) +@test_approx_eq m_sos_only_poles sosfilter_to_matrix(convert(SecondOrderSections, ZeroPoleGain(Float64[], p, k))) # Test that a numerically challenging filter (high order, clustered # roots) has acceptable errors in its coefficients after conversion to # SOS -f = ZPKFilter(ones(100), 0.99*ones(100), 1) -g = convert(SOSFilter, f) -tffilter_eq(convert(TFFilter, f), convert(TFFilter, g)) +f = ZeroPoleGain(ones(100), 0.99*ones(100), 1) +g = convert(SecondOrderSections, f) +tffilter_eq(convert(PolynomialRatio, f), convert(PolynomialRatio, g)) for f in (digitalfilter(Lowpass(0.5), Butterworth(1)), digitalfilter(Lowpass(0.5), Butterworth(2)), digitalfilter(Bandpass(0.25, 0.75), Butterworth(1))) - for ftype1 in (ZPKFilter, TFFilter, BiquadFilter, SOSFilter) + for ftype1 in (ZeroPoleGain, PolynomialRatio, Biquad, SecondOrderSections) f2 = convert(ftype1, f) - for ftype2 in (ZPKFilter, TFFilter, BiquadFilter, SOSFilter) + for ftype2 in (ZeroPoleGain, PolynomialRatio, Biquad, SecondOrderSections) f3 = convert(ftype2, f) try - zpkfilter_eq(convert(ZPKFilter, f), convert(ZPKFilter, f3), sqrt(eps())) + zpkfilter_eq(convert(ZeroPoleGain, f), convert(ZeroPoleGain, f3), sqrt(eps())) catch e println("Conversion from $ftype1 to $ftype2 failed:") rethrow(e) @@ -108,11 +108,11 @@ end for proto in (Butterworth(3), Chebyshev1(3, 1), Chebyshev2(3, 1)) f = digitalfilter(Lowpass(0.5), proto) - for ftype1 in (ZPKFilter, TFFilter, SOSFilter) + for ftype1 in (ZeroPoleGain, PolynomialRatio, SecondOrderSections) f2 = convert(ftype1, f) - for ftype2 in (ZPKFilter, TFFilter, SOSFilter) + for ftype2 in (ZeroPoleGain, PolynomialRatio, SecondOrderSections) f3 = convert(ftype2, f2) - zpkfilter_eq(convert(ZPKFilter, f), convert(ZPKFilter, f3), 2e-5) + zpkfilter_eq(convert(ZeroPoleGain, f), convert(ZeroPoleGain, f3), 2e-5) end end end diff --git a/test/filter_design.jl b/test/filter_design.jl index 1904641f8..265d31978 100644 --- a/test/filter_design.jl +++ b/test/filter_design.jl @@ -7,7 +7,7 @@ using DSP, Base.Test, FilterTestHelpers # Poles of 20 pole Butterworth filter prototype from MATLAB 2013b (buttap(20)) matlab_p = [-0.07845909572784487+0.996917333733128im,-0.07845909572784487-0.996917333733128im,-0.2334453638559053+0.9723699203976767im,-0.2334453638559053-0.9723699203976767im,-0.3826834323650897+0.9238795325112867im,-0.3826834323650897-0.9238795325112867im,-0.5224985647159488+0.8526401643540923im,-0.5224985647159488-0.8526401643540923im,-0.6494480483301835+0.760405965600031im,-0.6494480483301835-0.760405965600031im,-0.7604059656000308+0.6494480483301838im,-0.7604059656000308-0.6494480483301838im,-0.8526401643540922+0.5224985647159489im,-0.8526401643540922-0.5224985647159489im,-0.9238795325112867+0.3826834323650899im,-0.9238795325112867-0.3826834323650899im,-0.9723699203976766+0.2334453638559055im,-0.9723699203976766-0.2334453638559055im,-0.996917333733128+0.07845909572784507im,-0.996917333733128-0.07845909572784507im] -matlab_butter = ZPKFilter(Union()[], matlab_p, 1) +matlab_butter = ZeroPoleGain(Union()[], matlab_p, 1) # Test that our answers are close to MATLAB's and at least as accurate butter = Butterworth(20) @@ -18,8 +18,8 @@ zpkfilter_accuracy(butter, matlab_butter, Butterworth(BigFloat, 20)) matlab_p = [-0.08257934547233227+0.9965844930066698im,-0.08257934547233227-0.9965844930066698im,-0.2454854871407991+0.9694002659393304im,-0.2454854871407991-0.9694002659393304im,-0.4016954246529694+0.9157733266550574im,-0.4016954246529694-0.9157733266550574im,-0.5469481581224267+0.8371664782625287im,-0.5469481581224267-0.8371664782625287im,-0.6772815716257409+0.7357239106731317im,-0.6772815716257409-0.7357239106731317im,-0.7891405093963935+0.6142127126896679im,-0.7891405093963935-0.6142127126896679im,-0.8794737512064892+0.4759473930370733im,-0.8794737512064892-0.4759473930370733im,-0.9458172417006346+0.3246994692046836im,-0.9458172417006346-0.3246994692046836im,-0.9863613034027224+0.1645945902807336im,-0.9863613034027224-0.1645945902807336im,-1+0im] # Test that our answers are close to MATLAB's and at least as accurate -zpkfilter_eq(Butterworth(19), ZPKFilter(Union()[], matlab_p, 1)) -zpkfilter_accuracy(Butterworth(19), ZPKFilter(Union()[], matlab_p, 1), Butterworth(BigFloat, 19)) +zpkfilter_eq(Butterworth(19), ZeroPoleGain(Union()[], matlab_p, 1)) +zpkfilter_accuracy(Butterworth(19), ZeroPoleGain(Union()[], matlab_p, 1), Butterworth(BigFloat, 19)) # # Chebyshev type I filter @@ -34,8 +34,8 @@ matlab_p = [-0.005606643513655412+0.9994594480354867im,-0.01668187637027696+0.97 matlab_k = 3.748372513504540e-06 # Test that our answers are close to MATLAB's and at least as accurate -zpkfilter_eq(Chebyshev1(20, 1), ZPKFilter(Union()[], matlab_p, matlab_k)) -zpkfilter_accuracy(Chebyshev1(20, 1), ZPKFilter(Union()[], matlab_p, matlab_k), Chebyshev1(BigFloat, 20, 1)) +zpkfilter_eq(Chebyshev1(20, 1), ZeroPoleGain(Union()[], matlab_p, matlab_k)) +zpkfilter_accuracy(Chebyshev1(20, 1), ZeroPoleGain(Union()[], matlab_p, matlab_k), Chebyshev1(BigFloat, 20, 1)) # Poles of 19 pole Butterworth filter prototype with 1 dB passband ripple from MATLAB 2013b: #= @@ -47,8 +47,8 @@ matlab_p = [-0.006212227114275604+0.9994004289494353im,-0.0184672279812169+0.972 matlab_k = 7.496745027009062e-06 # Test that our answers are close to MATLAB's and at least as accurate -zpkfilter_eq(Chebyshev1(19, 1), ZPKFilter(Union()[], matlab_p, matlab_k)) -zpkfilter_accuracy(Chebyshev1(19, 1), ZPKFilter(Union()[], matlab_p, matlab_k), Chebyshev1(BigFloat, 19, 1)) +zpkfilter_eq(Chebyshev1(19, 1), ZeroPoleGain(Union()[], matlab_p, matlab_k)) +zpkfilter_accuracy(Chebyshev1(19, 1), ZeroPoleGain(Union()[], matlab_p, matlab_k), Chebyshev1(BigFloat, 19, 1)) # # Chebyshev type II filter @@ -64,7 +64,7 @@ zpkfilter_accuracy(Chebyshev1(19, 1), ZPKFilter(Union()[], matlab_p, matlab_k), matlab_z = [0+1.003092198482826im,0-1.003092198482826im,0+1.028415193665209im,0-1.028415193665209im,0+1.082392200292394im,0-1.082392200292394im,0+1.172827696614009im,0-1.172827696614009im,0+1.315086999890785im,0-1.315086999890785im,0+1.539769043222366im,0-1.539769043222366im,0+1.913880855430943im,0-1.913880855430943im,0+2.613125929752753im,0-2.613125929752753im,0+4.283657569731185im,0-4.283657569731185im,0+12.74549484318238im,0-12.74549484318238im] matlab_p = [-0.001929675700544753-1.002788598382701im,-0.006034873757627809-1.028072311003105im,-0.010957850142167-1.081957626858823im,-0.01756373888305481-1.172213900920771im,-0.02744258171352171-1.314120759169777im,-0.04403133250736632-1.538048178699878im,-0.07621942506983267-1.910267531994771im,-0.1536690174908018-2.6032737531287im,-0.4316587213861887-4.238414904224276im,-3.610083779585366-11.62012078608171im,-3.610083779585366+11.62012078608171im,-0.4316587213861887+4.238414904224276im,-0.1536690174908018+2.6032737531287im,-0.07621942506983267+1.910267531994771im,-0.04403133250736632+1.538048178699878im,-0.02744258171352171+1.314120759169777im,-0.01756373888305481+1.172213900920771im,-0.010957850142167+1.081957626858823im,-0.006034873757627809+1.028072311003105im,-0.001929675700544753+1.002788598382701im] matlab_k = 0.8912509381337452 -matlab_f = ZPKFilter(matlab_z, matlab_p, matlab_k) +matlab_f = ZeroPoleGain(matlab_z, matlab_p, matlab_k) # The gain shows a greater discrepancy with the gain of the enhanced # precision filter than MATLAB's, but AFAICT our filter is still more @@ -85,7 +85,7 @@ zpkfilter_accuracy(f, matlab_f, Chebyshev2(BigFloat, 20, 1), relerr=4) matlab_z = [0+1.003427212662145im,0-1.003427212662145im,0+1.031565634068626im,0-1.031565634068626im,0+1.091973276457601im,0-1.091973276457601im,0+1.194505544554793im,0-1.194505544554793im,0+1.359205519207709im,0-1.359205519207709im,0+1.628100459889458im,0-1.628100459889458im,0+2.101072544213108im,0-2.101072544213108im,0+3.079770972368366im,0-3.079770972368366im,0+6.075533820974263im,0-6.075533820974263im] matlab_p = [-0.002139218568677465-1.003090263923361im,-0.006720708432694556-1.031180124433753im,-0.01232195186345456-1.091472452757043im,-0.02007306444044342-1.193772338103026im,-0.03217434756636293-1.357992987527419im,-0.05375960613144559-1.625783486413104im,-0.09966387580015423-2.09563676642751im,-0.2295218019875045-3.061543704346429im,-0.9149742173123645-5.932401750359961im,-38.84170469908301+0im,-0.9149742173123645+5.932401750359961im,-0.2295218019875045+3.061543704346429im,-0.09966387580015423+2.09563676642751im,-0.05375960613144559+1.625783486413104im,-0.03217434756636293+1.357992987527419im,-0.02007306444044342+1.193772338103026im,-0.01232195186345456+1.091472452757043im,-0.006720708432694556+1.031180124433753im,-0.002139218568677465+1.003090263923361im] matlab_k = 37.33930783884512 -matlab_f = ZPKFilter(matlab_z, matlab_p, matlab_k) +matlab_f = ZeroPoleGain(matlab_z, matlab_p, matlab_k) f = Chebyshev2(19, 1) zpkfilter_eq(f, matlab_f) @@ -106,7 +106,7 @@ zpkfilter_accuracy(f, matlab_f, Chebyshev2(BigFloat, 19, 1), relerr=2) matlab_z = [0-1.953252853757711im,0+1.953252853757711im,0-1.069599937693626im,0+1.069599937693626im,0-1.007032209276402im,0+1.007032209276402im,0-1.000730367252677im,0+1.000730367252677im,0-1.000076070678288im,0+1.000076070678288im,0-1.000007925871874im,0+1.000007925871874im,0-1.000000826312751im,0+1.000000826312751im,0-1.000000086632384im,0+1.000000086632384im,0-1.000000009576065im,0+1.000000009576065im,0-1.000000001633984im,0+1.000000001633984im] matlab_p = [-0.6665552331000151-0.9586923119289487im,-0.6665552331000151+0.9586923119289487im,-0.06598422536270995-1.015686365686964im,-0.06598422536270995+1.015686365686964im,-0.006773291804375061-1.001821704927991im,-0.006773291804375061+1.001821704927991im,-0.0007045345890457818-1.000191780070487im,-0.0007045345890457818+1.000191780070487im,-7.339097059946433e-05-1.000020003037497im,-7.339097059946433e-05+1.000020003037497im,-7.646273200288023e-06-1.000002084836051im,-7.646273200288023e-06+1.000002084836051im,-7.966432964216136e-07-1.000000217756124im,-7.966432964216136e-07+1.000000217756124im,-8.299912436196738e-08-1.000000023227775im,-8.299912436196738e-08+1.000000023227775im,-8.637784231770464e-09-1.000000002962719im,-8.637784231770464e-09+1.000000002962719im,-8.070974080610083e-10-1.000000000874029im,-8.070974080610083e-10+1.000000000874029im] matlab_k = 0.3162277662398871 -matlab_f = ZPKFilter(matlab_z, matlab_p, matlab_k) +matlab_f = ZeroPoleGain(matlab_z, matlab_p, matlab_k) f = Elliptic(20, 0.1, 10) zpkfilter_eq(f, matlab_f) @@ -123,7 +123,7 @@ zpkfilter_accuracy(f, matlab_f, Elliptic(BigFloat, 20, 0.1, 10), eps=1e-9) matlab_z = [0-1.232609672486912im,0+1.232609672486912im,0-1.021948255265862im,0+1.021948255265862im,0-1.002264470627064im,0+1.002264470627064im,0-1.000235691798532im,0+1.000235691798532im,0-1.000024555183434im,0+1.000024555183434im,0-1.000002559984621im,0+1.000002559984621im,0-1.000000268394018im,0+1.000000268394018im,0-1.00000002966741im,0+1.00000002966741im,0-1.000000005062212im,0+1.000000005062212im] matlab_p = [-0.2102804655411482-1.034611529620449im,-0.2102804655411482+1.034611529620449im,-0.0210635609742992-1.005504639644632im,-0.0210635609742992+1.005504639644632im,-0.002183581313750937-1.00059265523267im,-0.002183581313750937+1.00059265523267im,-0.0002273805846473938-1.000061954788962im,-0.0002273805846473938+1.000061954788962im,-2.368886404726722e-05-1.000006458811389im,-2.368886404726722e-05+1.000006458811389im,-2.468065209676509e-06-1.00000067462382im,-2.468065209676509e-06+1.00000067462382im,-2.571378798158274e-07-1.000000071961468im,-2.571378798158274e-07+1.000000071961468im,-2.676054057433227e-08-1.000000009178736im,-2.676054057433227e-08+1.000000009178736im,-2.500451772444974e-09-1.00000000270781im,-2.500451772444974e-09+1.00000000270781im,-1.309071549907812+0im] matlab_k = 0.9266824319626478 -matlab_f = ZPKFilter(matlab_z, matlab_p, matlab_k) +matlab_f = ZeroPoleGain(matlab_z, matlab_p, matlab_k) f = Elliptic(19, 0.1, 10) zpkfilter_eq(f, matlab_f) @@ -136,12 +136,12 @@ zpkfilter_accuracy(f, matlab_f, Elliptic(BigFloat, 19, 0.1, 10), eps=4e-9) # Output of [z, p, k] = buttap(20); [b, a] = zp2tf(z, p, k) m_a = [1,12.74549484318237,81.22381939879423,343.6513712403923,1081.352361133001,2687.409807920676,5468.931438945091,9326.061201886809,13528.36656744904,16852.27707949905,18122.54155403868,16852.27707949905,13528.36656744904,9326.061201886809,5468.931438945092,2687.409807920676,1081.352361133001,343.6513712403923,81.22381939879423,12.74549484318237,1] -f = convert(TFFilter, Butterworth(20)) +f = convert(PolynomialRatio, Butterworth(20)) @test_approx_eq coefb(f) [1] @test_approx_eq coefa(f) m_a # Test that our answers are more accurate than MATLAB's -accurate_a = coefa(convert(TFFilter, Butterworth(BigFloat, 20))) +accurate_a = coefa(convert(PolynomialRatio, Butterworth(BigFloat, 20))) @test_approx_eq coefa(f) float64(accurate_a) @test sum(abs(coefa(f) - accurate_a)) <= sum(abs(m_a - accurate_a)) @@ -149,7 +149,7 @@ accurate_a = coefa(convert(TFFilter, Butterworth(BigFloat, 20))) # Conversion between tf and zpk # -f = convert(ZPKFilter, convert(TFFilter, Butterworth(20))) +f = convert(ZeroPoleGain, convert(PolynomialRatio, Butterworth(20))) zpkfilter_eq(f, butter, 1e-6) # TODO: Make this more accurate! @@ -157,7 +157,7 @@ zpkfilter_eq(f, butter, 1e-6) # Output of [z, p, k] = buttap(20); [b, a] = zp2tf(z, p, k); tf2zpk(b, a) m_p = [-0.07845909573254482+0.9969173337335029im,-0.07845909573254482-0.9969173337335029im,-0.2334453637958131+0.9723699203918822im,-0.2334453637958131-0.9723699203918822im,-0.3826834327796701+0.9238795325396184im,-0.3826834327796701-0.9238795325396184im,-0.5224985628488221+0.8526401643454914im,-0.5224985628488221-0.8526401643454914im,-0.6494480541398985+0.7604059651905597im,-0.6494480541398985-0.7604059651905597im,-0.760405952587916+0.6494480502272874im,-0.760405952587916-0.6494480502272874im,-0.8526401859847815+0.5224985598169277im,-0.8526401859847815-0.5224985598169277im,-0.9238795057196649+0.3826834415328767im,-0.9238795057196649-0.3826834415328767im,-0.9969173244841298+0.07845911266921719im,-0.9969173244841298-0.07845911266921719im,-0.97236994351794+0.2334453500964366im,-0.97236994351794-0.2334453500964366im] # println(complex128([sort(f.p, lt=lt) - sort(Butterworth(BigFloat, 20).p, lt=lt) sort(m_p, lt=lt) - sort(Butterworth(BigFloat, 20).p, lt=lt)])) -zpkfilter_accuracy(f, ZPKFilter(Union()[], m_p, 1), Butterworth(BigFloat, 20); eps=1e-6, relerr=9) +zpkfilter_accuracy(f, ZeroPoleGain(Union()[], m_p, 1), Butterworth(BigFloat, 20); eps=1e-6, relerr=9) # # Frequency scaling @@ -173,7 +173,7 @@ zpkfilter_accuracy(f, ZPKFilter(Union()[], m_p, 1), Butterworth(BigFloat, 20); e m_z = Union()[] m_p = [-0.498458666866501+0.03922954786337574im,-0.498458666866501-0.03922954786337574im,-0.4861849601989526+0.1167226819283556im,-0.4861849601989526-0.1167226819283556im,-0.4619397662555457+0.191341716182291im,-0.4619397662555457-0.191341716182291im,-0.4263200821771486+0.2612492823580798im,-0.4263200821771486-0.2612492823580798im,-0.3802029827999479+0.3247240241651102im,-0.3802029827999479-0.3247240241651102im,-0.3247240241650893+0.3802029827999696im,-0.3247240241650893-0.3802029827999696im,-0.2612492823580033+0.4263200821770542im,-0.2612492823580033-0.4263200821770542im,-0.1913417161825348+0.461939766255657im,-0.1913417161825348-0.461939766255657im,-0.1167226819279489+0.486184960198832im,-0.1167226819279489-0.486184960198832im,-0.03922954786392431+0.4984586668665641im,-0.03922954786392431-0.4984586668665641im] m_k = 9.5367431640625e-07 -m_f = ZPKFilter(m_z, m_p, m_k) +m_f = ZeroPoleGain(m_z, m_p, m_k) f = analogfilter(Lowpass(0.5), Butterworth(20)) zpkfilter_eq(f, m_f) @@ -193,9 +193,9 @@ zpkfilter_accuracy(f, m_f, accurate_ft) m_z = [0+0.6269347368248613im,0-0.6269347368248613im,3.244237104018702e-18+0.3275342448365736im,3.244237104018702e-18-0.3275342448365736im,-6.938893903907228e-18+0.3032929712822612im,-6.938893903907228e-18-0.3032929712822612im,-1.387778780781446e-17+0.3004076906327037im,-1.387778780781446e-17-0.3004076906327037im,-4.163336342344337e-17+0.3000506878920809im,-4.163336342344337e-17-0.3000506878920809im,6.938893903907228e-18+0.3000063060899686im,6.938893903907228e-18-0.3000063060899686im,-6.938893903907228e-18+0.3000007854095975im,-6.938893903907228e-18-0.3000007854095975im,-1.387778780781446e-17+0.30000009864114im,-1.387778780781446e-17-0.30000009864114im,1.387778780781446e-17+0.3000000132267227im,1.387778780781446e-17-0.3000000132267227im,2.775557561562891e-17+0.3000000027630185im,2.775557561562891e-17-0.3000000027630185im] m_p = [-0.1398677695014979+0.188138982052175im,-0.1398677695014979-0.188138982052175im,-0.02345522399724158+0.2890911154818891im,-0.02345522399724158-0.2890911154818891im,-0.003009381182870904+0.2987256455960404im,-0.003009381182870904-0.2987256455960404im,-0.0003757590363774529+0.2998428279105927im,-0.0003757590363774529-0.2998428279105927im,-4.676623056761031e-05+0.299980469734862im,-4.676623056761031e-05-0.299980469734862im,-5.818096677288886e-06+0.2999975716762768im,-5.818096677288886e-06-0.2999975716762768im,-7.237817530730828e-07+0.2999996988517393im,-7.237817530730828e-07-0.2999996988517393im,-9.003660077222531e-08+0.2999999634684986im,-9.003660077222531e-08-0.2999999634684986im,-1.117941275663448e-08+0.2999999963792452im,-1.117941275663448e-08-0.2999999963792452im,-1.220070558471953e-09+0.300000000410979im,-1.220070558471953e-09-0.300000000410979im] m_k = 0.1000000000276181 -m_f = ZPKFilter(m_z, m_p, m_k) +m_f = ZeroPoleGain(m_z, m_p, m_k) -f = convert(ZPKFilter, analogfilter(Lowpass(0.3), Elliptic(20, 0.5, 20))) +f = convert(ZeroPoleGain, analogfilter(Lowpass(0.3), Elliptic(20, 0.5, 20))) zpkfilter_eq(f, m_f) # @@ -212,7 +212,7 @@ zpkfilter_eq(f, m_f) m_z = [0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im] m_p = [-0.4984586668666513+0.03922954786370267im,-0.4984586668666513-0.03922954786370267im,-0.4861849601986916+0.1167226819280185im,-0.4861849601986916-0.1167226819280185im,-0.4619397662557133+0.191341716182565im,-0.4619397662557133-0.191341716182565im,-0.4263200821770351+0.2612492823579622im,-0.4263200821770351-0.2612492823579622im,-0.3802029828000168+0.3247240241650909im,-0.3802029828000168-0.3247240241650909im,-0.3247240241650923+0.3802029828000145im,-0.3247240241650923-0.3802029828000145im,-0.03922954786392298+0.4984586668665641im,-0.03922954786392298-0.4984586668665641im,-0.2612492823579744+0.4263200821770468im,-0.2612492823579744-0.4263200821770468im,-0.1913417161825449+0.4619397662556436im,-0.1913417161825449-0.4619397662556436im,-0.1167226819279526+0.4861849601988384im,-0.1167226819279526-0.4861849601988384im] m_k = 1 -m_f = ZPKFilter(m_z, m_p, m_k) +m_f = ZeroPoleGain(m_z, m_p, m_k) f = analogfilter(Highpass(0.5), Butterworth(20)) zpkfilter_eq(f, m_f) @@ -232,9 +232,9 @@ zpkfilter_accuracy(f, m_f, accurate_ft) m_z = [4.289315073341702e-17+0.1914074830304432im,4.289315073341702e-17-0.1914074830304432im,-1.734723475976807e-17+0.3663739040779542im,-1.734723475976807e-17-0.3663739040779542im,-1.387778780781446e-17+0.3956570424057772im,-1.387778780781446e-17-0.3956570424057772im,-2.775557561562891e-17+0.3994571502056489im,-2.775557561562891e-17-0.3994571502056489im,2.775557561562891e-17+0.3999324275609072im,2.775557561562891e-17-0.3999324275609072im,8.673617379884035e-18+0.3999915920567793im,8.673617379884035e-18-0.3999915920567793im,4.163336342344337e-17+0.399998952789945im,4.163336342344337e-17-0.399998952789945im,1.387778780781446e-17+0.3999998684785239im,1.387778780781446e-17-0.3999998684785239im,-2.775557561562891e-17+0.3999999963159753im,-2.775557561562891e-17-0.3999999963159753im,6.938893903907228e-18+0.3999999823643708im,6.938893903907228e-18-0.3999999823643708im] m_p = [-0.3053922020601836+0.4107892635097733im,-0.3053922020601836-0.4107892635097733im,-0.03345814372376468+0.4123794380387859im,-0.03345814372376468-0.4123794380387859im,-0.004046405082073851+0.4016656239382425im,-0.004046405082073851-0.4016656239382425im,-0.0005015366410947575+0.4002090441157958im,-0.0005015366410947575-0.4002090441157958im,-6.236309209528557e-05+0.400026032326622im,-6.236309209528557e-05-0.400026032326622im,-7.757587819075262e-06+0.4000032376407234im,-7.757587819075262e-06-0.4000032376407234im,-9.650442748948551e-07+0.4000004015290894im,-9.650442748948551e-07-0.4000004015290894im,-1.200488304875513e-07+0.4000000487086385im,-1.200488304875513e-07-0.4000000487086385im,-1.490588337482723e-08+0.4000000048276729im,-1.490588337482723e-08-0.4000000048276729im,-1.626761100825824e-09+0.3999999994520274im,-1.626761100825824e-09-0.3999999994520274im] m_k = 0.9440608762859236 -m_f = ZPKFilter(m_z, m_p, m_k) +m_f = ZeroPoleGain(m_z, m_p, m_k) -f = convert(ZPKFilter, analogfilter(Highpass(0.4), Elliptic(20, 0.5, 20))) +f = convert(ZeroPoleGain, analogfilter(Highpass(0.4), Elliptic(20, 0.5, 20))) zpkfilter_eq(f, m_f) # @@ -251,7 +251,7 @@ zpkfilter_eq(f, m_f) m_z = [0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im,0+0im] m_p = [-0.05852661385905927+0.7442329445709392im,-0.05852661385905927-0.7442329445709392im,-0.1665549471789192+0.6992510095482473im,-0.1665549471789192-0.6992510095482473im,-0.2479888914449238+0.615606020752747im,-0.2479888914449238-0.615606020752747im,-0.2869902139927978+0.5070583156429217im,-0.2869902139927978-0.5070583156429217im,-0.2738314211701858+0.3979722116506606im,-0.2738314211701858-0.3979722116506606im,-0.2200127491273796+0.3197549791305416im,-0.2200127491273796-0.3197549791305416im,-0.1585130481013887+0.280063065773154im,-0.1585130481013887-0.280063065773154im,-0.1055644991483508+0.2620526301594698im,-0.1055644991483508-0.2620526301594698im,-0.06044030269085397+0.2537477474540631im,-0.06044030269085397-0.2537477474540631im,-0.01969061866105566+0.2503887742733703im,-0.01969061866105566-0.2503887742733703im] m_k = 0.0009765624999999997 -m_f = ZPKFilter(m_z, m_p, m_k) +m_f = ZeroPoleGain(m_z, m_p, m_k) f = analogfilter(Bandpass(0.25, 0.75), Butterworth(10)) zpkfilter_eq(f, m_f) @@ -271,9 +271,9 @@ zpkfilter_accuracy(f, m_f, accurate_ft) m_z = [1.387778780781446e-16+1.370743857088904im,1.387778780781446e-16-1.370743857088904im,-5.204170427930421e-18+0.1167249440313361im,-5.204170427930421e-18-0.1167249440313361im,0+0.8445880526167882im,0-0.8445880526167882im,-1.734723475976807e-18+0.8053338099984824im,-1.734723475976807e-18-0.8053338099984824im,-1.387778780781446e-17+0.1894414673571001im,-1.387778780781446e-17-0.1894414673571001im,0+0.1986753790956593im,0-0.1986753790956593im,5.551115123125783e-17+0.800148411646084im,5.551115123125783e-17-0.800148411646084im,1.108054620280186e-16+0.8007109707175198im,1.108054620280186e-16-0.8007109707175198im,8.673617379884035e-18+0.199822415142662im,8.673617379884035e-18-0.199822415142662im,4.85722573273506e-17+0.1999629039703328im,4.85722573273506e-17-0.1999629039703328im] m_p = [-0.2019763467382846+0.6120628823384283im,-0.2019763467382846-0.6120628823384283im,-0.03721004055421873+0.7823115667177283im,-0.03721004055421873-0.7823115667177283im,-0.004810677763557675+0.7980130970318471im,-0.004810677763557675-0.7980130970318471im,-0.0006000695021327641+0.7998051371015736im,-0.0006000695021327641-0.7998051371015736im,-6.552554548894252e-05+0.8000220660203423im,-6.552554548894252e-05-0.8000220660203423im,-0.07779252812598642+0.235740074311183im,-0.07779252812598642-0.235740074311183im,-0.009705975806501373+0.2040604370920958im,-0.009705975806501373-0.2040604370920958im,-0.001208621817121024+0.2004906765377495im,-0.001208621817121024-0.2004906765377495im,-0.0001500903998086778+0.2000486149853388im,-0.0001500903998086778-0.2000486149853388im,-1.638048261950673e-05+0.1999944823054316im,-1.638048261950673e-05-0.1999944823054316im] m_k = 0.1000000000000025 -m_f = ZPKFilter(m_z, m_p, m_k) +m_f = ZeroPoleGain(m_z, m_p, m_k) -f = convert(ZPKFilter, analogfilter(Bandpass(0.2, 0.8), Elliptic(10, 0.5, 20))) +f = convert(ZeroPoleGain, analogfilter(Bandpass(0.2, 0.8), Elliptic(10, 0.5, 20))) zpkfilter_eq(f, m_f) # @@ -290,7 +290,7 @@ zpkfilter_eq(f, m_f) m_z = [0+0.4330127018922193im,-0-0.4330127018922193im,0+0.4330127018922193im,-0-0.4330127018922193im,0+0.4330127018922193im,-0-0.4330127018922193im,0+0.4330127018922193im,-0-0.4330127018922193im,0+0.4330127018922193im,-0-0.4330127018922193im,0+0.4330127018922193im,-0-0.4330127018922193im,0+0.4330127018922193im,-0-0.4330127018922193im,0+0.4330127018922193im,-0-0.4330127018922193im,0+0.4330127018922193im,-0-0.4330127018922193im,0+0.4330127018922193im,-0-0.4330127018922193im] m_p = [-0.05852661385905998+0.7442329445709392im,-0.05852661385905998-0.7442329445709392im,-0.1665549471789191+0.6992510095482469im,-0.1665549471789191-0.6992510095482469im,-0.2479888914449218+0.6156060207527428im,-0.2479888914449218-0.6156060207527428im,-0.2869902139927988+0.5070583156429307im,-0.2869902139927988-0.5070583156429307im,-0.2738314211701937+0.3979722116506589im,-0.2738314211701937-0.3979722116506589im,-0.2200127491273721+0.3197549791305355im,-0.2200127491273721-0.3197549791305355im,-0.1585130481013898+0.2800630657731571im,-0.1585130481013898-0.2800630657731571im,-0.1055644991483515+0.2620526301594707im,-0.1055644991483515-0.2620526301594707im,-0.06044030269085383+0.2537477474540633im,-0.06044030269085383-0.2537477474540633im,-0.01969061866105538+0.2503887742733704im,-0.01969061866105538-0.2503887742733704im] m_k = 1 -m_f = ZPKFilter(m_z, m_p, m_k) +m_f = ZeroPoleGain(m_z, m_p, m_k) f = analogfilter(Bandstop(0.25, 0.75), Butterworth(10)) zpkfilter_eq(f, m_f) @@ -309,7 +309,7 @@ zpkfilter_accuracy(f, m_f, accurate_ft) m_z = [-1.402517154063671e-17+0.5685129776423937im,-1.402517154063671e-17-0.5685129776423937im,-6.156235460644255e-18+0.2814359676774932im,-6.156235460644255e-18-0.2814359676774932im,-2.775557561562891e-17+0.760016963542146im,-2.775557561562891e-17-0.760016963542146im,-8.326672684688674e-17+0.7947386855861924im,-8.326672684688674e-17-0.7947386855861924im,5.551115123125783e-17+0.799851645232653im,5.551115123125783e-17-0.799851645232653im,8.326672684688674e-17+0.7992903327101535im,8.326672684688674e-17-0.7992903327101535im,0+0.2105216168522108im,0-0.2105216168522108im,-4.423544863740858e-17+0.2013240363176547im,-4.423544863740858e-17-0.2013240363176547im,6.938893903907228e-18+0.200037095570968im,6.938893903907228e-18-0.200037095570968im,5.551115123125783e-17+0.2001775743458425im,5.551115123125783e-17-0.2001775743458425im] m_p = [-0.3778783653696471+0.7819846151027801im,-0.3778783653696471-0.7819846151027801im,-0.04044889726976308+0.8144610469677399im,-0.04044889726976308-0.8144610469677399im,-0.004859687206700769+0.8019364482578354im,-0.004859687206700769-0.8019364482578354im,-0.0006006726587018951+0.8001940294215477im,-0.0006006726587018951-0.8001940294215477im,-6.551807382872143e-05+0.799977924147539im,-6.551807382872143e-05-0.799977924147539im,-0.08015534922525629+0.1658741427311564im,-0.08015534922525629-0.1658741427311564im,-0.009732315617052817+0.1959655887284332im,-0.009732315617052817-0.1959655887284332im,-0.00120901710644529+0.1995097303565812im,-0.00120901710644529-0.1995097303565812im,-0.0001500952639848091+0.1999513917362522im,-0.0001500952639848091-0.1999513917362522im,-1.638042236460496e-05+0.2000055177738602im,-1.638042236460496e-05-0.2000055177738602im] m_k = 0.9440608762859234 -m_f = ZPKFilter(m_z, m_p, m_k) +m_f = ZeroPoleGain(m_z, m_p, m_k) f = analogfilter(Bandstop(0.2, 0.8), Elliptic(10, 0.5, 20)) zpkfilter_eq(f, m_f) @@ -321,65 +321,65 @@ zpkfilter_eq(f, m_f) # Output of [b, a] = butter(20, 0.5) m_b = [8.555155699386467e-06,0.0001711031139877293,0.001625479582883429,0.009752877497300572,0.04144972936352743,0.1326391339632878,0.3315978349082195,0.663195669816439,1.077692963451713,1.436923951268951,1.580616346395846,1.436923951268951,1.077692963451713,0.663195669816439,0.3315978349082195,0.1326391339632878,0.04144972936352743,0.009752877497300572,0.001625479582883429,0.0001711031139877293,8.555155699386467e-06] m_a = [1,-9.216626485446244e-15,2.719352210996272,-2.276898740746355e-14,2.954502383565172,-2.181204855972978e-14,1.663404391798304,-9.886771142150971e-15,0.5272563634534938,-1.578399203426284e-15,0.09588816575455775,3.201156931050434e-16,0.009788250615318749,1.651392612127069e-16,0.0005259945756568433,3.034673947897289e-17,1.306795536212839e-05,3.205637858266449e-18,1.137794123801438e-07,9.233765069631315e-20,1.463813780864114e-10] -m_f = TFFilter(m_b, m_a) +m_f = PolynomialRatio(m_b, m_a) -f = convert(TFFilter, digitalfilter(Lowpass(0.5), Butterworth(20))) +f = convert(PolynomialRatio, digitalfilter(Lowpass(0.5), Butterworth(20))) tffilter_eq(f, m_f) # Output of [b, a] = butter(20, 0.3, 'high') m_b = [0.001797932208654781,-0.03595864417309561,0.3416071196444083,-2.04964271786645,8.710981550932413,-27.87514096298372,69.6878524074593,-139.3757048149186,226.4855203242427,-301.980693765657,332.1787631422226,-301.980693765657,226.4855203242427,-139.3757048149186,69.6878524074593,-27.87514096298372,8.710981550932413,-2.04964271786645,0.3416071196444083,-0.03595864417309561,0.001797932208654781] m_a = [1,-7.99378842342338,32.24776489137069,-86.15266953725099,169.613151737271,-260.1393113842562,321.1838937487486,-325.8437287835835,275.1584488419961,-194.8984651152305,116.2180984348268,-58.35420576527059,24.59604119108612,-8.645276014889031,2.506713994242244,-0.5898102957633149,0.1098868139124379,-0.01561185396257133,0.001590100744530764,-0.0001034620065564712,3.232560226924501e-06] -m_f = TFFilter(m_b, m_a) +m_f = PolynomialRatio(m_b, m_a) -f = convert(TFFilter, digitalfilter(Highpass(0.3), Butterworth(20))) +f = convert(PolynomialRatio, digitalfilter(Highpass(0.3), Butterworth(20))) tffilter_eq(f, m_f) # Output of [b, a] = butter(7, [0.1 0.4]) m_b = [0.0009628940476886417,0,-0.006740258333820491,0,0.02022077500146148,0,-0.03370129166910246,0,0.03370129166910246,0,-0.02022077500146148,0,0.006740258333820491,0,-0.0009628940476886417] m_a = [1,-7.763446908073567,29.02150968091795,-69.51575164764138,119.5092528789707,-156.1341322158939,159.8101214681526,-130.0847734566226,84.56503905088692,-43.67462798637182,17.64013826588496,-5.405682857208016,1.18954580728982,-0.1686342472129378,0.01166272804918956] -m_f = TFFilter(m_b, m_a) +m_f = PolynomialRatio(m_b, m_a) -f = convert(TFFilter, digitalfilter(Bandpass(0.1, 0.4), Butterworth(7))) +f = convert(PolynomialRatio, digitalfilter(Bandpass(0.1, 0.4), Butterworth(7))) tffilter_eq(f, m_f) # Output of [b, a] = butter(4, [0.2 0.25], 'stop') m_b = [0.8142545568862771,-4.968628804996451,14.62659178092118,-26.46885325790832,32.03454308505385,-26.46885325790833,14.62659178092118,-4.968628804996451,0.8142545568862771] m_a = [1,-5.789124865012897,16.16849931613174,-27.77244867328942,31.92014561624699,-25.06018377653858,13.16458034390183,-4.253206810966346,0.6630104843858931] -m_f = TFFilter(m_b, m_a) +m_f = PolynomialRatio(m_b, m_a) -f = convert(TFFilter, digitalfilter(Bandstop(0.2, 0.25), Butterworth(4))) +f = convert(PolynomialRatio, digitalfilter(Bandstop(0.2, 0.25), Butterworth(4))) tffilter_eq(f, m_f) # Output of [b, a] = ellip(10, 0.7, 13, 0.4) m_b = [0.2797942479261318,-0.546743606764335,1.704005589668604,-2.159911306584612,3.642222926761125,-3.210370872716824,3.642222926761128,-2.159911306584614,1.704005589668607,-0.5467436067643362,0.2797942479261327] m_a = [1,-3.029857317356546,7.982710263075236,-12.64912738840943,17.41532979440429,-17.06917827530357,14.5191214973975,-8.798609366466101,4.541539167299845,-1.419553904214128,0.3565809079146795] -m_f = TFFilter(m_b, m_a) +m_f = PolynomialRatio(m_b, m_a) -f = convert(TFFilter, digitalfilter(Lowpass(0.4), Elliptic(10, 0.7, 13))) +f = convert(PolynomialRatio, digitalfilter(Lowpass(0.4), Elliptic(10, 0.7, 13))) tffilter_eq(f, m_f) # Output of [b, a] = ellip(11, 0.7, 17, 0.2, 'high') m_b = [0.5737867105773529,-5.288884465999311,23.07976318423696,-62.6831981311594,117.4527496444787,-159.209133733912,159.2091337339121,-117.4527496444788,62.68319813115945,-23.079763184237,5.288884465999319,-0.5737867105773541] m_a = [1,-8.215565996888206,32.26875224082856,-79.26375768096621,134.6328215735552,-165.4634116073934,149.7532535390064,-99.57881504158784,47.56023313164873,-15.48547977535943,3.075141867250689,-0.2777992862430019] -m_f = TFFilter(m_b, m_a) +m_f = PolynomialRatio(m_b, m_a) -f = convert(TFFilter, digitalfilter(Highpass(0.2), Elliptic(11, 0.7, 17))) +f = convert(PolynomialRatio, digitalfilter(Highpass(0.2), Elliptic(11, 0.7, 17))) tffilter_eq(f, m_f) # Output of [b, a] = ellip(10, 0.5, 2, [0.2 0.3]) m_b = [0.7571867287399742,-10.55194327196835,73.54073467886568,-338.6101060102045,1150.502868412841,-3057.625219554799,6581.673203566225,-11732.90330745444,17574.06211811366,-22320.04109078996,24158.39342879073,-22320.04109078995,17574.06211811365,-11732.90330745443,6581.673203566216,-3057.625219554793,1150.502868412839,-338.6101060102037,73.54073467886548,-10.55194327196831,0.7571867287399715] m_a = [1,-13.88122062422027,96.34606972585827,-441.7050045576331,1494.048255114342,-3952.085137071483,8465.769048060451,-15015.81246941687,22374.64201809294,-28265.00095948501,30424.52053126076,-27950.27646663918,21879.36223420588,-14520.36940748522,8095.785094725445,-3737.670491911818,1397.479471832041,-408.6480215434079,88.17084042962101,-12.56723162073412,0.8957646298422474] -m_f = TFFilter(m_b, m_a) +m_f = PolynomialRatio(m_b, m_a) -f = convert(TFFilter, digitalfilter(Bandpass(0.2, 0.3), Elliptic(10, 0.5, 2))) +f = convert(PolynomialRatio, digitalfilter(Bandpass(0.2, 0.3), Elliptic(10, 0.5, 2))) tffilter_eq(f, m_f) # Output of [b, a] = ellip(15, 1.8, 52, [0.6 0.7], 'stop') m_b = [0.4754470525338341,6.428928219976483,47.47972043083799,245.8985324356427,989.107195159456,3259.995646867947,9099.649115772192,21987.91200123768,46709.48715187636,88217.96445932264,149368.0297431405,228141.9056208539,315792.8309895032,397458.2884412499,455878.980369108,477133.9777299722,455878.9803691082,397458.2884412502,315792.8309895035,228141.9056208542,149368.0297431408,88217.96445932281,46709.48715187647,21987.91200123774,9099.649115772219,3259.995646867959,989.1071951594597,245.8985324356436,47.4797204308382,6.428928219976513,0.475447052533836] m_a = [1,12.89634891736776,90.77856214451822,447.9765044361528,1716.574771803699,5388.380608104304,14321.19101752449,32940.21064000877,66586.59389679749,119619.3933180238,192555.4138276511,279453.5193544072,367301.6888247615,438620.3975638363,476900.358709065,472649.3359368506,427104.9678341324,351676.250633706,263451.4609235193,179107.598840823,110104.024869051,60897.74794125407,30103.22741782092,13182.01328029648,5052.946545447418,1668.118080642225,463.5003850459777,104.731419523004,18.20949251383043,2.194519514615899,0.1423868039113367] -m_f = TFFilter(m_b, m_a) +m_f = PolynomialRatio(m_b, m_a) -f = convert(TFFilter, digitalfilter(Bandstop(0.6, 0.7), Elliptic(15, 1.8, 52))) +f = convert(PolynomialRatio, digitalfilter(Bandstop(0.6, 0.7), Elliptic(15, 1.8, 52))) tffilter_eq(f, m_f) # diff --git a/test/filter_response.jl b/test/filter_response.jl index 397e15edb..9c42e3bbc 100644 --- a/test/filter_response.jl +++ b/test/filter_response.jl @@ -25,7 +25,7 @@ b = b0*conv(b1, b2) a = conv(a1, a2) #=w = linspace(0, 2*pi, 200)=# # Does not produce same values as matlab -h = freqz(TFFilter(b, a), matlab_w) # So use frequencies from matlab +h = freqz(PolynomialRatio(b, a), matlab_w) # So use frequencies from matlab h_abs = convert(Array{Float64}, abs(h)) # Test @@ -55,7 +55,7 @@ h_abs = convert(Array{Float64}, abs(h)) ####################################### matlab_resp = readdlm(joinpath(dirname(@__FILE__), "data", "responses-eg1.txt"),'\t') -df = TFFilter(b, a) +df = PolynomialRatio(b, a) w = matlab_resp[:,1] #Impulse response @@ -98,7 +98,7 @@ a = conv(a1, a2) fs = 8192 hz = linspace(0, fs, 200) -h = freqz(TFFilter(b, a), hz, fs) +h = freqz(PolynomialRatio(b, a), hz, fs) h_abs = convert(Array{Float64}, abs(h)) #=using Winston=# @@ -123,7 +123,7 @@ a = [1.0, 0.4, 1.0] b = [0.2, 0.3, 1.0] w = logspace(-1, 1, 50) -h = freqs(TFFilter(b, a), w) +h = freqs(PolynomialRatio(b, a), w) mag = convert(Array{Float64}, abs(h)) phasedeg = (180/pi)*convert(Array{Float64}, angle(h)) @@ -170,7 +170,7 @@ b = [0.2, 0.3, 1.0] fs = 8192 hz = linspace(0, fs, 50) -h = freqs(TFFilter(b, a), hz, fs) +h = freqs(PolynomialRatio(b, a), hz, fs) mag = convert(Array{Float64}, abs(h)) phasedeg = (180/pi)*convert(Array{Float64}, angle(h)) From 6f5fcc853519a93811c946bd8749f5708dc5360d Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 6 Apr 2015 16:38:37 -0400 Subject: [PATCH 20/26] Fix deprecation warnings --- src/periodograms.jl | 6 +++--- src/windows.jl | 2 +- test/FilterTestHelpers.jl | 32 ++++++++++++++++---------------- test/filter_design.jl | 4 ++-- test/periodograms.jl | 8 ++++---- test/util.jl | 8 ++++---- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/periodograms.jl b/src/periodograms.jl index 5d0be9542..ca52d5b02 100644 --- a/src/periodograms.jl +++ b/src/periodograms.jl @@ -120,19 +120,19 @@ function fft2pow2radial!{T}(out::Array{T}, s_fft::Matrix{Complex{T}}, n1::Int, n kj2 = ifelse(j <= n2>>1 + 1, j-1, -n2+j-1) kj2 = (kj2*c2)^2 - wavenum = int(sqrt( (c1*(1-1))^2 + kj2 )) + 1 + wavenum = round(Int, sqrt( (c1*(1-1))^2 + kj2 )) + 1 if wavenum<=kmax out[wavenum] += abs2(s_fft[1,j])*m1 wc[wavenum] += 1 end for i = 2:n1max-1 - wavenum = int(sqrt( (c1*(i-1))^2 + kj2 )) + 1 + wavenum = round(Int, sqrt( (c1*(i-1))^2 + kj2 )) + 1 if wavenum<=kmax out[wavenum] += abs2(s_fft[i,j])*m2 wc[wavenum] += 2 end end - wavenum = int(sqrt( (c1*(n1max-1))^2 + kj2 )) + 1 + wavenum = round(Int, sqrt( (c1*(n1max-1))^2 + kj2 )) + 1 if wavenum<=kmax out[wavenum] += abs2(s_fft[n1max,j])*ifelse(iseven(n1), m1, m2) wc[wavenum] += ifelse(iseven(n1), 1, 2) diff --git a/src/windows.jl b/src/windows.jl index 05b9d0c6d..fac9bbef6 100644 --- a/src/windows.jl +++ b/src/windows.jl @@ -115,7 +115,7 @@ function dpss(n::Int, nw::Real, ntapers::Int=ceil(Int, 2*nw)-1) [0.5.*(i*n - abs2(i)) for i=1:(n-1)]) # Get tapers - v = fliplr(eigfact!(mat, n-ntapers+1:n)[:vectors]::Matrix{Float64}) + v = flipdim(eigfact!(mat, n-ntapers+1:n)[:vectors]::Matrix{Float64}, 2) # Slepian's convention; taper starts with a positive element sgn = ones(size(v, 2)) diff --git a/test/FilterTestHelpers.jl b/test/FilterTestHelpers.jl index edea3e415..821dc1815 100644 --- a/test/FilterTestHelpers.jl +++ b/test/FilterTestHelpers.jl @@ -1,5 +1,5 @@ module FilterTestHelpers -using DSP, Base.Test +using DSP, Base.Test, Compat export tffilter_eq, zpkfilter_eq, tffilter_accuracy, zpkfilter_accuracy, matrix_to_sosfilter, sosfilter_to_matrix @@ -12,40 +12,40 @@ function lt(a, b) end end -function tffilter_eq(f1, f2) +@compat function tffilter_eq(f1, f2) b1, a1 = (coefb(f1), coefa(f1)) b2, a2 = (coefb(f2), coefa(f2)) - @test_approx_eq float64(b1) float64(b2) - @test_approx_eq float64(a1) float64(a2) + @test_approx_eq map(Float64, b1) map(Float64, b2) + @test_approx_eq map(Float64, a1) map(Float64, a2) end -function zpkfilter_eq(f1, f2) +@compat function zpkfilter_eq(f1, f2) if !isempty(f1.z) || !isempty(f2.z) - @test_approx_eq complex128(sort(f1.z, lt=lt)) complex128(sort(f2.z, lt=lt)) + @test_approx_eq map(Complex128, sort(f1.z, lt=lt)) map(Complex128, sort(f2.z, lt=lt)) end - @test_approx_eq complex128(sort(f1.p, lt=lt)) complex128(sort(f2.p, lt=lt)) - @test_approx_eq float64(f1.k) float64(f2.k) + @test_approx_eq map(Complex128, sort(f1.p, lt=lt)) map(Complex128, sort(f2.p, lt=lt)) + @test_approx_eq map(Float64, f1.k) map(Float64, f2.k) end -function zpkfilter_eq(f1, f2, eps) +@compat function zpkfilter_eq(f1, f2, eps) if !isempty(f1.z) || !isempty(f2.z) - @test_approx_eq_eps complex128(sort(f1.z, lt=lt)) complex128(sort(f2.z, lt=lt)) eps + @test_approx_eq_eps map(Complex128, sort(f1.z, lt=lt)) map(Complex128, sort(f2.z, lt=lt)) eps end - @test_approx_eq_eps complex128(sort(f1.p, lt=lt)) complex128(sort(f2.p, lt=lt)) eps - @test_approx_eq_eps float64(f1.k) float64(f2.k) eps + @test_approx_eq_eps map(Complex128, sort(f1.p, lt=lt)) map(Complex128, sort(f2.p, lt=lt)) eps + @test_approx_eq_eps map(Float64, f1.k) map(Float64, f2.k) eps end loss(x::Real, y::Real) = abs(float(x) - float(y))/eps(float(x)) loss(x::Union(Real,Complex), y::Union(Real,Complex)) = loss(real(x), real(y)) + loss(imag(x), imag(y)) loss(x::AbstractVector, y::AbstractVector) = sum(map(loss, x, y)) -function accuracy_check(err1, err2, part, relerr=1) +@compat function accuracy_check(err1, err2, part, relerr=1) try @test err1 <= relerr*err2 catch e - println("Filter 1 $part error (ULP): ", float64(err1)) - println("Filter 2 $part error (ULP): ", float64(err2)) - println("Ratio: ", float64(err1/err2)) + println("Filter 1 $part error (ULP): ", map(Float64, err1)) + println("Filter 2 $part error (ULP): ", map(Float64, err2)) + println("Ratio: ", map(Float64, err1/err2)) rethrow(e) end end diff --git a/test/filter_design.jl b/test/filter_design.jl index 265d31978..9c56d91c0 100644 --- a/test/filter_design.jl +++ b/test/filter_design.jl @@ -1,5 +1,5 @@ require(joinpath(dirname(@__FILE__), "FilterTestHelpers.jl")) -using DSP, Base.Test, FilterTestHelpers +using DSP, Base.Test, FilterTestHelpers, Compat # # Butterworth filter prototype @@ -142,7 +142,7 @@ f = convert(PolynomialRatio, Butterworth(20)) # Test that our answers are more accurate than MATLAB's accurate_a = coefa(convert(PolynomialRatio, Butterworth(BigFloat, 20))) -@test_approx_eq coefa(f) float64(accurate_a) +@compat @test_approx_eq coefa(f) map(Float64, accurate_a) @test sum(abs(coefa(f) - accurate_a)) <= sum(abs(m_a - accurate_a)) # diff --git a/test/periodograms.jl b/test/periodograms.jl index d0fa54b62..16270e065 100644 --- a/test/periodograms.jl +++ b/test/periodograms.jl @@ -14,7 +14,7 @@ # close(fid) #end -using DSP, Base.Test +using DSP, Base.Test, Compat x0 = vec(readdlm(joinpath(dirname(@__FILE__), "data", "spectrogram_x.txt"),'\t')) f0 = vec(readdlm(joinpath(dirname(@__FILE__), "data", "spectrogram_f.txt"),'\t')) @@ -226,7 +226,7 @@ x = zeros(n1,n2)*0im; x[ind] = [1+2im,1-2im] y = real(ifft(x)) -fwn = int(sqrt((a[1])^2+(a[2])^2)*n2) +fwn = round(Int, sqrt((a[1])^2+(a[2])^2)*n2) pe = zeros(n2>>1 + 1) pe[fwn+1] = 2*abs2(x[nf...])/n1/n2 P = periodogram(y,nfft=(n1,n2),radialsum=true) @@ -237,8 +237,8 @@ P = periodogram(y,nfft=(n1,n2),radialsum=true) fs = 16000 nfft = 512 -nwin = int(0.025*fs) -nhop = int(0.010*fs) +nwin = 400 +nhop = 160 s = vec(readdlm(joinpath(dirname(@__FILE__), "data", "stft_x.txt"),'\t')) Sjl = stft(s, nwin, nwin-nhop; nfft=nfft, fs=fs, window=hanning) diff --git a/test/util.jl b/test/util.jl index c07083567..1a404de1c 100644 --- a/test/util.jl +++ b/test/util.jl @@ -1,4 +1,4 @@ -using DSP, Base.Test +using DSP, Base.Test, Compat @test_approx_eq(unwrap([0.1, 0.2, 0.3, 0.4]), [0.1, 0.2, 0.3, 0.4]) @test_approx_eq(unwrap([0.1, 0.2 + 2pi, 0.3, 0.4]), [0.1, 0.2, 0.3, 0.4]) @@ -68,8 +68,8 @@ h2 = hilbert([ones(10); zeros(9)]) @test_approx_eq real(h2) [ones(10); zeros(9)] #Sanity check with integer arguments -r = int(rand(128)*20) -@test hilbert(r) == hilbert(float64(r)) +r = round(Int, rand(128)*20) +@compat @test hilbert(r) == hilbert(map(Float64, r)) # Test hilbert with 2D input @test_approx_eq h hilbert(a) @@ -113,7 +113,7 @@ end @test_approx_eq -3dBa db2amp(-3) @test isa(3e0dB, Float64) @test isa(3f0dB, Float32) -num = float64(pi) +num = convert(Float64, pi) @test_approx_eq pow2db(num) 10*log10(num) @test_approx_eq amp2db(num) 20*log10(num) @test_approx_eq num*dB db2pow(num) From 5187861310c7d995ce2eb272893218cd5c45918d Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 6 Apr 2015 16:48:06 -0400 Subject: [PATCH 21/26] Rename Filter -> FilterCoefficients --- src/Filters/design.jl | 8 ++++---- src/Filters/filt.jl | 6 +++--- src/Filters/response.jl | 18 +++++++++--------- src/Filters/types.jl | 12 ++++++------ 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Filters/design.jl b/src/Filters/design.jl index e13607ec3..345a7f3fd 100644 --- a/src/Filters/design.jl +++ b/src/Filters/design.jl @@ -347,14 +347,14 @@ function transform_prototype(ftype::Bandstop, proto::ZeroPoleGain) ZeroPoleGain(newz, newp, proto.k * real(num)/real(den)) end -transform_prototype(ftype, proto::Filter) = +transform_prototype(ftype, proto::FilterCoefficients) = transform_prototype(ftype, convert(ZeroPoleGain, proto)) -analogfilter(ftype::FilterType, proto::Filter) = +analogfilter(ftype::FilterType, proto::FilterCoefficients) = transform_prototype(ftype, proto) # Bilinear transform -bilinear(f::Filter, fs::Real) = bilinear(convert(ZeroPoleGain, f), fs) +bilinear(f::FilterCoefficients, fs::Real) = bilinear(convert(ZeroPoleGain, f), fs) function bilinear{Z,P,K}(f::ZeroPoleGain{Z,P,K}, fs::Real) ztype = typeof(0 + zero(Z)/fs) z = fill(convert(ztype, -1), max(length(f.p), length(f.z))) @@ -382,5 +382,5 @@ prewarp(ftype::Union(Lowpass, Highpass)) = (typeof(ftype))(4*tan(pi*ftype.w/2)) prewarp(ftype::Union(Bandpass, Bandstop)) = (typeof(ftype))(4*tan(pi*ftype.w1/2), 4*tan(pi*ftype.w2/2)) # Digital filter design -digitalfilter(ftype::FilterType, proto::Filter) = +digitalfilter(ftype::FilterType, proto::FilterCoefficients) = bilinear(transform_prototype(prewarp(ftype), proto), 2) diff --git a/src/Filters/filt.jl b/src/Filters/filt.jl index 9362cd5c1..ecbd3bef9 100644 --- a/src/Filters/filt.jl +++ b/src/Filters/filt.jl @@ -77,8 +77,8 @@ Base.filt{T,S<:Number}(f::Biquad{T}, x::AbstractArray{S}, si=_zerosi(f, x)) = filt!(Array(promote_type(T, S), size(x)), f, x, si) ## For arbitrary filters, convert to SecondOrderSections -Base.filt(f::Filter, x) = filt(convert(SecondOrderSections, f), x) -Base.filt!(out, f::Filter, x) = filt!(out, convert(SecondOrderSections, f), x) +Base.filt(f::FilterCoefficients, x) = filt(convert(SecondOrderSections, f), x) +Base.filt!(out, f::FilterCoefficients, x) = filt!(out, convert(SecondOrderSections, f), x) # # filtfilt @@ -211,7 +211,7 @@ function filtfilt{T,G,S}(f::SecondOrderSections{T,G}, x::AbstractArray{S}) end # Support for other filter types -filtfilt(f::Filter, x) = filtfilt(convert(SecondOrderSections, f), x) +filtfilt(f::FilterCoefficients, x) = filtfilt(convert(SecondOrderSections, f), x) filtfilt(f::PolynomialRatio, x) = filtfilt(coefb(f), coefa(f), x) ## Initial filter state diff --git a/src/Filters/response.jl b/src/Filters/response.jl index 231774199..016d81322 100644 --- a/src/Filters/response.jl +++ b/src/Filters/response.jl @@ -4,18 +4,18 @@ # Frequency response of a digital filter # -function freqz(filter::Filter, w::Number) +function freqz(filter::FilterCoefficients, w::Number) filter = convert(PolynomialRatio, filter) ejw = exp(-im * w) polyval(filter.b, ejw) ./ polyval(filter.a, ejw) end -function freqz(filter::Filter, w = linspace(0, π, 250)) +function freqz(filter::FilterCoefficients, w = linspace(0, π, 250)) filter = convert(PolynomialRatio, filter) [freqz(filter, i) for i = w] end -function freqz(filter::Filter, hz::Union(Number, AbstractVector), fs::Number) +function freqz(filter::FilterCoefficients, hz::Union(Number, AbstractVector), fs::Number) filter = convert(PolynomialRatio, filter) freqz(filter, hz_to_radians_per_second(hz, fs)) end @@ -25,7 +25,7 @@ end # Phase response of a digital filter # -function phasez(filter::Filter, w = linspace(0, π, 250)) +function phasez(filter::FilterCoefficients, w = linspace(0, π, 250)) h = freqz(filter, w) unwrap(-atan2(imag(h), real(h))) end @@ -35,7 +35,7 @@ end # Impulse response of a digital filter # -function impz(filter::Filter, n=100) +function impz(filter::FilterCoefficients, n=100) i = [1; zeros(n-1)] filt(filter, i) end @@ -44,7 +44,7 @@ end # Step response of a digital filter # -function stepz(filter::Filter, n=100) +function stepz(filter::FilterCoefficients, n=100) i = ones(n) filt(filter, i) end @@ -54,18 +54,18 @@ end # Frequency response of an analog filter # -function freqs(filter::Filter, w::Number) +function freqs(filter::FilterCoefficients, w::Number) filter = convert(PolynomialRatio, filter) s = im * w polyval(filter.b, s) ./ polyval(filter.a, s) end -function freqs(filter::Filter, w::AbstractVector) +function freqs(filter::FilterCoefficients, w::AbstractVector) filter = convert(PolynomialRatio, filter) [freqs(filter, i) for i = w] end -function freqs(filter::Filter, hz::Union(Number, AbstractVector), fs::Number) +function freqs(filter::FilterCoefficients, hz::Union(Number, AbstractVector), fs::Number) filter = convert(PolynomialRatio, filter) freqs(filter, hz_to_radians_per_second(hz, fs)) end diff --git a/src/Filters/types.jl b/src/Filters/types.jl index cfe35a8c5..7963090cc 100644 --- a/src/Filters/types.jl +++ b/src/Filters/types.jl @@ -1,12 +1,12 @@ # Filter types and conversions -abstract Filter +abstract FilterCoefficients # # Zero-pole gain form # -immutable ZeroPoleGain{Z<:Number,P<:Number,K<:Number} <: Filter +immutable ZeroPoleGain{Z<:Number,P<:Number,K<:Number} <: FilterCoefficients z::Vector{Z} p::Vector{P} k::K @@ -16,7 +16,7 @@ end # Transfer function form # -immutable PolynomialRatio{T<:Number} <: Filter +immutable PolynomialRatio{T<:Number} <: FilterCoefficients b::Poly{T} a::Poly{T} @@ -56,7 +56,7 @@ coefa(f::PolynomialRatio) = reverse(f.a.a) # A separate immutable to improve efficiency of filtering using SecondOrderSectionss # -immutable Biquad{T} <: Filter +immutable Biquad{T} <: FilterCoefficients b0::T b1::T b2::T @@ -110,7 +110,7 @@ end # Second-order sections (array of biquads) # -immutable SecondOrderSections{T,G} <: Filter +immutable SecondOrderSections{T,G} <: FilterCoefficients biquads::Vector{Biquad{T}} g::G end @@ -244,4 +244,4 @@ function Base.convert{Z,P}(::Type{SecondOrderSections}, f::ZeroPoleGain{Z,P}) SecondOrderSections(biquads, f.k) end -Base.convert(::Type{SecondOrderSections}, f::Filter) = convert(SecondOrderSections, convert(ZeroPoleGain, f)) +Base.convert(::Type{SecondOrderSections}, f::FilterCoefficients) = convert(SecondOrderSections, convert(ZeroPoleGain, f)) From 5c5ab91d00f9d11440b5fa583dc493c2a26b5f02 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 6 Apr 2015 16:50:12 -0400 Subject: [PATCH 22/26] Add NEWS.md and document filter name changes --- NEWS.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 NEWS.md diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 000000000..b3a8b5982 --- /dev/null +++ b/NEWS.md @@ -0,0 +1,8 @@ +# DSP v0.1.0 Release Notes + +- Filter coefficient types have been renamed to distinguish them from implementations (#96): + - The `Filter` abstract type is now `FilterCoefficients` + - `ZPKFilter` is now `ZeroPoleGain` + - `TFFilter` is now `PolynomialRatio` + - `BiquadFilter` is now `Biquad` + - `SOSFilter` is now `SecondOrderSections` From 5b2e06a49c9bf5f684566cbc02aa508fca6eb129 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 6 Apr 2015 16:50:57 -0400 Subject: [PATCH 23/26] Link PR in NEWS.md --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index b3a8b5982..7cadb2297 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ # DSP v0.1.0 Release Notes -- Filter coefficient types have been renamed to distinguish them from implementations (#96): +- Filter coefficient types have been renamed to distinguish them from implementations ([#96](https://github.com/JuliaDSP/DSP.jl/pull/96)): - The `Filter` abstract type is now `FilterCoefficients` - `ZPKFilter` is now `ZeroPoleGain` - `TFFilter` is now `PolynomialRatio` From a009d8c183af82ce2139196eee8e0067b3bb39df Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 6 Apr 2015 16:54:27 -0400 Subject: [PATCH 24/26] Fix version in NEWS.md --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 7cadb2297..9cac5adb9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# DSP v0.1.0 Release Notes +# DSP v0.0.7 Release Notes - Filter coefficient types have been renamed to distinguish them from implementations ([#96](https://github.com/JuliaDSP/DSP.jl/pull/96)): - The `Filter` abstract type is now `FilterCoefficients` From 73140cef460a3cf1263f56d71d00907f09720298 Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Mon, 6 Apr 2015 19:36:00 -0400 Subject: [PATCH 25/26] Add stateful filters `DF2TFilter(::FilterCoefficients)` constructs a stateful direct form II transposed filter. Calling `filt` or `filt!` on the resulting object filters the input data and preserves the state. --- src/Filters/Filters.jl | 6 +- src/Filters/{types.jl => coefficients.jl} | 0 src/Filters/filt.jl | 141 ++++++++++++++++++---- test/filt.jl | 16 ++- 4 files changed, 138 insertions(+), 25 deletions(-) rename src/Filters/{types.jl => coefficients.jl} (100%) diff --git a/src/Filters/Filters.jl b/src/Filters/Filters.jl index 5ee984a88..bf6e48b5f 100644 --- a/src/Filters/Filters.jl +++ b/src/Filters/Filters.jl @@ -1,11 +1,11 @@ module Filters using Polynomials, Compat, ..Util -include("types.jl") -export Filter, ZeroPoleGain, PolynomialRatio, Biquad, SecondOrderSections, coefa, coefb +include("coefficients.jl") +export FilterCoefficients, ZeroPoleGain, PolynomialRatio, Biquad, SecondOrderSections, coefa, coefb include("filt.jl") -export filtfilt, fftfilt, firfilt +export DF2TFilter, filtfilt, fftfilt, firfilt include("design.jl") export FilterType, Butterworth, Chebyshev1, Chebyshev2, Elliptic, diff --git a/src/Filters/types.jl b/src/Filters/coefficients.jl similarity index 100% rename from src/Filters/types.jl rename to src/Filters/coefficients.jl diff --git a/src/Filters/filt.jl b/src/Filters/filt.jl index ecbd3bef9..ce22f5180 100644 --- a/src/Filters/filt.jl +++ b/src/Filters/filt.jl @@ -16,6 +16,26 @@ Base.filt(f::PolynomialRatio, x, si=_zerosi(f, x)) = filt(coefb(f), coefa(f), x, _zerosi{T,G,S}(f::SecondOrderSections{T,G}, x::AbstractArray{S}) = zeros(promote_type(T, G, S), 2, length(f.biquads)) +# filt! algorithm (no checking, returns si) +function _filt!{S,N}(out::AbstractArray, si::AbstractArray{S,N}, f::SecondOrderSections, + x::AbstractArray, col::Int) + g = f.g + biquads = f.biquads + n = length(biquads) + @inbounds for i = 1:size(x, 1) + yi = x[i, col] + for fi = 1:n + biquad = biquads[fi] + xi = yi + yi = si[1, fi] + biquad.b0*xi + si[1, fi] = si[2, fi] + biquad.b1*xi - biquad.a1*yi + si[2, fi] = biquad.b2*xi - biquad.a2*yi + end + out[i, col] = yi*g + end + si +end + function Base.filt!{S,N}(out::AbstractArray, f::SecondOrderSections, x::AbstractArray, si::AbstractArray{S,N}=_zerosi(f, x)) biquads = f.biquads @@ -26,19 +46,10 @@ function Base.filt!{S,N}(out::AbstractArray, f::SecondOrderSections, x::Abstract error("si must be 2 x nbiquads or 2 x nbiquads x nsignals") initial_si = si + g = f.g + n = length(biquads) for col = 1:ncols - si = initial_si[:, :, N > 2 ? col : 1] - @inbounds for i = 1:size(x, 1) - yi = x[i, col] - for fi = 1:length(biquads) - biquad = biquads[fi] - xi = yi - yi = si[1, fi] + biquad.b0*xi - si[1, fi] = si[2, fi] + biquad.b1*xi - biquad.a1*yi - si[2, fi] = biquad.b2*xi - biquad.a2*yi - end - out[i, col] = yi*f.g - end + _filt!(out, initial_si[:, :, N > 2 ? col : 1], f, x, col) end out end @@ -50,6 +61,20 @@ Base.filt{T,G,S<:Number}(f::SecondOrderSections{T,G}, x::AbstractArray{S}, si=_z _zerosi{T,S}(f::Biquad{T}, x::AbstractArray{S}) = zeros(promote_type(T, S), 2) +# filt! algorithm (no checking, returns si) +function _filt!(out::AbstractArray, si1::Number, si2::Number, f::Biquad, + x::AbstractArray, col::Int) + @inbounds for i = 1:size(x, 1) + xi = x[i, col] + yi = si1 + f.b0*xi + si1 = si2 + f.b1*xi - f.a1*yi + si2 = f.b2*xi - f.a2*yi + out[i, col] = yi + end + (si1, si2) +end + +# filt! variant that preserves si function Base.filt!{S,N}(out::AbstractArray, f::Biquad, x::AbstractArray, si::AbstractArray{S,N}=_zerosi(f, x)) ncols = Base.trailingsize(x, 2) @@ -60,15 +85,7 @@ function Base.filt!{S,N}(out::AbstractArray, f::Biquad, x::AbstractArray, initial_si = si for col = 1:ncols - si1 = initial_si[1, N > 1 ? col : 1] - si2 = initial_si[2, N > 1 ? col : 1] - @inbounds for i = 1:size(x, 1) - xi = x[i, col] - yi = si1 + f.b0*xi - si1 = si2 + f.b1*xi - f.a1*yi - si2 = f.b2*xi - f.a2*yi - out[i, col] = yi - end + _filt!(out, initial_si[1, N > 1 ? col : 1], initial_si[2, N > 1 ? col : 1], f, x, col) end out end @@ -80,6 +97,88 @@ Base.filt{T,S<:Number}(f::Biquad{T}, x::AbstractArray{S}, si=_zerosi(f, x)) = Base.filt(f::FilterCoefficients, x) = filt(convert(SecondOrderSections, f), x) Base.filt!(out, f::FilterCoefficients, x) = filt!(out, convert(SecondOrderSections, f), x) +# +# Direct form II transposed filter with state +# + +immutable DF2TFilter{T<:FilterCoefficients,S<:Array} + coef::T + state::S + + function DF2TFilter(coef::PolynomialRatio, state::Vector) + length(state) == length(coef.a)-1 == length(coef.b)-1 || + throw(ArgumentError("length of state vector must match filter order")) + new(coef, state) + end + function DF2TFilter(coef::SecondOrderSections, state::Matrix) + (size(state, 1) == 2 && size(state, 2) == length(coef.biquads)) || + throw(ArgumentError("state must be 2 x nbiquads")) + new(coef, state) + end + function DF2TFilter(coef::Biquad, state::Vector) + length(state) == 2 || throw(ArgumentError("length of state must be 2")) + new(coef, state) + end +end + +## PolynomialRatio +DF2TFilter{T,S}(coef::PolynomialRatio{T}, + state::Vector{S}=zeros(T, max(length(coef.a), length(coef.b))-1)) = + DF2TFilter{PolynomialRatio{T}, Vector{S}}(coef, state) + +function Base.filt!{T,S}(out::AbstractVector, f::DF2TFilter{PolynomialRatio{T},Vector{S}}, x::AbstractVector) + length(x) != length(out) && throw(ArgumentError("out size must match x")) + + si = f.state + # Note: these are in the Polynomials.jl convention, which is + # reversed WRT the usual DSP convention + b = f.coef.b.a + a = f.coef.a.a + n = length(b) + if n == 1 + scale!(out, x, b[1]) + else + @inbounds for i=1:length(x) + xi = x[i] + val = si[1] + b[n]*xi + for j=1:n-2 + si[j] = si[j+1] + b[n-j]*xi - a[n-j]*val + end + si[n-1] = b[1]*xi - a[1]*val + out[i] = val + end + end + out +end + +## SecondOrderSections +DF2TFilter{T,G,S}(coef::SecondOrderSections{T,G}, + state::Matrix{S}=zeros(promote_type(T, G), 2, length(coef.biquads))) = + DF2TFilter{SecondOrderSections{T,G}, Matrix{S}}(coef, state) + +function Base.filt!{T,G,S}(out::AbstractVector, f::DF2TFilter{SecondOrderSections{T,G},Matrix{S}}, x::AbstractVector) + length(x) != length(out) && throw(ArgumentError("out size must match x")) + _filt!(out, f.state, f.coef, x, 1) + out +end + +## Biquad +DF2TFilter{T,S}(coef::Biquad{T}, state::Vector{S}=zeros(T, 2)) = + DF2TFilter{Biquad{T}, Vector{S}}(coef, state) +function Base.filt!{T,S}(out::AbstractVector, f::DF2TFilter{Biquad{T},Vector{S}}, x::AbstractVector) + length(x) != length(out) && throw(ArgumentError("out size must match x")) + si = f.state + (si[1], si[2]) =_filt!(out, si[1], si[2], f.coef, x, 1) + out +end + +# Variant that allocates the output +Base.filt{T,S<:Array}(f::DF2TFilter{T,S}, x::AbstractVector) = + filt!(Array(eltype(S), length(x)), f, x) + +# Fall back to SecondOrderSections +DF2TFilter(coef::FilterCoefficients) = DF2TFilter(convert(SecondOrderSections, coef)) + # # filtfilt # diff --git a/test/filt.jl b/test/filt.jl index e19ddd361..793fb7199 100644 --- a/test/filt.jl +++ b/test/filt.jl @@ -21,7 +21,8 @@ for n = 1:6 res = filt(sos, x) # Test with filt with tf/sos - @test_approx_eq res filt(tf, x) + tfres = filt(tf, x) + @test_approx_eq res tfres @test_approx_eq res filt!(similar(x), sos, x) @test_approx_eq res filt!(similar(x), tf, x) @@ -29,14 +30,27 @@ for n = 1:6 if n <= 2 @test_approx_eq res filt(bq, x) @test_approx_eq res filt!(similar(x), bq, x) + f = DF2TFilter(bq) + @test tfres == [filt(f, x[1:50]); filt(f, x[51:end])] end # Test that filt with zpk converts @test res == filt(zpk, x) @test res == filt!(similar(x), zpk, x) + + # Test with DF2TFilter + f = DF2TFilter(sos) + @test res == [filt(f, x[1:50]); filt(f, x[51:end])] + f = DF2TFilter(tf) + @test tfres == [filt(f, x[1:50]); filt(f, x[51:end])] + f = DF2TFilter(zpk) + @test res == [filt(f, x[1:50]); filt(f, x[51:end])] end end +# Test simple scaling with DF2TFilter +@test filt(DF2TFilter(PolynomialRatio([3.7], [4.2])), x) == scale(x, 3.7/4.2) + # # filtfilt # From 8ddce88e9bffe3635fdc9357e80f7d88590190af Mon Sep 17 00:00:00 2001 From: Simon Kornblith Date: Tue, 7 Apr 2015 11:38:41 -0400 Subject: [PATCH 26/26] Document stateful filter --- NEWS.md | 5 +++++ doc/filters.rst | 55 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/NEWS.md b/NEWS.md index 9cac5adb9..c2d8b71cc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,8 @@ +# DSP v0.0.8 Release Notes + +- The `DF2TFilter` object provides a filter that preserves state + between invocations ([#100](https://github.com/JuliaDSP/DSP.jl/pull/100)). + # DSP v0.0.7 Release Notes - Filter coefficient types have been renamed to distinguish them from implementations ([#96](https://github.com/JuliaDSP/DSP.jl/pull/96)): diff --git a/doc/filters.rst b/doc/filters.rst index 9a45ea390..67b831b06 100644 --- a/doc/filters.rst +++ b/doc/filters.rst @@ -1,11 +1,19 @@ :mod:`Filters` - filter design and filtering ============================================ -Linear time-invariant filter representations --------------------------------------------- +DSP.jl differentiates between filter coefficients and filters. Filter +coefficient objects specify the response of the filter in one of +several standard forms. Filter objects carry the state of the filter +together with filter coefficients in an implementable form +(``PolynomialRatio``, ``Biquad``, or ``SecondOrderSections``). +When invoked on a filter coefficient object, ``filt`` preserves state +between invocations. -DSP.jl supports common filter representations. Filters can be converted -from one type to another using ``convert``. +Linear time-invariant filter coefficient objects +------------------------------------------------ + +DSP.jl supports common filter representations. Filter coefficients can +be converted from one type to another using ``convert``. .. function:: ZeroPoleGain(z, p, k) @@ -45,28 +53,45 @@ from one type to another using ``convert``. sections and gain. ``biquads`` must be specified as a vector of ``Biquads``. + +Filter objects +---------------------------------- + +.. function:: DF2TFilter(coef[, si]) + + Construct a stateful direct form II transposed filter with + coefficients ``coef``. ``si`` is an optional array representing the + initial filter state (defaults to zeros). If ``f`` is a + ``PolynomialRatio``, ``Biquad``, or ``SecondOrderSections``, + filtering is implemented directly. If ``f`` is a ``ZeroPoleGain`` + object, it is first converted to a ``SecondOrderSections`` object. + + Filter application ------------------ .. function:: filt(f, x[, si]) - Apply filter ``f`` along the first dimension of array ``x``. ``si`` - is an optional array representing the initial filter state - (defaults to zeros). If ``f`` is a ``PolynomialRatio``, ``Biquad``, - or ``SecondOrderSections``, filtering is implemented directly. If ``f`` is a - ``ZeroPoleGain``, it is first converted to an ``SecondOrderSections``. + Apply filter or filter coefficients ``f`` along the first dimension + of array ``x``. If ``f`` is a filter coefficient object, ``si`` + is an optional array representing the initial filter state (defaults + to zeros). If ``f`` is a ``PolynomialRatio``, ``Biquad``, or + ``SecondOrderSections``, filtering is implemented directly. If + ``f`` is a ``ZeroPoleGain`` object, it is first converted to a + ``SecondOrderSections`` object. .. function:: filt!(out, f, x[, si]) Same as :func:`filt()` but writes the result into the ``out`` argument, which may alias the input ``x`` to modify it in-place. -.. function:: filtfilt(f, x) +.. function:: filtfilt(coef, x) - Filter ``x`` in the forward and reverse directions. The initial - state of the filter is computed so that its response to a step - function is steady state. Before filtering, the data is - extrapolated at both ends with an odd-symmetric extension of length + Filter ``x`` in the forward and reverse directions using filter + coefficients ``f``. The initial state of the filter is computed so + that its response to a step function is steady state. Before + filtering, the data is extrapolated at both ends with an + odd-symmetric extension of length ``3*(max(length(b), length(a))-1)``. Because ``filtfilt`` applies the given filter twice, the effective @@ -84,6 +109,7 @@ Filter application choosing the optimal algorithm based on the lengths of ``b`` and ``x``. + Filter design ------------- @@ -95,6 +121,7 @@ Filter design Construct a digital filter. + Filter response types ---------------------