PumasModel Domains

Domains are used to define the param portion of a PumasModel. This segment of the documentation describes the available Domain types that can be used within the param portions.

Matching Parameter Types and Domains

A param specification in a PumasModel directly defines the types which are required to be given as the input to the model's interface functions such as simobs and fit. For example, if the param specification is given as:

@param begin
    θ ∈ VectorDomain(2; lower = [0, 0], upper = [20, 20])
    Ω ∈ PSDDomain(2)
    Σ ∈ RealDomain(; lower = 0.01, upper = 0.2)
end

Then in simobs(model, data, param) or fit(model, data, param), the parameters param must be a NamedTuple of values where the type fits in the domain. For example, param must have param.θ as a Vector. Thus, the following would be a valid definition of param for this structure:

param = (; θ = [0.4, 7.0], Ω = [
    0.04 0.0
    0.0 0.01
], Σ = 0.1)

Below are the specifications of the Domain types and their matching value types.

RealDomain and VectorDomain

RealDomain and VectorDomain are the core domain types of Pumas. A RealDomain defines a scalar value which exists in the real line, while a VectorDomain defines a real-valued vector which lives in a hypercube of $\mathbb{R}^n$. The length n of a VectorDomain is a required positional argument. Each of these allow keyword arguments for setting an upper and lower bound for the segment, where for the RealDomain these are scalars and for the VectorDomain it is a vector of upper and lower bound for each component of the vector. Thus, the constructors are:

Pumas.RealDomainType
@param x ∈ RealDomain(;lower=-∞,upper=∞,init=0)

Specifies a parameter as a real value. lower and upper are the respective bounds, init sets the initial value of the parameter and is used for init_params.

Pumas.VectorDomainType
@param x ∈ VectorDomain(n::Int; lower=-∞,upper=∞,init=0)

Specifies a parameter as a real vector of length n. lower and upper are the respective bounds, init sets the initial value of the parameter and is used for init_params. The keyword arguments can all take either numbers or vectors. If numbers then the same value will be applied to all n vector elements. If a you specify a vector (of length n) then you can adjust the parameters of the VectorDomain elements individually.

A RealDomain requires that the matching parameters are an AbstractFloat type. A VectorDomain requires that the matching parameters are a Vector of an AbstractFloat type which has the correct size.

Positive-Definite Matrix Domains

In many cases, one may wish to specify a positive-definite covariance matrix as a parameter in a model. A common use case for this functionality is for defining the domain of a random effect. There are two domains for positive-definite matrices: PSDDomain and PDiagDomain. Both of the constructors require the size n of the n x n positive-definite matrix:

Pumas.PSDDomainType
@param x ∈ PSDDomain(n::Int)
@param x ∈ PSDDomain(; init=Matrix{Float64}(I, n, n))

Specifies a parameter as a symmetric n-by-n positive semi-definite matrix. The user must either specify n as the number of rows and columns in the matrix or init as the initial value of the parameter. init should be a positive semi- definite Matrix of Float64s.

Pumas.PDiagDomainType
@param x ∈ PDiagDomain(n::Int; init=ones(n))

Specifies a parameter as a positive diagonal matrix, with initial diagonal elements specified by init.

A PSDDomain requires that the matching matrix input is positive definite but puts no further restrictions on the matrix. If a domain is specified as Ω ∈ PSDDomain(2), then

Ω = [
    0.04 0.0
    0.0 0.01
]

is a valid parameter specification. The PDiagDomain restricts the parameter space to positive definite diagonal matrices is, i.e. diagonal matrices with positive diagonal elements. Thus, if a domain is specified as Ω ∈ PDiagDomain(2), then

Ω = Diagonal([0.0, 1.0])

is a valid parameter specification.

Distributional Domains

Instead of using a Domain type from Pumas, a Distribution can be used to specify a domain. For example,

Ω ~ Normal(0.0, 1.0)

is a valid domain specification. If this is done, then the probability distribution is used and interpreted as the prior distribution. Implicitly, the domain of a distribution is treated as the support of the distribution. A distributional domain requires that the matching parameter is of the same type as a sample from the domain. For example, if Ω ~ Normal(0,1), then Ω should be given as a scalar.

Constrained Domains

The Constrained domain is for defining a Constrained probability distribution. Constrained takes in a distribution and has keyword arguments for upper and lower bounds.

Pumas.ConstrainedType
Constrained

Constrain a Distribution within a Domain. The most common case is an MvNormal constrained within a VectorDomain. The only supported method for Constrained is logpdf. Notice that the result does not represent a probability distribution since the remaining probability mass is not scaled by the mass excluded by the constraints.

Example

julia> d = Constrained(MvNormal(fill(1.0, 1, 1)), lower=-1, upper=1)
Constrained{ZeroMeanFullNormal{Tuple{Base.OneTo{Int64}}}, VectorDomain{Vector{Int64}, Vector{Int64}, Vector{Float64}}}(ZeroMeanFullNormal(
dim: 1
μ: Zeros(1)
Σ: [1.0;;]
)
, VectorDomain{Vector{Int64}, Vector{Int64}, Vector{Float64}}([-1], [1], [0.0]))


julia> logpdf(d, [ 0])
-0.9189385332046728

julia> logpdf(d, [-2])
-Inf

For example, ψ ~ Constrained(MVNormal(Ω),lower=[0.0,0.0]) defines a ψ to be from the distributional domain which corresponds to a multivariate normal distribution, but is constrained to be positive. Like with the distributional domains, Constrained requires that the matching parameter is of the same type as a sample from the domain.