Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,16 @@ Imports:
checkmate,
distspec (>= 0.2.0),
ggplot2,
juliaready,
juliabridge,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
posterior,
rlang,
stats
Suggests:
withr,
knitr,
rmarkdown,
testthat (>= 3.2.0)
Remotes:
sbfnk/juliaready
epiforecasts/juliabridge
VignetteBuilder: knitr
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.3
Expand Down
11 changes: 7 additions & 4 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ S3method(as_draws_df,cidm_fit)
S3method(as_draws_list,cidm_fit)
S3method(as_draws_matrix,cidm_fit)
S3method(as_draws_rvars,cidm_fit)
S3method(as_julia_value,dist_spec)
S3method(plot,cidm_fit)
S3method(predict,cidm_fit)
S3method(print,cidm_component)
S3method(print,cidm_fit)
S3method(print,cidm_nuts)
S3method(simulate,cidm_julia)
S3method(simulate,cidm_model)
S3method(simulate,julia_spec)
S3method(summary,cidm_fit)
export(AR)
export(Ascertainment)
Expand Down Expand Up @@ -42,9 +41,9 @@ export(Weibull)
export(as_julia)
export(cidm_available)
export(cidm_setup_julia)
export(component)
export(fit)
export(julia)
export(julia_spec)
export(nuts)
export(truncated)
importFrom(distspec,Beta)
Expand All @@ -55,6 +54,10 @@ importFrom(distspec,LogNormal)
importFrom(distspec,NonParametric)
importFrom(distspec,Normal)
importFrom(distspec,Weibull)
importFrom(juliabridge,as_julia)
importFrom(juliabridge,as_julia_value)
importFrom(juliabridge,julia)
importFrom(juliabridge,julia_spec)
importFrom(posterior,as_draws_array)
importFrom(posterior,as_draws_df)
importFrom(posterior,as_draws_list)
Expand Down
19 changes: 18 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,21 @@
* `fit(model, y, method = nuts())` takes a numeric vector of observations and
replaces `nuts_sampler()` with `nuts()`. Pathfinder initialisation has been
removed.
* `epiaware_call()` has been replaced by `component()` and `julia()`.
* `epiaware_call()` has been replaced by `julia_spec()` and `julia()`.
* `plot(type = "posterior")` has been removed; use bayesplot on
`posterior::as_draws_array(fit)` instead.
* The Julia setup dependency is now
[juliabridge](https://github.com/epiforecasts/juliabridge), which juliaready
was renamed to. An install from GitHub picks it up through `Remotes`; an
existing checkout needs the dependency reinstalled.
* `julia_spec()`, `julia()` and `as_julia()` come from juliabridge, which
composableIDModelR re-exports. The code that renders a component to Julia
source moved there so that other packages can build Julia calls the same
way. The role of a component is given as `.role`, leaving every Julia
keyword name free; components carry classes such as `julia_latent` and
`julia_model`; and one prints as `<julia model spec>`. A component built
without a role is accepted wherever one is expected, since the role is what
the caller says the component is.

## New features

Expand All @@ -43,6 +55,11 @@
* `plot()` gains `type = "infections"`, `type = "latent"` and a `horizon`
argument for forecasts.

## Bug fixes

* Forecasting from a fit whose Julia session has gone says so, rather than
setting Julia up again and then failing inside Julia.

# EpiAwareR 0.2.0

## New Features
Expand Down
20 changes: 11 additions & 9 deletions R/dist-convert.R
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#'
#' @param x A distspec distribution or a composableIDModelR component.
#' @param arg_name Name used in error messages.
#' @return A component of class `cidm_distribution`.
#' @return A component of class `julia_distribution`.
#' @keywords internal
.as_prior <- function(x, arg_name = deparse(substitute(x))) {
if (!inherits(x, "dist_spec")) {
Expand All @@ -56,19 +56,19 @@
if (!distribution %in% names(.julia_distributions)) {
stop(
"`", arg_name, "` is a ", distribution, " distribution, which cannot be ",
"used as a prior. Use a parametric distribution, or `component()` for a ",
"Distributions.jl distribution with no distspec equivalent.",
"used as a prior. Use a parametric distribution, or `julia_spec()` ",
"for a Distributions.jl distribution with no distspec equivalent.",
call. = FALSE
)
}
spec <- .julia_distributions[[distribution]]
args <- lapply(spec$args(distspec::get_parameters(x)), as.numeric)
prior <- do.call(
component, c(spec$fn, args, role = "distribution")
julia_spec, c(spec$fn, args, .role = "distribution")
)
max <- .dist_max(x)
if (is.finite(max)) {
prior <- component("truncated", prior, -Inf, max, role = "distribution")
prior <- julia_spec("truncated", prior, -Inf, max, .role = "distribution")
}
prior
}
Expand Down Expand Up @@ -191,9 +191,9 @@
priors <- lapply(names(parameters), function(name) {
prior <- .as_prior(parameters[[name]], arg_name)
if (is.finite(bounds[[name]])) {
prior <- component(
prior <- julia_spec(
"truncated", prior, as.numeric(bounds[[name]]), Inf,
role = "distribution"
.role = "distribution"
)
}
prior
Expand All @@ -202,7 +202,9 @@
unname(priors), D = as.numeric(max_delay))
args[["\u0394d"]] <- if (!is.null(delta_d)) as.numeric(delta_d)
list(
dist = do.call(component, c("UncertainDelay", args, role = "distribution")),
dist = do.call(
julia_spec, c("UncertainDelay", args, .role = "distribution")
),
max_delay = NULL, delta_d = NULL
)
}
Expand Down Expand Up @@ -260,7 +262,7 @@
if (is.null(x)) {
return(NULL)
}
if (is.list(x) && !inherits(x, c("cidm_component", "dist_spec"))) {
if (is.list(x) && !inherits(x, c("julia_spec", "dist_spec"))) {
return(lapply(seq_along(x), function(i) {
.as_prior(x[[i]], paste0(arg_name, "[[", i, "]]"))
}))
Expand Down
8 changes: 4 additions & 4 deletions R/distributions.R
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#' @param lower,upper Numeric truncation bounds. Use `-Inf` or `Inf` to leave
#' a side unbounded.
#'
#' @return A component of class `cidm_distribution`.
#' @return A component of class `julia_distribution`.
#'
#' @family components
#' @name distributions
Expand All @@ -50,7 +50,7 @@ NULL
# nolint start: object_name_linter.
HalfNormal <- function(mean = 1) {
checkmate::assert_number(mean, lower = 0, finite = TRUE)
component("HalfNormal", as.numeric(mean), role = "distribution")
julia_spec("HalfNormal", as.numeric(mean), .role = "distribution")
}
# nolint end

Expand All @@ -63,8 +63,8 @@ truncated <- function(dist, lower = -Inf, upper = Inf) {
if (lower >= upper) {
stop("`lower` must be less than `upper`.", call. = FALSE)
}
component("truncated", dist, as.numeric(lower), as.numeric(upper),
role = "distribution")
julia_spec("truncated", dist, as.numeric(lower), as.numeric(upper),
.role = "distribution")
}

#' @importFrom distspec Normal
Expand Down
18 changes: 9 additions & 9 deletions R/fit.R
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ fit <- function(model, y, method = nuts(), dates = NULL, seed = NULL) {
y = y,
dates = dates,
method = method,
julia = .julia_handle(result$handle, result$session)
julia = juliabridge::julia_handle(
result$handle, result$session, .cidm_env
)
),
class = "cidm_fit"
)
Expand Down Expand Up @@ -190,9 +192,9 @@ fit <- function(model, y, method = nuts(), dates = NULL, seed = NULL) {
#' }
#' @importFrom stats simulate
#' @export
simulate.cidm_model <- function(object, nsim = 1, seed = NULL, n, ...) {
# An untyped `julia()` expression dispatches here too, as do typed ones of
# every role, so the role is checked rather than left to dispatch.
simulate.julia_spec <- function(object, nsim = 1, seed = NULL, n, ...) {
# Every specification dispatches here, whatever role it carries and whether
# it carries one, so the role is checked here rather than left to dispatch.
.assert_role(object, "model")
checkmate::assert_count(nsim, positive = TRUE)
checkmate::assert_count(n, positive = TRUE)
Expand All @@ -204,10 +206,6 @@ simulate.cidm_model <- function(object, nsim = 1, seed = NULL, n, ...) {
.with_rt(.generated_list(result), object)
}

#' @rdname simulate.cidm_model
#' @export
simulate.cidm_julia <- simulate.cidm_model

#' Convert bridge output to a draws_df
#'
#' @param values Matrix of draws (rows) by variables (columns).
Expand Down Expand Up @@ -253,7 +251,9 @@ simulate.cidm_julia <- simulate.cidm_model
#' as Julia code has no components to read, so it gets none.
#' @keywords internal
.with_rt <- function(generated, model) {
if (inherits(model, "cidm_julia")) {
# `IDModel()` passes both models positionally, so a specification with no
# positional arguments was written by hand and says nothing about infections.
if (inherits(model, "julia_code") || length(model$args) == 0) {
return(generated)
}
infection <- model$args[[1]]
Expand Down
4 changes: 2 additions & 2 deletions R/id-model.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#' @param observation An observation model, e.g. from
#' [NegativeBinomialError()].
#'
#' @return An object of class `cidm_model`.
#' @return An object of class `julia_model`.
#'
#' @family components
#' @examples
Expand All @@ -28,5 +28,5 @@
IDModel <- function(infection, observation) { # nolint: object_name_linter.
.assert_role(infection, "infection")
.assert_role(observation, "observation")
component("IDModel", infection, observation, role = "model")
julia_spec("IDModel", infection, observation, .role = "model")
}
18 changes: 9 additions & 9 deletions R/infection-models.R
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#' distribution, taken from the distribution's `max` when it has one.
#' @param delta_d Numeric. Discretisation interval width.
#'
#' @return An object of class `cidm_infection`.
#' @return An object of class `julia_infection`.
#'
#' @family components
#' @name infection-models
Expand All @@ -52,14 +52,14 @@ Renewal <- function(generation_time, rt = NULL, initialisation = NULL,
max_name = "D_gen")
rt <- .as_prior_slot(rt)
initialisation <- .as_prior_slot(initialisation)
.assert_role(transformation, "julia", null_ok = TRUE)
.assert_role(transformation, "code", null_ok = TRUE)
args <- list(
generation_time = gen$dist, rt = rt,
initialisation = initialisation, transformation = transformation,
D_gen = if (!is.null(gen$max_delay)) as.numeric(gen$max_delay)
)
args[["\u0394d"]] <- if (!is.null(gen$delta_d)) as.numeric(gen$delta_d)
do.call(component, c("Renewal", args, role = "infection"))
do.call(julia_spec, c("Renewal", args, .role = "infection"))
}

#' @rdname infection-models
Expand All @@ -68,10 +68,10 @@ DirectInfections <- function(Z = NULL, initialisation = NULL,
transformation = NULL) {
Z <- .as_prior_slot(Z)
initialisation <- .as_prior_slot(initialisation)
.assert_role(transformation, "julia", null_ok = TRUE)
component(
.assert_role(transformation, "code", null_ok = TRUE)
julia_spec(
"DirectInfections", Z = Z, initialisation = initialisation,
transformation = transformation, role = "infection"
transformation = transformation, .role = "infection"
)
}

Expand All @@ -81,10 +81,10 @@ ExpGrowthRate <- function(rt = NULL, initialisation = NULL,
transformation = NULL) {
rt <- .as_prior_slot(rt)
initialisation <- .as_prior_slot(initialisation)
.assert_role(transformation, "julia", null_ok = TRUE)
component(
.assert_role(transformation, "code", null_ok = TRUE)
julia_spec(
"ExpGrowthRate", rt = rt, initialisation = initialisation,
transformation = transformation, role = "infection"
transformation = transformation, .role = "infection"
)
}

Expand Down
Loading
Loading