Skip to content

Commit b5d3a85

Browse files
authored
Merge pull request #72 from SebKrantz/development
Development
2 parents 8e354a9 + 0adcfed commit b5d3a85

File tree

3 files changed

+137
-4
lines changed

3 files changed

+137
-4
lines changed

R/DFM.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
#' BM14[, BM14_Models$freq == "M"] %<>% diff()
139139
#' BM14[, BM14_Models$freq == "Q"] %<>% diff(3)
140140
#'
141-
#'
141+
#' \donttest{
142142
#' ### Small Model ---------------------------------------
143143
#'
144144
#' # IC for number of factors
@@ -188,7 +188,7 @@
188188
#'
189189
#'
190190
#' ### Large Model ---------------------------------
191-
#' \donttest{
191+
#'
192192
#' # IC for number of factors
193193
#' IC_large <- ICr(BM14)
194194
#' plot(IC_large)

R/EMBM_MQ_idio.R

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Define the inputs of the function
2+
# X: a matrix with n rows and TT columns representing the observed data at each time t.
3+
# A: a transition matrix with size r*p+r*r.
4+
# C: an observation matrix with size n*r.
5+
# Q: a covariance matrix for the state equation disturbances with size r*p+r*r.
6+
# R: a covariance matrix for the observation disturbances with size n*n.
7+
# Z_0: the initial value of the state variable.
8+
# V_0: the initial value of the variance-covariance matrix of the state variable.
9+
# r: order of the state autoregression (AR) process.
10+
# p: number of lags in the state AR process.
11+
# i_idio: a vector of indicators specifying which variables are idiosyncratic noise variables.'
12+
13+
# TODO: FINISH and VERIFY!!
14+
# Z_0 = F_0; V_0 = P_0
15+
EMstepBMMQidio = function(X, A, C, Q, R, Z_0, V_0, XW0, NW, dgind, dnkron, dnkron_ind, r, p, R_mat, n, nq, sr, TT, rQi, rRi) {
16+
17+
# Define dimensions of the input arguments
18+
rC = 5L # ncol(Rcon)
19+
pC = max(p, rC)
20+
rp = r * p
21+
rpC = r * pC
22+
nm = n - nq
23+
rC = rC * r # Note here replacing rC!!
24+
25+
snm = seq_len(nm)
26+
srp = seq_len(rp)
27+
srpC = seq_len(rpC)
28+
rpC1nq = (rpC+1L):(rpC+nq)
29+
30+
# Run Kalman filter with current parameter estimates
31+
kfs_res = SKFS(X, A, C, Q, R, Z_0, V_0, TRUE)
32+
33+
# Extract values from the Kalman Filter output
34+
Zsmooth = kfs_res$F_smooth
35+
Vsmooth = kfs_res$P_smooth
36+
VVsmooth = kfs_res$PPm_smooth
37+
Zsmooth0 = kfs_res$F_smooth_0
38+
Vsmooth0 = kfs_res$P_smooth_0
39+
loglik = kfs_res$loglik
40+
41+
# Normal Expectations for factors
42+
tmp = rbind(Zsmooth0[srpC], Zsmooth[-TT, srpC, drop = FALSE])
43+
tmp2 = sum3(Vsmooth[srpC, srpC, -TT, drop = FALSE])
44+
EZZ = crossprod(Zsmooth[, srpC, drop = FALSE]) %+=% (tmp2 + Vsmooth[srpC, srpC, TT]) # E(Z'Z)
45+
EZZ_BB = crossprod(tmp) %+=% (tmp2 + Vsmooth0[srpC, srpC]) # E(Z(-1)'Z(-1))
46+
EZZ_FB = crossprod(Zsmooth[, srpC, drop = FALSE], tmp) %+=% sum3(VVsmooth[srpC, srpC,, drop = FALSE]) # E(Z'Z(-1))
47+
48+
# Expectations for idiosyncratic errors
49+
tmp = rbind(Zsmooth0[rpC1nq], Zsmooth[-TT, rpC1nq, drop = FALSE])
50+
tmp2 = sum3(Vsmooth[rpC1nq, rpC1nq, -TT, drop = FALSE])
51+
EZZ_u = diag(crossprod(Zsmooth[, rpC1nq, drop = FALSE])) + diag(tmp2 + Vsmooth[rpC1nq, rpC1nq, TT]) # E(Z'Z)
52+
EZZ_BB_u = diag(crossprod(tmp)) + diag(tmp2 + Vsmooth0[rpC1nq, rpC1nq]) # E(Z(-1)'Z(-1))
53+
EZZ_FB_u = diag(diag(crossprod(Zsmooth[, rpC1nq, drop = FALSE], tmp)) + diag(rowSums(VVsmooth[rpC1nq, rpC1nq,, drop = FALSE], dims = 2L))) # E(Z'Z(-1))
54+
55+
# Update matrices A and Q
56+
A_new = A
57+
Q_new = Q
58+
59+
# System matrices for factors
60+
A_new[sr, srp] = EZZ_FB[sr, , drop = FALSE] %*% ainv(EZZ_BB)
61+
if(rQi) {
62+
Qsr = (EZZ[sr, sr] - tcrossprod(A_new[sr, srp, drop = FALSE], EZZ_FB[sr,, drop = FALSE])) / TT
63+
Q_new[sr, sr] = if(rQi == 2L) Qsr else diag(diag(Qsr))
64+
} else Q_new[sr, sr] = diag(r)
65+
66+
# System matrices for errors
67+
A_new[rpC1nq, rpC1nq] = EZZ_FB_u / EZZ_BB_u
68+
if(rRi) {
69+
if(rRi == 2L) stop("Cannot estimate unrestricted observation covariance matrix together with AR(1) serial correlation")
70+
Q_new[rpC1nq, rpC1nq] = (diag(EZZ_u) - A_new[rpC1nq, rpC1nq] * EZZ_FB_u) / TT
71+
} else Q_new[rpC1nq, rpC1nq] = diag(nm)
72+
73+
# Estimate matrix C using maximum likelihood approach
74+
denom = numeric(nm*r^2)
75+
nom = matrix(0, nm, r)
76+
77+
for (t in seq_len(TT)) {
78+
nmiss = as.double(NW[t, 1:nm])
79+
tmp = t(Zsmooth[t, sr])
80+
tmp2 = crossprod(tmp) + Vsmooth[sr, sr, t]
81+
dim(tmp2) = NULL
82+
denom %+=% tcrossprod(tmp2, nmiss)
83+
nom %+=% (XW0[t, 1:nm] %*% tmp)
84+
nom %-=% ((Zsmooth[t, rpC1nq] %*% tmp + Vsmooth[rpC1nq, sr, t]) * nmiss)
85+
}
86+
87+
dim(denom) = c(r, r, nm)
88+
dnkron[dnkron_ind] = aperm.default(denom, c(1L, 3L, 2L))
89+
vec_C = solve.default(dnkron, unattrib(nom))
90+
C_new = C
91+
C_new[1:nm, sr] = vec_C
92+
93+
# Now updating the quarterly observation matrix C
94+
for (i in (nm+1):n) {
95+
denom = numeric(rC^2)
96+
nom = numeric(rC)
97+
i_idio_jQ = rpC + nm + 5*((i-nm)-1) + 1:5
98+
99+
for (t in 1:TT) {
100+
if(NW[t, i]) {
101+
denom %+=% (crossprod(Zsmooth[t, 1:rC, drop = FALSE]) + Vsmooth[1:rC, 1:rC, t])
102+
nom %+=% (XW0[t, i] * Zsmooth[t, 1:rC])
103+
nom %-=% (c(1,2,3,2,1) %*% (Zsmooth[t, i_idio_jQ] %*% t(Zsmooth[t, 1:rC]) + Vsmooth[i_idio_jQ, 1:rC, t]))
104+
}
105+
}
106+
107+
dim(denom) = c(rC, rC)
108+
denom_inv = ainv(denom)
109+
C_i = denom_inv %*% nom
110+
tmp = tcrossprod(denom_inv, R_mat)
111+
C_i_constr = C_i - tmp %*% ainv(R_mat %*% tmp) %*% R_mat %*% C_i
112+
C_new[i, 1:rC] = C_i_constr
113+
114+
# Update AR parameters for quarterly idiosyncratic errors
115+
V_0_new = V_0
116+
V_0_new[i_idio_jQ, i_idio_jQ] = Vsmooth[i_idio_jQ, i_idio_jQ, 1]
117+
A_new[i_idio_jQ[1], i_idio_jQ[1]] = A_new[rpC1nq[i-nm], rpC1nq[i-nm]]
118+
Q_new[i_idio_jQ[1], i_idio_jQ[1]] = Q_new[rpC1nq[i-nm], rpC1nq[i-nm]]
119+
}
120+
121+
# Set initial conditions
122+
V_0_new = V_0
123+
V_0_new[srpC, srpC] = Vsmooth0[srpC, srpC]
124+
V_0_new[rpC1nq, rpC1nq] = diag(diag(Vsmooth0[rpC1nq, rpC1nq, drop = FALSE]))
125+
126+
return(list(A = A_new,
127+
C = C_new,
128+
Q = Q_new,
129+
R = R, # R stays fixed
130+
F_0 = drop(Zsmooth0),
131+
P_0 = V_0_new,
132+
loglik = loglik))
133+
}

man/DFM.Rd

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)