This function implements the cross-sectional forecast reconciliation procedure that extends the original proposal by Hollyman et al. (2021). Level conditional coherent reconciled forecasts are conditional on (i.e., constrained by) the base forecasts of a specific upper level in the hierarchy (exogenous constraints). It also allows handling the linear constraints linking the variables endogenously (Di Fonzo and Girolimetto, 2022). The function can calculate Combined Conditional Coherent (CCC) forecasts as simple averages of Level-Conditional Coherent (LCC) and bottom-up reconciled forecasts, with either endogenous or exogenous constraints.

## Usage

cslcc(base, agg_mat, nodes = "auto", comb = "ols", res = NULL, CCC = TRUE,
const = "exogenous", bts = NULL, approach = "proj", nn = NULL,
settings = NULL, ...)

## Arguments

base

A ($$h \times n$$) numeric matrix or multivariate time series (mts class) containing the base forecasts to be reconciled; $$h$$ is the forecast horizon, and $$n$$ is the total number of time series ($$n = n_a + n_b$$).

agg_mat

A ($$n_a \times n_b$$) numeric matrix representing the cross-sectional aggregation matrix. It maps the $$n_b$$ bottom-level (free) variables into the $$n_a$$ upper (constrained) variables.

nodes

A ($$L \times 1$$) numeric vector indicating the number of variables in each of the upper $$L$$ levels of the hierarchy. The default value is the string "auto" which calculates the number of variables in each level.

comb

A string specifying the reconciliation method. For a complete list, see [cscov].

res

An ($$N \times n$$) optional numeric matrix containing the in-sample residuals. This matrix is used to compute some covariance matrices.

CCC

A logical value indicating whether the Combined Conditional Coherent reconciled forecasts reconciliation should include bottom-up forecasts (TRUE, default), or not.

const

A string specifying the reconciliation constraints:

• "exogenous" (default): Fixes the top level of each sub-hierarchy.

• "endogenous": Coherently revises both the top and bottom levels.

bts

A ($$h \times n_b$$) numeric matrix or multivariate time series (mts class) containing bottom base forecasts defined by the user (e.g., seasonal averages, as in Hollyman et al., 2021). This parameter can be omitted if only base forecasts are used (see Di Fonzo and Girolimetto, 2024).

approach

A string specifying the approach used to compute the reconciled forecasts. Options include:

• "proj" (default): Projection approach according to Byron (1978, 1979).

• "strc": Structural approach as proposed by Hyndman et al. (2011).

• "proj_osqp": Numerical solution using osqp for projection approach.

• "strc_osqp": Numerical solution using osqp for structural approach.

nn

A string specifying the algorithm to compute non-negative reconciled forecasts:

• "osqp": quadratic programming optimization (osqp solver).

• "sntz": heuristic "set-negative-to-zero" (Di Fonzo and Girolimetto, 2023).

settings

An object of class osqpSettings specifying settings for the osqp solver. For details, refer to the osqp documentation (Stellato et al., 2020).

...

Arguments passed on to cscov

mse

If TRUE (default) the residuals used to compute the covariance matrix are not mean-corrected.

shrink_fun

Shrinkage function of the covariance matrix, [shrink_estim] (default).

## Value

A ($$h \times n$$) numeric matrix of cross-sectional reconciled forecasts.

## References

Byron, R.P. (1978), The estimation of large social account matrices, Journal of the Royal Statistical Society, Series A, 141, 3, 359-367. doi:10.2307/2344807

Byron, R.P. (1979), Corrigenda: The estimation of large social account matrices, Journal of the Royal Statistical Society, Series A, 142(3), 405. doi:10.2307/2982515

Di Fonzo, T. and Girolimetto, D. (2024), Forecast combination-based forecast reconciliation: Insights and extensions, International Journal of Forecasting, 40(2), 490–514. doi:10.1016/j.ijforecast.2022.07.001

Di Fonzo, T. and Girolimetto, D. (2023b) Spatio-temporal reconciliation of solar forecasts. Solar Energy 251, 13–29. doi:10.1016/j.solener.2023.01.003

Hyndman, R.J., Ahmed, R.A., Athanasopoulos, G. and Shang, H.L. (2011), Optimal combination forecasts for hierarchical time series, Computational Statistics & Data Analysis, 55, 9, 2579-2589. doi:10.1016/j.csda.2011.03.006

Hollyman, R., Petropoulos, F. and Tipping, M.E. (2021), Understanding forecast reconciliation. European Journal of Operational Research, 294, 149–160. doi:10.1016/j.ejor.2021.01.017

Stellato, B., Banjac, G., Goulart, P., Bemporad, A. and Boyd, S. (2020), OSQP: An Operator Splitting solver for Quadratic Programs, Mathematical Programming Computation, 12, 4, 637-672. doi:10.1007/s12532-020-00179-2

Level conditional coherent reconciliation: ctlcc(), telcc()

Cross-sectional framework: csboot(), csbu(), cscov(), csmo(), csrec(), cstd(), cstools()

## Examples

set.seed(123)
# Aggregation matrix for Z = X + Y, X = XX + XY and Y = YX + YY
A <- matrix(c(1,1,1,1,1,1,0,0,0,0,1,1), 3, byrow = TRUE)
# (2 x 7) base forecasts matrix (simulated)
base <- matrix(rnorm(7*2, mean = c(40, 20, 20, 10, 10, 10, 10)), 2, byrow = TRUE)
# (10 x 7) in-sample residuals matrix (simulated)
res <- matrix(rnorm(n = 7*10), ncol = 7)
# (2 x 7) Naive bottom base forecasts matrix: all forecasts are set equal to 10
naive <- matrix(10, 2, 4)

## EXOGENOUS CONSTRAINTS (Hollyman et al., 2021)
# Level Conditional Coherent (LCC) reconciled forecasts
exo_LC <- cslcc(base = base, agg_mat = A, comb = "wls", bts = naive,
res = res, nodes = "auto", CCC = FALSE)

# Combined Conditional Coherent (CCC) reconciled forecasts
exo_CCC <- cslcc(base = base, agg_mat = A, comb = "wls", bts = naive,
res = res, nodes = "auto", CCC = TRUE)

# Results detailed by level:
# L-1: Level 1 immutable reconciled forecasts for the whole hierarchy
# L-2: Middle-Out reconciled forecasts
# L-3: Bottom-Up reconciled forecasts
info_exo <- recoinfo(exo_CCC, verbose = FALSE)
info_exo$lcc #>$L-1
#>          s-1      s-2      s-3      s-4      s-5      s-6      s-7
#> h-1 39.43952 19.76757 19.67196 9.893588 9.873979 9.744387 9.927570
#> h-2 38.73494 19.47537 19.25957 9.759815 9.715556 9.423051 9.836517
#> attr(,"FoReco")
#> <environment: 0x14346f960>
#>
#> $L-2 #> s-1 s-2 s-3 s-4 s-5 s-6 s-7 #> h-1 41.32853 19.76982 21.55871 9.894620 9.875202 11.214555 10.344153 #> h-2 38.86749 19.31315 19.55434 9.685546 9.627601 9.652737 9.901601 #> attr(,"FoReco") #> <environment: 0x126f80aa0> #> #>$L-3
#>          s-1     s-2      s-3      s-4      s-5      s-6      s-7
#> h-1 42.37578 20.1998 22.17598 10.07051 10.12929 11.71506 10.46092
#> h-2 42.09535 21.5839 20.51145 11.22408 10.35981 10.40077 10.11068
#> attr(,"FoReco")
#> <environment: 0x126ffcbb8>
#>

## ENDOGENOUS CONSTRAINTS (Di Fonzo and Girolimetto, 2024)
# Level Conditional Coherent (LCC) reconciled forecasts
endo_LC <- cslcc(base = base, agg_mat = A, comb = "wls",
res = res, nodes = "auto", CCC = FALSE,
const = "endogenous")

# Combined Conditional Coherent (CCC) reconciled forecasts
endo_CCC <- cslcc(base = base, agg_mat = A, comb = "wls",
res = res, nodes = "auto", CCC = TRUE,
const = "endogenous")

# Results detailed by level:
# L-1: Level 1 reconciled forecasts for L1 + L3 (bottom level)
# L-2: Level 2 reconciled forecasts for L2 + L3 (bottom level)
# L-3: Bottom-Up reconciled forecasts
info_endo <- recoinfo(endo_CCC, verbose = FALSE)
info_endo$lcc #>$L-1
#>          s-1      s-2      s-3       s-4      s-5       s-6       s-7
#> h-1 40.23685 19.31277 20.92408  9.664411 9.648359 10.739579 10.184505
#> h-2 39.64745 20.56873 19.07871 10.759321 9.809413  9.284371  9.794343
#> attr(,"FoReco")
#> <environment: 0x14428f5d8>
#>
#> $L-2 #> s-1 s-2 s-3 s-4 s-5 s-6 s-7 #> h-1 41.70862 19.94714 21.76149 9.954836 9.992300 11.392087 10.369398 #> h-2 40.11832 20.24956 19.86876 10.613199 9.636364 9.899977 9.968779 #> attr(,"FoReco") #> <environment: 0x1444113a8> #> #>$L-3
#>          s-1     s-2      s-3      s-4      s-5      s-6      s-7
#> h-1 42.37578 20.1998 22.17598 10.07051 10.12929 11.71506 10.46092
#> h-2 42.09535 21.5839 20.51145 11.22408 10.35981 10.40077 10.11068
#> attr(,"FoReco")
#> <environment: 0x144489488>
#>