Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Covariance function assumed in optimal proposal not guaranteed to match that used for process noise #213

Closed
matt-graham opened this issue Jan 20, 2022 · 0 comments · Fixed by #216

Comments

@matt-graham
Copy link
Member

matt-graham commented Jan 20, 2022

Currently the covariance function (in the Gaussian process / random field sense) used for computing the mean and covariance of the (Gaussian) optimal proposal is hardcoded in the following

# Covariance function r(x,y), equation 1 in Dietrich and Newsam 96
function covariance(x::T, y::T, noise_params::NamedTuple) where T
return noise_params.sigma^2 * exp(-(abs(x) + abs(y))/(2 * noise_params.lambda))
end

Separately each model is expected to define a update_particle_noise! method which perturbs the state particles (post propagating forwards in time under the deterministic model dynamics) with additive Gaussian state / process noise. In both the currently implemented TDAC model in test/model and in @DanGiles' ongoing implementation of the SPEEDY model in #203 the update_particle_noise! methods use the GaussianRandomFields package to sample a Gaussian random field to use as the additive Gaussian state noise. GaussianRandomFields itself provides methods for evaluating a covariance function at one or multiple pairs of points.

The current covariance implementation in src/OptimalFilter.jl hardcodes both the family of covariance function and the specific parameterization used. If a model uses a covariance function from a different family or from the same family but with a different parameterization then the state noise covariances computed to construct the optimal proposal and in simulating the state noise will not match and lead to incorrect results.

If the covariance implementation in src/OptimalFilter.jl was instead passed the CovarianceStructure struct used to define the state noise Gaussian random field, and used the apply method from GaussianRandomFields internally, this would both ensure consistency between the definitions without having to worry about the particular parameterization used and also allow the implementation to straight away generalize to any of the other stationary covariance functions defined in GaussianRandomFields.

As a related point, it is not entirely clear if the covariance function definition for the TDAC model does match that in the optimal proposal implementation currently. In

function init_gaussian_random_field_generator(lambda::Vector{T},
nu::Vector{T},
sigma::Vector{T},
x::AbstractVector{T},
y::AbstractVector{T},
pad::Int,
primes::Bool) where T
# Let's limit ourselves to two-dimensional fields
dim = 2
function _generate(l, n, s)
cov = CovarianceFunction(dim, Matern(l, n, σ = s))
grf = GaussianRandomField(cov, CirculantEmbedding(), x, y, minpadding=pad, primes=primes)
v = grf.data[1]
xi = Array{eltype(grf.cov)}(undef, size(v)..., nthreads())
w = Array{complex(float(eltype(v)))}(undef, size(v)..., nthreads())
z = Array{eltype(grf.cov)}(undef, length.(grf.pts)..., nthreads())
RandomField(grf, xi, w, z)
end
return [_generate(l, n, s) for (l, n, s) in zip(lambda, nu, sigma)]
end

the state noise Gaussian random field (for the fields for each of the three state variables) is set to have a Matern covariance function with lengthscale parameter lambda = 1e4, smoothness parameter nu = 2.5 and marginal standard deviation sigma = 1. The documentation for the Matern covariance function in the GaussianRandomFields package suggests the corresponding covariance function definition is

r(x_1, x_2) = sigma * (2^(1 - nu)) / (gamma(nu)) * (rho(x_1, x_2) / lambda)^nu * besselk(nu, rho(x_1, x_2) / lambda)

with rho(x_1, x_2) = sum(abs(x_1 .- x_y).^2). While the Matern covariance (under a different parametrization) does simplify for certain values of the smoothness parameter nu it is not clear this matches the corresponding defnition in OptimalFilter.jl

r(x_1, x_2) = sigma^2 * exp(−(sum(abs(x_1 .- x_2)) / (2 * lambda))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant