Skip to content

Commit

Permalink
Defer inclusion of generated quantity code (#364)
Browse files Browse the repository at this point in the history
  • Loading branch information
gowerc authored Jun 21, 2024
1 parent 36864eb commit fe04d4a
Show file tree
Hide file tree
Showing 22 changed files with 269 additions and 116 deletions.
7 changes: 7 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,15 @@ S3method(coalesceGridTime,GridPrediction)
S3method(coalesceGridTime,default)
S3method(compileStanModel,JointModel)
S3method(dim,Quantities)
S3method(enableGQ,JointModel)
S3method(enableGQ,LongitudinalGSF)
S3method(enableGQ,LongitudinalRandomSlope)
S3method(enableGQ,LongitudinalSteinFojo)
S3method(enableGQ,default)
S3method(enableLink,LongitudinalGSF)
S3method(enableLink,LongitudinalRandomSlope)
S3method(enableLink,LongitudinalSteinFojo)
S3method(enableLink,default)
S3method(extractVariableNames,DataSubject)
S3method(extractVariableNames,DataSurvival)
S3method(generateQuantities,JointModelSamples)
Expand Down Expand Up @@ -202,6 +208,7 @@ export(as_stan_list)
export(autoplot)
export(brierScore)
export(compileStanModel)
export(enableGQ)
export(enableLink)
export(generateQuantities)
export(getParameters)
Expand Down
15 changes: 10 additions & 5 deletions R/JointModel.R
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,24 @@ JointModel <- function(
}


#' @export
enableGQ.JointModel <- function(object, ...) {
merge(
enableGQ(object@survival),
enableGQ(object@longitudinal)
)
}


#' `JointModel` -> `StanModule`
#'
#' Converts a [`JointModel`] object to a [`StanModule`] object
#'
#' @inheritParams JointModel-Shared
#' @param include_gq (`logical`)\cr whether to include the generated quantities block.
#' @family JointModel
#' @family as.StanModule
#' @export
as.StanModule.JointModel <- function(object, include_gq = FALSE, ...) {
as.StanModule.JointModel <- function(object, ...) {

base_model <- read_stan("base/base.stan")

Expand All @@ -113,9 +121,6 @@ as.StanModule.JointModel <- function(object, include_gq = FALSE, ...) {
StanModule(stan_full)
)

if (!include_gq) {
x@generated_quantities <- ""
}
return(x)
}

Expand Down
10 changes: 7 additions & 3 deletions R/JointModelSamples.R
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,13 @@ generateQuantities.JointModelSamples <- function(object, generator, type, ...) {
) |>
StanModule()

stanobj <- merge(
as.StanModule(object@model, include_gq = TRUE),
quant_stanobj
stanobj <- Reduce(
merge,
list(
as.StanModule(object@model),
enableGQ(object@model),
quant_stanobj
)
)

model <- compileStanModel(stanobj)
Expand Down
7 changes: 7 additions & 0 deletions R/LongitudinalGSF.R
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ LongitudinalGSF <- function(
}



#' @export
enableGQ.LongitudinalGSF <- function(object, ...) {
StanModule("lm-gsf/quantities.stan")
}


#' @export
enableLink.LongitudinalGSF <- function(object, ...) {
object@stan <- merge(
Expand Down
5 changes: 5 additions & 0 deletions R/LongitudinalRandomSlope.R
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ LongitudinalRandomSlope <- function(
}


#' @export
enableGQ.LongitudinalRandomSlope <- function(object, ...) {
StanModule("lm-random-slope/quantities.stan")
}

#' @export
enableLink.LongitudinalRandomSlope <- function(object, ...) {
object@stan <- merge(
Expand Down
5 changes: 5 additions & 0 deletions R/LongitudinalSteinFojo.R
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ LongitudinalSteinFojo <- function(



#' @export
enableGQ.LongitudinalSteinFojo <- function(object, ...) {
StanModule("lm-stein-fojo/quantities.stan")
}

#' @export
enableLink.LongitudinalSteinFojo <- function(object, ...) {
object@stan <- merge(
Expand Down
21 changes: 21 additions & 0 deletions R/generics.R
Original file line number Diff line number Diff line change
Expand Up @@ -410,11 +410,32 @@ resolvePromise.default <- function(object, ...) {
enableLink <- function(object, ...) {
UseMethod("enableLink")
}
#' @export
enableLink.default <- function(object, ...) {
object
}


#' Enable Generated Quantities Generic
#'
#' @param object ([`StanModel`])\cr to enable generated quantities for.
#' @param ... Not used.
#'
#' Optional hook method that is called on a [`StanModel`] if attempting to use
#' either [`LongitudinalQuantities`] or [`SurvivalQuantities`]
#'
#' @return [`StanModule`] object
#'
#' @export
enableGQ <- function(object, ...) {
UseMethod("enableGQ")
}
#' @export
enableGQ.default <- function(object, ...) {
StanModule()
}



#' Get Prediction Names
#'
Expand Down
1 change: 1 addition & 0 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ reference:
- sampleObservations
- sampleSubjects
- enableLink
- enableGQ
- as_formula
- getPredictionNames

Expand Down
10 changes: 0 additions & 10 deletions inst/stan/lm-gsf/functions.stan
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,5 @@ functions {
);
return result;
}

vector lm_predict_value(vector time, matrix long_gq_parameters) {
return sld(
time,
long_gq_parameters[,1],
long_gq_parameters[,2],
long_gq_parameters[,3],
long_gq_parameters[,4]
);
}
}

18 changes: 0 additions & 18 deletions inst/stan/lm-gsf/model.stan
Original file line number Diff line number Diff line change
Expand Up @@ -94,21 +94,3 @@ model {
lm_gsf_psi_phi ~ beta(lm_gsf_a_phi[subject_arm_index], lm_gsf_b_phi[subject_arm_index]);
}


generated quantities {
//
// Source - lm-gsf/model.stan
//
matrix[n_subjects, 4] long_gq_parameters;
long_gq_parameters[, 1] = lm_gsf_psi_bsld;
long_gq_parameters[, 2] = lm_gsf_psi_ks;
long_gq_parameters[, 3] = lm_gsf_psi_kg;
long_gq_parameters[, 4] = lm_gsf_psi_phi;


matrix[gq_n_quant, 4] long_gq_pop_parameters;
long_gq_pop_parameters[, 1] = exp(lm_gsf_mu_bsld[gq_long_pop_study_index]);
long_gq_pop_parameters[, 2] = exp(lm_gsf_mu_ks[gq_long_pop_arm_index]);
long_gq_pop_parameters[, 3] = exp(lm_gsf_mu_kg[gq_long_pop_arm_index]);
long_gq_pop_parameters[, 4] = lm_gsf_a_phi[gq_long_pop_arm_index] ./ (lm_gsf_a_phi[gq_long_pop_arm_index] + lm_gsf_b_phi[gq_long_pop_arm_index]);
}
29 changes: 29 additions & 0 deletions inst/stan/lm-gsf/quantities.stan
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
functions {
vector lm_predict_value(vector time, matrix long_gq_parameters) {
return sld(
time,
long_gq_parameters[,1],
long_gq_parameters[,2],
long_gq_parameters[,3],
long_gq_parameters[,4]
);
}
}

generated quantities {
//
// Source - lm-gsf/quantities.stan
//
matrix[n_subjects, 4] long_gq_parameters;
long_gq_parameters[, 1] = lm_gsf_psi_bsld;
long_gq_parameters[, 2] = lm_gsf_psi_ks;
long_gq_parameters[, 3] = lm_gsf_psi_kg;
long_gq_parameters[, 4] = lm_gsf_psi_phi;


matrix[gq_n_quant, 4] long_gq_pop_parameters;
long_gq_pop_parameters[, 1] = exp(lm_gsf_mu_bsld[gq_long_pop_study_index]);
long_gq_pop_parameters[, 2] = exp(lm_gsf_mu_ks[gq_long_pop_arm_index]);
long_gq_pop_parameters[, 3] = exp(lm_gsf_mu_kg[gq_long_pop_arm_index]);
long_gq_pop_parameters[, 4] = lm_gsf_a_phi[gq_long_pop_arm_index] ./ (lm_gsf_a_phi[gq_long_pop_arm_index] + lm_gsf_b_phi[gq_long_pop_arm_index]);
}
24 changes: 0 additions & 24 deletions inst/stan/lm-random-slope/model.stan
Original file line number Diff line number Diff line change
@@ -1,15 +1,4 @@

functions {
//
// Source - lm-random-slope/model.stan
//
vector lm_predict_value(vector time, matrix long_gq_parameters) {
int nrow = rows(time);
return (
long_gq_parameters[, 1] + long_gq_parameters[, 2] .* time
);
}
}


parameters {
Expand Down Expand Up @@ -61,16 +50,3 @@ model {
}


generated quantities {
//
// Source - lm-random-slope/model.stan
//
matrix[n_subjects, 2] long_gq_parameters;
long_gq_parameters[, 1] = lm_rs_ind_intercept;
long_gq_parameters[, 2] = lm_rs_ind_rnd_slope;


matrix[gq_n_quant, 2] long_gq_pop_parameters;
long_gq_pop_parameters[, 1] = to_vector(lm_rs_intercept[gq_long_pop_study_index]);
long_gq_pop_parameters[, 2] = to_vector(lm_rs_slope_mu[gq_long_pop_arm_index]);
}
26 changes: 26 additions & 0 deletions inst/stan/lm-random-slope/quantities.stan
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

functions {
//
// Source - lm-random-slope/quantities.stan
//
vector lm_predict_value(vector time, matrix long_gq_parameters) {
int nrow = rows(time);
return (
long_gq_parameters[, 1] + long_gq_parameters[, 2] .* time
);
}
}

generated quantities {
//
// Source - lm-random-slope/quantities.stan
//
matrix[n_subjects, 2] long_gq_parameters;
long_gq_parameters[, 1] = lm_rs_ind_intercept;
long_gq_parameters[, 2] = lm_rs_ind_rnd_slope;


matrix[gq_n_quant, 2] long_gq_pop_parameters;
long_gq_pop_parameters[, 1] = to_vector(lm_rs_intercept[gq_long_pop_study_index]);
long_gq_pop_parameters[, 2] = to_vector(lm_rs_slope_mu[gq_long_pop_arm_index]);
}
8 changes: 0 additions & 8 deletions inst/stan/lm-stein-fojo/functions.stan
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,5 @@ functions {
);
return result;
}
vector lm_predict_value(vector time, matrix long_gq_parameters) {
return sld(
time,
long_gq_parameters[,1],
long_gq_parameters[,2],
long_gq_parameters[,3]
);
}
}

14 changes: 0 additions & 14 deletions inst/stan/lm-stein-fojo/model.stan
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,3 @@ model {
{%- endif -%}
}

generated quantities {
//
// Source - lm-stein-fojo/model.stan
//
matrix[n_subjects, 3] long_gq_parameters;
long_gq_parameters[, 1] = lm_gsf_psi_bsld;
long_gq_parameters[, 2] = lm_gsf_psi_ks;
long_gq_parameters[, 3] = lm_gsf_psi_kg;

matrix[gq_n_quant, 3] long_gq_pop_parameters;
long_gq_pop_parameters[, 1] = exp(lm_sf_mu_bsld[gq_long_pop_study_index]);
long_gq_pop_parameters[, 2] = exp(lm_sf_mu_ks[gq_long_pop_arm_index]);
long_gq_pop_parameters[, 3] = exp(lm_sf_mu_kg[gq_long_pop_arm_index]);
}
26 changes: 26 additions & 0 deletions inst/stan/lm-stein-fojo/quantities.stan
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

functions {
vector lm_predict_value(vector time, matrix long_gq_parameters) {
return sld(
time,
long_gq_parameters[,1],
long_gq_parameters[,2],
long_gq_parameters[,3]
);
}
}

generated quantities {
//
// Source - lm-stein-fojo/quantities.stan
//
matrix[n_subjects, 3] long_gq_parameters;
long_gq_parameters[, 1] = lm_gsf_psi_bsld;
long_gq_parameters[, 2] = lm_gsf_psi_ks;
long_gq_parameters[, 3] = lm_gsf_psi_kg;

matrix[gq_n_quant, 3] long_gq_pop_parameters;
long_gq_pop_parameters[, 1] = exp(lm_sf_mu_bsld[gq_long_pop_study_index]);
long_gq_pop_parameters[, 2] = exp(lm_sf_mu_ks[gq_long_pop_arm_index]);
long_gq_pop_parameters[, 3] = exp(lm_sf_mu_kg[gq_long_pop_arm_index]);
}
4 changes: 1 addition & 3 deletions man/as.StanModule.JointModel.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions man/enableGQ.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit fe04d4a

Please sign in to comment.