Skip to content

Commit

Permalink
Merge #281
Browse files Browse the repository at this point in the history
281: pass RNG instead of seeds r=costachris a=costachris

Closes #260 

Pass RNG  objects instead of seeds to make randomness more traceable. 

Co-authored-by: costachris <[email protected]>
  • Loading branch information
bors[bot] and costachris committed May 31, 2023
2 parents a27fc58 + e3700cc commit 91db990
Show file tree
Hide file tree
Showing 10 changed files with 22 additions and 33 deletions.
4 changes: 3 additions & 1 deletion examples/AerosolActivation/aerosol_activation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ using Plots
using Distributions
using LinearAlgebra
using Random

rng_seed = 44
rng = Random.seed!(Random.GLOBAL_RNG, rng_seed)

using EnsembleKalmanProcesses
using EnsembleKalmanProcesses.ParameterDistributions
Expand Down Expand Up @@ -169,7 +171,7 @@ nothing # hide
N_ens = 50
N_iter = 10

initial_par = EKP.construct_initial_ensemble(priors, N_ens; rng_seed)
initial_par = EKP.construct_initial_ensemble(rng, priors, N_ens)
ekiobj = EKP.EnsembleKalmanProcess(initial_par, truth_sample, truth_array.obs_noise_cov, EKP.Inversion())
nothing # hide

Expand Down
3 changes: 2 additions & 1 deletion examples/Cloudy/Cloudy_example_eki.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ using .DynamicalModel

rng_seed = 41
Random.seed!(rng_seed)
rng = Random.seed!(Random.GLOBAL_RNG, rng_seed)

homedir = pwd()
figure_save_directory = homedir * "/output/"
Expand Down Expand Up @@ -121,7 +122,7 @@ truth_sample = truth.mean
N_ens = 50 # number of ensemble members
N_iter = 8 # number of EKI iterations
# initial parameters: N_par x N_ens
initial_par = construct_initial_ensemble(priors, N_ens; rng_seed)
initial_par = construct_initial_ensemble(rng, priors, N_ens)
ekiobj = EnsembleKalmanProcess(initial_par, truth_sample, truth.obs_noise_cov, Inversion(), Δt = 0.1)

# Initialize a ParticleDistribution with dummy parameters. The parameters
Expand Down
2 changes: 1 addition & 1 deletion examples/Darcy/calibrate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ function main()
N_ens = dofs + 2 # number of ensemble members
N_iter = 10 # number of EKI iterations
# initial parameters: N_params x N_ens
initial_params = construct_initial_ensemble(prior, N_ens; rng_seed = seed)
initial_params = construct_initial_ensemble(rng, prior, N_ens)
ekiobj = EKP.EnsembleKalmanProcess(initial_params, truth_sample, obs_noise_cov, Inversion())

println("Begin inversion")
Expand Down
4 changes: 2 additions & 2 deletions examples/Lorenz/Lorenz_example.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ using EnsembleKalmanProcesses.ParameterDistributions
const EKP = EnsembleKalmanProcesses

rng_seed = 4137
Random.seed!(rng_seed)
rng = Random.seed!(Random.GLOBAL_RNG, rng_seed)

# Output figure save directory
homedir = pwd()
Expand Down Expand Up @@ -192,7 +192,7 @@ lorenz_settings_G = lorenz_settings; # initialize to truth settings
N_ens = 20 # number of ensemble members
N_iter = 5 # number of EKI iterations
# initial parameters: N_params x N_ens
initial_params = construct_initial_ensemble(priors, N_ens; rng_seed = rng_seed)
initial_params = construct_initial_ensemble(rng, priors, N_ens)

ekiobj = EKP.EnsembleKalmanProcess(initial_params, truth_sample, truth.obs_noise_cov, Inversion())

Expand Down
4 changes: 2 additions & 2 deletions examples/Lorenz/distributed_Lorenz_example.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ using EnsembleKalmanProcesses.ParameterDistributions
const EKP = EnsembleKalmanProcesses

rng_seed = 4137
Random.seed!(rng_seed)
rng = Random.seed!(Random.GLOBAL_RNG, rng_seed)

# Output figure save directory
homedir = pwd()
Expand Down Expand Up @@ -216,7 +216,7 @@ lorenz_settings_G = lorenz_settings; # initialize to truth settings
N_ens = 20 # number of ensemble members
N_iter = 5 # number of EKI iterations
# initial parameters: N_params x N_ens
initial_params = construct_initial_ensemble(priors, N_ens; rng_seed = rng_seed)
initial_params = construct_initial_ensemble(rng, priors, N_ens)

ekiobj = EKP.EnsembleKalmanProcess(initial_params, truth_sample, truth.obs_noise_cov, Inversion())

Expand Down
8 changes: 4 additions & 4 deletions examples/LossMinimization/loss_minimization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ nothing # hide

# We set the seed for pseudo-random number generator for reproducibility.
rng_seed = 41
Random.seed!(rng_seed)
rng = Random.seed!(Random.GLOBAL_RNG, rng_seed)
nothing # hide

# We set a stabilization level, which can aid the algorithm convergence
Expand Down Expand Up @@ -54,7 +54,7 @@ N_iterations = 10
nothing # hide

# The initial ensemble is constructed by sampling the prior
initial_ensemble = EKP.construct_initial_ensemble(prior, N_ensemble; rng_seed = rng_seed)
initial_ensemble = EKP.construct_initial_ensemble(rng, prior, N_ensemble)

# We then initialize the Ensemble Kalman Process algorithm, with the initial ensemble, the
# target, the stabilization and the process type (for EKI this is `Inversion`, initialized
Expand Down Expand Up @@ -127,7 +127,7 @@ nothing # hide

# We set the seed for pseudo-random number generator for reproducibility,
rng_seed = 10
Random.seed!(rng_seed)
rng = Random.seed!(Random.GLOBAL_RNG, rng_seed)
nothing # hide

# A positive function can be minimized with a target of 0,
Expand All @@ -152,7 +152,7 @@ prior = combine_distributions([prior_u1, prior_u2])
N_ensemble = 20
N_iterations = 20

initial_ensemble = EKP.construct_initial_ensemble(prior, N_ensemble; rng_seed = rng_seed)
initial_ensemble = EKP.construct_initial_ensemble(rng, prior, N_ensemble)

ensemble_kalman_process = EKP.EnsembleKalmanProcess(initial_ensemble, G_target, Γ_stabilization, Inversion())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ nothing # hide

# We set the seed for pseudo-random number generator for reproducibility.
rng_seed = 41
Random.seed!(rng_seed)
rng = Random.seed!(Random.GLOBAL_RNG, rng_seed)
nothing # hide

# We set a stabilization level, which can aid the algorithm convergence
Expand Down Expand Up @@ -52,7 +52,7 @@ N_iterations = 10
nothing # hide

# The initial ensemble is constructed by sampling the prior
initial_ensemble = EKP.construct_initial_ensemble(prior, N_ensemble; rng_seed = rng_seed)
initial_ensemble = EKP.construct_initial_ensemble(rng, prior, N_ensemble)

# Sparse EKI parameters
γ = 1.0
Expand Down
2 changes: 1 addition & 1 deletion examples/example_template.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ priors = ParameterDistribution(prior_dict)
##

# initial ensemble of parameters
params = construct_initial_ensemble(priors, N_ens; rng_seed = rng_seed)
params = construct_initial_ensemble(priors, N_ens)

# constructor for the EKI object
ekiobj =
Expand Down
21 changes: 5 additions & 16 deletions src/EnsembleKalmanProcess.jl
Original file line number Diff line number Diff line change
Expand Up @@ -372,30 +372,19 @@ end
construct_initial_ensemble(
rng::AbstractRNG,
prior::ParameterDistribution,
N_ens::IT;
rng_seed::Union{IT, Nothing} = nothing,
N_ens::IT
) where {IT <: Int}
construct_initial_ensemble(prior::ParameterDistribution, N_ens::IT; kwargs...) where {IT <: Int}
construct_initial_ensemble(prior::ParameterDistribution, N_ens::IT) where {IT <: Int}
Construct the initial parameters, by sampling `N_ens` samples from specified
prior distribution. Returned with parameters as columns.
"""
function construct_initial_ensemble(
rng::AbstractRNG,
prior::ParameterDistribution,
N_ens::IT;
rng_seed::Union{IT, Nothing} = nothing,
) where {IT <: Int}
# Ensuring reproducibility of the sampled parameter values:
# re-seed the rng *only* if we're given a seed
if rng_seed !== nothing
rng = Random.seed!(rng, rng_seed)
end
function construct_initial_ensemble(rng::AbstractRNG, prior::ParameterDistribution, N_ens::IT) where {IT <: Int}
return sample(rng, prior, N_ens) #of size [dim(param space) N_ens]
end
# first arg optional; defaults to GLOBAL_RNG (as in Random, StatsBase)
construct_initial_ensemble(prior::ParameterDistribution, N_ens::IT; kwargs...) where {IT <: Int} =
construct_initial_ensemble(Random.GLOBAL_RNG, prior, N_ens; kwargs...)
construct_initial_ensemble(prior::ParameterDistribution, N_ens::IT) where {IT <: Int} =
construct_initial_ensemble(Random.GLOBAL_RNG, prior, N_ens)

"""
compute_error!(ekp::EnsembleKalmanProcess)
Expand Down
3 changes: 0 additions & 3 deletions test/EnsembleKalmanProcess/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -456,8 +456,5 @@ end
u = ParameterDistribution(Dict("distribution" => d, "constraint" => no_constraint(), "name" => "test"))
draw_1 = construct_initial_ensemble(rng, u, 1)
draw_2 = construct_initial_ensemble(u, 1)
# Re-seeded draw should be the same as first draw
draw_3 = construct_initial_ensemble(rng, u, 1; rng_seed = rng_seed)
@test !isapprox(draw_1, draw_2)
@test isapprox(draw_1, draw_3)
end

0 comments on commit 91db990

Please sign in to comment.