baggepinnen / LowLevelParticleFilters.jl

State estimation, smoothing and parameter estimation using Kalman and particle filters.
https://baggepinnen.github.io/LowLevelParticleFilters.jl/stable
Other
114 stars 15 forks source link

Passing dynamics noise density makes stochastic dynamics less expressive #105

Closed mjyshin closed 1 year ago

mjyshin commented 1 year ago

I really like the level of flexibility this package affords compared to other particle filtering packages in Julia, so first of all, thank you for developing and maintaining it. I had a quick comment about the source code, where the propagation of the dynamics model occurs. The dynamics model has an option for injecting noise into the dynamics (set to false as default), so shouldn't this be utilized in the propagation step? The following code makes it seem like you can only make the dynamic noise be additive:

Base.@propagate_inbounds function propagate_particles!(pf::ParticleFilter,u,j::Vector{Int}, p, t::Int, d::Union{Nothing, Distributions.Sampleable}=pf.dynamics_density)
    f = dynamics(pf)
    s = state(pf)
    x,xp = s.x, s.xprev
    VecT = eltype(s.x)
    D = length(VecT)
    noise = zeros(D)
    if d === nothing
        for i = eachindex(x)
            x[i] =  f(xp[j[i]], u, p, t)
        end
    else
        for i = eachindex(x)
            x[i] =  f(xp[j[i]], u, p, t) + VecT(rand!(pf.rng, d, noise))
        end
    end
    x
end

I was thinking something like this would make more sense to let the dynamics be arbitrarily stochastic:

...
    if d === nothing
        for i = eachindex(x)
            x[i] =  f(xp[j[i]], u, p, t)
        end
    else
        for i = eachindex(x)
            x[i] =  f(xp[j[i]], u, p, t, true)
        end
    end
...

To be quite frank, I would think you don't even need to pass the dynamics noise density into the filter to initialize it since it'll be redundant (just like we don't pass the observation noise density), and we need only pass the initial condition density.

baggepinnen commented 1 year ago

I think you might be looking for the AdvancedParticleFilter type? The standard ParticleFilter does assume additive noise, an assumption that is lifted by the AdvancedParticleFilter type. See the docs or the Advanced tutorial for an example of how it's used.

mjyshin commented 1 year ago

Ah, my apologies, I didn't see the propagate_particles! function for pf::AdvancedParticleFilter. When creating the AdvancedParticleFilter object, the dynamics_density does not get used then, right? That is, we can pass whatever density, but the noise is added according to the definition in the dynamics function we pass?

baggepinnen commented 1 year ago

That is, we can pass whatever density, but the noise is added according to the definition in the dynamics function we pass?

Correct, this filter was added later, and the dynamics density is following along just to match the interface of the other filters. The dynamics_density field of the advanced filter has a default value set to an arbitrary `Normal() distribution so that it does not have to be provided by the user.