|
3 | 3 | #' Create a new set of live points/particles for a new nested sampling run, or |
4 | 4 | #' check the current state of the live points before continuing a previous run. |
5 | 5 | #' |
6 | | -#' @param object An object of class `ernest_sampler`. |
| 6 | +#' @param object (ernest_sampler) An object of class `ernest_sampler`. |
7 | 7 | #' @inheritParams rlang::args_dots_empty |
8 | | -#' @param seed Either a single value, interpretted as an integer, or `NA` or |
9 | | -#' `NULL`. |
10 | | -#' * If an integer or NULL, `seed` is passed to [set.seed()] to set the state |
11 | | -#' of the random number generator. `NULL` reinitializes the generator as if |
| 8 | +#' @param seed (integer or NA, optional) Specification for the random number |
| 9 | +#' generator. |
| 10 | +#' * integer: Passed to [set.seed()]. |
| 11 | +#' * `NULL`: Passed to [set.seed()], which reinitializes the generator as if |
12 | 12 | #' no seed has yet been set. |
13 | | -#' * If `NA`, the random number generator is set with the seed stored in the |
14 | | -#' `ernest_run` object bound to `object`. If this object does not exist (i.e., |
15 | | -#' if not prior runs have been performed), the current state of the generator |
16 | | -#' is recorded and stored for future objects. |
17 | | -#' @param clear A logical value indicating whether to reload `object` before |
18 | | -#' creating new live points. If `TRUE`, former results from the sampler are |
19 | | -#' removed from the object. If `FALSE`, the sampler will not drop prior results, |
20 | | -#' and continue using live points from the last sampling iteration performed. |
| 13 | +#' * `NA`: Make no changes to the current seed if set. If `compile` has been |
| 14 | +#' called on `object` before, then `NA` will ensure that the seed remain |
| 15 | +#' identical between runs. |
| 16 | +#' @param clear (boolean) Whether to reset the sampler before compiling. |
| 17 | +#' * `TRUE`: Previous results stored in `object` are removed, and live points |
| 18 | +#' are generated and validated. |
| 19 | +#' * `FALSE`: Previous results stored in `object` are retained, and live points |
| 20 | +#' are validated. |
21 | 21 | #' |
22 | 22 | #' @details |
23 | 23 | #' The `compile` function prepares an `ernest_sampler` object for nested |
24 | 24 | #' sampling by ensuring that its set of live points is valid and ready for use. |
25 | | -#' In addition to constructing the live point set for new runs, the live points |
26 | | -#' are validated for a number of conditions: |
| 25 | +#' In addition to constructing the live point set for new runs or when |
| 26 | +#' `clear = FALSE`, compile also ensures that: |
27 | 27 | #' |
28 | | -#' * Ensures that the points are each represented within the unit hypercube. |
29 | | -#' * Ensures that the wrapped likelihood function `ernest_likelihood` has a |
30 | | -#' valid return value for each point (finite double or `-Inf`). |
31 | | -#' * Ensures that the likelihood isn't at a plateau, warning you if there are |
32 | | -#' duplicate likelihood values. |
| 28 | +#' * The live points are each represented within the unit hypercube. |
| 29 | +#' * The wrapped likelihood function `ernest_likelihood` has a valid return |
| 30 | +#' value for each point (either a finite double or `-Inf`). |
| 31 | +#' * The live points don't represent a perfect plateau (i.e., all points share |
| 32 | +#' the same likelihood). You are warned if more than 25% of the points |
| 33 | +#' share the same likelihood value. |
33 | 34 | #' |
34 | | -#' If `compile` fails these validation steps, the function will fail and the |
35 | | -#' set of live points will be removed from `object` with an informative error |
36 | | -#' message encouraging you to run the sampler from scratch with `clear = TRUE`. |
| 35 | +#' If `compile` fails these validation steps, the set of live points will be |
| 36 | +#' removed from `object`, preventing you from calling [generate()] on a |
| 37 | +#' malformed sampler. |
| 38 | +#' |
| 39 | +#' Random number generation can be seeded either through the `seed` argument, |
| 40 | +#' or by calling [set.seed()] before running `compile` or `generate`. |
37 | 41 | #' |
38 | 42 | #' @returns `object`, invisibly. |
39 | 43 | #' @examples |
@@ -67,7 +71,7 @@ compile.ernest_sampler <- function(object, ..., seed = NA, clear = FALSE) { |
67 | 71 | #' @return A list containing `unit`, `point`, and `log_lik` matrices/vectors. |
68 | 72 | #' @noRd |
69 | 73 | create_live <- function(lrps, n_points, call = caller_env()) { |
70 | | - rlang::try_fetch( |
| 74 | + try_fetch( |
71 | 75 | lrps$propose_uniform(criteria = rep(-1e300, n_points)), |
72 | 76 | error = function(cnd) { |
73 | 77 | cli::cli_abort( |
@@ -100,64 +104,59 @@ create_live <- function(lrps, n_points, call = caller_env()) { |
100 | 104 | #' NULL. |
101 | 105 | #' @noRd |
102 | 106 | check_live <- function(unit, log_lik, n_points, n_var, call = caller_env()) { |
103 | | - # Check live point matrix. |
104 | | - if (!is.numeric(unit) || !is.matrix(unit)) { |
105 | | - stop_input_type(unit, "a numeric matrix", call = call) |
106 | | - } |
107 | | - if (ncol(unit) != n_var || nrow(unit) != n_points) { |
108 | | - cli::cli_abort( |
109 | | - c( |
110 | | - "Live points matrix must have dim. {n_points} x {n_var}.", |
111 | | - "x" = "Points are currently {nrow(unit)} x {ncol(unit)}." |
112 | | - ), |
113 | | - call = call |
114 | | - ) |
115 | | - } |
116 | | - if (!all(is.finite(unit))) { |
117 | | - cli::cli_abort( |
118 | | - "Live points matrix must only contain finite values.", |
119 | | - call = call |
120 | | - ) |
| 107 | + # Check live point matrix using checkmate. |
| 108 | + msg <- checkmate::check_matrix( |
| 109 | + unit, |
| 110 | + mode = "numeric", |
| 111 | + nrows = n_points, |
| 112 | + ncols = n_var, |
| 113 | + any.missing = FALSE, |
| 114 | + all.missing = FALSE |
| 115 | + ) |
| 116 | + if (!isTRUE(msg)) { |
| 117 | + format_checkmate(msg, "unit", call = call) |
121 | 118 | } |
122 | | - if (any(unit < 0 | unit > 1)) { |
123 | | - cli::cli_abort( |
124 | | - "Live points matrix must only contain values between 0 and 1.", |
125 | | - call = call |
126 | | - ) |
| 119 | + msg <- checkmate::check_numeric( |
| 120 | + unit, |
| 121 | + lower = 0, |
| 122 | + upper = 1, |
| 123 | + any.missing = FALSE, |
| 124 | + all.missing = FALSE, |
| 125 | + finite = TRUE |
| 126 | + ) |
| 127 | + if (!isTRUE(msg)) { |
| 128 | + format_checkmate(msg, "unit", call = call) |
127 | 129 | } |
128 | 130 |
|
129 | | - if (!is_double(log_lik, n = n_points)) { |
130 | | - cli::cli_abort( |
131 | | - c( |
132 | | - "`log_lik` must be a double vector of length {n_points}", |
133 | | - "!" = "You provided {obj_type_friendly(log_lik)}." |
134 | | - ), |
135 | | - call = call |
136 | | - ) |
| 131 | + msg <- checkmate::check_numeric( |
| 132 | + log_lik, |
| 133 | + len = n_points, |
| 134 | + any.missing = FALSE, |
| 135 | + all.missing = FALSE |
| 136 | + ) |
| 137 | + if (!isTRUE(msg)) { |
| 138 | + format_checkmate(msg, "log_lik", call = call) |
137 | 139 | } |
138 | 140 | if (any(!is.finite(log_lik) & log_lik != -Inf)) { |
139 | | - n_nonfinite <- sum(!is.finite(log_lik) & log_lik != -Inf) |
140 | | - cli::cli_abort( |
141 | | - c( |
142 | | - "Live points' log-likelihoods must be finite or -Inf.", |
143 | | - "x" = "Found {n_nonfinite} non-finite values." |
144 | | - ), |
| 141 | + nonfinite <- unique(log_lik[!is.finite(log_lik) & log_lik != -Inf]) |
| 142 | + cli_abort( |
| 143 | + "`{log_lik}` must contain only finite values or -Inf, not {nonfinite}.", |
145 | 144 | call = call |
146 | 145 | ) |
147 | 146 | } |
148 | 147 |
|
149 | 148 | n_unique <- vctrs::vec_unique_count(log_lik) |
150 | 149 | if (n_unique == 1L) { |
151 | | - cli::cli_abort( |
| 150 | + cli_abort( |
152 | 151 | c( |
153 | 152 | "Log likelihoods of the live points must not be a plateau.", |
154 | | - "x" = "Log likelihood of all {n_points} points = {log_lik[1]}." |
| 153 | + "!" = "Log likelihood of all {n_points} points = {log_lik[1]}." |
155 | 154 | ), |
156 | 155 | call = call |
157 | 156 | ) |
158 | 157 | } |
159 | 158 | if (n_unique < (n_points * 0.75)) { |
160 | | - cli::cli_warn( |
| 159 | + cli_warn( |
161 | 160 | c( |
162 | 161 | "Potential likelihood plateau; proceed with caution.", |
163 | 162 | "!" = "{n_unique} unique likelihoods across {n_points} live points." |
|
0 commit comments