CliMA / CliMA/EnsembleKalmanProcesses.jl
Named tuples for parameters
- Dominant language
- Julia
- Stars
- 125
- Forks
- 24
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 5
Description
For applications with large numbers of parameters input into complex models, it's useful (even necessary) to use objects like `NamedTuple` that associate parameter names with values to hold / transport lists of parameters.
However, as far as I can tell, parameters are constrained to be vectors. Throughout the code in fact, many data structures seem constrained to `Array` or `Vector`. Eg, this code does not work:
```julia
using Distributions
using LinearAlgebra
using Random
using EnsembleKalmanProcesses.EnsembleKalmanProcessModule
using EnsembleKalmanProcesses.ParameterDistributionStorage
using EnsembleKalmanProcesses.EnsembleKalmanProcessModule: EnsembleKalmanProcess, construct_initial_ensemble
rng_seed = 41
Random.seed!(rng_seed)
# The system
θ★ = (a=1, b=-1)
G₁(θ) = [sqrt((θ.a - θ★.a)^2 + (θ.b - θ★.b)^2)]
# Hyperparameters
N_ensemble = 50
noise_level = 1e-3
unconstrained_prior_distributions = (a=Parameterized(Normal(0, 1)), b=Parameterized(Normal(0, 1)))
constraints = (a=no_constraint(), b=no_constraint())
parameter_names = ("a", "b")
prior = ParameterDistribution(unconstrained_prior_distributions, constraints, parameter_names)
```
and I get
```julia
julia> prior = ParameterDistribution(unconstrained_prior_distributions, constraints, ["a", "b"])
ERROR: MethodError: no method matching ParameterDistribution(::NamedTuple{(:a, :b), Tuple{Parameterized, Parameterized}}, ::NamedTuple{(:a, :b), Tuple{Constraint, Constraint}}, ::Vector{String})
```
Is it necessary to constrain parameters to type `Vector`? It seems like it should be possible to generically support any iterable object (or objects that support broadcasting?) In the case that we need to perform `LinearAlgebra` operations, we can constructor the appropriate matrices or vectors from iterable containers as needed:
```julia
julia> parameters = (a=1, b=2)
(a = 1, b = 2)
julia> parameter_vector =[θ for θ in parameters]
2-element Vector{Int64}:
1
2
```
Allocations could even be minimized, though I think this is usually unnecessary because typical applications of `EnsembleKalmanProcesses.jl` have computations _dominated_ by the cost of evaluating a loss function.
I'm happy to get to work on refactoring the internals to support more general parameter containers if someone can identify the minimal requirements for the parameters object. It's tough to figure out what methods would have to be defined without detailed knowledge of the code because the `struct` definitions are over-constrained, preventing experimentation.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at the ParameterDistribution constructor and inspect the Array or Vector constraints in EnsembleKalmanProcessModule and ParameterDistributionStorage. Identify the minimal parameter-container requirements, then verify that the NamedTuple example can construct a prior without breaking existing parameter operations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- julia
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100