% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/reconc_t.R
\name{reconc_t}
\alias{reconc_t}
\title{t-Rec: reconciliation via conditioning with uncertain covariance via multivariate t-distribution}
\usage{
reconc_t(
  A,
  base_fc_mean,
  y_train = NULL,
  residuals = NULL,
  ...,
  return_upper = FALSE,
  return_parameters = FALSE
)
}
\arguments{
\item{A}{Matrix (n_upp x n_bott) defining the hierarchy (u = Ab).}

\item{base_fc_mean}{Vector of base forecasts (length n = n_upp + n_bott).}

\item{y_train}{mts (or matrix) of historical training data (T x n) used for setting prior parameters.}

\item{residuals}{Matrix (T x n) of base forecast residuals.}

\item{...}{Additional arguments for advanced usage: see details.}

\item{return_upper}{Logical; if TRUE, also returns parameters for the upper-level reconciled distribution.}

\item{return_parameters}{Logical; if TRUE, also returns prior and posterior parameters.}
}
\value{
A list containing:
\itemize{
\item \code{bottom_rec_mean}: reconciled bottom-level mean.
\item \code{bottom_rec_scale_matrix}: reconciled bottom-level scale matrix.
\item \code{bottom_rec_df}: reconciled degrees of freedom.
}
If \code{return_upper} is TRUE, also returns:
\itemize{
\item \code{upper_rec_mean}: reconciled upper-level mean.
\item \code{upper_rec_scale_matrix}: reconciled upper-level scale matrix.
\item \code{upper_rec_df}: reconciled upper-level degrees of freedom.
}
If \code{return_parameters} is TRUE, also returns:
\itemize{
\item \code{prior_nu}: prior degrees of freedom.
\item \code{prior_Psi}: prior scale matrix.
\item \code{posterior_nu}: posterior degrees of freedom.
\item \code{posterior_Psi}: posterior scale matrix.
}
}
\description{
Reconciles base forecasts in a hierarchy by conditioning on the hierarchical
constraints, specified by the aggregation matrix A.
The base forecasts are assumed to be jointly Gaussian, conditionally on the
covariance matrix of the forecast errors.
A Bayesian approach is adopted to account for the uncertainty of the covariance matrix.
An Inverse-Wishart prior is specified on the covariance matrix,
leading to a multivariate t-distribution for the base forecasts.
The reconciliation via conditioning is in closed-form, yielding a multivariate t
reconciled distribution.
}
\details{
\strong{Standard usage.}

The standard workflow for this function is to provide the in-sample \code{residuals}
and the historical training data \code{y_train}.
The parameters of the Inverse-Wishart prior distribution of the covariance matrix
are set as follows:
\itemize{
\item Prior scale matrix (Psi): set as the covariance of the residuals of naive (or seasonal naive,
a criterion is used to choose between the two) forecasts computed on \code{y_train}.
\item Prior degrees of freedom (nu): estimated via Bayesian Leave-One-Out
Cross-Validation (LOOCV) to maximize out-of-sample performance.
}
The posterior distribution of the covariance matrix is still Inverse-Wishart.
The parameters of the posterior are computed in closed-form using the sample
covariance of the provided \code{residuals}.

\strong{Advanced Options.}

Users can bypass the automated estimation by specifying:
\enumerate{
\item \code{prior}: a list with entries 'nu' and 'Psi'.
This skips the LOOCV step for \eqn{\nu_0} and the covariance estimation from \code{y_train}.
It requires \code{residuals} to compute the posterior.
\item \code{posterior}: a list with entries 'nu' and 'Psi'.
This skips all internal estimation and updating logic.
}
Moreover, users can specify:
\itemize{
\item \code{freq}: positive integer, used as frequency of data for the seasonal naive forecast in the specification of the prior scale matrix.
By default, if \code{y_train} is a multivariate time series, the frequency of the data is used; otherwise, it is set to 1 (no seasonality).
\item \code{criterion}: either 'RSS' (default) or 'seas-test', specifying which criterior is used to choose between
the naive and seasonal naive forecasts for the specification of the prior scale matrix.
'RSS' computes the residual sum of squares for both methods and chooses the one with lower RSS,
while 'seas-test' uses a statistical test for seasonality
(currently implemented using the number of seasonal differences suggested by the \code{forecast} package,
which must be installed).
}

\strong{Reconciled distribution.}

The reconciled distribution is a multivariate t-distribution,
specified by a vector of means, a scale matrix, and a number of degrees of freedom.
These parameters are computed in closed-form.
By default, only the parameters of the reconciled distribution for the bottom-level
series are returned. See examples.
}
\examples{

\donttest{
library(bayesRecon)

if (requireNamespace("forecast", quietly = TRUE)) {

  set.seed(1234)
  n_obs <- 100

  # Simulate 2 bottom series from AR(1) processes
  y1 <- arima.sim(model = list(ar = 0.8), n = n_obs)
  y2 <- arima.sim(model = list(ar = 0.5), n = n_obs)

  y_upper <- y1 + y2   # upper series is the sum of the two bottoms
  A <- matrix(c(1, 1), nrow = 1)  # Aggregation matrix

  # Fit additive ETS models
  fit1 <- forecast::ets(y1, additive.only = TRUE)
  fit2 <- forecast::ets(y2, additive.only = TRUE)
  fit_upper <- forecast::ets(y_upper, additive.only = TRUE)

  # Point forecasts (h = 1)
  fc_upper <- as.numeric(forecast::forecast(fit_upper, h = 1)$mean)
  fc1 <- as.numeric(forecast::forecast(fit1, h = 1)$mean)
  fc2 <- as.numeric(forecast::forecast(fit2, h = 1)$mean)
  base_fc_mean <- c(fc_upper, fc1, fc2)

  # Residuals and training data (n_obs x n matrices, columns in same order as base_fc_mean)
  res <- cbind(residuals(fit_upper), residuals(fit1), residuals(fit2))
  y_train <- cbind(y_upper, y1, y2)

  # --- 1) Generate joint reconciled samples ---
  result <- reconc_t(A, base_fc_mean, y_train = y_train, residuals = res)

  # Sample from the reconciled bottom-level t-distribution
  n_samples <- 2000
  L_chol <- t(chol(result$bottom_rec_scale_matrix))
  z <- matrix(rt(ncol(A) * n_samples, df = result$bottom_rec_df), nrow = ncol(A))
  bottom_samples <- result$bottom_rec_mean + L_chol \%*\% z  # 2 x n_samples

  # Aggregate bottom samples to get upper samples
  upper_samples <- A \%*\% bottom_samples              
  joint_samples <- rbind(upper_samples, bottom_samples)
  rownames(joint_samples) <- c("upper", "bottom_1", "bottom_2")

  cat("Reconciled means (from samples):\n")
  print(round(rowMeans(joint_samples), 3))

  cat("Reconciled standard deviations (from samples):\n")
  print(round(apply(joint_samples, 1, sd), 3))

  # --- 2) 95\% prediction intervals via t-distribution quantiles ---
  result2 <- reconc_t(A, base_fc_mean, y_train = y_train,
                      residuals = res, return_upper = TRUE)

  alpha <- 0.05
  # Bottom series intervals
  for (i in seq_len(ncol(A))) {
    s_i <- sqrt(result2$bottom_rec_scale_matrix[i, i])
    lo  <- result2$bottom_rec_mean[i] + s_i * qt(alpha / 2,     df = result2$bottom_rec_df)
    hi  <- result2$bottom_rec_mean[i] + s_i * qt(1 - alpha / 2, df = result2$bottom_rec_df)
    cat(sprintf("Bottom \%d: 95\%\% PI = [\%.3f, \%.3f]\n", i, lo, hi))
  }
  # Upper series interval
  s_u <- sqrt(result2$upper_rec_scale_matrix[1, 1])
  lo  <- result2$upper_rec_mean[1] + s_u * qt(alpha / 2,     df = result2$upper_rec_df)
  hi  <- result2$upper_rec_mean[1] + s_u * qt(1 - alpha / 2, df = result2$upper_rec_df)
  cat(sprintf("Upper:    95\%\% PI = [\%.3f, \%.3f]\n", lo, hi))
}
}

}
\references{
Carrara, C., Corani, G., Azzimonti, D., & Zambon, L. (2025). Modeling the uncertainty on the covariance
matrix for probabilistic forecast reconciliation. arXiv preprint arXiv:2506.19554.
\url{https://arxiv.org/abs/2506.19554}
}
\seealso{
\code{\link[=reconc_gaussian]{reconc_gaussian()}}
}
