This R6 object manages two related parameter spaces: the Optimization Space (for optimization) and the Interpretation Space (for easier interpretation).
In the Optimization Space, parameters are stored as a numeric
vector
, the standard format for numerical optimizers. Parameters in
this space are typically identified.
In the Interpretation Space, parameters are stored as a list
and can
take different formats (e.g., matrix
). Parameters here do not need to
be identified.
The user can define transformation functions (not necessarily bijective) to
switch between these two spaces via the $o2i()
and $i2o()
methods.
Methods
Method new()
Initializes a new ParameterSpaces
object.
Usage
ParameterSpaces$new(parameter_names, parameter_lengths_in_o_space)
Arguments
parameter_names
[
character()
]
Unique names for the parameters.parameter_lengths_in_o_space
[
integer()
]
The length of each parameter in the optimization space.
Method print()
Print an overview of the parameter spaces.
Method switch()
Switch between Optimization Space and Interpretation Space.
Arguments
x
[
numeric()
|list()
]
The parameters, either as anumeric vector
(will be switched to Interpretation Space), or as alist()
(will be switched to Optimization Space).to
[
character(1)
|NULL
]
Explicitly switch to a specific space, either"o"
: Optimization Space"i"
: Interpretation Space
If
NULL
, the function will switch to the other space.
Method o2i()
Define transformation functions when switching from Optimization Space to Interpretation Space.
Method i2o()
Define transformation functions when switching from Interpretation Space to Optimization Space.
Arguments
...
[
function
]
One or more transformers functions, named according to the parameters.Transformers from Interpretation Space to Optimization Space (i2o) must return a
numeric
. The default isas.vector()
.
Examples
### Log-likelihood function of two-class Gaussian mixture model with
### parameter vector `theta` that consists of
### - `mu`, mean vector of length 2
### - `sd`, standard deviation vector of length 2, must be positive
### - `lambda`, class probability of length 1, must be between 0 and 1
normal_mixture_llk <- function(theta, data) {
mu <- theta[1:2]
sd <- exp(theta[3:4])
lambda <- plogis(theta[5])
c1 <- lambda * dnorm(data, mu[1], sd[1])
c2 <- (1 - lambda) * dnorm(data, mu[2], sd[2])
sum(log(c1 + c2))
}
### define parameter spaces
### - `mu` needs no transformation
### - `sd` needs to be real in optimization space and positive in
### interpretation space
### - `lambda` needs to be real and of length `1` in optimization space, and
### a probability vector of length `2` in interpretation space
normal_mixture_spaces <- ParameterSpaces$
new(
parameter_names = c("mu", "sd", "lambda"),
parameter_lengths_in_o_space = c(2, 2, 1)
)$
o2i(
"mu" = function(x) x,
"sd" = function(x) exp(x),
"lambda" = function(x) c(plogis(x), 1 - plogis(x))
)$
i2o(
"mu" = function(x) x,
"sd" = function(x) log(x),
"lambda" = function(x) qlogis(x[1])
)
### switch between parameter spaces
par <- list( # parameters in interpretation space
"mu" = c(2, 4),
"sd" = c(0.5, 1),
"lambda" = c(0.4, 0.6)
)
(x <- normal_mixture_spaces$switch(par)) # switch to optimization space
#> [1] 2.0000000 4.0000000 -0.6931472 0.0000000 -0.4054651
normal_mixture_llk(
theta = x, data = datasets::faithful$eruptions
)
#> [1] -382.1072
normal_mixture_spaces$switch(x) # switch back
#> $mu
#> [1] 2 4
#>
#> $sd
#> [1] 0.5 1.0
#>
#> $lambda
#> [1] 0.4 0.6
#>