-
-
Save merl-dev/bea25beffa0413fcdbc9913af4becefb to your computer and use it in GitHub Desktop.
An implementation of the Savitzky-Golay filter using generated functions. Accompanies https://medium.com/@acidflask/smoothing-data-with-julia-s-generated-functions-c80e240e05f3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Savitzky-Golay filter of window half-width M and degree N | |
M is the number of points before and after to interpolate, i.e. the full width | |
of the window is 2M+1 | |
""" | |
immutable SavitzkyGolayFilter{M,N} end | |
@generated function Base.call{M,N,T}(::Type{SavitzkyGolayFilter{M,N}}, | |
data::AbstractVector{T}) | |
#Create Jacobian matrix | |
J = zeros(2M+1, N+1) | |
for i=1:2M+1, j=1:N+1 | |
J[i, j] = (i-M-1)^(j-1) | |
end | |
e₁ = zeros(N+1) | |
e₁[1] = 1.0 | |
#Compute filter coefficients | |
C = J' \ e₁ | |
#Evaluate filter on data matrix | |
To = typeof(C[1] * one(T)) #Calculate type of output | |
expr = quote | |
n = size(data, 1) | |
smoothed = zeros($To, n) | |
@inbounds for i in eachindex(smoothed) | |
smoothed[i] += $(C[M+1])*data[i] | |
end | |
smoothed | |
end | |
for j=1:M | |
insert!(expr.args[6].args[2].args[2].args, 1, | |
:(if i - $j ≥ 1 | |
smoothed[i] += $(C[M+1-j])*data[i-$j] | |
end) | |
) | |
push!(expr.args[6].args[2].args[2].args, | |
:(if i + $j ≤ n | |
smoothed[i] += $(C[M+1+j])*data[i+$j] | |
end) | |
) | |
end | |
return expr | |
end | |
#Two sample invocations | |
@show SavitzkyGolayFilter{2,3}([1:11;]) | |
@show SavitzkyGolayFilter{1,1}([1:11;]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment