Skip to contents

The middle-out forecast reconciliation (Athanasopoulos et al., 2009) combines top-down ([cstd]) and bottom-up ([csbu]) for genuine hierarchical/grouped time series. Given the base forecasts of variables at an intermediate level \(l\), it performs

  • a top-down approach for the levels \(<l\);

  • a bottom-up approach for the levels \(>l\).


csmo(base, agg_mat, id_rows = 1, weights, normalize = TRUE)



A (\(h \times n_l\)) numeric matrix containing the \(l\)-level base forecast; \(n_l\) is the number of variables at level \(l\), and \(h\) is the forecast horizon.


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.


A numeric vector indicating the \(l\)-level rows of agg_mat.


A (\(h \times n_b\)) numeric matrix containing the proportions for the bottom time series; \(h\) is the forecast horizon, and \(n_b\) is the total number of bottom variables.


If TRUE (default), the weights will sum to 1.


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


Athanasopoulos, G., Ahmed, R. A. and Hyndman, R.J. (2009) Hierarchical forecasts for Australian domestic tourism. International Journal of Forecasting 25(1), 146–166. doi:10.1016/j.ijforecast.2008.07.004

See also

Middle-out reconciliation: ctmo(), temo()

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


# 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)
# (3 x 2) top base forecasts vector (simulated), forecast horizon = 3
baseL2 <- matrix(rnorm(2*3, 5), 3, 2)
# Same weights for different forecast horizons
fix_weights <- runif(4)
reco <- csmo(base = baseL2, agg_mat = A, id_rows = 2:3, weights = fix_weights)

# Different weights for different forecast horizons
h_weights <- matrix(runif(4*3), 3, 4)
recoh <- csmo(base = baseL2, agg_mat = A, id_rows = 2:3, weights = h_weights)