R/hypothesis-model-backends.R
hypothesis_density_backend.RdThe density backend of a point hypothesis (the
density_method of hypothesis_BF() and hypothesis_BF_model())
decides how the posterior ordinate at the null value is obtained. The
built-in backends "KDE" and "normal" estimate it from the
posterior draws, and "precomputed" uses ordinates that are stored on
the draws (it is for draw inputs only, not for fitted models). A package
that computes posterior ordinates itself, for example by a likelihood-aware
estimator that cannot be written as a function of the draws, registers an
ordinate backend. hypothesis_density_backend() creates a backend
object, register_hypothesis_density_backend() adds it to the registry (a
package registers its backends in .onLoad() and removes them with
unregister_hypothesis_density_backend() in .onUnload()), and
hypothesis_density_backends() lists the registered backends.
hypothesis_density_backend(
name,
type = c("ordinate", "draws", "stored"),
available = NULL,
control = NULL,
attach = NULL,
reuse = NULL,
warnings = NULL,
diagnostics = NULL,
bind_diagnostics = NULL,
rescale_failure = NULL,
refusal_classes = NULL,
clear_cache = NULL,
method = NULL,
policy = list(),
advertised = TRUE,
package = NULL
)
register_hypothesis_density_backend(backend, overwrite = FALSE)
unregister_hypothesis_density_backend(name)
hypothesis_density_backends()the name of the density method (a single string that starts with a letter).
"ordinate", "draws", or "stored".
the callbacks of the backend, functions or NULL for the default;
see Details.
for a "draws" backend, the evaluation of
hypothesis_BF() that it stands for: "KDE" or "normal".
a list of declared settings of the backend.
whether hypothesis_quantities() lists the backend among
the methods that evaluate a quantity.
the name of the package that provides the backend.
a backend created with hypothesis_density_backend().
whether registering replaces a registered backend of the same name. Replacing a built-in backend is not possible.
hypothesis_density_backend() returns an object of class
BayesTools_hypothesis_density_backend.
register_hypothesis_density_backend() returns the backend
invisibly, and unregister_hypothesis_density_backend() returns
whether a backend was removed (invisibly).
hypothesis_density_backends() returns a data frame with one row per
registered backend in the order of registration: name,
type, package, advertised, and the list column
policy.
A backend has a type: "draws" (evaluated from the
posterior draws by hypothesis_BF() with the density method
method), "ordinate" (the backend attaches the posterior
ordinates of the tested values to the draws; they are then evaluated as
"precomputed" ordinates), or "stored" (the ordinates are
already attached to the draws). Matching of density_method to the
registered names ignores case and accepts unambiguous partial names.
The engine calls the callbacks of a backend as follows; each is optional
except attach of an ordinate backend.
available(object, plan, control)whether the backend can
evaluate the statement plan of the model object (the
capability_object of the provider) with the normalized
control, the settings that control() returns for the call
(for the stored marginal means of a model, for the settings of the call or
the stored settings that the provider inherits). For the stored marginal
means, settings that control() refuses reach available() as
they were supplied, and the engine stops with the failure of
control() after the plans are checked; for a fitted model, the
failure of control() stops the call before any plan is checked. It
is evaluated on every call and never cached. It
returns NULL when the backend can, and otherwise a refusal: a list
with the reason (a string) and optionally class (additional
condition classes appended to BayesTools_hypothesis_method and
BayesTools_hypothesis_unavailable) and fields (a named list
of further fields of the condition). The engine stops with the refusal
before any statement is evaluated.
control(control)the normalized density_control of
the backend (defaults filled in), stopping on invalid settings. It is
called with the settings of the call (or the stored settings of the
provider) on every call with an ordinate backend, and for the settings
that a call supplies to another backend, after the
check_density_control() of the provider
(hypothesis_provider()). The default accepts no settings: NULL
and an empty list give NULL, anything else is an error.
attach(posterior, request, control, cache)the whole
ordinate step of an ordinate backend. posterior is the marginal
posterior of the tested quantity (a vector, or for the request of a
factor level the list of the posteriors of the levels of the factor
term); it returns it with the ordinates of the requested values stored in
its posterior_ordinate metadata (posterior_metadata(),
posterior_ordinate_attribute(), posterior_ordinate_append()), one
entry per value, and the parameter, conditional,
conditional_rule, and condition_key metadata of the draws,
or stops with its own typed condition when an ordinate cannot be
constructed. cache is an environment that lives for the
evaluation of one group of statements, for objects that the requests of
the group share. The request is a list with the elements
kind ("scalar": the values of the vector posterior;
"level": the values of the level level), route (the
kind of the statement plan: "scalar", "linear",
"random", "exp_affine", or "marginal_mean"),
object (the model object, or the object that the provider names as
its capability_object), model (the object of the provider),
parameter, label (the tested quantity, as the table names
it), level, values (the point values to compute),
conditional (the conditioning of the draws: the parameter whose
inclusion event the draws are conditioned on, or NULL),
condition (the declared conditioning of the draws that the
ordinates belong to, read from their metadata
(posterior_metadata(), "condition"): the elements
conditional (the effective conditioning, a character vector that
is empty for averaged draws), conditional_rule,
condition_key, condition_event, and
resolved_condition_event, those the draws declare; an empty list
for draws without a declaration), spec (the structure of the tested quantity that the provider
declares: for example type = "primitive" or "linear" with
the weights on the fitted coordinates and the prior_density),
display_transform (the transformation from the evaluated to the
tested scale, or NULL), density_method (the name of the
backend), and inference_type (marginal means: the marginal
inference the draws belong to).
reuse(entry, request, control, posterior)whether the
ordinate entry that is stored on the draws posterior at a
requested value is current for the request (the method, control,
source of the fit, target, and conditioning agree), so that it is not
computed again. posterior are the draws that carry entry
(for the request of a factor level, the draws of that level), with their
metadata; request$condition is their declared conditioning. The
default reuses nothing: stored ordinates at the requested values are
replaced.
warnings(posterior, request)the warnings of the ordinates
stored on posterior (recursively over the levels of a list), as a
data frame with the columns warning, parameter,
level, label, and value. The engine puts each
warning on the rows of the statements it belongs to. The default reads
the warning element of the diagnostics of each stored ordinate.
The request is the request that attach received for the
group of statements, before the values whose stored ordinates
reuse accepted were left out of values; for a group that
is attached level by level (the levels of a factor term, marginal
means) it is the request of the first level, and the requests of the
group differ in their level, values, label,
spec, and condition only.
diagnostics(posterior, request)the public diagnostics of
the stored ordinates (a data frame; request as for
warnings), stored as the density_diagnostics attribute of
the table, and bind_diagnostics(list), which combines the
diagnostics of several groups of statements. Without diagnostics
the table has no such attribute; the default of bind_diagnostics
row-binds the data frames.
rescale_failure(condition, requested, evaluated, label,
density_method)restates a condition that attach raised for the
evaluated values evaluated of a request for the values
requested of a quantity that is evaluated through a
transformation of itself (a variance through its standard deviation); it
returns the condition to signal, or NULL to signal the original
one.
refusal_classes(cause)additional condition classes for the
refusals of the ordinate backends for a generic cause
("original_scale", "conditional_random", or
"random_target"); they follow the classes of the refusal of the
engine (for example BayesTools_hypothesis_target and
BayesTools_hypothesis_unavailable). A provider names the cause of
the refusal of a random-effect quantity (hypothesis_provider()).
clear_cache()drops the caches of the backend; the engine calls it when it drops its own caches.
policy is a list of the settings that the backend declares for its
acceptance of ordinates (thresholds on its error estimates, for example). It
is reported by hypothesis_density_backends() and not used by the engine:
the backend applies its own acceptance rules in attach, and the
engine only checks that the attached ordinates are valid
(posterior_ordinate_supports_bf()).
hypothesis_density_backends()
#> name type package advertised policy
#> 1 KDE draws BayesTools TRUE
#> 2 normal draws BayesTools FALSE
#> 3 precomputed stored BayesTools FALSE
# a toy backend that evaluates the ordinate of a normal posterior exactly
normal_ordinate <- hypothesis_density_backend(
name = "exactNormal",
type = "ordinate",
attach = function(posterior, request, control, cache) {
draws <- as.numeric(posterior)
ordinate <- stats::dnorm(request$values, mean(draws), stats::sd(draws))
posterior_metadata(posterior, "posterior_ordinate") <-
posterior_ordinate_attribute(
value = request$values, ordinate = ordinate,
method = "exact normal", density_method = "exactNormal",
parameter = attr(posterior, "parameter")
)
posterior
}
)
register_hypothesis_density_backend(normal_ordinate)
hypothesis_density_backends()$name
#> [1] "KDE" "normal" "precomputed" "exactNormal"
unregister_hypothesis_density_backend("exactNormal")