-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathmint.R
81 lines (69 loc) · 2.16 KB
/
mint.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# All the functions needed to compute the MinT forecasts.
compute_pmint <- function(objhts, method = "diagonal", residuals){
J <- Matrix(cbind(matrix(0, nrow = objhts$nbts, ncol = objhts$nts - objhts$nbts), diag(objhts$nbts)), sparse = TRUE)
U <- Matrix(rbind(diag(objhts$nts - objhts$nbts), -t(objhts$A)), sparse = TRUE)
P_BU <- cbind(matrix(0, objhts$nbts, objhts$nts - objhts$nbts), diag(objhts$nbts))
#if(!is.null(residuals))
# R1 <- t(residuals)
R1 <- t(residuals)
if(is.null(method))
method <- "diagonal"
if(method == "diagonal"){
# Diagonal matrix
W <- Diagonal(x = vec_w(R1))
}else if(method == "shrink"){
# Shrunk matrix
target_diagonal <- lowerD(R1)
shrink_results <- shrink.estim(R1, target_diagonal)
W <- shrink_results$shrink.cov
}else if(method == "ols"){
W <- diag(objhts$nts)
}else if(method == "sample"){
n <- nrow(R1)
W <- crossprod(R1) / n
if(is.positive.definite(W)==FALSE)
{
stop("MinT needs covariance matrix to be positive definite.", call. = FALSE)
}
}
MAT1 <- W %*% U
MAT2 <- crossprod(U,MAT1)
MAT3 <- tcrossprod(solve(MAT2), U)
C1 <- J %*% MAT1
P_MINT <- P_BU - C1 %*% MAT3
S <- objhts$S
n_agg <- objhts$naggts
n_total <- objhts$nts
V <- S %*% P_MINT %*% W %*% t(P_MINT) %*% t(S)
#V_agg <- diag(V)[seq(n_agg)]
#V_bot <- diag(V)[seq(n_agg + 1, n_total)]
#list(V_agg = V_agg, V_bot = V_bot)
list(P_MINT = P_MINT, W = W, V = V)
}
shrink.estim <- function(x, tar)
{
if (is.matrix(x) == TRUE && is.numeric(x) == FALSE)
stop("The data matrix must be numeric!")
p <- ncol(x)
n <- nrow(x)
covm <- crossprod(x) / n
corm <- cov2cor(covm)
xs <- scale(x, center = FALSE, scale = sqrt(diag(covm)))
v <- (1/(n * (n - 1))) * (crossprod(xs^2) - 1/n * (crossprod(xs))^2)
diag(v) <- 0
corapn <- cov2cor(tar)
d <- (corm - corapn)^2
lambda <- sum(v)/sum(d)
lambda <- max(min(lambda, 1), 0)
shrink.cov <- lambda * tar + (1 - lambda) * covm
return(list(shrink.cov = shrink.cov, lambda = lambda ))
}
vec_w <- function(x){
n <- nrow(x)
apply(x, 2, crossprod) / n
}
lowerD <- function(x)
{
n <- nrow(x)
return(diag(vec_w(x)))
}