danigiro / FoReco

Forecast Reconciliation - Classical (bottom-up), optimal and heuristic combination forecast reconciliation procedures for cross-sectional, temporal, and cross-temporal linearly constrained time series.
https://danigiro.github.io/FoReco/
GNU General Public License v3.0
30 stars 5 forks source link

Constraints for immutable set #6

Closed AngelPone closed 2 months ago

AngelPone commented 3 months ago

In theory, not any user-specified immutable set is feasible. Here are two examples:

  1. Y = A+B. You can not keep immutable for Y, A, and B, and at the same time, give incoherent base forecasts for Y, A, and B.
  2. Y = X1 + X2, X1 = X11 + X12, X2 = X21 + X22. You can not keep X1, X11, X12 to be immutable simultaneously. You can not also keep Y, X1 and X2 to be immutable simutaneously.

In general, the number of immutable series should not be bigger than the number of bottom-level series (or basis time series in general linear constraints). And the immutable set should satisfy some conditions.

AngelPone commented 3 months ago

The code below should raise an error instead of giving user the incoherent base forecasts.

base <- matrix(rnorm(14, mean = c(20, 10, 10)), 2, byrow = TRUE)
res <- t(matrix(rnorm(n = 70), nrow = 7))

A <- rbind(c(1,1, 1, 1), c(1, 1, 0, 0), c(0, 0, 1, 1))
reco <- csrec(base = base, agg_mat = A,immutable = 1:7)
reco
> reco
          s-1       s-2      s-3        s-4       s-5      s-6       s-7
h-1 34.899866  10.69596 28.98481 -46.193154 -6.136965 26.51998 34.420399
h-2  9.434925 -21.07783 11.04862  -5.474498 17.339714 19.32744 -5.459129
attr(,"FoReco")
<environment: 0x1294b31d0>
AngelPone commented 3 months ago

Also, I think when the user pass the 1:7 as the immutable set, the projection can not give results because some matrix are singular. For example, continuing from the code above, keep c(2, 4, 5) to be immutable, which is infeasible,

Ut <- rbind(c(1, 0,0, -1,-1, -1, -1), c(0, 1, 0, -1, -1, 0, 0), 
            c(0, 0, 1, 0, 0, -1, -1))
Ut <- rbind(Ut, c(0, 1, 0, 0, 0, 0, 0), c(0, 0, 0, 1, 0, 0, 0), c(0, 0, 0, 0, 1, 0, 0))
U <- t(Ut)
yhat <- base[1,]
> Ut
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    1    0    0   -1   -1   -1   -1
[2,]    0    1    0   -1   -1    0    0
[3,]    0    0    1    0    0   -1   -1
[4,]    0    1    0    0    0    0    0
[5,]    0    0    0    1    0    0    0
[6,]    0    0    0    0    1    0    0
> ytilde = yhat - U %*% solve(Ut %*% U, Ut %*% yhat - matrix(c(0, 0, 0, yhat[c(2,4,5)]), ncol=1))
Error in solve.default(Ut %*% U, Ut %*% yhat - matrix(c(0, 0, 0, yhat[c(2,  : 
  system is computationally singular: reciprocal condition number = 5.04647e-18

I think there are some issues with the function lin_sys

danigiro commented 3 months ago

The code below should raise an error instead of giving user the incoherent base forecasts.

base <- matrix(rnorm(14, mean = c(20, 10, 10)), 2, byrow = TRUE)
res <- t(matrix(rnorm(n = 70), nrow = 7))

A <- rbind(c(1,1, 1, 1), c(1, 1, 0, 0), c(0, 0, 1, 1))
reco <- csrec(base = base, agg_mat = A,immutable = 1:7)
reco
> reco
          s-1       s-2      s-3        s-4       s-5      s-6       s-7
h-1 34.899866  10.69596 28.98481 -46.193154 -6.136965 26.51998 34.420399
h-2  9.434925 -21.07783 11.04862  -5.474498 17.339714 19.32744 -5.459129
attr(,"FoReco")
<environment: 0x1294b31d0>

Unfortunately, the version you had sent was not general enough and worked with the S matrix which is not always necessary. I think I solved the problem with commit 13c4707 (for all the cases: cross-sectional, temporal and cross-temporal). Please check and let me know.