Skip to content

Commit 538b190

Browse files
authored
Merge pull request #56 from SebKrantz/development
Development
2 parents da0bd13 + 623e49a commit 538b190

File tree

12 files changed

+632
-9
lines changed

12 files changed

+632
-9
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: dfms
2-
Version: 0.2.1
2+
Version: 0.2.2
33
Title: Dynamic Factor Models
44
Authors@R: c(person("Sebastian", "Krantz", role = c("aut", "cre"), email = "[email protected]"),
55
person("Rytis", "Bagdziunas", role = "aut"))

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# dfms 0.2.1.9000
2+
3+
* Replace Armadillo `inv_sympd()` by Armadillo `inv()` in C++ Kalman Filter to improve numerical robustness at a minor performance cost.
4+
15
# dfms 0.2.1
26

37
* Fixed print bug in `summary.dfm`: print method showed that model had AR(1) errors even though `idio.ar1 = FALSE` by default.

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
[![minimal R version](https://img.shields.io/badge/R%3E%3D-3.3.0-6666ff.svg)](https://cran.r-project.org/)
1212
[![status](https://tinyverse.netlify.com/badge/dfms)](https://CRAN.R-project.org/package=dfms)
1313
[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
14-
[![R-CMD-check](https://github.com/SebKrantz/dfms/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/SebKrantz/dfms/actions/workflows/R-CMD-check.yaml)
1514
<!-- badges: end -->
1615

1716
<!-- **NOTE**: This package is under [rOpenSci Statistical Software Peer Review](https://stats-devguide.ropensci.org/). Peer review might result in changes to the API. -->

docs/index.html

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

docs/news/index.html

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
###########################################
2+
# Julia Implementation of Single Frequency
3+
# DFM with AR(1) Observation Residuals
4+
###########################################
5+
6+
# Installation and loading
7+
# using Pkg
8+
# Pkg.add("NaNStatistics") # nanmean etc.
9+
# Pkg.add("DSP") # filt()
10+
# Pkg.add("DataInterpolations") # CubicSpline()
11+
# Pkg.add("BlockDiagonals") # BlockDiagonal()
12+
using Statistics
13+
using NaNStatistics
14+
using DSP
15+
using DataInterpolations
16+
using LinearAlgebra
17+
using BlockDiagonals
18+
19+
eye(n) = Matrix{Float64}(I, n, n)
20+
21+
# Parameters
22+
P = (r = 5, p = 2, max_iter = 100,
23+
# Building the matrix of restrictions on the loadings for the quarterly variables
24+
Rconstr = [2 -1 0 0 0;
25+
3 0 -1 0 0;
26+
2 0 0 -1 0;
27+
1 0 0 0 -1],
28+
q = zeros(4,1),
29+
restr = "_restrMQ",
30+
nQ = 10 # need to set number of quarterly variables
31+
)
32+
33+
34+
mutable struct Nanopt
35+
method
36+
k
37+
end
38+
39+
# Functions
40+
include("runKF.jl")
41+
include("remNaNs_spline.jl")
42+
include("Procedures.jl")
43+
44+
45+
function EM_DFM_SS_restrMQ(X, P)
46+
47+
# X: T x N panel of data
48+
# P: structure containing settings of the model and estimation
49+
50+
thresh = 1e-4
51+
r = P.r # number of factors
52+
p = P.p # number of lags in the factor VAR
53+
max_iter = P.max_iter # maximal number of EM iterations
54+
R_mat = P.Rconstr # matrix of restrictions on the loadings for the quarterly variables
55+
q = P.q
56+
nQ = P.nQ # number of quarterly variables
57+
58+
#--------------------------------------------------------------------------
59+
# Preparation of the data
60+
#--------------------------------------------------------------------------
61+
T, N = size(X)
62+
63+
# Standardise x
64+
Mx = nanmean(X, dims = 1)
65+
Wx = nanstd(X, dims = 1)
66+
67+
# Standardize X using Mx and Wx
68+
xNaN = (X .- Mx) ./ Wx
69+
# xNaN = X;
70+
71+
#--------------------------------------------------------------------------
72+
# Initial Conditions
73+
#--------------------------------------------------------------------------
74+
75+
#Removing missing values (for initial estimators)
76+
77+
optNaN = Nanopt(2, 3) # Remove leading and closing zeros
78+
79+
A, C, Q, R, Z_0, V_0 = InitCond(xNaN, r, p, optNaN, R_mat, q, nQ)
80+
81+
# some auxiliary variables for the iterations
82+
previous_loglik = -Inf
83+
num_iter = 0
84+
LL = -Inf
85+
converged = false
86+
87+
# y for the estimation is WITH missing data
88+
y = xNaN'
89+
90+
#--------------------------------------------------------------------------
91+
#THE EM LOOP
92+
#--------------------------------------------------------------------------
93+
94+
#The model can be written as
95+
#y = C*Z + e;
96+
#Z = A*Z(-1) + v
97+
#where y is NxT, Z is (pr)xT, etc
98+
99+
#remove the leading and ending nans for the estimation
100+
optNaN.method = 3
101+
y_est = remNaNs_spline(xNaN, optNaN)[1]'
102+
103+
decrease = zeros(max_iter+1)
104+
LL = zeros(max_iter+1)
105+
106+
while num_iter < max_iter && !converged
107+
C_new, R_new, A_new, Q_new, loglik, Z_0, V_0 = EMstep(y_est, A, C, Q, R, Z_0, V_0, r, p, R_mat, q, nQ)
108+
109+
C = C_new
110+
R = R_new
111+
A = A_new
112+
Q = Q_new
113+
114+
if num_iter > 2
115+
converged, decrease[num_iter+1] = em_converged(loglik, previous_loglik, thresh, true)
116+
end
117+
118+
LL[num_iter+1] = loglik
119+
previous_loglik = loglik
120+
num_iter += 1
121+
end
122+
123+
#final run of the Kalman filter
124+
Zsmooth = runKF(y, A, C, Q, R, Z_0, V_0)[1]'
125+
Res = Dict()
126+
Res["x_sm"] = Zsmooth[2:end,:] * C'
127+
Res["X_sm"] = Wx .* Res["x_sm"] .+ Mx
128+
Res["F"] = Zsmooth[2:end, 1:r]
129+
130+
#--------------------------------------------------------------------------
131+
# Loading the structure with the results
132+
#--------------------------------------------------------------------------
133+
Res["C"] = C
134+
Res["R"] = R
135+
Res["A"] = A
136+
Res["Q"] = Q
137+
Res["Z_0"] = Z_0
138+
Res["V_0"] = V_0
139+
Res["r"] = r
140+
Res["p"] = p
141+
Res["Mx"] = Mx
142+
Res["Wx"] = Wx
143+
Res["loglik"] = LL
144+
Res["num_iter"] = num_iter
145+
Res["converged"] = converged;
146+
Res["decreases"] = any(decrease .== 1)
147+
Res["decr_min_iter"] = minimum(findall(decrease .== 1))
148+
149+
return Res
150+
end

0 commit comments

Comments
 (0)