From cbb84401a42f85aa091110af50ec451f1313bb21 Mon Sep 17 00:00:00 2001 From: Fredrik Bagge Carlsson <cont-frb@ulund.org> Date: Sat, 19 Sep 2015 12:19:37 +0200 Subject: [PATCH] updates to particle filters, speedy performance improvements --- src/particle_filters/particle_filter_test.jl | 7 + src/particle_filters/pf_bootstrap.jl | 163 +++++++++---------- 2 files changed, 80 insertions(+), 90 deletions(-) diff --git a/src/particle_filters/particle_filter_test.jl b/src/particle_filters/particle_filter_test.jl index c13f89b..3698ee7 100644 --- a/src/particle_filters/particle_filter_test.jl +++ b/src/particle_filters/particle_filter_test.jl @@ -21,6 +21,13 @@ function f(x::Vector, t::Int64) end f(x::Float64, t::Int64) = 0.5*x + 25*x/(1+x^2) + 8*cos(1.2*(t-1)) +f(xn,x,t::Int64) = begin + c = 8*cos(1.2*(t-1)) + @inbounds for i = 1:length(x) + xn[i] = 0.5*x[i] + 25*x[i]./(1+x[i]^2) + c + σw*randn() + end +end + function f_sample(x::Vector, t::Int64) c = 8*cos(1.2*(t-1)) @inbounds for i = 1:length(x) diff --git a/src/particle_filters/pf_bootstrap.jl b/src/particle_filters/pf_bootstrap.jl index e7ab1e5..5cdb02c 100644 --- a/src/particle_filters/pf_bootstrap.jl +++ b/src/particle_filters/pf_bootstrap.jl @@ -1,39 +1,36 @@ # module Tmp using Devectorize +using StatsBase function pf_bootstrap!(xp,w, y, N, g_density, f) T = length(y) - w0 = fill(log(1/N),N) - xp[:,1] = f(zeros(N),1) - w1 = copy(w0) - g_density(y[1],xp[:,1], w1) - w[:,1] = w1 - @devec w[:,1] -= log(sum(exp(w[:,1]))) + xp[:,1] = 2*σw*randn(N) + wT = slice(w,:,1) + xT = slice(xp,:,1) + fill!(wT,log(1/N)) + g(y[1],xT, wT) + wT -= logsumexp(wT) j = Array(Int64,N) # tw = Float64(N) for t = 2:T + xT1 = xT + xT = slice(xp,:,t) + wT1 = wT + wT = slice(w,:,t) # Resample if t%2 == 0 - resample_systematic!(j,slice(w,:,t-1),N) - xpT = xp[j,t-1] - wT = copy(w0) + resample_systematic!(j,wT1,N) + f(xT,xT1[j],t-1) + fill!(wT,log(1/N)) else # Resample not needed - xpT = xp[:,t-1] - wT = w[:,t-1] + f(xT,xT1,t-1) + copy!(wT,wT1) end # Time update - f(xpT,t-1) - xp[:,t] = xpT - g_density(y[t],xp[:,t], wT) - w[:,t] = wT + g(y[t],xT, wT) # Normalize weights - offset = maximum(w[:,t]) - normConstant = 0.0 - for i = 1:N - normConstant += exp(w[i,t]-offset) - end - w[:,t] -= log(normConstant)+offset + wT -= logsumexp(wT) # tw = 1/sum(w(:,t).*2) end @@ -44,38 +41,34 @@ function pf_bootstrap(y, N, g_density, f) T = length(y) xp = Array(Float64,(N,T)) w = Array(Float64,(N,T)) - w0 = fill(log(1/N),N) - xp[:,1] = f(zeros(N),1) - w1 = copy(w0) - g_density(y[1],xp[:,1], w1) - w[:,1] = w1 - @devec w[:,1] -= log(sum(exp(w[:,1]))) + xp[:,1] = 2*σw*randn(N) + wT = slice(w,:,1) + xT = slice(xp,:,1) + fill!(wT,log(1/N)) + g(y[1],xT, wT) + wT -= logsumexp(wT) j = Array(Int64,N) # tw = Float64(N) for t = 2:T + xT1 = xT + xT = slice(xp,:,t) + wT1 = wT + wT = slice(w,:,t) # Resample if t%2 == 0 - resample_systematic!(j,slice(w,:,t-1),N) - xpT = xp[j,t-1] - wT = copy(w0) + resample_systematic!(j,wT1,N) + f(xT,xT1[j],t-1) + fill!(wT,log(1/N)) else # Resample not needed - xpT = xp[:,t-1] - wT = w[:,t-1] + f(xT,xT1,t-1) + copy!(wT,wT1) end # Time update - f(xpT,t-1) - xp[:,t] = xpT - g_density(y[t],xp[:,t], wT) - w[:,t] = wT + g(y[t],xT, wT) # Normalize weights - offset = maximum(w[:,t]) - normConstant = 0.0 - for i = 1:N - normConstant += exp(w[i,t]-offset) - end - w[:,t] -= log(normConstant)+offset + wT -= logsumexp(wT) # tw = 1/sum(w(:,t).*2) end @@ -87,42 +80,37 @@ end function pf_bootstrap_nn(xp, w, wnn, y, N, g_density, f) T = length(y) - - w0 = fill(log(1/N),N) - xp[:,1] = f(zeros(N),1) - w1 = copy(w0) - g_density(y[1],xp[:,1], w1) - wnn[:,1] = w1 - @devec w[:,1] = wnn[:,1] - log(sum(exp(wnn[:,1]))) + xp[:,1] = 2*σw*randn(N) + wT = slice(w,:,1) + xT = slice(xp,:,1) + fill!(wT,log(1/N)) + g(y[1],xT, wT) + wnn[:,t] = wT + wT -= logsumexp(wT) j = Array(Int64,N) # tw = Float64(N) for t = 2:T + xT1 = xT + xT = slice(xp,:,t) + wT1 = wT + wT = slice(w,:,t) # Resample if t%2 == 0 - resample_systematic!(j,w[:,t-1],N) - # resample_systematic!(j,slice(w,:,t-1),N) - xpT = xp[j,t-1] - wT = copy(w0) + resample_systematic!(j,wT1,N) + f(xT,xT1[j],t-1) + fill!(wT,log(1/N)) else # Resample not needed - xpT = xp[:,t-1] - wT = copy(w[:,t-1]) + f(xT,xT1,t-1) + copy!(wT,wT1) end # Time update - f(xpT,t-1) - xp[:,t] = xpT g_density(y[t],xp[:,t], wT) wnn[:,t] = wT # Normalize weights #some strange error with this normalization method, I totally have no clue why it's working elsewhere but not here - offset = maximum(wnn[:,t]) - normConstant = 0.0 - for i = 1:N - normConstant += exp(wnn[i,t]-offset) - end - nc = log(normConstant)+offset - w[:,t] = wnn[:,t]- nc -# @assert isapprox(nc,log(sum(exp(wnn[:,t])))) + wT -= logsumexp(wT) + # @assert isapprox(nc,log(sum(exp(wnn[:,t])))) # tw = 1/sum(w(:,t).*2) end @@ -132,7 +120,7 @@ end function pf_aux_nn(xp, w, wnn, y, N, g_density, f) T = length(y) - + xp[:,1] = 2*σw*randn(N) w0 = fill(log(1/N),N) xp[:,1] = f(zeros(N),1) wnn[:,1] = w0 + g_density(y[1],xp[:,1]) @@ -184,41 +172,36 @@ end function pf_CSMC!(xp,w, y, N, g_density, f, xc ) - T = length(y) - w0 = fill(log(1/N),N) - xp[:,1] = f(zeros(N),1) + xp[:,1] = 2*σw*randn(N) xp[N,1] = xc[1] - w1 = copy(w0) - g_density(y[1],xp[:,1], w1) - w[:,1] = w1 - @devec w[:,1] -= log(sum(exp(w[:,1]))) + T = length(y) + wT = slice(w,:,1) + xT = slice(xp,:,1) + fill!(wT,log(1/N)) + g(y[1],xT, wT) + wT -= logsumexp(wT) j = Array(Int64,N) # tw = Float64(N) for t = 2:T + xT1 = xT + xT = slice(xp,:,t) + wT1 = wT + wT = slice(w,:,t) # Resample if t%2 == 0 - resample_systematic!(j,slice(w,:,t-1),N) - xpT = xp[j,t-1] - wT = copy(w0) + resample_systematic!(j,wT1,N) + f(xT,xT1[j],t-1) + fill!(wT,log(1/N)) else # Resample not needed - xpT = xp[:,t-1] - wT = w[:,t-1] + f(xT,xT1,t-1) + copy!(wT,wT1) end - - # Time update - f(xpT,t-1) - xp[:,t] = xpT xp[N,t] = xc[t] - g_density(y[t],xp[:,t], wT) - w[:,t] = wT + # Time update + g(y[t],xT, wT) # Normalize weights - offset = maximum(w[:,t]) - normConstant = 0.0 - for i = 1:N - normConstant += exp(w[i,t]-offset) - end - w[:,t] -= log(normConstant)+offset + wT -= logsumexp(wT) # tw = 1/sum(w(:,t).*2) end -- GitLab