Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
905091e
usual R behavior that changes the attributes of an object in a non pr…
dazzimonti Mar 11, 2026
3430177
simplified expression to test seasonality
dazzimonti Mar 13, 2026
6931501
new version of README (draft)
LorenzoZambon Mar 13, 2026
d67fc9c
reconc_t stops when Cholesky fails; removed suppress_warnings flag
LorenzoZambon Mar 16, 2026
59cc2e6
removed old figures
LorenzoZambon Mar 17, 2026
17923e0
updated README
LorenzoZambon Mar 17, 2026
a1717c0
updated README
LorenzoZambon Mar 20, 2026
4e196bc
minor update readme
LorenzoZambon Mar 20, 2026
63b7357
Minor fixes to readme
dazzimonti Mar 26, 2026
7fbfb2e
updated readme
LorenzoZambon Mar 27, 2026
c7199be
Merge pull request #29 from IDSIA/dev_bugs_v1_readme
LorenzoZambon Mar 27, 2026
b32eb06
minor update to README
LorenzoZambon Mar 27, 2026
7b8299c
updated descriptions of reconciliation functions in readme and bayesR…
LorenzoZambon Mar 27, 2026
001d678
changed output reconc_gaussian: covariance -> cov
LorenzoZambon Mar 27, 2026
42d4490
First version of t-rec vignette, added suggests for ggplot2 in DESCRI…
dazzimonti Apr 2, 2026
41d2368
minor changes to vignette t-rec
LorenzoZambon Apr 2, 2026
4ba361d
Updated vignette
dazzimonti Apr 9, 2026
58952ab
updated t-rec vignette
LorenzoZambon Apr 9, 2026
53e4de2
Fixed bug and updated text in documentation
dazzimonti Apr 14, 2026
fa07d1a
minor update vignette t-rec
LorenzoZambon Apr 14, 2026
80e1711
updated PMF_get_quantile to take also a vector of probabilities.
dazzimonti Apr 16, 2026
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
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Suggests:
forecast,
glarma,
scoringRules,
ggplot2,
testthat (>= 3.0.0)
Config/testthat/edition: 3
VignetteBuilder: knitr
Expand Down
7 changes: 4 additions & 3 deletions R/PMF.R
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ PMF_from_params <- function(params, distr, Rtoll = .RTOLL) {
#'
#' @param pmf A PMF object (numeric vector where element j+1 is the probability of value j).
#' @param N_samples Number of samples to draw from the PMF.
#' @param p Probability level for quantile computation (between 0 and 1).
#' @param p Probability level for quantile computation. Either a number or a vector with all elements between 0 and 1.
#' @param Ltoll Lower tolerance for computing the minimum of the PMF (default: 1e-15).
#' @param Rtoll Upper tolerance for computing the maximum of the PMF (default: 1e-9).
#'
Expand Down Expand Up @@ -189,6 +189,7 @@ PMF_from_params <- function(params, distr, Rtoll = .RTOLL) {
#' Computes the quantile of the distribution at probability level \code{p}.
#' Returns the smallest value \code{x} such that the cumulative probability up to \code{x}
#' is greater than or equal to \code{p}. For example, \code{p=0.5} gives the median.
#' The parameter \code{p} can be a single number or a vector of probabilities.
#' }
#'
#' \item{\code{PMF_summary(pmf, Ltoll, Rtoll)}}{
Expand Down Expand Up @@ -225,11 +226,11 @@ PMF_get_var <- function(pmf) {
#' @rdname PMF
#' @export
PMF_get_quantile <- function(pmf, p) {
if (p <= 0 | p >= 1) {
if (min(p) <= 0 | max(p) >= 1) {
stop("Input error: probability p must be between 0 and 1")
}
cdf <- cumsum(pmf)
x <- min(which(cdf >= p))
x <- pmin(findInterval(p, cdf) + 1, length(cdf))
return(x - 1)
}

Expand Down
20 changes: 10 additions & 10 deletions R/bayesRecon-package.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
#' @section Reconciliation functions:
#'
#' The package implements reconciliation via conditioning for probabilistic forecasts
#' of hierarchical time series. The main functions are:
#' of hierarchical time series. The reconciliation functions are:
#'
#' * [reconc_gaussian()]: reconciliation via conditioning, assumes multivariate Gaussian
#' * [reconc_gaussian()]: reconciliation via conditioning assuming multivariate Gaussian
#' base forecasts; this is done analytically;
#' * [reconc_t()]: reconciliation via conditioning assuming multivariate Gaussian
#' base forecasts with uncertain covariance matrix;
#' the reconciled forecasts are multivariate Student-t; this is done analytically;
#' * [reconc_BUIS()]: reconciliation via conditioning of any probabilistic forecast
#' via importance sampling; this is the recommended option for non-Gaussian base forecasts;
#' * [reconc_MCMC()]: reconciliation via conditioning of discrete probabilistic
#' forecasts via Markov Chain Monte Carlo;
#' * [reconc_MixCond()]: reconciliation via conditioning of mixed hierarchies, where
#' via bottom-up importance sampling; an alternative method for discrete forecasts
#' is implemented in [reconc_MCMC()], but we recommend using `reconc_BUIS`;
#' * [reconc_MixCond()] and [reconc_TDcond()]: reconciliation of mixed hierarchies, where
#' the upper forecasts are multivariate Gaussian and the bottom forecasts are discrete distributions;
#' * [reconc_TDcond()]: reconciliation via top-down conditioning of mixed hierarchies, where
#' the upper forecasts are multivariate Gaussian and the bottom forecasts are discrete distributions;
#' * [reconc_t()]: reconciliation via conditioning with uncertain covariance matrix;
#' the reconciled forecasts are multivariate Student-t; this is done analytically.
#' `reconc_MixCond` implements conditioning via importance sampling,
#' while `reconc_TDcond` implements top-down conditioning.
#'
#' @section Utility functions:
#'
Expand Down
2 changes: 1 addition & 1 deletion R/reconc_TDcond.R
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ reconc_TDcond <- function(A, base_fc_bottom, base_fc_upper,
U <- .MVN_sample(
n_samples = num_samples,
mu = rec_gauss_u$bottom_rec_mean,
Sigma = rec_gauss_u$bottom_rec_covariance
Sigma = rec_gauss_u$bottom_rec_cov
)
U <- round(U) # round
mode(U) <- "integer" # convert to integer
Expand Down
14 changes: 7 additions & 7 deletions R/reconc_gaussian.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
#' @return A list containing the reconciled forecasts. The list has the following named elements:
#'
#' * `bottom_rec_mean`: reconciled mean for the bottom forecasts;
#' * `bottom_rec_covariance`: reconciled covariance for the bottom forecasts;
#' * `bottom_rec_cov`: reconciled covariance for the bottom forecasts;
#' * `upper_rec_mean`: (only if `return_upper = TRUE`) reconciled mean for the upper forecasts;
#' * `upper_rec_covariance`: (only if `return_upper = TRUE`) reconciled covariance for the upper forecasts.
#' * `upper_rec_cov`: (only if `return_upper = TRUE`) reconciled covariance for the upper forecasts.
#'
#'
#' @examples
Expand Down Expand Up @@ -55,7 +55,7 @@
#' )
#'
#' bottom_mean_rec <- analytic_rec$bottom_rec_mean
#' bottom_cov_rec <- analytic_rec$bottom_rec_covariance
#' bottom_cov_rec <- analytic_rec$bottom_rec_cov
#'
#' # To obtain reconciled samples for the entire hierarchy, sample from the reconciled
#' # bottom distribution and then aggregate using A.
Expand Down Expand Up @@ -110,9 +110,9 @@
#' result <- reconc_gaussian(A, base_fc_mean = base_fc_mean, residuals = res, return_upper = TRUE)
#'
#' bottom_mean <- result$bottom_rec_mean
#' bottom_cov <- result$bottom_rec_covariance
#' bottom_cov <- result$bottom_rec_cov
#' upper_mean <- result$upper_rec_mean
#' upper_cov <- result$upper_rec_covariance
#' upper_cov <- result$upper_rec_cov
#'
#' # Print reconciled means
#' cat("Reconciled bottom means:", round(bottom_mean, 3), "\n")
Expand Down Expand Up @@ -203,12 +203,12 @@ reconc_gaussian <- function(A, base_fc_mean,

out <- list(
bottom_rec_mean = as.vector(mu_b_tilde),
bottom_rec_covariance = Sigma_b_tilde
bottom_rec_cov = Sigma_b_tilde
)

if (return_upper) {
out$upper_rec_mean <- as.vector(A %*% mu_b_tilde)
out$upper_rec_covariance <- A %*% Sigma_b_tilde %*% t(A)
out$upper_rec_cov <- A %*% Sigma_b_tilde %*% t(A)
}

return(out)
Expand Down
21 changes: 8 additions & 13 deletions R/reconc_t.R
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@
)
}
# Seasonality test for each time series
is_seas = as.logical(apply(stats::ts(y_train, frequency = freq), 2,
function(col) forecast::nsdiffs(col)))
is_seas = as.logical(apply(y_train, 2,
function(col) forecast::nsdiffs(stats::ts(col,frequency = freq))))

} else if (criterion == "RSS") {
# Compute RSS for both methods, for each series
Expand Down Expand Up @@ -453,8 +453,7 @@ reconc_t <- function(A,

out <- .core_reconc_t(
A = A, base_fc_mean = base_fc_mean, Psi_post = Psi_post, nu_post = nu_post,
return_upper = return_upper, suppress_warnings = FALSE
)
return_upper = return_upper)

if (return_parameters) {
if(!is.null(posterior)) {
Expand Down Expand Up @@ -483,7 +482,6 @@ reconc_t <- function(A,
#' multivariate t-distribution.
#' @param nu_post Degrees of freedom of the posterior multivariate t-distribution.
#' @param return_upper Logical, whether to return the reconciled parameters for the upper variables (default is FALSE).
#' @param suppress_warnings Logical. If TRUE, suppresses warnings about numerical issues. Default is FALSE.
#'
#' @return A list containing:
#' \itemize{
Expand All @@ -501,7 +499,7 @@ reconc_t <- function(A,
#' @keywords internal
#' @export
.core_reconc_t <- function(A, base_fc_mean, Psi_post, nu_post, return_upper = FALSE,
return_parameters = FALSE, suppress_warnings = FALSE) {
return_parameters = FALSE) {
# Indices for Upper and Bottom
k <- nrow(A)
m <- ncol(A)
Expand All @@ -524,15 +522,12 @@ reconc_t <- function(A,

# Invert Q using Cholesky (should be p.d.)
Q_chol <- tryCatch(chol(Q), error = function(e) NULL)
# If Cholesky fails, stop
if (is.null(Q_chol)) {
# Fallback to standard solve if Cholesky fails (numerical issues)
if (!suppress_warnings) {
warning("Cholesky decomposition of Q failed; using standard inversion.")
}
inv_Q <- solve(Q)
} else {
inv_Q <- chol2inv(Q_chol)
stop("A numerical error occured during a Cholesky decomposition.
This may be due to redundant aggregated series.")
}
inv_Q <- chol2inv(Q_chol)

# Incoherence
delta <- (A %*% b_hat) - u_hat
Expand Down
Loading
Loading