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

Prevent DataMisfitController scheduler from modifying EKP obs_noise_cov #338

Merged
merged 1 commit into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/LearningRateSchedulers.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# included in EnsembleKalmanProcess.jl

export DefaultScheduler, MutableScheduler, EKSStableScheduler, DataMisfitController
export calculate_timestep!
export calculate_timestep!, posdef_correct

# default unless user overrides

Expand Down Expand Up @@ -222,6 +222,7 @@ $(DocStringExtensions.TYPEDSIGNATURES)
Makes square matrix `mat` positive definite, by symmetrizing and bounding the minimum eigenvalue below by `tol`
"""
function posdef_correct(mat::AbstractMatrix; tol::Real = 1e8 * eps())
mat = deepcopy(mat)
if !issymmetric(mat)
out = 0.5 * (mat + permutedims(mat, (2, 1))) #symmetrize
if isposdef(out)
Expand Down
5 changes: 5 additions & 0 deletions test/EnsembleKalmanProcess/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ end
else #no initial ensemble for UKI
ekpobj = EKP.EnsembleKalmanProcess(y_obs, Γy, process, rng = copy(rng), scheduler = scheduler)
end
initial_obs_noise_cov = deepcopy(ekpobj.obs_noise_cov)
for i in 1:N_iter
params_i = get_ϕ_final(prior, ekpobj)
g_ens = G(params_i)
Expand All @@ -290,9 +291,13 @@ end
if !isnothing(terminated)
break
end
# ensure Δt is updated
@test length(ekpobj.Δt) == i
end
push!(init_means, vec(mean(get_u_prior(ekpobj), dims = 2)))
push!(final_means, vec(mean(get_u_final(ekpobj), dims = 2)))
# ensure obs_noise_cov matrix remains unchanged
@test initial_obs_noise_cov == ekpobj.obs_noise_cov

# this test is fine so long as N_iter is large enough to hit the termination time
if nameof(typeof(scheduler)) == DataMisfitController
Expand Down
Loading