Direct Filter Approach (DFA)
Marc Wildi
August 2, 2013
Contents
1 Introduction
1.1 Bird’s Eye Perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Potentially Interesting Links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3 Disclaimer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
3
4
5
2 Frequency Domain
2.1 Orthonormal Basis: Decomposition of Periodic Functions into Sines and Cosines .
2.1.1 The Generic Ideal Low-Pass Filter . . . . . . . . . . . . . . . . . . . . . . .
2.1.2 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.3 Building General Real-Valued Functions . . . . . . . . . . . . . . . . . . . .
2.1.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Discrete Fourier Transformation (DFT) and Inverse Discrete Transformation (IDFT)
2.2.1 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 Periodogram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3.1 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
5
5
7
12
17
18
19
33
34
3 Filters
3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.1 Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.2 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.3 Filter-Classes: MA-, AR- and ARMA-Filters . . . . . . . . . . . .
3.2 Filter Effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2.1 Transfer function: Amplitude, Phase and Time-Shift Functions . .
3.2.2 Transferfunction of MA- and Stable AR- and ARMA-Filters . . . .
3.2.3 The Time-Shift in Frequency Zero∗ . . . . . . . . . . . . . . . . . .
3.2.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 Finite Sample Discrete Convolution Theorem and Serial Linkage of Filters
3.3.1 Stationary Processes . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.2 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.3 Non-stationary Integrated I(1)-Processes . . . . . . . . . . . . . . .
3.3.4 Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.5 Non-Stationary Processes: Additional Unit-Roots . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
40
41
41
41
42
43
43
44
46
46
64
64
66
75
76
79
4 Direct Filter Approach (DFA)
4.1 Mean-Square Paradigm . . . . . . . . . . . . . . . . .
4.1.1 Exercises . . . . . . . . . . . . . . . . . . . . .
4.2 Revisions: Releases, Vintage Triangle, Revision Error .
4.2.1 Introduction . . . . . . . . . . . . . . . . . . .
4.2.2 Filter Revisions . . . . . . . . . . . . . . . . . .
4.2.3 Examples/Exercices . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
79
79
81
101
101
102
104
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4.3
Customization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3.1 Decomposition of the MS-Criterion . . . . . . . . . . . . . . . . .
4.3.2 Accuracy, Timeliness and Smoothness (ATS-) Error-Components
4.3.3 General Customized Criterion . . . . . . . . . . . . . . . . . . . .
4.3.4 I-DFA: Numerically Tractable Customization∗ . . . . . . . . . .
4.3.5 R-code: I-DFA . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
109
109
110
110
112
113
5 ATS-Trilemma
115
6 Seasonal Adjustment
6.1 Narrow Seasonal Peak: Seasonal Line Spectrum . . . . . . . . . . . . . . . . . . . .
6.1.1 The DGP: AR(1) plus Single Line Spectrum . . . . . . . . . . . . . . . . .
6.1.2 Manual Gamma-Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.1.3 A ‘Short’ Real-Time MSE (SA-)Filter . . . . . . . . . . . . . . . . . . . . .
6.1.4 Customizing the Real-Time (SA-)Filter . . . . . . . . . . . . . . . . . . . .
6.1.5 A High-Order (SA-) Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.1.6 Out-of-Sample Performances and Finite Sample Distributions of Filter Coefficients, Amplitude and Time-Shift Functions . . . . . . . . . . . . . . . .
6.1.7 Revision Sequence: First, Final and Last Releases . . . . . . . . . . . . . .
6.1.8 Revision Sequence: Vintages and Tentacle Plot . . . . . . . . . . . . . . . .
6.2 General Composite Seasonal Spectrum . . . . . . . . . . . . . . . . . . . . . . . . .
6.2.1 The DGP: Deterministic, Stochastic, Stationary and Non-Stationary Seasonal ‘Mixed-Bag’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2.2 The Gamma-Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2.3 Automatic Seasonal Adjustment . . . . . . . . . . . . . . . . . . . . . . . .
6.2.4 Out-of-Sample Performances: Amplitude Effect . . . . . . . . . . . . . . . .
6.2.5 Out-of-Sample Performances: Time-Shift and Revision Error . . . . . . . .
6.3 Real-Time Seasonal Adjustment and Misspecification . . . . . . . . . . . . . . . . .
115
115
116
118
120
123
127
133
140
143
145
145
147
149
152
154
156
7 Trend Extraction
156
7.1 Performance Measures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
7.1.1 Time-Domain: Curvature and Peak-Correlation . . . . . . . . . . . . . . . . 156
7.1.2 Frequency-Domain: Selectivity and Mean-Shift . . . . . . . . . . . . . . . . 157
7.1.3 A Link Between Curvature and Smoothness∗ . . . . . . . . . . . . . . . . . 157
7.1.4 R-Code: Performance Measures . . . . . . . . . . . . . . . . . . . . . . . . . 158
7.2 MSE-Criterion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
7.2.1 Empirical setting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
7.2.2 Unconstrained MSE-Solution . . . . . . . . . . . . . . . . . . . . . . . . . . 163
7.2.3 Constrained MSE-Solutions: i1 and i2 Constraints . . . . . . . . . . . . . . 166
7.2.4 Revision Sequence: Vintage Triangle . . . . . . . . . . . . . . . . . . . . . . 168
7.3 Customization: Enhancing Either Speed or Noise-suppression (Timeliness-Smoothness
Dilemma) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
7.3.1 Emphasizing Smoothness Only . . . . . . . . . . . . . . . . . . . . . . . . . 168
7.3.2 Dilemma: Timeliness vs. Smoothness, Selectivity vs. Mean-Shift and Curvature vs. Peak-Correlation . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
7.3.3 Emphasizing Timeliness Only . . . . . . . . . . . . . . . . . . . . . . . . . . 172
7.3.4 Dilemma: Selectivity vs. Mean-Shift and Timeliness vs. Smoothness and
Curvature vs. Peak-Correlation . . . . . . . . . . . . . . . . . . . . . . . . . 174
7.4 Customization: Enhancing Speed And Smoothness in the ATS-Trilemma . . . . . 176
7.4.1 Experimental Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
7.4.2 In-Sample Analysis: Frequency-Domain Statistics . . . . . . . . . . . . . . . 176
7.4.3 Trilemma: Improving Selectivity and Mean-Shift; Timeliness and Smoothness; Curvature and Peak-Correlation . . . . . . . . . . . . . . . . . . . . . 178
7.4.4 In- and Out-of-Sample Empirical Distributions of Curvature and Peak-Correlation181
2
8 Replication and Customization of Model-Based and Classic (HP/CF/Henderson)
Filters by DFA
187
8.1 Replication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
8.1.1 True Spectrum when the DGP is Known . . . . . . . . . . . . . . . . . . . . 188
8.1.2 Model-Based Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
8.1.3 DFA Replicates MBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
8.2 Customization: Improving Timeliness and Smoothness, Selectivity and Mean-Shift,
Curvature and Peak-Correlation of Real-Time Model-Based Filters . . . . . . . . . 193
8.3 Replication of HP- and CF-Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
9 Multivariate Direct Filter Approach: MDFA
198
10 Appendix
198
10.1 A Proof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
10.2 A Bad ‘Smart’ Idea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
1
1.1
Introduction
Bird’s Eye Perspective
At the end of the previous course on SARIMA-models1 I stated
SARIMA-models are an approved long-term state-of-the-art approach to forecasting.
However, they assume fixed coefficients and iid innovations. Also, estimation of unknown coefficients relies on short-term (one-step ahead mean-square) forecast performances which are not always suitable when inferring future ‘trends’ or turningpoints. Finally, univariate approaches fail to capture potentially interesting comovements across time series. In the upcoming course we discuss more general univariate and multivariate real-time signal-extraction methods (DFA/MDFA), conditional
heteroscedasticity models (ARCH/GARCH/EGARCH/TGARCH) and adaptive approaches ((M)DFA/State-Space models2 ) which address some of the potential flaws of
the SARIMA-methodology.
As claimed I here propose and analyze more general forecasting and nowcasting procedures
which emphasize mid- and long-term dynamics of a time series (cycles, trends). Besides ordinary
mean-square performances I’ll address the detection of ‘turning-points’ by controlling explicitly
Timeliness and Smoothness characteristics of real-time filters based on a new, original and general optimization paradigm. In contrast to the somewhat rigid mean-square orthodoxy, I provide
additional flexibility (and assign responsibility) to the user by proposing a comprehensive interface which allows to implement specific research priorities: the ordinary mean-square solution is
but one possible outcome of the proposed customized optimization criteria. I also replicate (up
to arbitrary precision) classical approaches – model-based, HP, CF, Henderson,... – and propose
customizations thereof: proponents of a particular approach can replicate their ‘baby’ by DFA
and enhance true out-of-sample performances, staying firmly into their preferred paradigm. DFA
assimilates whatever is fed to her (she’s a lady) and refines the meal, if desired.
This book breaks the rules by going beyond the frontiers of classic dichotomic trade-offs: it proposes solutions which outperform theoretically best mean-square (model-based) filters – assuming
knowledge of the true data-generating process (DGP) – in terms of Timeliness and Smoothness,
Mean-Shift and Selectivity, Peak-Correlation and Curvature; simultaneously; out-of-sample. In
1 http://blog.zhaw.ch/idp/sefblog/index.php?/archives/352-Introduction-to-SARIMA-Models-Script-and-R-Code.
html
2 http://blog.zhaw.ch/idp/sefblog/index.php?/archives/353-Introduction-to-State-Space-Models-Script-and-R-Code-with-s
html
3
other words: I make full (ab)use of the fundamental ATS-trilemma (to be defined...). On a lighter
note, our results on (real-time) seasonal-adjustment (SA) bear a sensible touch of controversy, as
well.
I’m proposing an atheoretical empirical introduction to a sophisticated ‘hot’ forecasting problem, whose complexity is systematically underrated in the time-series literature. Since the true
‘effective’ structure of the problem cannot be obtained in the time-domain (ATS-trilemma), I’ll
have to introduce frequency-domain concepts. No theory! Just simple straightforward examples
based on unsophisticated – primitive and inelegant but graspable – R-code (man do I hate these
cryptic lines of monosyllabic R-code!). You don’t have to be a time series expert: everything is
self-contained and intuitive. Each graph, each table, each result is obtained solely by the code
contained in this book. You do not have to download tons of series, not a single one in fact: for
convenience, everything is based on simulated data as generated by R3 . The book is generated in
the Sweave-environment: it is completely reproducible at any location and at any time-point by
any R-user.
1.2
Potentially Interesting Links
• I maintain a comprehensive Blog on the topic where you can find applications to financial
trading and real-time macro-indicators: http://blog.zhaw.ch/idp/sefblog/. There, you
will find tons of material on MDFA (a multivariate extension of the DFA).
• Chris maintains a nice Blog on trading applications of MDFA, see http://imetricablog.
com/.
• Real-time macro-applications can be seen on http://www.idp.zhaw.ch/usri as well as on
http://www.idp.zhaw.ch/euri.
• For those in need of theoretical background and further applications/research reports I may
refer to
– My ‘good ole’ DFA-book http://blog.zhaw.ch/idp/sefblog/index.php?/archives/
168-RTSE-My-Good-Old-Book.html. It dates back to 2008: at that time I didn’t have
a computationally fast algorithm and numerical processing was a nightmare. It contains
a lot more information on non-stationary DGP’s, see chapter 6.
– The ‘trilemma paper’ on DFA, co-authored with Tucker McElroy http://blog.zhaw.
ch/idp/sefblog/index.php?/archives/271-Trilemma-Paper-Latest-Sweaved-Version-Available.
html#extended. A very clean and sober presentation (thanks to Tucker) leading systematically from one-step ahead forecasting to full customization.
– The only officially recognized reference for the multivariate DFA (MDFA): my ‘elements
vade-mecum’ http://blog.zhaw.ch/idp/sefblog/index.php?/archives/259-Elements-of-Forecasti
html (go down the chronological list and download the latest version of the working
vade-mecum).
– A report on a common research with the OECD (application of MDFA): http://blog.
zhaw.ch/idp/sefblog/index.php?/archives/340-I-MDFA-and-OECD-CLIs.html.
– An interresting independent research from Ginters (application of MDFA): http://
blog.zhaw.ch/idp/sefblog/index.php?/archives/341-Another-Article-on-I-MDFA-FORECASTING-A
html.
– And, finally, let me conclude on an infinite regress of this book on itself (and Rcode as ‘Rtangled’ from itself too): http://blog.zhaw.ch/idp/sefblog/index.php?
/archives/359-DFA-the-Standard-is-Released.html.
3 Don’t
blame me on using artificial data. Not me!
4
Let me now adopt the majestic ‘We’ when speaking of Ourself.
1.3
Disclaimer
This oeuvre summarizes recent material and tutorials published in a loose unsystematic manner
on SEFBlog. It is a comprehensive unifying tutorial on DFA. The first version was released
on May 1 2013 (worker’s day is a pure coincidence: We could have released her on Christmas as
well): although the Sweave-environment helps in sorting out ‘dirt’, this original version is certainly
contaminated by an unknown number of more or less minor bugs. We will comment modifications
in later revisions. We are happy to collect feedback and perfect the subject-matter. Obviously, We
are not English Grammarian (should We use the plural here?). And We did not apply automatic
spell-facilities. Absorb the poison ‘as is’.
2
Frequency Domain
Frequency-domain and Time-domain offer general frameworks (spaces) to work on time series
data. Whereas both perspectives are equally general, the frequency-domain offers some crucial
structural advantages which allow for a straightforward and practically relevant generalization of
the mean-square (one-step ahead) orthodoxy.
2.1
2.1.1
Orthonormal Basis: Decomposition of Periodic Functions into Sines
and Cosines
The Generic Ideal Low-Pass Filter
Any ‘well-behaved’ periodic function Γ(ω), with periodicity 2π i.e. Γ(ω) = Γ(ω ± k2π) for any
integer k, can be decomposed into a sum of sines and cosines. As a generic example We here
consider
1 ω ∈ 2kπ + [−cutoff, cutoff]
Γ(ω, cutoff) =
0
otherwise
where 0 < cutoff < π, see fig.1. If not explicitly needed, We can suppress the cutoff-term in the
notation and write Γ(ω) instead to signify that Γ(·) is a one-parametric function in the variable
ω, whereby the shape of the function is specified by the fixed parameter cutoff.
>
>
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
cutoff<-pi/6
K<-1200
Gamma_h<-((0:K)*pi/K)<cutoff
Gamma<-rep(c(Gamma_h[length(Gamma_h):2],Gamma_h),3)
file = paste("z_Gamma_t.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
plot(Gamma,col="blue",main="Periodic Gamma",xlab="",ylab="",type="l",axes="F")
axis(1,at=c(c(1,0,0,0)+(length(Gamma)/3)*(0:(length(Gamma)/(length(Gamma)/3))),
length(Gamma)/2),labels=c("-3pi","-pi","pi","3pi","0"))
axis(2)
box()
plot(Gamma_h,col="blue",main="Gamma in [0,pi]",xlab="",ylab="",type="l",axes="F")
axis(1,at=c(1,(K/6)*1:6),labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
5
null device
1
0.0
0.4
0.8
Periodic Gamma
−3pi
−pi
0
pi
3pi
0.0
0.4
0.8
Gamma in [0,pi]
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Figure 1: Ideal lowpass with cutoff pi/6
Note that We may restrict the periodic Γ(·) to the range [−π, π] because of periodicity (all other
values are redundant). Moreover, since it is an even function (Γ(ω) = Γ(−ω)) We just need to
plot the function for ω ∈ [0, π], as done in the bottom graph of fig.1. Γ(·) will play a crucial role as
an ideal lowpass target which is used to generalize traditional forecast criteria, see later sections.
The frequency band |ω| < cutoff is called passband : Γ(ω) = 1 in the passband; the frequency band
|ω| > cutoff is called stopband : Γ(ω) = 0 in the stopband.
6
Suppose that Γ(ω) can be decomposed into a weighted sum of cosines and sines
Γ(ω)
=
∞
X
γk exp(−ikω)
k=−∞
where exp(−iω) = cos(−ω) + i sin(−ω) is the complex exponential function on the unit-circle
| exp(−iω)| = 1 and where γk are called Fourier coefficients. We would be interested in finding
the Fourier coefficients γk associated to this hypothetical decomposition. Consider
1
2π
Z
π
Γ(ω) exp(ijω)dω
=
−π
=
1
2π
Z
π
γk exp(−ikω) exp(ijω)dω
(1)
−π k=−∞
∞
X
k=−∞
=
∞
X
γk
1
2π
Z
π
exp(−ikω) exp(ijω)dω
−π
γj
where the last equality follows from the fact that the integral vanishes if exp(−ikω) exp(ijω) 6= 1,
by periodicity of the complex exponential4 . The transformation 1 mapping Γ(ω) to its Fourier
coefficients γj , j = −∞, ..., 0, , ∞ is called inverse Fourier transformation.
We have thus found a way to compute the Fourier coefficients γk . Specifically, in the case of
the above lowpass We find
Z π
1
γj =
Γ(ω) exp(ijω)dω
2π −π
Z cutoff
1
exp(ijω)dω
=
2π −cutoff
cutoff
1 exp(ijω) =
2π
ij
−cutoff
sin(j
·
cutoff)
j 6= 0
jπ
=
(2)
cutoff
j=0
π
It follows that
Γ(ω)
=
=
=
∞
X
γk exp(−ikω)
k=−∞
∞
X
1
π
k=−∞
sin(k · cutoff)
exp(−ikω)
k
∞
cutoff
2 X sin(k · cutoff)
+
cos(kω)
π
π
k
(3)
k=1
Now consider what we just did: we replicated a discontinuous step-function by a sum of infinitely
differentiable trigonometric functions. Weird! But... what happens in the discontinuity?
2.1.2
Exercises
1. Compute the first 1000 (thousand) Fourier coefficients of the lowpass function with cutoff=
π/6. Make a plot, see fig.2.
4 Exchanging integral and the infinite sum is not trivial but We could approximate Γ(·) arbitrarily well by a
finite sum which would allow for the swap.
7
>
>
>
>
>
>
cutoff<-pi/6
# Order of approximation : 10, 100, 1000, 10000
ord<-K
# Compute coefficients gamma
gamma<-c(cutoff/pi,(1/pi)*sin(cutoff*1:ord)/(1:ord))
sum(gamma)+sum(gamma[2:ord])
[1] 0.99901
>
>
>
+
>
>
+
+
>
>
>
>
+
+
>
>
>
>
# Plot
file = paste("z_gamma.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(2,1))
plot(c(gamma[min(1000,ord):2],gamma[1:min(1000,ord)]),col="black",
main="Fourier coefficients of Gamma: -1000:1000",xlab="",ylab="",
type="l",axes="F")
axis(1,at=c(0:4)*ord/2,labels=c(-ord,-ord/2,0,ord/2,ord))
axis(2)
box()
plot(c(gamma[min(1000,ord/10):2],gamma[1:min(1000,ord/10)]),col="black",
main="Fourier coefficients of Gamma: -100:100",xlab="",ylab="",
type="l",axes="F")
axis(1,at=c(0:4)*ord/20,labels=c(-ord/10,-ord/20,0,ord/20,ord/10))
axis(2)
box()
dev.off()
null device
1
8
0.00
0.10
Fourier coefficients of Gamma: −1000:1000
−1200
−600
0
600
0.00
0.10
Fourier coefficients of Gamma: −100:100
−120
−60
0
60
120
Figure 2: Fourier coefficients of Gamma: from -1000 to 1000 (top) and -100 to 100 (bottom)
We can recognize the damped sinusoidal with frequency cutoff= π/6. Note, however, that the
Fourier coefficients decay slowly – at a linear rate – which is due to the fact that Our ideal
lowpass function is discontinuous: rapid (instantaneous) changes require high-frequencies
cos(kω), k large, in 3 to be weighted strongly, thus Fourier-coefficients γk cannot decay too
rapidly.
2. Compute the finite approximation
m
2 X sin(k · cutoff)
cutoff
+
cos(kω)
Γ̂m (ω) :=
π
π
k
k=1
of Γ(ω) of orders m = 10, 100, 1000, 10000 and check graphically that the finite sums converge
to the discontinuous Γ(ω), see fig.3. Hint: compute Γ̂m (ωk ) on an equidistant discrete
9
kπ
, k = 0, ..., N , where N is a ‘large’ multiple of 6 (N = 1200 in the
N
following code). Note that ωN/6 = π/6 such that We can track the singularity in ω = π/6.
frequency grid ωk =
>
>
>
>
>
>
>
>
>
>
+
+
+
+
>
>
+
>
+
>
>
+
>
>
>
cutoff<-pi/6
# Order of approximation : 10, 100, 1000, 10000
ord<-K
# Compute coefficients gamma
gamma<-c(cutoff/pi,(1/pi)*sin(cutoff*1:ord)/(1:ord))
# Compute finite sum
# len1: Number of frequency ordinates (resolution of discrete grid in [-pi,pi])
len1<-K
Gamma_hat<-0:len1
for (k in 0:len1)#k<-0
{
omegak<-k*pi/len1
Gamma_hat[k+1]<-gamma%*%(cos(omegak*0:ord)*c(1,rep(2,ord)))
}
file = paste("z_Gamma_a.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
plot(Gamma_hat,type="l",axes=F,
main="Gamma (blue) and finite approximation (black)",xlab="",ylab="")
lines(Gamma_h,col="blue")
axis(1, at=c(0,1+1:6*len1/6),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
10
0.0
0.2
0.4
0.6
0.8
1.0
Gamma (blue) and finite approximation (black)
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Figure 3: Finite approximation m=1000 (black) vs. Gamma (blue)
For m = 1000 the approximation is pretty good. Visible approximation errors are concentrated in the vicinity of the singularity ω = π/6 (so-called Gibbs-phenomenon).
3. What happens in the discontinuity ω = π/6? Hint: the finite sums are infinitely differentiable
and therefore We must have a continuous transition from the passband (Γ̂(ω) ≈ 1) to the
stopband (Γ̂(ω) ≈ 0).
> Gamma_hat[1+round(len1/6)]
[1] 0.4997703
We can see that Γ̂m (π/6) ≈ 0.5, the mean value or midposition between 1 (passband on the
left) and 0 (stopband on the right).
4. Generate a white noise sequence t of length 300 and apply the Fourier coefficients γk =
sin(k·cutoff)
, k = −100, ..., 0, ..., 100, of the lowpass to the white noise sequence
k
yt =
100
X
γk t−k
k=−100
Note that yt can be computed for t = 100, ..., 200 only. Compare t and yt graphically.
>
>
>
>
>
len<-300
set.seed(10)
eps<-rnorm(len)
y<-rep(NA,len)
for (k in 100:200)#k<-0
11
+
+
+
>
>
+
>
+
+
>
>
+
>
>
>
{
y[k]<-gamma[1:100]%*%eps[k+(0:99)]+gamma[2:100]%*%eps[k-(1:99)]
}
file = paste("z_Gamma_n.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
ts.plot(as.ts(eps),type="l",axes=F,
main="Noise (blue) and lowpassed noise(red)",xlab="",
ylab="",col="blue")
lines(y,col="red",lwd=2)
axis(1, at=c(0,1+1:6*len1/6),labels=c("0","pi/6","2pi/6",
"3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
−2
−1
0
1
2
Noise (blue) and lowpassed noise(red)
0
50
100
150
200
pi/6
250
300
Figure 4: Noise (blue) and lowpassed noise (red)
We observe that yt (red line) tracks t but many of the short-term random movements of
the noise are eliminated or damped: yt is much smoother than the original t .
2.1.3
Building General Real-Valued Functions
We here briefly suggest that one can approximate general ‘well-behaved’ (periodic) functions arbitrarily well by relying on suitable linear combinations of the above ideal lowpass function. To
12
see this We first define a so-called ideal passband function
Γpb (ω, cutoff1 , cutoff2 ) = I{cutoff1 ≤|ω|≤cutoff2 }
1 cutoff1 ≤ |ω| ≤ cutoff2
where cutoff1 < cutoff2 and where I{cutoff1 ≤|ω|≤cutoff2 }
is the indica0
otherwise
tor function. The bandpass function can be obtained as a simple linear combination of two lowpass
functions:
Γpb (ω, cutoff1 , cutoff2 ) = Γ(ω, cutoff2 ) − Γ(ω, cutoff1 )
As for the lowpass function above, We frequently suppress the fixed parameters cutoff1 , cutoff2 in
Our notation, if not explicitly required, and write Γpb (ω) instead, to signify that the bandpass is
a function of the variable ω. A bandpass with cutoff1 = π6 , cutoff2 = 2π
6 is plotted in fig.5.
>
>
>
>
>
>
>
+
>
+
>
>
>
cutoff_1<-pi/6
cutoff_2<-2*pi/6
K<-1200
Gamma_pb<-((0:K)*pi/K)>cutoff_1&((0:K)*pi/K)<cutoff_2
file = paste("z_Gamma_pb.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
plot(Gamma_pb,col="blue",main="Gamma passband in [0,pi]",xlab="",
ylab="",type="l",axes="F")
axis(1,at=c(1,(K/6)*1:6),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
13
0.0
0.2
0.4
0.6
0.8
1.0
Gamma passband in [0,pi]
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Figure 5: Ideal passband with cutoffs pi/60 and pi/6
The Fourier coefficients of Γpb (ω, cutoff1 , cutoff2 ) can be obtained directly, by inverse Fourier
transformation 1, or by
γj,pb (cutoff1 , cutoff2 ) = γj (cutoff2 ) − γj (cutoff1 )
(4)
where γj (cutoff1 ) and γj (cutoff2 ) are the Fourier coefficients of the corresponding lowpass functions5 .
By scaling and adding bandpasses We are in a position to approximate any well-behaved
(periodic) function arbitrarily well, see fig.6.
>
>
>
>
>
>
>
+
+
>
+
+
>
>
len1<-1200
f<-cos(2*pi*(1:len1)/len1)
file = paste("z_cos_pb.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(3,1))
resolution<-10
plot(f,col="black",
main=paste("Approximation of Cosine by bp-functions: resolution=",resolution,sep=""),
xlab="",ylab="",type="l",axes="F")
for (i in 0:resolution)
lines(cos(2*pi*(i+0.5)/resolution)*((1:len1)>(i)*len1/resolution&(1:len1)<
(i+1)*len1/resolution),col="blue")
resolution<-33
axis(1,at=c(1,(K/6)*1:6),labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
5 The
inverse Fourier transformation is a linear functional.
14
>
>
>
>
+
+
>
+
+
>
>
>
>
>
+
+
>
+
+
>
>
>
>
axis(2)
box()
resolution<-33
plot(f,col="black",
main=paste("Approximation of Cosine by bp-functions: resolution=",resolution,sep=""),
xlab="",ylab="",type="l",axes="F")
for (i in 0:resolution)
lines(cos(2*pi*(i+0.5)/resolution)*((1:len1)>(i)*len1/resolution&(1:len1)<
(i+1)*len1/resolution),col="red")
axis(1,at=c(1,(K/6)*1:6),labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
resolution<-100
plot(f,col="black",
main=paste("Approximation of Cosine by bp-functions: resolution=",resolution,sep=""),
xlab="",ylab="",type="l",axes="F")
for (i in 0:resolution)
lines(cos(2*pi*(i+0.5)/resolution)*((1:len1)>(i)*len1/resolution&(1:len1)<
(i+1)*len1/resolution),col="green")
axis(1,at=c(1,(K/6)*1:6),labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
15
−1.0
0.0
1.0
Approximation of Cosine by bp−functions: resolution=10
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
−1.0
0.0
1.0
Approximation of Cosine by bp−functions: resolution=33
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
−1.0
0.0
1.0
Approximation of Cosine by bp−functions: resolution=100
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Figure 6: Approximation of cosine by bandpass functions
Since any passband function can be decomposed into cosines/sines We infer that any ‘well behaved’
periodic function f (ω) can be decomposed too
f (ω) =
∞
X
fk exp(−ikω)
(5)
k=−∞
by linear combination of the decomposed passband functions. The Fourier coefficients fk can
be obtained either directly, by inverse Fourier transformation 1, or by linear combination of the
Fourier coefficients corresponding to the bandpass functions in the discrete approximation of f (ω)
(and going to the limit of the resolution). If f (ω) is a real-valued function, then fk = f−k and the
imaginary parts cancel on both sides of 5 thus leaving
f (ω) = f0 + 2
∞
X
k=1
16
fk cos(kω)
2.1.4
Exercises
1. Verify that the Fourier coefficient defined in 4 replicate the corresponding bandpass function.
Specifically, approximate Γpb (ω, cutoff1 , cutoff2 ) by finite Fourier approximations of order 100
and 1000 and check the quality of the approximation, see fig.7.
>
>
>
>
>
>
+
+
+
+
+
>
>
+
>
+
+
>
>
+
>
>
>
# Compute coefficients gamma of the two lowpass filters
gamma_1<-c(cutoff_1/pi,(1/pi)*sin(cutoff_1*1:ord)/(1:ord))
gamma_2<-c(cutoff_2/pi,(1/pi)*sin(cutoff_2*1:ord)/(1:ord))
# Compute finite sum (approximation)
Gamma_hat_pb<-0:len1
for (k in 0:len1)#k<-0
{
omegak<-k*pi/len1
Gamma_hat_pb[k+1]<-(gamma_2-gamma_1)%*%
(cos(omegak*0:ord)*c(1,rep(2,ord)))
}
file = paste("z_Gammapb_a.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
plot(Gamma_hat_pb,type="l",axes=F,
main="Passband Gamma (blue) and finite approximation (black)",xlab="",
ylab="")
lines(Gamma_pb,col="blue")
axis(1, at=c(0,1+1:6*len1/6),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
17
0.0
0.2
0.4
0.6
0.8
1.0
Passband Gamma (blue) and finite approximation (black)
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Figure 7: Finite approximation m=1000 (black) vs. passband Gamma (blue)
We observe once again the Gibbs phenomenon at the edges of the two discontinuities π/6 and 2π/6
but otherwise the fit is good. Selecting larger approaximation errors would result in arbitrary good
approximations.
2.2
Discrete Fourier Transformation (DFT) and Inverse Discrete Transformation (IDFT)
A time series xt , t = 1, ..., T can be transformed into the frequency domain by the so-called DFT:
ΞT X (ω) := √
T
1 X
xt exp(−itω)
2πT t=1
(6)
The DFT ΞT X (ω) of xt is a periodic function and it is generally specified on the discrete grid
k2π
ωk =
, where k = −T /2, ..., 0, ..., T /2 for even T . For odd T one uses T 0 = T − 1 in these
T
expressions instead of T .
The DFT is equivalent to the data xt , in informational terms, and in fact the data can be
recovered from the DFT by applying the inverse transformation
xt
=
=
√
2π
√
T
[T /2]
X
wk ΞT X (ωk ) exp(itωk )
(7)
k=−[T /2]
√
[T /2]
X
2π
√
ΞT X (0) + 2
wk < (ΞT X (ωk ) exp(itωk ))
T
k=1
18
(8)
T /2
T even
where [T /2] =
and where
(T
−
1)/2
T odd
1
, [−T /2] ≤ k ≤ [T /2] if T is odd
1 |k| < T /2
wk =
: please do not confound the
if T is even
1/2 |k| = T /2
weights wk and the frequencies ωk . In practice, the effect of the weights wk is negligible and
therefore We generally omit them. However, they are necessary when replicating the data xt exactly by the IDFT. The second equation 8 is due to the fact that the real part of ΞT X (ωk ) exp(itωk )
is even whereas its imaginary part is odd if the data xt is real.
Strictly speaking the above identity 7 is a tautological number identity which applies to any
sequence of numbers xt , t = 1, ..., T irrespective of ‘model’ assumptions. From a substantial
perspective the identity shows that the data xt can be decomposed into a linear combination
of sines and cosines as weighted by the DFT: ΞT X (ωk ) determines the weight of exp(itωk ) =
cos(tωk ) + i sin(tωk ) in the decomposition of xt . If |ΞT X (ωk )| is ‘large’ (in relative terms), then
the corresponding component exp(itωk ) will dominate in xt and We should see a cycle with the
corresponding frequency ωk in the time series xt . This decomposition of the data in the frequencydomain is crucial because it will enable to design filters with ‘desirable’ properties and the resulting
Direct Filter Approach (DFA) will generalize the traditional forecasting paradigm to a whole bunch
of new practically relevant prospective estimation problems.
Note that exp(itωk ) is a periodic function and therefore the identity 7 implies
x̂T +t
=
=
=
√
2π
√
T
√
2π
√
T
√
2π
√
T
[T /2]
X
wk ΞT X (ωk ) exp(i(t + T )ωk )
k=−[T /2]
[T /2]
X
wk ΞT X (ωk ) exp(itωk ) exp(iT ωk )
k=−[T /2]
[T /2]
X
wk ΞT X (ωk ) exp(itωk )
k=−[T /2]
= xt
k2π
where We used the fact that exp(iT ωk ) = exp iT
= 1 if T is even (and similarly for odd
T
T ). Therefore, the DFT 6 implicitly assumes that the data is periodic. This is a very unfortunate
assumption because it would imply that the best forecast x̂T +1 of xT +1 is the first observation
x1 : a very bad rule in typical economic applications. Fortunately We can affranchise from this
unrealistic assumption since We shall use the DFT or the periodogram as weighting-functions
in a general optimization problem: in this case the unrealistic periodicity assumption does not
interfer anymore with the relevant forecast problem, assuming some elementary precaution applies6
2.2.1
Exercises
1. Generate a realization of length T = 301 (odd number: wk = 1 for all k) of the seasonal
SAR(1)-process
yt = 0.9yt−12 + t
Compute the DFT and plot the data, the acf as well as the absolute value of the DFT
|ΞT X (ωk )|, see fig.8.
6 Non-stationary trending time series must be trimmed to stationarity (by differencing) before applying the DFT,
see later sections.
19
>
>
>
>
>
>
>
>
>
+
+
+
+
+
+
+
+
+
+
+
>
>
+
>
>
>
>
>
+
>
>
>
len<-301
set.seed(10)
# Seasonal AR(1)
model<-list(order=c(12,0,0),ar=c(rep(0,11),0.9))
y<-arima.sim(model,n=len)
# DFT
DFT<-0:(len/2)
DFT_c<-0:(len/2)
for (k in 0:(len/2))
{
cexp <- complex(arg=-(1:len)*2*pi*k/len)
# Complex conjugate: this will be used for computing the IDFT
cexpt <- complex(arg=(1:len)*2*pi*k/len)
four<-sum(cexp*y*sqrt(1/(2*pi*len)))
# Complex conjugate: this will be used for computing the IDFT
fourc<-sum(cexpt*y*sqrt(1/(2*pi*len)))
DFT[k+1]<-four
# Complex conjugate: this will be used for computing the IDFT
DFT_c[k+1]<-fourc
}
file = paste("z_sar1.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(3,1))
ts.plot(y,main="Data: SAR(1)")
acf(y)
plot(abs(DFT),type="l",axes=F,col="blue",main="DFT")
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
20
0
−4
y
4
Data: SAR(1)
0
50
100
150
200
250
300
Time
ACF
0.0 0.4 0.8
Series y
0
5
10
15
20
Lag
3.0
1.5
0.0
abs(DFT)
DFT
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Index
Figure 8: Seasonal process: data (top), acf (middle) and DFT (bottom)
The strong seasonality induces large slowly decaying peaks of the acf at seasonal lags k · 12,
k = 1, 2, .... The absolute DFT in the bottom plot shows that the data is dominated by
2π
cycles of frequencies kπ/6, k = 0, 1, ..., 6 with durations kπ
= ∞, 12, 6, 4, 3, 2.4 and 2 months
(zero-frequency is a particulat cycle with infinite duration). In a way the (absolute value of
the) DFT is more informative than the acf about the dominant components in the series.
2. Verify the identity 7 for the above SAR(1).
>
>
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
z<-1:len
zh<-z
for (k in 1:len)#k<-1
{
cexp <- complex(arg=(0:(len/2))*2*pi*k/len)
# Complex canjugate
cexpt <- complex(arg=-(0:(len/2))*2*pi*k/len)
# Account for weights w_k
if (abs(len/2-as.integer(len/2))<0.1)
{
cexp<-cexp*c(rep(1,length(cexp)-1),(1/2))
cexpt<-cexpt*c(rep(1,length(cexp)-1),(1/2))
}
# IDFT
z[k]<-sum(cexp[1:length(cexp)]*DFT[1:length(DFT)]*sqrt((2*pi)/len))+
sum(cexpt[2:length(cexpt)]*DFT_c[2:length(DFT_c)]*sqrt((2*pi)/len))
zh[k]<-sum(c(cexp[1]*DFT[1]*sqrt((2*pi)/len),2*Re(cexp[2:length(cexp)]*
DFT[2:length(DFT)]*sqrt((2*pi)/len))))
21
+ }
> cbind(y,z,zh)[(len-30):len,]
[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,]
y
1.02560572+0i
1.47772429+0i
2.48080781+0i
1.72883400+0i
-0.69621857+0i
1.17622338+0i
2.40463142+0i
1.99763017+0i
2.85602693+0i
-1.09185706+0i
1.05364471+0i
0.08710738+0i
0.41636932+0i
0.63476792+0i
2.77433484+0i
0.97487330+0i
-0.19576467+0i
1.73030223+0i
1.73066097+0i
1.01688373+0i
2.98672242+0i
-1.80429196+0i
1.15935613+0i
0.83321981+0i
2.15484214+0i
1.23723881+0i
2.48616754+0i
-0.32366863+0i
-0.81958598+0i
2.35456432+0i
2.08584315+0i
z
1.02560572+0i
1.47772429+0i
2.48080781+0i
1.72883400+0i
-0.69621857+0i
1.17622338+0i
2.40463142+0i
1.99763017+0i
2.85602693+0i
-1.09185706+0i
1.05364471+0i
0.08710738+0i
0.41636932+0i
0.63476792+0i
2.77433484+0i
0.97487330+0i
-0.19576467+0i
1.73030223+0i
1.73066097+0i
1.01688373+0i
2.98672242+0i
-1.80429196+0i
1.15935613+0i
0.83321981+0i
2.15484214+0i
1.23723881+0i
2.48616754+0i
-0.32366863+0i
-0.81958598+0i
2.35456432+0i
2.08584315+0i
zh
1.02560572+0i
1.47772429+0i
2.48080781+0i
1.72883400+0i
-0.69621857+0i
1.17622338+0i
2.40463142+0i
1.99763017+0i
2.85602693+0i
-1.09185706+0i
1.05364471+0i
0.08710738+0i
0.41636932+0i
0.63476792+0i
2.77433484+0i
0.97487330+0i
-0.19576467+0i
1.73030223+0i
1.73066097+0i
1.01688373+0i
2.98672242+0i
-1.80429196+0i
1.15935613+0i
0.83321981+0i
2.15484214+0i
1.23723881+0i
2.48616754+0i
-0.32366863+0i
-0.81958598+0i
2.35456432+0i
2.08584315+0i
The R-objects are ‘automatically’ complex since We work with complex -valued numbers
but all imaginary parts vanish, as expected. The identical columns (We restrict the above
list to the last 30 observations to save space) confirm the tautological number identities 7
and 8.
3. Generate a realization of length T = 101 (odd number: wk = 1 for all k) of the MA(1)-process
xt = µ + t + b1 t−1
for b1 = −0.9, b1 = 0 and b1 = 0.9 and plot the absolute values |ΞT X (ωk )| of the corresponding DFT’s, see fig.9.
>
>
>
>
>
>
>
# MA(1)
model_1<-list(order=c(0,0,1),ma=-0.9)
model_3<-list(order=c(0,0,1),ma=0.9)
set.seed(10)
y_1<-arima.sim(model_1,n=len)
set.seed(10)
y_2<-rnorm(len)
22
>
>
>
>
>
>
>
+
+
+
+
+
+
>
>
+
>
>
>
+
>
>
>
>
+
>
>
>
>
+
>
>
>
set.seed(10)
y_3<-arima.sim(model_3,n=len)
# DFT----------DFT_1<-0:(len/2)
DFT_2<-0:(len/2)
DFT_3<-0:(len/2)
for (k in 0:(len/2))
{
cexp <- complex(arg=-(1:len)*2*pi*k/len)
DFT_1[k+1]<-sum(cexp*y_1*sqrt(1/(2*pi*len)))
DFT_2[k+1]<-sum(cexp*y_2*sqrt(1/(2*pi*len)))
DFT_3[k+1]<-sum(cexp*y_3*sqrt(1/(2*pi*len)))
}
file = paste("z_ma1_dft.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(3,1))
plot(abs(DFT_1),type="l",axes=F,col="blue",main="|DFT|: b_1=-0.9",xlab="")
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
plot(abs(DFT_2),type="l",axes=F,col="blue",main="|DFT|: b_1=0",xlab="")
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
plot(abs(DFT_3),type="l",axes=F,col="blue",main="|DFT|: b_1=0.9",xlab="")
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
23
1.2
0.6
0.0
abs(DFT_1)
|DFT|: b_1=−0.9
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
4pi/6
5pi/6
pi
4pi/6
5pi/6
pi
0.6
0.2
abs(DFT_2)
|DFT|: b_1=0
0
pi/6
2pi/6
3pi/6
1.2
0.6
0.0
abs(DFT_3)
|DFT|: b_1=0.9
0
pi/6
2pi/6
3pi/6
Figure 9: MA(1): positive (top), zero (middle) and negative (bottom) MA-coefficients
For b1 = −0.9 (top graph) We observe that high-frequency components are weighted more
heavily than low-frequency components and conversely for b1 = 0.9 (bottom graph). The
white noise b1 = 0 seems to have equally weighted components.
4. Compute 100 realizations of the above MA-processes, average the absolute DFT’s and plot
the averages, see fig.10.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
+
+
+
+
+
# MA(1)
model_1<-list(order=c(0,0,1),ma=-0.9)
model_3<-list(order=c(0,0,1),ma=0.9)
# AR(2)
pers=0.99;
phi=pi/2;
a1=2*pers*cos(phi);
a2= -pers^2;
model<-list(order=c(2,0,0),ar=c(a1,a2))
simanz<-100
DFT<-matrix(nrow=len/2+1,ncol=3)
abs_dft<-matrix(rep(0,3*(1+(len-1)/2)),nrow=len/2+1,ncol=3)
# Simulation runs
for (i in 1:simanz)
{
set.seed(i)
y_1<-arima.sim(model_1,n=len)
set.seed(i)
y_2<-rnorm(len)
24
+
+
+
+
+
+
+
+
+
+
+
+
>
>
>
+
>
>
>
>
+
>
+
>
>
>
>
+
>
+
>
>
>
>
+
>
+
>
>
>
set.seed(i)
y_3<-arima.sim(model_3,n=len)
# DFT----------for (k in 0:(len/2))
{
cexp <- complex(arg=-(1:len)*2*pi*k/len)
DFT[k+1,1]<-sum(cexp*y_1*sqrt(1/(2*pi*len)))
DFT[k+1,2]<-sum(cexp*y_2*sqrt(1/(2*pi*len)))
DFT[k+1,3]<-sum(cexp*y_3*sqrt(1/(2*pi*len)))
}
abs_dft<-abs_dft+abs(DFT)
}
abs_dft<-abs_dft/simanz
file = paste("z_ma1s_dft.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(3,1))
ymin<-0
ymax<-max(abs_dft[,1])
plot(abs_dft[,1],type="l",axes=F,col="blue",main="|DFT|: b_1=-0.9",
xlab="",ylim=c(ymin,ymax))
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6",
"5pi/6","pi"))
axis(2)
box()
ymax<-max(abs_dft[,2])
plot(abs_dft[,2],type="l",axes=F,col="blue",main="|DFT|: b_1=0",xlab="",
ylim=c(ymin,ymax))
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6",
"5pi/6","pi"))
axis(2)
box()
ymax<-max(abs_dft[,3])
plot(abs_dft[,3],type="l",axes=F,col="blue",main="|DFT|: b_1=0.9",
xlab="",ylim=c(ymin,ymax))
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6",
"5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
25
0.4
0.0
abs_dft[, 1]
|DFT|: b_1=−0.9
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
4pi/6
5pi/6
pi
4pi/6
5pi/6
pi
0.2
0.0
abs_dft[, 2]
0.4
|DFT|: b_1=0
0
pi/6
2pi/6
3pi/6
0.4
0.0
abs_dft[, 3]
|DFT|: b_1=0.9
0
pi/6
2pi/6
3pi/6
Figure 10: MA(1): positive (top), zero (middle) and negative (bottom) MA-coefficients
Averaging the absolute DFT’s leads to a clearer picture by damping realization-specific
noise disturbances: positive autocorrelation (b1 > 0) emphasizes low-frequency components
whereas negative autocorrelation (b1 < 0) means stronger high-frequency components. In
contrast, the white noise is characterized by a flat absolute DFT: all frequency-components
are weighted equally; likewise, all colours are weighted equally in white-light, from which the
(physical) analogy is taken.
5. To conclude We analyze an AR(2)-process with a strong cycle
yt = 0.99yt−1 − 0.9801yt−2 + t
Looking at the roots of the characteristic polynomial
> abs(polyroot(c(0.9801,-0.99,1)))
[1] 0.99 0.99
> Arg(polyroot(c(0.9801,-0.99,1)))/pi
[1]
0.3333333 -0.3333333
> 2*pi/Arg(polyroot(c(0.9801,-0.99,1)))
[1]
6 -6
We find the absolute value to be large (0.99). The frequency of the cycle is π/3 with
periodicity 6. These characteristics should be reflected by the DFT.
26
>
>
>
>
>
>
>
>
>
>
>
+
+
+
+
>
>
+
>
>
>
+
>
+
>
>
>
# AR(2)
pers=0.99;
phi=pi/3;
a1=2*pers*cos(phi)
a2= -pers^2
model<-list(order=c(2,0,0),ar=c(a1,a2))
set.seed(10)
y_ar2<-arima.sim(model,n=len)
# DFT----------DFT_ar2<-0:(len/2)
for (k in 0:(len/2))
{
cexp <- complex(arg=-(1:len)*2*pi*k/len)
DFT_ar2[k+1]<-sum(cexp*y_ar2*sqrt(1/(2*pi*len)))
}
file = paste("z_ar2_dft.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(2,1))
ts.plot(y,xlab="",main="Data: AR(2)")
plot(abs(DFT_ar2),type="l",axes=F,col="blue",
main="|DFT| cyclical AR(2)",xlab="")
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6",
"5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
27
0
−4
y
4
Data: AR(2)
0
50
100
150
200
250
300
5pi/6
pi
8 12
4
0
abs(DFT_ar2)
|DFT| cyclical AR(2)
0
pi/6
2pi/6
3pi/6
4pi/6
Figure 11: AR(2): data (top) and abs(DFT) (bottom)
6. Compute and plot the IDFT of a so-called spectral line
1
k = k1
ΞT X (ωk ) =
0 otherwise
as well as a double line
k = k1
1
2
k = k2
ΞT X (ωk ) =
0 otherwise
For Our example We assume that T = 1000 and k1 = 10, k2 = 20.
>
>
>
>
>
>
>
>
+
+
+
+
+
+
+
len<-1000
z_1<-1:len
z_2<-z
DFT_1<-rep(0,1+len/2)
DFT_1[10]<-1
DFT_2<-DFT_1
DFT_2[20]<-2
for (k in 1:len)#k<-1
{
cexp <- complex(arg=(0:(len/2))*2*pi*k/len)
# Weights w_k
if (abs(len/2-as.integer(len/2))<0.1)
{
cexp<-cexp*c(rep(1,length(cexp)-1),(1/2))
}
28
+
+
+
+
+
+
>
>
>
>
>
>
# IDFT
z_1[k]<-sum(c(cexp[1]*DFT_1[1]*sqrt((2*pi)/len),
2*Re(cexp[2:length(cexp)]*DFT_1[2:length(DFT_1)]*sqrt((2*pi)/len))))
z_2[k]<-sum(c(cexp[1]*DFT_2[1]*sqrt((2*pi)/len),
2*Re(cexp[2:length(cexp)]*DFT_2[2:length(DFT_2)]*sqrt((2*pi)/len))))
}
file = paste("z_ls.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
ts.plot(z_1,xlab="",main="IDFT of single line spectrum")
ts.plot(z_2,xlab="",main="IDFT of double line spectrum")
dev.off()
null device
1
0.05
−0.15
z_1
IDFT of single line spectrum
0
200
400
600
800
1000
0.0
−0.4
z_2
0.4
IDFT of double line spectrum
0
200
400
600
800
1000
Figure 12: IDFT applied to single (top) and double (bottom) line spectra
A single line spectrum in the frequency-domain corresponds to a single cosine function with
the corresponding frequency. A double line corresponds to the weighted sum of two cosine
functions. Arbitrary data can be generated or replicated by more complex line spectra: this
is the ‘core message’ of the DFT and the IDFT. Moreover, We do not require any possibly unrealistic model assumption: the tautological essence of the identity confers illimited
generality to the decomposition.
7. Consider the non-stationary integrated time series
yt = yt−1 + t
29
where t is a white noise sequence with σ 2 = 1. Generate a realization of length 300 of the
above time series, compute the DFT 6 and the IDFT 7 and verify the identity 7. Plot the
absolute DFT and the data, see fig.13.
>
>
>
>
>
>
+
+
+
+
>
>
>
+
+
+
+
+
+
+
+
+
+
+
>
set.seed(10)
len<-300
y<-cumsum(rnorm(len))
# DFT----------DFT<-0:(len/2)
for (k in 0:(len/2))
{
cexp <- complex(arg=-(1:len)*2*pi*k/len)
DFT[k+1]<-sum(cexp*y*sqrt(1/(2*pi*len)))
}
# IDFT
z<-y
for (k in 1:len)#k<-1
{
cexp <- complex(arg=(0:(len/2))*2*pi*k/len)
# Weights w_k
if (abs(len/2-as.integer(len/2))<0.1)
{
cexp<-cexp*c(rep(1,length(cexp)-1),(1/2))
}
# IDFT
z[k]<-sum(c(cexp[1]*DFT[1]*sqrt((2*pi)/len),2*Re(cexp[2:length(cexp)]*
DFT[2:length(DFT)]*sqrt((2*pi)/len))))
}
cbind(y,z)[(len-20):len,]
[1,]
[2,]
[3,]
[4,]
[5,]
[6,]
[7,]
[8,]
[9,]
[10,]
[11,]
[12,]
[13,]
[14,]
[15,]
[16,]
[17,]
[18,]
[19,]
[20,]
[21,]
y
-23.93087+0i
-23.60336+0i
-23.53950+0i
-24.67906+0i
-23.49865+0i
-23.45726+0i
-24.67085+0i
-24.59766+0i
-24.85498+0i
-24.58818+0i
-23.20045+0i
-23.00737+0i
-22.41505+0i
-23.24503+0i
-22.85246+0i
-22.46759+0i
-21.41654+0i
-20.26075+0i
-21.29518+0i
-21.54965+0i
-20.27597+0i
z
-23.93087+0i
-23.60336+0i
-23.53950+0i
-24.67906+0i
-23.49865+0i
-23.45726+0i
-24.67085+0i
-24.59766+0i
-24.85498+0i
-24.58818+0i
-23.20045+0i
-23.00737+0i
-22.41505+0i
-23.24503+0i
-22.85246+0i
-22.46759+0i
-21.41654+0i
-20.26075+0i
-21.29518+0i
-21.54965+0i
-20.27597+0i
> file = paste("z_ns.pdf", sep = "")
> pdf(file = paste(path.out,file,sep=""), paper = "special",
30
+
>
>
>
+
>
+
>
>
>
width = 6, height = 6)
par(mfrow=c(2,1))
ts.plot(y,xlab="",main="Non-stationary data")
plot(abs(DFT),type="l",axes=F,col="blue",
main="|DFT| non-stationary data",xlab="")
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
−15
−30
y
0
Non−stationary data
0
50
100
150
200
250
300
5pi/6
pi
80
40
0
abs(DFT)
|DFT| non−stationary data
0
pi/6
2pi/6
3pi/6
4pi/6
Figure 13: Non-stationary data (top) and absolute DFT (bottom)
The non-stationarity (stochastic trend) of yt is refelected by a huge peak of |DFT| towards
frequency zero: the low-frequency components dominate the data.
8. Compute x̂T +1 , x̂T +2 , ..., x̂T +601 based on the IDFT 7 and plot the ‘forecasts’.
>
>
>
+
+
+
+
# IDFT
z<-rep(y,3)
for (k in len+1:(2*len))#k<-1
{
cexp <- complex(arg=(0:(len/2))*2*pi*k/len)
# Weights w_k
if (abs(len/2-as.integer(len/2))<0.1)
31
+
+
+
+
+
+
+
>
>
>
+
>
+
>
>
{
cexp<-cexp*c(rep(1,length(cexp)-1),(1/2))
}
# IDFT
z[k]<-sum(c(cexp[1]*DFT[1]*sqrt((2*pi)/len),
2*Re(cexp[2:length(cexp)]*DFT[2:length(DFT)]*sqrt((2*pi)/len))))
}
z<-Re(z)
file = paste("z_nsf.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
ts.plot(c(z[1:len],rep(NA,2*len)),xlab="",
main="Non-stationary data (black) and forecasts based on IDFT (blue)")
lines(c(rep(NA,len),z[len+1:(2*len)]),col="blue",lwd=1)
dev.off()
null device
1
−10
−15
−20
−30
−25
c(z[1:len], rep(NA, 2 * len))
−5
0
Non−stationary data (black) and forecasts based on IDFT (blue)
0
200
400
600
800
Figure 14: Non-stationary data (black) and IDFT forecasts
The above forecasts confirm the periodicity argument. Obviously, periodicity heavily conflicts with the non-stationarity of the data because it implies an unrealistic disruption of the
dominating trend component at the end of the time series.
32
2.3
Periodogram
The periodogram IT X (ωk ) is defined in terms of the squared absolute DFT:
IT X (ωk ) = |ΞT X (ωk )|
2
(9)
The periodogram is less informative than the DFT because the phase angle of the complex number
ΞT X (ωk ) is lost/ignored. In fact one can show that the periodogram is the DFT of the sample
autocovariance function R̂(k):
T
−1
X
1
R̂(j) exp(−ijωk ) , |k| = 1, ..., T /2
2π
IT X (ωk ) =
(10)
j=−(T −1)
T
2
x
,
k=0
2π
where
R̂(j) :=
T −|j|
1 X
xt xt+|j|
T t=1
(11)
is the sample autocovariance of a zero-mean stationary process. For |j| = 0, ..., T − 1 one obtains
‘almost’ an inverse transformation
2π
T
[T /2]
X
wk exp(−ijωk )IT X (ωk ) =
k=−[T /2]
R̂(j) + R̂(T − j) ,
t 6= 0
R̂(0)
, otherwise
(12)
P|j|
Note that for large sample sizes T and small j, the sample autocovariance R̂(T −|j|) := T1 t=1 xt xt+|j|
will be small compared to R̂(|j|) and therefore 12 is ‘nearly’ the inverse of 10. A formal proof of
these identities is to be found in proposition 1 in the appendix where it is shown, also, that the
additional R̂(T − j) in 12 is an expression of the implicit periodicity of the data.
The periodogram can be interpreted as a decomposition of the sample variance into contributions by components of frequency ωk :
R̂(0) =
2π
T
[T /2]
X
k=−[T /2]
IT X (ωk ) =
[T /2]
2π
2π X
IT X (0) + 2
IT X (ωk )
T
T
(13)
k=1
where for simplicity of notation We discarded the practically negligible weights wk . The value
2 2π
T IT X (ωk ) measures that part of the sample variance which is attributable to components with
frequency ωk .
For a stationary zero-mean process the statistics R̂(k) in 11 are the natural sample estimates
of the autocovariance function R(k). Then the periodogram is a natural estimate of the so-called
spectral density
∞
1 X
R(j) exp(−ijω)
h(ω) =
2π j=−∞
of the stationary process. The spectral density measures contributions of components with frequency ω to the variance of the process7 . For a white noise sequence R(k) = 0 for |k| > 0 so
that
σ2
h(ω) =
2π
7 Instead of the discrete sum of the periodogram one would need to integrate the spectral density on a pre-specified
frequency-interval but We here omit practically irrelevant details of this classical theory.
33
is constant: all components contribute equally to the variance (physical analogy: white light).
Unfortunately, the sample estimates do not vanish: R̂(k) 6= 0; therefore the periodogram 10 of a
realization of a white noise is not a constant function. But in the mean, over many realizations,
the sample autocovariances tend to zero and therefore the average periodogram converges to a
constant – a flat spectrum – too, recall exercise 4, fig. 10 middle graph: the average absolute DFT
(the square root of the periodogram) is concentrated in a narrow band about a constant level.
Therefore We could rely on the periodogram statistic for diagnostic purposes: model residuals
should have a flat spectrum i.e. the periodogram should be ‘approximately’ flat8 .
In the case of a non-stationary integrated process the autocovariance function is no more timeinvariant. However, one can difference the process – until stationarity is achieved – and then define
a so-called pseudo spectral density based on the density of the differenced (stationary) process.
We here omit details and refer to later sections where We shall introduce a pseudo-periodogram.
Note that 10 and 12 are once again tautological number identities which hold irrespective
of model assumptions. Substance is obtained by interpreting 11 as sample estimates of the autocovariance function which requires the process to be stationary. However, Our usage of the
periodogram and the DFT will be ‘different’ than in classical time series analysis and therefore
We can neglect, to some extent, typical model-based arguments.
2.3.1
Exercises
1. Compute the sample Autocovariance function of the AR(2) process in the previous exercise
and verify pertinence of 10.
>
>
>
>
+
+
+
>
>
>
+
+
+
+
>
len<-length(y_ar2)
Rk<-1:len
# Compute sample autocovariances
for (j in 1:len)
{
Rk[j]<-y_ar2[j:len]%*%y_ar2[1:(len-j+1)]/len
}
# Compute periodogram based on sample autocovariances
per<-rep(0,1+len/2)
for (k in 0:as.integer(len/2)) #k<-1
{
omega_k<-k*pi*2/len
per[k+1]<-(1/(2*pi))*(Rk[1]+2*Re(Rk[2:len]%*%exp(-1.i*omega_k*1:(len-1))))
}
cbind(abs(DFT_ar2)^2,per)[1:30,]
[1,]
[2,]
[3,]
[4,]
[5,]
[6,]
[7,]
[8,]
[9,]
[10,]
[11,]
8 The
0.241520552
0.064751577
0.193784316
0.878443813
0.021949703
0.347430183
0.180453510
0.191588094
0.127472421
0.067948927
0.012723790
per
0.241520552
0.064751577
0.193784316
0.878443813
0.021949703
0.347430183
0.180453510
0.191588094
0.127472421
0.067948927
0.012723790
periodogram is used as a dignostic statistic in X-12-ARIMA or X-13-SEATS, for example.
34
[12,]
[13,]
[14,]
[15,]
[16,]
[17,]
[18,]
[19,]
[20,]
[21,]
[22,]
[23,]
[24,]
[25,]
[26,]
[27,]
[28,]
[29,]
[30,]
0.113731244
0.461707983
0.274940063
0.199814718
0.107146365
0.170392328
0.062302323
0.036632699
0.104488897
0.713856097
0.088343213
0.105389880
0.009737464
0.044015537
0.259779773
0.649703402
0.183598036
0.307831728
0.566435079
0.113731244
0.461707983
0.274940063
0.199814718
0.107146365
0.170392328
0.062302323
0.036632699
0.104488897
0.713856097
0.088343213
0.105389880
0.009737464
0.044015537
0.259779773
0.649703402
0.183598036
0.307831728
0.566435079
The series are identical, thus confirming 10.
2. Write a function which computes the DFT as well as the periodogram of a time series xt .
Hint: from now on We ignore the weights wk .
> per<-function(x,plot_T)
+ {
+
len<-length(x)
+
per<-0:(len/2)
+
DFT<-per
+
+
for (k in 0:(len/2))
+
{
+
cexp <- complex(arg=-(1:len)*2*pi*k/len)
+
DFT[k+1]<-sum(cexp*x*sqrt(1/(2*pi*len)))
+
}
+
per<-abs(DFT)^2
+
if (plot_T)
+
{
+
par(mfrow=c(2,1))
+
plot(per,type="l",axes=F,xlab="Frequency",ylab="Periodogram",
+
main="Periodogram")
+
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6",
+
"4pi/6","5pi/6","pi"))
+
axis(2)
+
box()
+
plot(log(per),type="l",axes=F,xlab="Frequency",ylab="Log-periodogram",
+
main="Log-periodogram")
+
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6",
+
"4pi/6","5pi/6","pi"))
+
axis(2)
+
box()
+
}
+
return(list(DFT=DFT,per=per))
+ }
35
3. Verify that the function replicates the periodogram of the above AR(2)-realization.
> plot_T<-F
> cbind(per(y_ar2,plot_T)$per,abs(DFT_ar2)^2)[1:30,]
[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,]
[,1]
0.241520552
0.064751577
0.193784316
0.878443813
0.021949703
0.347430183
0.180453510
0.191588094
0.127472421
0.067948927
0.012723790
0.113731244
0.461707983
0.274940063
0.199814718
0.107146365
0.170392328
0.062302323
0.036632699
0.104488897
0.713856097
0.088343213
0.105389880
0.009737464
0.044015537
0.259779773
0.649703402
0.183598036
0.307831728
0.566435079
[,2]
0.241520552
0.064751577
0.193784316
0.878443813
0.021949703
0.347430183
0.180453510
0.191588094
0.127472421
0.067948927
0.012723790
0.113731244
0.461707983
0.274940063
0.199814718
0.107146365
0.170392328
0.062302323
0.036632699
0.104488897
0.713856097
0.088343213
0.105389880
0.009737464
0.044015537
0.259779773
0.649703402
0.183598036
0.307831728
0.566435079
4. Compute the periodogram of the white noise sequence as well as of the lowpassed series in
fig.4 by relying on the new periodogram function, see fig.15. Hint: use the common time
sample t = 100, ..., 200 for both the noise t as well as the lowpassed yt .
>
>
>
>
>
+
+
+
>
>
>
>
+
+
len<-300
set.seed(10)
eps<-rnorm(len)
y<-rep(NA,len)
for (k in 100:200)#k<-0
{
y[k]<-gamma[1:100]%*%eps[k+(0:99)]+gamma[2:100]%*%eps[k-(1:99)]
}
file = paste("z_per_n_lpn.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
plot_T<-F
plot(per(na.exclude(y),plot_T)$per,type="l",axes=F,
main="Periodograms of noise (blue) and lowpassed noise(red)",xlab="",
ylab="",col="red",lwd=2)
36
>
>
>
+
>
>
>
lines(per(eps[!is.na(y)],plot_T)$per,col="blue",lwd=2)
K<-length(per(na.exclude(y),plot_T)$per)-1
axis(1, at=c(0,1+1:6*K/6),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
0.0
0.2
0.4
0.6
0.8
Periodograms of noise (blue) and lowpassed noise(red)
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Figure 15: Noise (blue) and lowpassed noise (red)
We can see that the periodogram of the lowpassed series (red) is close to zero for frequencies
in the stopband ωk > π/6 = cutoff. In the passband ωk < π/6 = cutoff both periodograms
are similar. Note that We applied a finite approximation of the lowpass of order 100. By
letting the order increase arbitrarily (the time series must be lengthened accordingly) We
could verify that the periodogram of the lowpassed series (red) would converge to zero in
the stopband; in the passband it would converge to the periodogram of the original noise
(blue). The term lowpass means that the low frequencies (in the passband) of an arbitrary
time series ‘go through’ whereas the higher frequencies (in the stopband) are damped or
even eliminated. Since We are able to design arbitrary bandpass functions and since any
‘well behaved’ function can be approximated arbitrary well by a suitable linear combination
of bandpasses We could in principle extract (highlight) or eliminate arbitrary components
in a series. Note, however, that the above filter cannot be applied towards the sample-end
because of symmetry: it is not designed for real-time applications.
37
5. We here rely on the periodogram for diagnostic purposes. Generate a realization of length
100 of the AR(2)-process
xt = 1.4xt−1 − 0.7xt−2 + t
with σ 2 = 1.
• Plot the data as well as acf and pacf and determine a plausible model, see fig.16.
>
>
>
>
>
>
+
>
>
>
>
>
len<-100
set.seed(10)
model<-list(order=c(2,0,0),ar=c(1.4,-0.7))
y<-arima.sim(model,n=len)
file = paste("z_acf_ar2.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(3,1))
ts.plot(y,main="Data AR(2)")
acf(y)
acf(y,type="partial")
dev.off()
null device
1
y
−4
0
4
Data AR(2)
0
20
40
60
80
100
Time
ACF
−0.4
0.2
0.8
Series y
0
5
10
15
20
Lag
0.5
−0.5
Partial ACF
Series y
5
10
15
20
Lag
Figure 16: Data AR(2) and sample acf/pacf
• Fit true AR(2)- as well as false AR(1)-, MA(2)- and MA(5)-models: compute and plot
periodograms of the resulting model residuals, see fig.17.
> # false models
> model_ar1<-list(order=c(1,0,0))
38
>
>
>
>
>
>
>
>
>
>
>
>
+
>
>
>
+
+
>
>
+
>
>
>
+
+
>
>
>
>
>
>
>
+
>
>
>
model_ma2<-list(order=c(0,0,2))
model_ma5<-list(order=c(0,0,5))
y.true<-arima(y,order=model$order)
res_true<-y.true$residuals
y.ar1<-arima(y,order=model_ar1$order)
res_ar1<-y.ar1$residuals
y.ma2<-arima(y,order=model_ma2$order)
res_ma2<-y.ma2$residuals
y.ma5<-arima(y,order=model_ma5$order)
res_ma5<-y.ma5$residuals
file = paste("z_per_ar2_diag.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(2,1))
plot_T<-F
plot(per(res_true,plot_T)$per,type="l",axes=F,
main="Periodograms of residuals : true AR(2)",xlab="",
ylab="",col="black",lwd=2)
K<-length(per(res_true,plot_T)$per)-1
axis(1, at=c(0,1+1:6*K/6),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
plot(per(res_ar1,plot_T)$per,type="l",axes=F,
main="Periodograms of residuals: false AR(1), MA(2), MA(5)",xlab="",
ylab="",col="red",lwd=2)
lines(per(res_ma2,plot_T)$per,col="green",lwd=2)
lines(per(res_ma5,plot_T)$per,col="blue",lwd=2)
mtext("AR(1)", side = 3, line = -1,at=len/4,col="red")
mtext("MA(2)", side = 3, line = -2,at=len/4,col="green")
mtext("MA(5)", side = 3, line = -3,at=len/4,col="blue")
K<-length(per(res_true,plot_T)$per)-1
axis(1, at=c(0,1+1:6*K/6),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
39
0.0 0.2 0.4
Periodograms of residuals : true AR(2)
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Periodograms of residuals: false AR(1), MA(2), MA(5)
0.0
1.0
2.0
AR(1)
MA(2)
MA(5)
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Figure 17: Periodograms of true AR(2) (top) and false AR(1), MA(2), MA(5)
The periodogram of the residuals of the true AR(2)-model is typically ‘noisy’ but otherwise flat: no portions of the frequency band seem over- or underemphasized. In
contrast, the residuals of the misspecified AR(1) and MA(2)-models show evidence of a
strong peak in the vicinity of π/6. Due to its larger model order, the peak of the false
MA(5) is less prominent. By computing the roots of the characteristic polynomial of
the process
> polyroot(c(0.7,-1.4,1))
[1] 0.7+0.4582576i 0.7-0.4582576i
We see that the frequency
> Arg(polyroot(c(0.7,-1.4,1)))
[1]
0.5796397 -0.5796397
of the AR(2)-cycle is π/5.42 which corresponds to the frequency of the residual peaks
in the misspecified models.
3
Filters
The DFA relies on ‘filters’ rather than ‘models’. In a model-based approach, ‘filters’ are generally
obtained from ‘models’ (of the DGP). In the DFA We jump over the model-based bottle-neck9
and compute filters ‘directly’, without allusion to a hypothetical DGP. This way, We can derive
targeted – customized – optimization criteria which allow to control filter characteristics according
to important user-priorities.
9 The classic model-based paradigm relies on rigid one-step ahead forecast performances. We overcome this issue
by proposing a more general estimation paradigm.
40
3.1
Introduction
We here present some ordinary definitions and propose the main filter-classe(s).
3.1.1
Definitions
A filter is a general (linear) transformation, mapping an input series/signal xt to an output series/signal yt :
∞
X
yt =
γk xt−k
(14)
k=−∞
If there does not exist a k0 > 0 such γ|k| = 0 for |k| > k0 then the filter is called bi-infinite: the
filter-coefficients stretch indefinitely on both (positive/negative) ‘sides’. If γk = γ−k then the filter
is called symmetric: the lowpass in section 2.1.1
is a ‘typical’ example. If γk = 0 for k < 0 then
P∞
the resulting one-sided filter is called causal. If k=−∞ |γk |2 < ∞ then the filter is called stable 10 .
In applications one has to rely on a finite sample x1 , ..., xT for estimating yT +h , where T is the
sample size and h ∈ ZZ is any positive or negative integer:
ŷT +h :=
L−1+h
X
bkh xT +h−k
(15)
k=h
We distinguish the target filter and the approximating filter in notational terms by using γk for
the former and bkh for the latter. Note that
• the estimate ŷT +h can be computed for any t = T + h by setting h := t − T
• the estimate ŷT +h always relies on x1 , ..., xT , uniquely
• the time-shift h is obtained by designing filter-coefficients bkh accordingly
If Γ(·) is symmetric (no time-shift) and if h = 0, then ŷT is called a nowcast or real-time estimate
(of yT ) and bkh are (the coefficients of) a real-time filter. For h > 0 the estimate ŷT +h is called a
forecast and bkh are sometimes referred as a forecast filter. For h < 0 the expression 15 is called
a smoother and ŷT +h is sometimes referred to as a backcast.
A filter transformation is often identified with its filter coefficients or (slightly abusively) with
its output; therefore the term ‘filter’ refers either to the transformation (14, 15) or to the coefficients (γk , bkh ) or to the output (yt , ŷT +h )11 .
3.1.2
Examples
Conceptually, a ‘filter’ is a transformation. As an example, an invertible MA(1)-process
xt = t + b1 t−1
can be interpreted as a one-sided finite stable and causal filter with weights γ0 = 1, γ1 = b1 whose
input series is white noise t and whose output is the MA(1)-process. The transformation maps
the uncorrelated noise to an autocorrelated process. A stationary AR(1)-process
xt = a1 xt−1 + t =
∞
X
ak1 t−k
k=0
P∞
the literature one often finds the classical
k=−∞ |γk | < ∞ which is more constraining. We
here adopt a slightly more general L2 -perspective, relying on the Wold-decomposition theorem (according to which
MA-ceofficients must be square summable, too).
11 Note that the output alone (without the corresponding input) does not determine the filter coefficients. Therefore the last reference is formally abusive but effective and useful in notational terms.
10 In
L1 -stability
41
is a one-sided stable causal infinite filter with coefficients γk = ak1 and input series t . More
generally, SARIMA-models can be interpreted as particular one-sided filters whose input series is
invariably white noise (if the process is integrated then the filter is not stable anymore). Generalizing even further, the input series does not have to be white noise: literally any input series is
allowed.
Filter weights are generally specified/designed in view of performing a particular task. As an
example, exercise 4 on p.36 illustrated that the ideal lowpass filter 3 eliminates high-frequency
noise components, see fig.15: the resulting filter output yt in fig.4 is smooth. Alternatively, a
(finite) filter can be designed in view of estimating a particular target 14 based on data x1 , ..., xT .
As an example, We shall be interested in deriving an optimal finite-sample filter 15 whose output
approximates the ideal (bi-infinite) lowpass
yT +h
∞
1 X sin(k · cutoff)
xT +h−k
=
π
k
k=−∞
in t = T +h. We proposed and analyzed simple finite-sample filters approximating the ideal lowpass
in section 2.1.2, by truncating filter coefficients. More sophisticated ‘user-relevant’ estimates will
be presented later. Alternatively, We might be interested in forecasting the above MA(1)- or
AR(1)-processes such that the target becomes
yt =
∞
X
γk xt−k = xt+1
k=−∞
i.e. γ−1 = 1, γk = 0, k 6= −1: the target filter is finite, asymmetric and non-causal. The best finite
sample approximation of this target in the AR(1)-case is the well-known one-step ahead forecast
function
ŷt = x̂t+1 = a1 xt
a1
k=0
which is of length L = 1: the coefficients of the approximating filter are bk =
.
0 otherwise
In the MA(1)-case We obtain
ŷt = x̂t+1 =
∞
X
(−1)k bk+1
xt−k ≈
1
k=0
T
−1
X
(−1)k bk+1
xt−k
1
k=0
where the finite approximation of length L = T is ‘good’ if the process is invertible (|b1 | < 1)
and the sample size T is ‘large’. The coefficients of the approximating filter are (−1)k bk+1
,k =
1
0, ..., L − 1.
3.1.3
Filter-Classes: MA-, AR- and ARMA-Filters
An MA-filter of length L relates output yt and input xt+h−j , j = 0, ..., L − 1 according to
yt :=
L−1
X
bj−h xt+h−j
j=0
where h allows for arbitrary time-shifts. An AR-filter of length L0 links the output yt to lagged
outputs yt−k , k = 1, ..., L0 and the input xt+h
0
yt :=
L
X
ak yt−k + b−h xt+h
k=1
42
where h allows for arbitrary time-shifts and b−h is a scaling term. Finally, an ARMA-filter of
order (L, L0 ) relates yt to lagged yt−k , k = 1, ..., L0 and xt+h−j , j = 0, ..., L − 1:
0
yt :=
L
X
ak yt−k +
L−1
X
bj−h xt+h−j
j=0
k=1
The most important class in Our applications, by far, will be the MA-filters. AR and/or ARMAfilters will be used episodically, in exercices. Both filter types can be inverted into MA(∞)-designs:
the resulting filter is stable if the AR-part is ‘stationary’ i.e. if all roots of the characteristic polynomial are strictly smaller than one in absolute value.
As illustrated by the above examples, filters allow to address general prospective estimation
problems: traditional SARIMA-models and classical forecast functions are but one possible application. We now propose to analyze the link between input and output series and to characterize
‘filters’ according to their ‘effects’. Once completed, We can proceed to design filters according
to desirable properties/effects/characteristics. Neither of these requirements can be addressed
satisfactorily in the time domain.
3.2
3.2.1
Filter Effects
Transfer function: Amplitude, Phase and Time-Shift Functions
Let yt be the output of a general filter
yt =
∞
X
γk xt−k
k=−∞
In order to derive the important filter effect We assume a particular (complex-valued) input series
xt := exp(itω). The output signal is thus
yt
∞
X
=
γk exp(iω(t − k))
(16)
k=−∞
=
exp(iωt)
∞
X
γk exp(−ikω)
(17)
k=−∞
=
exp(iωt)Γ(ω)
(18)
where the (generally complex) function
Γ(ω) :=
∞
X
γ exp(−ikω)
(19)
k=−∞
is called the transfer function of the filter and γk are its Fourier coefficients. The lowpass in section
2.1.1 is an example of a (filter) transfer function. We can represent the complex number Γ(ω) in
polar coordinates according to
Γ(ω) = A(ω) exp(−iΦ(ω))
(20)
where A(ω) = |Γ(ω)| is called the amplitude of the filter and Φ(ω) is its phase.
We deduce from 16 that xt is a periodic eigensignal of the filter with eigenvalue Γ(ω): the
output is again a complex trigonometric signal with the same frequency. If the filter coefficients
are real, then linearity of the filter implies that real and imaginary parts of xt are mapped onto
real and imaginary parts of yt :
F (xt ) = F (<(xt ) + i=(xt )) = F (<(xt )) + iF (=(xt )) = <(F (xt )) + i=(F (xt ))
43
where F (<(xt )), F (=(xt )), <(F (xt )) and =(F (xt )) are all real. Therefore the cosine (real-part of
the input) is mapped to
cos(tω) →
<(exp(iωt)Γ(ω))
(21)
=
A(ω) [cos(tω) cos(−Φ(ω)) − sin(tω) sin(−Φ(ω))]
=
A(ω) cos(tω − Φ(ω))
=
A(ω) cos(ω(t − Φ(ω)/ω))
(22)
The amplitude function A(ω) can be interpreted as the weight (damping if A(ω) < 1, amplification
if A(ω) > 1) attributed by the filter to a sinusoidal input signal with frequency ω. The function
φ(ω) := −Φ(ω)/ω
(23)
can be interpreted as the time shift of the filter in ω 12 . For the lowpass in section 2.1.1 We have
Γ(ω) = 0 if ω > cutoff . Therefore, all high-frequency components are ‘cut’, as illustrated in fig.15.
Since the lowpass filter is symmetric, the imaginary part must vanish and since Γ(ω) ≥ 0 the phase
must vanish too (the phase of a positive real number is zero). Therefore the time-shift φ(ω) must
vanish too (in the passband).
Remark
The time-shift is defined by φ(ω) := −Φ(ω)/ω. This sign is convention: a positive shift then
amounts to a delay (lag) whereas a negative shift means an anticipation (lead). We note that the
transfer function could have been defined by
Γ0 (ω) :=
∞
X
γ exp(ikω)
k=−∞
which is just the complex conjugate of Our definition. In this case the phase (the angle of the complex transfer function) would change sign and We would define the time-shift as φ(ω) := Φ(ω)/ω.
We feel free to use either definition(s) in Our R-code. However, time-shifts are always defined such
that positive numbers correspond the lags/delays and negative numbers reflect leads/anticipation.
3.2.2
Transferfunction of MA- and Stable AR- and ARMA-Filters
The transferfunction of the MA(L)-filter
yt =
L−1
X
bj−h xt+h−j
j=0
is
L−1
X
Γ(ω) =
bj−h exp(−i(j − h)ω)
j=0
The transfer function of the stable AR(L0 )-filter
0
yt =
L
X
ak yt−k + b−h xt+h
k=1
can be obtained by inversion of the stable AR-part. Specifically if
L0
X
1 −
ak B k yt = b−h xt+h
k=1
12 The singularity in ω = 0 is resolved by noting that Φ(0) = 0 for filters satisfying Γ(0) > 0. As a result
φ(0) := Φ̇(0), see section 3.2.3, below.
44
then
yt =
(1 −
b−h
PL0
k=1
ak B k )
xt+h
and the transferfunction becomes
Γ(ω) =
b−h exp(ihω)
PL0
1 − k=1 ak exp(−ikω)
As an example let
yt = a1 yt−1 + b−h xt+h = b−h
∞
X
ak1 xt+h−k
k=0
Then
Γ(ω) = b−h
∞
X
ak1 exp(−i(k − h)ω) =
k=0
b−h exp(ihω)
1 − a1 exp(−iω)
as claimed.
The stable ARMA(L, L0 ) filter
0
yt =
L
X
ak yt−k +
L−1
X
bj−h xt+h−j
j=0
k=1
can be inverted into an infinite MA. Specifically, if
L0
L
X
X
1 −
ak B k yt =
bj−h B j xt+h
j=0
k=1
then
PL
yt =
1
j
j=0 bj−h B
xt+h
PL0
− k=1 ak B k
and thus the transferfunction becomes
PL
exp(ihω) j=0 bj−h exp(−ijω)
Γ(ω) =
PL0
1 − k=1 ak exp(−ikω)
As an example let
yt = a1 yt−1 + b−h xt+h + b1−h xt+h−1 = b−h
∞
X
ak1 xt+h−k + b1−h
k=0
∞
X
ak+1
xt+h−k
1
k=0
Then
Γ(ω)
= b−h
∞
X
ak1 exp(i(h − k)ω) + b1−h
k=0
=
∞
X
ak+1
exp(i(h − k)ω)
1
k=0
b−h + b1−h exp(−iω)
exp(ihω)
1 − a1 exp(−iω)
as claimed.
We note that the time-domain backshift operator B k corresponds to the frequency-domain
‘operator’ exp(−ikω) (and conversely): a time-shift of φ(ω) = k time units corresponds to a
phase-angle Φ(ω) = −φ(ω)ω = −kω i.e. the frequency-domain expression is rotated by an angle
of −kω or, alternatively, it is multiplied by exp(−ikω).
45
The Time-Shift in Frequency Zero∗
3.2.3
The time-shift Φ̂(ω)/ω is subject to a singularity in frequency zero: a zero-over-zero quotient.
However, one can apply first order Taylor approximations to both terms of the quotient (l’Hôpital’s
rule) which leads to
φ̂(0)
=
=
=
Φ̂(ω)
ω
d
dω Φ̂(ω)
lim
ω→0
ω=0
1 d
dω Γ̂(ω)
ω=0
−iÂ(0)
PL−1
=
j=0 jbj
PL−1
j=0 bj
(24)
Second and third equalities are obtained by looking at
−i
L−1
X
jbj
=
j=0
=
=
d
Γ̂(ω)
dω
ω=0
d
d
exp(−iΦ(0)) − iÂ(0) exp(−iΦ(0))
Â(ω)
Φ̂(ω)
dω
dω
ω=0
ω=0
d
−iÂ(0)
Φ̂(ω)
dω
ω=0
The derivative of the amplitude vanishes in zero because the amplitude is a continuous even
function i.e. Â(−ω) = Â(ω).
3.2.4
Exercises
1. Consider the MA(1)-filter
yt = b0 xt + b1 xt−1
and assume xt = cos(tω) is a trigonometric input signal with frequency ω. Compute, plot and
compare in- and output signals for different ω for the two filters with coefficients b0 = b1 = 1
and b0 = 1, b1 = −1, see fig.18 (We used ω = π/20 and ω = pi/5).
>
>
>
>
+
>
>
>
>
>
>
>
+
+
>
>
len<-100
b0<-1
file = paste("z_cos_in_out.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(2,2))
b1<--1
omega1<-pi/20
y<-rep(0,len)
x<-cos((1:len)*omega1)
y[2:len]<-b0*x[2:len]+b1*x[1:(len-1)]
ts.plot(x,type="l",main=paste("MA(1): b1 = ",b1,
", omega=",round(omega1,3),sep=""),xlab="",
ylab="",col="blue",lwd=1)
lines(y,col="red",lwd=1)
mtext("Input", side = 3, line = -1,at=len/2,col="blue")
46
>
>
>
>
+
+
>
>
>
>
>
>
>
>
>
+
+
>
>
>
>
>
>
+
+
>
>
>
>
mtext("Output", side = 3, line = -2,at=len/2,col="red")
b1<-1
y[2:len]<-b0*x[2:len]+b1*x[1:(len-1)]
ts.plot(y,type="l",main=paste("MA(1): b1 = ",b1,
", omega=",round(omega1,3),sep=""),xlab="",
ylab="",col="red",lwd=1)
lines(x,col="blue",lwd=1)
mtext("Input", side = 3, line = -1,at=len/2,col="blue")
mtext("Output", side = 3, line = -2,at=len/2,col="red")
b1<--1
omega2<-pi/5
y<-rep(0,len)
x<-cos((1:len)*omega2)
y[2:len]<-b0*x[2:len]+b1*x[1:(len-1)]
ts.plot(x,type="l",main=paste("MA(1): b1 = ",b1,
", omega=",round(omega2,3),sep=""),xlab="",
ylab="",col="blue",lwd=1)
lines(y,col="red",lwd=1)
mtext("Input", side = 3, line = -1,at=len/2,col="blue")
mtext("Output", side = 3, line = -2,at=len/2,col="red")
b1<-1
y[2:len]<-b0*x[2:len]+b1*x[1:(len-1)]
ts.plot(y,type="l",main=paste("MA(1): b1 = ",b1,
", omega=",round(omega2,3),sep=""),xlab="",
ylab="",col="red",lwd=1)
lines(x,col="blue",lwd=1)
mtext("Input", side = 3, line = -1,at=len/2,col="blue")
mtext("Output", side = 3, line = -2,at=len/2,col="red")
dev.off()
null device
1
47
MA(1): b1 = 1, omega=0.157
2
1.0
MA(1): b1 = −1, omega=0.157
Input
Output
−2
−1.0
−1
0
0.0
1
0.5
Input
Output
0
20
40
60
80
100
0
20
40
60
80
100
Input
Output
Input
Output
0.5
−1.0
−1
0
0.0
1
MA(1): b1 = 1, omega=0.628
1.0
MA(1): b1 = −1, omega=0.628
0
20
40
60
80
100
0
20
40
60
80
100
Figure 18: Filter effect of MA(1) on trigonometric input
2. Compute amplitude and time-shift functions of the two MA(1)-filters and verify the observed
filter effects in the above figure.
>
>
+
>
>
>
>
>
>
>
>
file = paste("z_amp_pha_ma1.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(2,2))
# Resolution of discrete frequency grid
len1<-1001
omega_k<-(0:len1)*pi/len1
# Compute transfer function, amplitude, phase and time-shift
b1<-1
trffkt1<-1+b1*complex(arg=-omega_k)
amplitude1<-abs(trffkt1)
48
>
>
>
+
>
>
>
+
>
+
>
+
>
>
>
+
+
>
>
>
+
>
+
>
+
>
>
>
>
>
>
>
>
+
>
>
>
+
>
+
>
+
>
>
>
+
>
>
>
+
>
+
>
+
phase1<-Arg(trffkt1)
shift1<--phase1/omega_k
plot(amplitude1,type="l",main=paste("Amplitude MA(1): b1 = ",b1,sep=""),
axes=F,xlab="Frequency",ylab="Amplitude",col="black")
abline(v=(len1-1)/(pi/omega1),lty=2,col="blue")
abline(v=(len1-1)/(pi/omega2),lty=2,col="orange")
mtext(paste("pi/",pi/omega1,sep=""), side = 3, line = -4,
at=len1/20,col="blue")
mtext(paste("pi/",pi/omega2,sep=""), side = 3, line = -6,
at=len1/5,col="orange")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6",
"3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(shift1,type="l",main=paste("Time-shift MA(1): b1 = ",b1,sep=""),
axes=F,xlab="Frequency",ylab="Shift",col="green",
ylim=c(min(na.exclude(shift1))-0.5,max(na.exclude(shift1))+0.5))
abline(v=(len1-1)/(pi/omega1),lty=2,col="blue")
abline(v=(len1-1)/(pi/omega2),lty=2,col="orange")
mtext(paste("pi/",pi/omega1,sep=""), side = 3, line = -4,
at=len1/20,col="blue")
mtext(paste("pi/",pi/omega2,sep=""), side = 3, line = -6,
at=len1/5,col="orange")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6",
"3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
b1<--1
trffkt2<-1+b1*complex(arg=-omega_k)
amplitude2<-abs(trffkt2)
phase2<-Arg(trffkt2)
shift2<--phase2/omega_k
plot(amplitude2,type="l",main=paste("Amplitude MA(1): b1 = ",b1,sep=""),
axes=F,xlab="Frequency",ylab="Amplitude",col="black")
abline(v=(len1-1)/(pi/omega1),lty=2,col="blue")
abline(v=(len1-1)/(pi/omega2),lty=2,col="orange")
mtext(paste("pi/",pi/omega1,sep=""), side = 3, line = -4,
at=len1/20,col="blue")
mtext(paste("pi/",pi/omega2,sep=""), side = 3, line = -6,
at=len1/5,col="orange")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6",
"3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(shift2,type="l",main=paste("Time-shift MA(1): b1 = ",b1,sep=""),
axes=F,xlab="Frequency",ylab="Shift",col="green")
abline(v=(len1-1)/(pi/omega1),lty=2,col="blue")
abline(v=(len1-1)/(pi/omega2),lty=2,col="orange")
mtext(paste("pi/",pi/omega1,sep=""), side = 3, line = -4,
at=len1/20,col="blue")
mtext(paste("pi/",pi/omega2,sep=""), side = 3, line = -6,
at=len1/5,col="orange")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6",
"3pi/6","4pi/6","5pi/6","pi"))
49
> axis(2)
> box()
> dev.off()
null device
1
>
>
+
+
+
+
>
>
+
+
# Compute table with shifts and amplitudes in omega=pi/20 and omega=pi/5
table_amp_shift<rbind(c(amplitude1[(len1-1)/(pi/omega1)+1],shift1[(len1-1)/(pi/omega1)+1]),
c(amplitude2[(len1-1)/(pi/omega1)+1],shift2[(len1-1)/(pi/omega1)+1]),
c(amplitude1[(len1-1)/(pi/omega2)+1],shift1[(len1-1)/(pi/omega2)+1]),
c(amplitude2[(len1-1)/(pi/omega2)+1],shift2[(len1-1)/(pi/omega2)+1]))
dimnames(table_amp_shift)[[2]]<-c("Amplitude","Shift")
dimnames(table_amp_shift)[[1]]<-c(paste("pi/",pi/omega1,",b1=1",sep=""),
paste("pi/",pi/omega1,",b1=-1",sep=""),
paste("pi/",pi/omega2,",b1=1",sep=""),paste("pi/",pi/omega2,",b1=-1",sep=""))
50
Time−shift MA(1): b1 = 1
0.8
Shift
pi/20
0.4
1.5
pi/5
pi/5
0.0
0.5
1.0
pi/20
0.0
Amplitude
2.0
Amplitude MA(1): b1 = 1
0
pi/6
3pi/6
5pi/6
0
pi/6
3pi/6
5pi/6
Frequency
Amplitude MA(1): b1 = −1
Time−shift MA(1): b1 = −1
−100
Shift
pi/20
−300
1.5
pi/5
pi/5
−500
0.5
1.0
pi/20
0.0
Amplitude
2.0
Frequency
0
pi/6
3pi/6
5pi/6
0
pi/6
Frequency
3pi/6
5pi/6
Frequency
Figure 19: Amplitude and time-shifts of MA(1)-filters
The amplitude and time shifts at frequencies π/20 and π/5 for the two MA-filters are summarized in table 1. These numbers coincide with the effects observed in fig.18. The difference
pi/20,b1=1
pi/20,b1=-1
pi/5,b1=1
pi/5,b1=-1
Amplitude
1.994
0.157
1.902
0.617
Shift
0.500
-9.510
0.500
-2.002
Table 1: Amplitudes and time-shifts of MA(1)-filters in pi/20 and pi/5
filter
yt = xt − xt−1
51
(b1 = −1) is important in time series analysis because it is used to transform a non-stationary
(trending/integrated) series into a stationary constant-level series. The lower left panel in
fig.19 illustrates that the amplitude function of the difference filter vanishes in frequency
zero: thus the filter can eliminate a (zero-frequency) trend in a non-stationary series. But
We see also that the filter amplifies high-frequency noise. Interestingly, the time-shift of
the filter is negative 13 : as can be seen in the left panels of fig.18, the output series (red)
is shifted to the right and turning-points of the input signal are anticipated14 . In contrast,
the MA-filter with positive b1 = 1 damps/eliminates the highest frequencies; its time-shift
φ(ω) = 0.5 is positive and constant everywhere: turning-points are (slightly) delayed in the
output series (red) of the right panels in fig.18. The observed characteristics are typical for
one-sided (causal) lowpass filters: the low-frequency components in the passband tend to be
delayed and hence turning-points are delayed15 .
3. Shift and scale the input signal according to amplitude and time-shift functions and verify
that the resulting series coincides with the output signal, see fig.20 (We compute results for
the case ω = π/20 and b1 = 1 only). Hint: the resulting amplitude and time-shifts in table
1 are stored in the object table amp shift.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
+
+
>
>
>
>
# We verify the claim for omega=pi/20 and b1=1
amp_scaling<-table_amp_shift[1,1]
shift<-table_amp_shift[1,2]
len<-100
b0<-1
b1<-1
omega1<-pi/20
y<-rep(0,len)
x<-cos((1:len)*omega1)
y[2:len]<-b0*x[2:len]+b1*x[1:(len-1)]
# Here We scale and shift the input signal
z<-amp_scaling*cos((1:len-shift)*omega1)
file = paste("z_out_ssout.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
ts.plot(y,type="l",main=paste("Output vs. scaled and shifted input: b0 = b1 = ",
b1,", omega=",round(omega1,3),sep=""),xlab="",
ylab="",col="red",lwd=1)
lines(z,col="green",lwd=1)
mtext("Scaled and shifted input", side = 3, line = -1,at=len/2,col="green")
mtext("Output", side = 3, line = -2,at=len/2,col="red")
dev.off()
null device
1
13 The
divergence towards −∞ in ω = 0 is due to φ(0) = − limω→0 Φ(ω)/ω = −π/0.
slope of a growing (smooth) time series must decrease before the series can decline: first differences are
anticipative. But not every turning-point of the slope (of first differences) leads to a turning-point of the original
series.
15 The positive time-shift has some deep repercussions: as an example recession down-turns in macro-series cannot
be detected timely and trading orders (buy/sells) cannot be executed at the optimal turning-points of an asset series.
14 The
52
Output vs. scaled and shifted input: b0 = b1 = 1, omega=0.157
−2
−1
0
1
2
Scaled and shifted input
Output
0
20
40
60
80
100
Figure 20: Output of MA(1) vs. scaled and shifted input
Both series overlap perfectly except at the start where the output is (deliberately wrongly)
initialized with zero: so that We can see that both series are indeed computed differently!
4. We now look at the AR(1)-filter
yt = a1 yt−1 + b0 xt
and assume, again, that xt = cos(tω) is a trigonometric input signal with frequency ω.
Compute, plot and compare in- and output signals for different ω for the two filters with
coefficients b0 = 1, a1 = 0.9 and b0 = 0.1, a1 = 0.9, see fig.21 (We used ω = π/20 and
ω = pi/5).
>
>
>
>
>
>
>
>
>
>
>
+
>
+
+
len<-1000
a1<-0.9
file = paste("z_cos_in_out_ar1.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
len<-1000
par(mfrow=c(2,2))
b0<-1
omega1<-pi/20
y<-rep(0,len)
x<-cos((1:len)*omega1)
for (i in 2:len)
y[i]<-b0*x[i]+a1*y[i-1]
ts.plot(y[(len-99):len],type="l",main=paste("AR(1): b0 = ",
b0, ", a1 = ",a1,", omega=",round(omega1,3),sep=""),xlab="",
ylab="",col="red",lwd=1)
53
>
>
>
>
>
>
+
>
+
+
>
>
>
>
>
>
>
>
+
>
+
+
>
>
>
>
>
+
>
+
+
>
>
>
>
lines(x[(len-99):len],col="blue",lwd=1)
mtext("Input", side = 3, line = -1,at=50,col="blue")
mtext("Output", side = 3, line = -2,at=50,col="red")
b0<-0.1
y<-rep(0,len)
for (i in 2:len)
y[i]<-b0*x[i]+a1*y[i-1]
ts.plot(x[(len-99):len],type="l",main=paste("AR(1): b0 = ",
b0, ", a1 = ",a1,", omega=",round(omega1,3),sep=""),xlab="",
ylab="",col="blue",lwd=1)
lines(y[(len-99):len],col="red",lwd=1)
mtext("Input", side = 3, line = -1,at=50,col="blue")
mtext("Output", side = 3, line = -2,at=50,col="red")
b0<-1
omega2<-pi/5
y<-rep(0,len)
x<-cos((1:len)*omega2)
for (i in 2:len)
y[i]<-b0*x[i]+a1*y[i-1]
ts.plot(y[(len-99):len],type="l",main=paste("AR(1): b0 = ",
b0, ", a1 = ",a1,", omega=",round(omega2,3),sep=""),xlab="",
ylab="",col="red",lwd=1)
lines(x[(len-99):len],col="blue",lwd=1)
mtext("Input", side = 3, line = -1,at=50,col="blue")
mtext("Output", side = 3, line = -2,at=50,col="red")
b0<-0.1
for (i in 2:len)
y[i]<-b0*x[i]+a1*y[i-1]
ts.plot(x[(len-99):len],type="l",main=paste("AR(1): b0 = ",
b0, ", a1 = ",a1,", omega=",round(omega2,3),sep=""),xlab="",
ylab="",col="blue",lwd=1)
lines(y[(len-99):len],col="red",lwd=1)
mtext("Input", side = 3, line = -1,at=50,col="blue")
mtext("Output", side = 3, line = -2,at=50,col="red")
dev.off()
null device
1
54
1.0
6
AR(1): b0 = 1, a1 = 0.9, omega=0.157 AR(1): b0 = 0.1, a1 = 0.9, omega=0.157
0.5
Input
Output
−6
−1.0
−2 0
0.0
2
4
Input
Output
0
20
40
60
80
100
0
20
40
60
80
100
1.0
AR(1): b0 = 1, a1 = 0.9, omega=0.628 AR(1): b0 = 0.1, a1 = 0.9, omega=0.628
0.5
Input
Output
−1.0
−1.5 −0.5
0.0
0.5
1.5
Input
Output
0
20
40
60
80
100
0
20
40
60
80
100
Figure 21: Filter effect of AR(1) on trigonometric input
The coefficient b0 corresponds to a simple scaling of the filter-output.
5. Compute amplitude and time-shift functions of the two AR(1)-filters and verify the observed
filter effects in the above figure.
>
>
+
>
>
>
>
>
>
file = paste("z_amp_pha_ar1.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(2,2))
# Resolution of discrete frequency grid
len1<-1001
omega_k<-(0:len1)*pi/len1
# Compute transfer function, amplitude, phase and time-shift
a1<-0.9
55
>
>
>
>
>
>
+
+
>
>
>
+
>
+
>
+
>
>
>
+
+
>
>
>
+
>
+
>
+
>
>
>
>
>
>
>
>
+
+
>
>
>
+
>
+
>
+
>
>
>
+
+
>
>
b0<-1
trffkt1<-b0/(1-a1*complex(arg=-omega_k))
amplitude1<-abs(trffkt1)
phase1<-Arg(trffkt1)
shift1<--phase1/omega_k
plot(amplitude1,type="l",
main=paste("Amplitude AR(1): b0 = ",b0," ,a1 = ",a1,sep=""),
axes=F,xlab="Frequency",ylab="Amplitude",col="black")
abline(v=(len1-1)/(pi/omega1),lty=2,col="blue")
abline(v=(len1-1)/(pi/omega2),lty=2,col="orange")
mtext(paste("pi/",pi/omega1,sep=""), side = 3,
line = -4,at=len1/20,col="blue")
mtext(paste("pi/",pi/omega2,sep=""), side = 3,
line = -6,at=len1/5,col="orange")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6",
"3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(shift1,type="l",
main=paste("Time-shift AR(1): b0 = ",b0," ,a1 = ",a1,sep=""),
axes=F,xlab="Frequency",ylab="Shift",col="green")
abline(v=(len1-1)/(pi/omega1),lty=2,col="blue")
abline(v=(len1-1)/(pi/omega2),lty=2,col="orange")
mtext(paste("pi/",pi/omega1,sep=""), side = 3,
line = -4,at=len1/20,col="blue")
mtext(paste("pi/",pi/omega2,sep=""), side = 3,
line = -6,at=len1/5,col="orange")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6",
"3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
b0<-0.1
trffkt2<-b0/(1-a1*complex(arg=-omega_k))
amplitude2<-abs(trffkt2)
phase2<-Arg(trffkt2)
shift2<--phase2/omega_k
plot(amplitude2,type="l",
main=paste("Amplitude AR(1): b0 = ",b0," ,a1 = ",a1,sep=""),
axes=F,xlab="Frequency",ylab="Amplitude",col="black")
abline(v=(len1-1)/(pi/omega1),lty=2,col="blue")
abline(v=(len1-1)/(pi/omega2),lty=2,col="orange")
mtext(paste("pi/",pi/omega1,sep=""), side = 3,
line = -4,at=len1/20,col="blue")
mtext(paste("pi/",pi/omega2,sep=""), side = 3,
line = -6,at=len1/5,col="orange")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6",
"3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(shift2,type="l",
main=paste("Time-shift AR(1): b0 = ",b0," ,a1 = ",a1,sep=""),
axes=F,xlab="Frequency",ylab="Shift",col="green")
abline(v=(len1-1)/(pi/omega1),lty=2,col="blue")
abline(v=(len1-1)/(pi/omega2),lty=2,col="orange")
56
>
+
>
+
>
+
>
>
>
mtext(paste("pi/",pi/omega1,sep=""), side = 3,
line = -4,at=len1/20,col="blue")
mtext(paste("pi/",pi/omega2,sep=""), side = 3,
line = -6,at=len1/5,col="orange")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6",
"3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
>
>
+
+
+
+
>
>
+
+
# Compute table with shifts and amplitudes in omega=pi/20 and omega=pi/5
table_amp_shift_ar1<-rbind(c(amplitude1[(len1-1)/(pi/omega1)+1],
shift1[(len1-1)/(pi/omega1)+1]),
c(amplitude2[(len1-1)/(pi/omega1)+1],shift2[(len1-1)/(pi/omega1)+1]),
c(amplitude1[(len1-1)/(pi/omega2)+1],shift1[(len1-1)/(pi/omega2)+1]),
c(amplitude2[(len1-1)/(pi/omega2)+1],shift2[(len1-1)/(pi/omega2)+1]))
dimnames(table_amp_shift_ar1)[[2]]<-c("Amplitude","Shift")
dimnames(table_amp_shift_ar1)[[1]]<-c(paste("pi/",pi/omega1,",b0=1",sep=""),
paste("pi/",pi/omega1,",b0=0.1",sep=""),
paste("pi/",pi/omega2,",b0=1",sep=""),paste("pi/",pi/omega2,",b0=0.1",sep=""))
57
Time−shift AR(1): b0 = 1 ,a1 = 0.9
6
pi/5
pi/20
4
Shift
6
pi/20
pi/5
0
2
2
4
Amplitude
8
8
10
Amplitude AR(1): b0 = 1 ,a1 = 0.9
0
pi/6
3pi/6
5pi/6
0
pi/6
3pi/6
5pi/6
Frequency
Amplitude AR(1): b0 = 0.1 ,a1 = 0.9
Time−shift AR(1): b0 = 0.1 ,a1 = 0.9
pi/5
6
2
pi/5
pi/20
4
Shift
0.6
pi/20
0
0.2
Amplitude
8
1.0
Frequency
0
pi/6
3pi/6
5pi/6
0
pi/6
Frequency
3pi/6
5pi/6
Frequency
Figure 22: Amplitude and time-shifts of AR(1)-filters
The amplitude and time shifts at frequencies π/20 and π/5 for the two MA-filters are summarized in table 2. These numbers coincide with the effects observed in fig.21. The AR(1)-filter
pi/20,b0=1
pi/20,b0=0.1
pi/5,b0=1
pi/5,b0=0.1
Amplitude
5.580
0.558
1.683
0.168
Shift
5.751
5.751
1.746
1.746
Table 2: Amplitudes and time-shifts of AR(1)-filters in pi/20 and pi/5
yt = a1 yt−1 + b0 xt
58
is important in time series analysis because of its strong smoothing effect: the amplitude
functions in the left panels of fig.22 suggest that the filter with a1 = 0.9 damps high-frequency
components (relative to low-frequency components) very heavily. The AR(1) with positive
a1 > 0 is a typical example of a lowpass filter. As such the time-shift is positive: the stronger
the smoothing (the larger a1 < 1) the larger the time-shift in the passband. The strength of
both effects, the smoothing as well as the shift, is a consequence of the (more or less) slowly
decaying filter weights in the MA(∞) respresentation
yt =
∞
X
ak1 xt−k
k=0
If a1 is close to one, then the effective average extends over many lagged xt−k ’s and therefore
smoothing is strong but, unfortunately, the time-shift will be strong too. For Our example
with a1 = 0.9, turning-points will be substantially delayed. We note that the effect of b0 is
a simple scaling of the output. For b0 = 0.1 We have A(0) = b0 /(1 − a1 ) = 1 which is often
a desirable property of filters: it means that the important trend component in frequency
zero is not altered in scale. The normalization by b0 has no effect on the time-shift, at least
as long as b0 > 0.
6. Scale and shift the input signal according to amplitude and time-shift functions and compare
the resulting series with the filter output, see fig.23 (We compute results for the case ω = π/20
and b0 = 1 only). Hint: the resulting amplitude and time-shifts in table 2 are stored in the
object table amp shift ar1.
>
>
>
>
>
>
>
>
>
+
>
>
>
>
>
+
+
>
>
>
>
# We verify the claim for omega=pi/20 and b1=1
amp_scaling<-table_amp_shift_ar1[1,1]
shift<-table_amp_shift_ar1[1,2]
len<-200
b0<-1
omega1<-pi/20
y<-rep(0,len)
x<-cos((1:len)*omega1)
for (i in 2:len)
y[i]<-b0*x[i]+a1*y[i-1]
# Here We scale and shift the input signal
z<-amp_scaling*cos((1:len-shift)*omega1)
file = paste("z_out_ssout_ar1.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
ts.plot(y,type="l",main=paste("Output vs. scaled and shifted input: b0 = ",b0,
", a1 = ", a1,", omega=",round(omega1,3),sep=""),xlab="",
ylab="",col="red",lwd=1)
lines(z,col="green",lwd=1)
mtext("Scaled and shifted input", side = 3, line = -1,at=len/2,col="green")
mtext("Output", side = 3, line = -2,at=len/2,col="red")
dev.off()
null device
1
59
6
Output vs. scaled and shifted input: b0 = 1, a1 = 0.9, omega=0.157
−6
−4
−2
0
2
4
Scaled and shifted input
Output
0
50
100
150
200
Figure 23: Output of AR(1) vs. scaled and shifted input
Both series differ at the start and the output series (red) needs some time to stabilize
because it is deliberately wrongly initialized in zero16 . But We can observe that the output
converges to the scaled and shifted input (green) ‘asymptotically’: both series are virtually
indistinguishable for t > 50.
7. To conclude We analyze the effects of the classical MA(12) seasonal difference filter
yt = xt − xt−12
with coefficients b0 = 1, b12 = −1 and bk = 0, k 6= 0, 12. verify that the filter eliminates
trigonometric signals with frequencies kπ/6, k = 0, 1, ..., 6, multiples of π/6.
>
>
>
>
>
>
>
>
>
>
>
+
+
16 The
len<-120
b0<-1
b12<--1
file = paste("z_cos_in_out_sd.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,2))
omega1<-pi/20
y<-rep(0,len)
x<-cos((1:len)*omega1)
y[13:len]<-b0*x[13:len]+b12*x[1:(len-12)]
ts.plot(y,type="l",main=paste("Seasonal difference MA(12): b0 =1, b12 = ",
b12,", omega=",round(omega1,3),sep=""),xlab="",
ylab="",col="red",lwd=1)
filter coefficients b0 ak1 of the corresponding MA(∞)-filter decay slowly towards zero.
60
>
>
>
>
>
>
>
>
+
+
>
>
>
>
>
>
>
>
+
+
>
>
>
>
>
>
>
>
+
+
>
>
>
>
lines(x,col="blue",lwd=1)
mtext("Input", side = 3, line = -1,at=len/2,col="blue")
mtext("Output", side = 3, line = -2,at=len/2,col="red")
omega2<-pi/5
y<-rep(0,len)
x<-cos((1:len)*omega2)
y[13:len]<-b0*x[13:len]+b12*x[1:(len-12)]
ts.plot(y,type="l",main=paste("Seasonal difference MA(12): b0 =1, b12 = ",
b12,", omega=",round(omega1,3),sep=""),xlab="",
ylab="",col="red",lwd=1)
lines(x,col="blue",lwd=1)
mtext("Input", side = 3, line = -1,at=len/2,col="blue")
mtext("Output", side = 3, line = -2,at=len/2,col="red")
omega3<-pi/6
y<-rep(0,len)
x<-cos((1:len)*omega3)
y[13:len]<-b0*x[13:len]+b12*x[1:(len-12)]
ts.plot(x,type="l",main=paste("Seasonal difference MA(12): b0 =1, b12 = ",
b12,", omega=",round(omega1,3),sep=""),xlab="",
ylab="",col="blue",lwd=1)
lines(y,col="red",lwd=1)
mtext("Input", side = 3, line = -1,at=len/2,col="blue")
mtext("Output", side = 3, line = -2,at=len/2,col="red")
omega4<-4*pi/6
y<-rep(0,len)
x<-cos((1:len)*omega4)
y[13:len]<-b0*x[13:len]+b12*x[1:(len-12)]
ts.plot(x,type="l",main=paste("Seas. diff. MA(12), omega=",
round(omega1,3),sep=""),xlab="",
ylab="",col="blue",lwd=1)
lines(y,col="red",lwd=1)
mtext("Input", side = 3, line = -1,at=len/2,col="blue")
mtext("Output", side = 3, line = -2,at=len/2,col="red")
dev.off()
null device
1
61
1.5
Seasonal difference MA(12): b0 =1, b12
Seasonal
= −1, omega=0.157
difference MA(12): b0 =1, b12 = −1, omega=0.157
Input
Output
−1.5
−1.0
−0.5
0.0
0.5
1.0
Input
Output
0
20
40
60
80
120
0
20
40
60
80
120
1.0
1.0
Seasonal difference MA(12): b0 =1, b12 = −1, omega=0.157
Seas. diff. MA(12), omega=0.157
Input
Output
−0.5
−1.0
0.0
0.0
0.5
0.5
Input
Output
0
20
40
60
80
120
0
20
40
60
80
120
Figure 24: Filter effect of seasonal difference MA(12) on trigonometric inputs
The first two signals with frequencies π/20 (upper left panel) and π/5 (upper right panel)
are amplified by the filter. The signals with frequencies π/6 (lower left panel) and 4π/6
(lower right panel) are eliminated.
8. Compute amplitude and time-shift functions of the filter.
>
>
>
>
>
>
>
>
file = paste("z_amp_pha_ma12.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
# Resolution of discrete frequency grid
len1<-1200
omega_k<-(0:len1)*pi/len1
# Compute transfer function, amplitude, phase and time-shift
b1<-1
b12<--1
62
>
>
>
>
>
>
+
>
>
>
+
>
+
>
+
>
>
>
+
>
>
>
+
>
+
>
+
>
>
>
trffkt<-1+b12*complex(arg=-12*omega_k)
amplitude<-abs(trffkt)
phase<-Arg(trffkt)
shift<--phase/omega_k
par(mfrow=c(2,1))
plot(amplitude,type="l",main="Amplitude seasonal difference MA(12)",
axes=F,xlab="Frequency",ylab="Amplitude",col="black")
abline(v=(len1-1)/(pi/omega1),lty=2,col="blue")
abline(v=(len1-1)/(pi/omega2),lty=2,col="orange")
mtext(paste("pi/",pi/omega1,sep=""), side = 3, line = -2,
at=len1/20,col="blue")
mtext(paste("pi/",pi/omega2,sep=""), side = 3, line = -4,
at=len1/5,col="orange")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
plot(shift,type="l",main="Time shift seasonal difference MA(12)",
axes=F,xlab="Frequency",ylab="Amplitude",col="black")
abline(v=(len1-1)/(pi/omega1),lty=2,col="blue")
abline(v=(len1-1)/(pi/omega2),lty=2,col="orange")
mtext(paste("pi/",pi/omega1,sep=""), side = 3, line = -2,
at=len1/20,col="blue")
mtext(paste("pi/",pi/omega2,sep=""), side = 3, line = -4,
at=len1/5,col="orange")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
63
1.0
pi/20
pi/5
0.0
Amplitude
2.0
Amplitude seasonal difference MA(12)
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Frequency
pi/20
−600 −300
Amplitude
0
Time shift seasonal difference MA(12)
pi/5
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Frequency
Figure 25: Amplitude and time-shifts of seasonal difference MA(12)-filter
The amplitude function of the seasonal difference filter vanishes in multiples jπ/6, j =
1, ..., 6 of the seasonal fundamental π/6. Note, however, that the trend in frequency zero is
eliminated too (which is undesirable) and that the amplitude exceeds one in frequency-bands
between the seasonal harmonics. In particular, the amplitude is larger than one in π/20 and
π/5 which explains that the outputs (red) in the upper panels of fig.24 are magnified. The
amplitude function suggests heavy distortions by this filter.
3.3
3.3.1
Finite Sample Discrete Convolution Theorem and Serial Linkage of
Filters
Stationary Processes
The transferfunction or, alternatively, the amplitude and the phase (or time-shift) functions, describe comprehensively the effect of a filter as applied to an elementary (periodic and deterministic)
64
trigonometric signal xt = exp(itω):
∞
X
yt =
γj xt−j = Γ(ω)xt
j=−∞
An arbitrary sequence x1 , ..., xT , neither periodic nor deterministic, can be decomposed into a
weighted sum of trigonometric sinusoids
√
2π
xt = √
T
and similarly for yt
√
2π
yt = √
T
[T /2]
X
wk ΞT X (ωk ) exp(itωk )
(25)
wk ΞT Y (ωk ) exp(itωk )
(26)
k=−[T /2]
[T /2]
X
k=−[T /2]
recall 7. Therefore, when applying the filter to a general sequence x1 , ..., xT We might proceed as
follows
yt
=
∞
X
γj xt−j
j=−∞
≈
=
=
√
2π
γj √
T
j=−∞
∞
X
√
2π
√
T
√
2π
√
T
[T /2]
X
wk ΞT X (ωk ) exp(i(t − j)ωk )
(27)
k=−[T /2]
[T /2]
X
wk ΞT X (ωk )
∞
X
γj exp(i(t − j)ωk )
j=−∞
k=−[T /2]
[T /2]
X
wk ΞT X (ωk )Γ(ωk ) exp(itωk )
(28)
k=−[T /2]
Comparing 26 and 28 suggests that the DFT ΞT Y (ωk ) of the output signal is linked to the DFT
ΞT X (ωk ) of the input signal via
ΞT Y (ω) ≈ Γ(ω)ΞT X (ω)
(29)
This result is not a strict equality (because 27 is an approximation) but from a practical perspective We can ignore the error which is small if some elementary precaution-principles apply17 .
Equation 29 is of crucial importance because it describes the filter effect as applied to a nonperiodic/non deterministic sequence of numbers x1 , ..., xT . So for example the periodograms of
output and input are linked via
2
2
IT Y (ω) = |ΞT Y (ω)| ≈ |Γ(ω)| IT X (ω)
(30)
This equation is a finite sample discrete analogon of the so-called spectral convolution theorem
which states that the spectral densities hy (ω), hx (ω) of (stationary18 ) input and output signals are
linked by
2
hy (ω) = |Γ(ω)| hx (ω)
(31)
PT
problem is that the DFT of xt−j on the left hand-side is √ 1
t=1 xt−j exp(i − tω) which is not strictly
2πT
P
T
the same as ΞT X (ω) := √ 1
x
exp(i
−
tω)
used
on
the
right-hand
side because the data is shifted by j
t
t=1
2πT
time-units. But one can show that the approximation error in 27 is small, at least if the data is stationary
18 The autocovariances should be absolutely summable which can be assumed in typical economic applications
(at least for stationary data).
17 The
65
Recall that We here assume a stationary framework. For non-stationary integrated series one can
derive similar (discrete finite sample) results based on the pseudo-DFT or the pseudo-periodogram,
to be defined later.
Assume now that We apply two filters γj1 and γj2 , j = −∞, ..., 0, ...∞, with transferfuctions
Γ1 (ω) and Γ2 (ω), in series:
yt
zt
∞
X
=
j=−∞
∞
X
=
γj1 xt−j
γj2 yt−j
j=−∞
where zt is the output of the series linkage. To see what happens We can rely on
zt
∞
X
=
γj2 yt−j
j=−∞
≈
≈
√
2π
√
T
√
2π
√
T
[T /2]
X
wk ΞT Y (ωk )Γ2 (ωk ) exp(itωk )
(32)
wk ΞT X (ωk )Γ1 (ωk )Γ2 (ωk ) exp(itωk )
(33)
k=−[T /2]
[T /2]
X
k=−[T /2]
where We inserted 29 into 32 to obtain 33. We infer that the DFT ΞT Z (ωk ) of the output signal
is linked to the DFT ΞT X (ωk ) of the input signal via
ΞT Z (ω) ≈ Γ1 (ω)Γ2 (ω)ΞT X (ω)
(34)
and the periodogram obtains
2
2
2
IT Z (ω) = |ΞT Z (ω)| ≈ |Γ1 (ω)| |Γ2 (ω)| IT X (ω)
(35)
accordingly. Once again, the approximation error is generally small (at least for stationary data)
which means that We can often ignore its effect in practice. Putting several (more than two) filters
in series just prolonges the multiplicative chain in the above expressions.
3.3.2
Exercises
We here analyze the effects of classical filters on particular processes and we check pertinence of
the discrete finite sample convolution theorem for the DFT and the Periodogram. In contrast
to the previous exercises We here consider ‘complex’ stochastic input series (not deterministic
trigonometric signals).
1. We here analyze the effect of the ordinary difference filter
yt = xt − xt−1
where b0 = 1, b1 = −1, on white noise xt = t and verify the quality of the approximations
29 and 30. Generate a realization of length T = 100 of t and compare graphically
• The periodogram IT X (ωk ) of the input signal (white noise)
• the periodogram IT Y (ωk ) of the output signal
• the convolution |Γ(ωk )|2 IT X (ωk ) of input signal and filter.
66
see fig.26.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
>
+
>
>
>
+
>
>
>
set.seed(10)
len<-100
x<-rnorm(len)
y<-c(0,diff(x))
# Resolution of discrete frequency grid
len1<-len/2
omega_k<-(0:len1)*pi/len1
# Compute transfer function, amplitude, phase and time-shift
b1<--1
trffkt<-1+b1*complex(arg=-omega_k)
amplitude<-abs(trffkt)
phase<-Arg(trffkt)
shift<-phase/omega_k
plot_T<-F
file = paste("z_convo_diff.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,2))
plot(amplitude,type="l",main="Convolution: ordinary difference filter",
axes=F,xlab="Frequency",ylab="periodograms",col="black",ylim=c(0,2))
lines(amplitude^2*per(x,plot_T)$per,col="green")
lines(per(y,plot_T)$per,col="red",lty=2)
lines(per(x,plot_T)$per,col="blue")
mtext("Amplitude", side = 3, line = -1,at=len1/2,col="black")
mtext("Convolution", side = 3, line = -2,at=len1/2,col="green")
mtext("Periodogram output", side = 3, line = -3,at=len1/2,col="red")
mtext("Periodogram input", side = 3, line = -4,at=len1/2,col="blue")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
ts.plot(x,col="blue",main="Input and output series",ylab="")
lines(y,col="red")
mtext("Input series", side = 3, line = -1,at=len/2,col="blue")
mtext("Output series", side = 3, line = -2,at=len/2,col="red")
plot(Re(trffkt),type="l",main="Convolution: real-parts of DFT",
axes=F,xlab="Frequency",ylab="Real parts of DFT",col="black",ylim=c(-1,2))
lines(Re(trffkt*per(x,plot_T)$DFT),col="green")
lines(Re(per(y,plot_T)$DFT),col="red",lty=2)
lines(Re(per(x,plot_T)$DFT),col="blue")
mtext("Re(transfer function)", side = 3, line = -1,at=len1/2,col="black")
mtext("Re(convolution of DFT)", side = 3, line = -2,at=len1/2,col="green")
mtext("Re(DFT output)", side = 3, line = -3,at=len1/2,col="red")
mtext("Re(DFT input)", side = 3, line = -4,at=len1/2,col="blue")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
plot(Im(trffkt),type="l",main="Convolution: imaginary-parts of DFT",
axes=F,xlab="Frequency",ylab="Imaginary parts of DFT",col="black",ylim=c(-1,1))
lines(Im(trffkt*per(x,plot_T)$DFT),col="green")
lines(Im(per(y,plot_T)$DFT),col="red",lty=2)
lines(Im(per(x,plot_T)$DFT),col="blue")
67
>
>
>
>
>
+
>
>
>
mtext("Im(transfer function)", side = 3, line = -1,at=len1/2,col="black")
mtext("Im(convolution of DFT)", side = 3, line = -2,at=len1/2,col="green")
mtext("Im(DFT output)", side = 3, line = -3,at=len1/2,col="red")
mtext("Im(DFT input)", side = 3, line = -4,at=len1/2,col="blue")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
1
2
Input series
Output series
−1
−2
0.5
0
pi/6
3pi/6
5pi/6
0
20
40
60
80
100
Convolution: real−parts of DFT
Convolution: imaginary−parts of DFT
0
pi/6
3pi/6
5pi/6
0.0
0.5
Im(transfer function)
Im(convolution of DFT)
Im(DFT output)
Im(DFT input)
−1.0
Imaginary parts of DFT
0.0
1.0
Re(transfer function)
Re(convolution of DFT)
Re(DFT output)
Re(DFT input)
1.0
Time
2.0
Frequency
−1.0
Real parts of DFT
Input and output series
0
1.0
1.5
Amplitude
Convolution
Periodogram output
Periodogram input
0.0
periodograms
2.0
Convolution: ordinary difference filter
0
Frequency
pi/6
3pi/6
5pi/6
Frequency
Figure 26: Convolution of difference filter (green), periodogram of input (blue) and output (red)
signals and amplitude function of ordinary differences (black)
68
We observe that the convolution |Γ(ωk )|2 IT X (ωk ) (green) and the periodogram of the output
series IT Y (ωk ) (red) in the top-left panel are almost indistinguishable: the convolution error
in the discrete spectral convolution 30 is very small (negligible by all practical means).
As expected, low-frequency components are damped and high-frequency components are
magnified and the output series (red line in top right panel) is ‘more volatile’. The bottom
panels confirm that the convolution of the DFT 29 applies for real and imaginary parts.
Note that these results are much more general than the exercises in section 3.2.4 because the
new input series xt = t is not a deterministic trigonometric line spectrum: all frequencies
are ‘excited’ and contribute equally to the process (to its variance).
2. We now analyze the AR(1)-filter
yt = 0.95yt−1 + 0.1xt
with a1 = 0.95, b0 = 1 − a1 = 0.0519 and xt = t is again a white noise sequence. Compute
and compare periodograms of input and output signals as well as the convolution, see fig.27.
>
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
+
>
>
+
+
>
>
>
>
>
>
>
19 The
set.seed(10)
len2<-1000
a1<-0.95
b0<-1-a1
omega1<-pi/20
y1<-rep(0,len2)
x1<-rnorm(len2)
for (i in 2:len2)
y1[i]<-b0*x1[i]+a1*y1[i-1]
# The first 900 observations are discarded (initialization)
len<-100
y<-y1[(len2-len+1):len2]
x<-x1[(len2-len+1):len2]
# Resolution of discrete frequency grid
len1<-len/2
omega_k<-(0:len1)*pi/len1
# Compute transfer function, amplitude, phase and time-shift
trffkt<-b0/(1-a1*complex(arg=-omega_k))
amplitude<-abs(trffkt)
phase<-Arg(trffkt)
shift<-phase/omega_k
plot_T<-F
file = paste("z_convo_ar1.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(2,2))
plot(amplitude,type="l",main=paste("Convolution AR(1)-filter: b0 = ",
b0," a1 = ",a1,sep=""),
axes=F,xlab="Frequency",ylab="periodograms",col="black",ylim=c(0,1))
lines(amplitude^2*per(x,plot_T)$per,col="green")
lines(per(y,plot_T)$per,col="red",lty=2)
lines(per(x,plot_T)$per,col="blue")
mtext("Amplitude", side = 3, line = -1,at=len1/2,col="black")
mtext("Convolution", side = 3, line = -2,at=len1/2,col="green")
mtext("Periodogram output", side = 3, line = -3,at=len1/2,col="red")
mtext("Periodogram input", side = 3, line = -4,at=len1/2,col="blue")
amplitude in frequency zero is A(0) = |b0 /(1 − a1 )| so that A(0) = 1 if b0 = 1 − a1 .
69
>
+
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
>
+
>
>
>
+
>
>
>
>
>
>
>
>
+
>
>
>
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
ts.plot(x,col="blue",main="Input and output series",ylab="")
lines(y,col="red")
mtext("Input series", side = 3, line = -1,at=len/2,col="blue")
mtext("Output series", side = 3, line = -2,at=len/2,col="red")
plot(Re(trffkt),type="l",main="Convolution: real-parts of DFT",
axes=F,xlab="Frequency",ylab="Real parts of DFT",col="black",ylim=c(-1,1))
lines(Re(trffkt*per(x,plot_T)$DFT),col="green")
lines(Re(per(y,plot_T)$DFT),col="red",lty=2)
lines(Re(per(x,plot_T)$DFT),col="blue")
mtext("Re(transfer function)", side = 3, line = -1,at=len1/2,col="black")
mtext("Re(convolution of DFT)", side = 3, line = -2,at=len1/2,col="green")
mtext("Re(DFT output)", side = 3, line = -3,at=len1/2,col="red")
mtext("Re(DFT input)", side = 3, line = -4,at=len1/2,col="blue")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
plot(Im(trffkt),type="l",main="Convolution: imaginary-parts of DFT",
axes=F,xlab="Frequency",ylab="Imaginary parts of DFT",col="black",ylim=c(-1,1))
lines(Im(trffkt*per(x,plot_T)$DFT),col="green")
lines(Im(per(y,plot_T)$DFT),col="red",lty=2)
lines(Im(per(x,plot_T)$DFT),col="blue")
mtext("Im(transfer function)", side = 3, line = -1,at=len1/2,col="black")
mtext("Im(convolution of DFT)", side = 3, line = -2,at=len1/2,col="green")
mtext("Im(DFT output)", side = 3, line = -3,at=len1/2,col="red")
mtext("Im(DFT input)", side = 3, line = -4,at=len1/2,col="blue")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
70
Input series
Output series
−2
0.0
−1
0.4
0
1
2
Amplitude
Convolution
Periodogram output
Periodogram input
0.8
Input and output series
0
3pi/6
5pi/6
0
20
40
60
80
100
Convolution: real−parts of DFT
Convolution: imaginary−parts of DFT
0
pi/6
3pi/6
5pi/6
0.5
Im(transfer function)
Im(convolution of DFT)
Im(DFT output)
Im(DFT input)
0.0
Imaginary parts of DFT
0.0
0.5
Re(transfer function)
Re(convolution of DFT)
Re(DFT output)
Re(DFT input)
1.0
Time
1.0
Frequency
−1.0
Real parts of DFT
pi/6
−1.0
periodograms
Convolution AR(1)−filter: b0 = 0.05 a1 = 0.95
0
Frequency
pi/6
3pi/6
5pi/6
Frequency
Figure 27: Convolution of AR(1)-filter (green), periodogram of input (blue) and output (red)
signals and amplitude function of AR(1) filter (black)
Convolution (green) and periodogram of output (red) in the top-left panel are almost indistinguishable, which confirms 30, at least up to frequency zero: the latter error is still
small and its impact (on optimized filters in the DFA) will be negligible when compared to
the natural sampling error. The strong smoothing obtained by the large AR(1)-coefficient
a1 = 0.95 implies that high-frequency components are heavily damped by the filter as can
be seen in the top-right panel of fig.27. The bottom panel confirms 29 for real (left) and
imaginary (right) parts of the DFT’s involved.
3. We here analyze the inverse of the seasonal MA(12) analyzed in exercise 7, p.60, namely the
AR(12) filter
yt = yt−12 + xt
where xt = t is again white noise and where ak = 0, k 6= 12, a12 = 1. This filter is particular
71
because it is unstable: the roots of the characteristic polynomial
> polyroot(c(1,rep(0,11),-1))
[1]
[11]
0.5000000+0.8660254i -0.8660254+0.5000000i -0.5000000-0.8660254i
0.5000000-0.8660254i 0.8660254+0.5000000i
0.8660254-0.5000000i
all lie on the unit circle i.e. their absolute value is one
> abs(polyroot(c(1,rep(0,11),-1)))
[1] 1 1 1 1 1 1 1 1 1 1 1 1
In such a case the classical spectral convolution theorem 31 cannot be applied because the
output yt of the filter is not stationary. In contrast, Our frequency-domain number-identities
apply irrespective of model assumptions. It is therefore interesting to check if the discrete
finite sample spectral convolution 30 applies or, more precisely, if the approximation error is
still ‘small’. We now generate a realization of length 100 of the above process and compare
periodograms and DFT’s of input and output signals with spectral estimates obtained by
convolution.
>
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
+
>
>
+
>
>
>
>
>
set.seed(10)
len2<-1000
a12<-1
b0<-1
omega1<-pi/20
y1<-rep(0,len2)
x1<-rnorm(len2)
for (i in 13:len2)
y1[i]<-b0*x1[i]+a12*y1[i-12]
# The first 900 observations are discarded (initialization)
len<-120
y<-y1[(len2-len+1):len2]
x<-x1[(len2-len+1):len2]
# Resolution of discrete frequency grid
len1<-len/2
omega_k<-(0:len1)*pi/len1
# Compute transfer function, amplitude, phase and time-shift
trffkt<-b0/(1-a12*complex(arg=-12*omega_k))
# The transfer function is infinite at the seasonal frequencies
trffkt[c(1,1+1:6*(len1/6))]<-Inf
amplitude<-abs(trffkt)
phase<-Arg(trffkt)
shift<-phase/omega_k
plot_T<-F
file = paste("z_convo_ar12.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(2,2))
plot(amplitude,type="l",main="Convolution seasonal AR(12)",
axes=F,xlab="Frequency",ylab="periodograms",col="black",ylim=c(0,5))
lines(amplitude^2*per(x,plot_T)$per,col="green")
lines(per(y,plot_T)$per,col="red",lty=2)
lines(per(x,plot_T)$per,col="blue")
mtext("Amplitude", side = 3, line = -1,at=len1/2,col="black")
mtext("Convolution", side = 3, line = -2,at=len1/2,col="green")
72
>
>
>
+
>
>
>
+
>
>
>
>
+
>
>
>
>
>
>
>
>
+
>
>
>
+
>
>
>
>
>
>
>
>
+
>
>
>
mtext("Periodogram output", side = 3, line = -3,at=len1/2,col="red")
mtext("Periodogram input", side = 3, line = -4,at=len1/2,col="blue")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
ts.plot(x,col="blue",main="Input and output series",ylab="",
ylim=c(min(y),max(y)))
lines(y,col="red")
mtext("Input series", side = 3, line = -1,at=len/2,col="blue")
mtext("Output series", side = 3, line = -2,at=len/2,col="red")
plot(Re(trffkt),type="l",main="Convolution: real-parts of DFT",
axes=F,xlab="Frequency",ylab="Real parts of DFT",col="black",ylim=c(-5,5))
lines(Re(trffkt*per(x,plot_T)$DFT),col="green")
lines(Re(per(y,plot_T)$DFT),col="red",lty=2)
lines(Re(per(x,plot_T)$DFT),col="blue")
mtext("Re(transfer function)", side = 3, line = -1,at=len1/2,col="black")
mtext("Re(convolution of DFT)", side = 3, line = -2,at=len1/2,col="green")
mtext("Re(DFT output)", side = 3, line = -3,at=len1/2,col="red")
mtext("Re(DFT input)", side = 3, line = -4,at=len1/2,col="blue")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
plot(Im(trffkt),type="l",main="Convolution: imaginary-parts of DFT",
axes=F,xlab="Frequency",ylab="Imaginary parts of DFT",col="black",ylim=c(-5,5))
lines(Im(trffkt*per(x,plot_T)$DFT),col="green")
lines(Im(per(y,plot_T)$DFT),col="red",lty=2)
lines(Im(per(x,plot_T)$DFT),col="blue")
mtext("Im(transfer function)", side = 3, line = -1,at=len1/2,col="black")
mtext("Im(convolution of DFT)", side = 3, line = -2,at=len1/2,col="green")
mtext("Im(DFT output)", side = 3, line = -3,at=len1/2,col="red")
mtext("Im(DFT input)", side = 3, line = -4,at=len1/2,col="blue")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
73
Amplitude
Convolution
Periodogram output
Periodogram input
Input series
Output series
4
−5
3
2
−15
1
0
pi/6
3pi/6
5pi/6
0
20
40
60
80
120
Convolution: imaginary−parts of DFT
Re(transfer function)
Re(convolution of DFT)
Re(DFT output)
Re(DFT input)
Im(transfer function)
Im(convolution of DFT)
Im(DFT output)
Im(DFT input)
pi/6
3pi/6
5pi/6
2
0
2
0
0
4
Convolution: real−parts of DFT
Imaginary parts of DFT
Time
4
Frequency
−4
Real parts of DFT
0
−4
periodograms
5
Input and output series
5
Convolution seasonal AR(12)
0
Frequency
pi/6
3pi/6
5pi/6
Frequency
Figure 28: Convolution of unstable seasonal AR(12)-filter (green), periodogram of input (blue)
and output (red) signals and amplitude function of seasonal AR(12) (black)
Please note that green and black lines in the above graphs are not defined at the singularities
jπ/6, j = 0, 1, ..., 6 because the transferfunction
Γ(ω) =
1
1 − exp(−i12ω)
is infinite whenever exp(−i12ω) = 1 i.e. whenever ω = jπ/6. Therefore, the convolution
|Γ(ωk )|2 IT X (ωk ) (green) is infinite. In contrast, the periodogram of the output series IT Y (ωk )
(red, top-left panel) must be finite since yt is a well-defined (finite) time series. But We can
see that IT Y (ωk ) (red line, top-left) peaks at ω = jπ/6, as desired20 . At all other frequencies
the correspondence between green and red lines is good thus confirming pertinence of Our
20 These peaks would diverge asymptotically if T → ∞: you can convince yourself by increasing len2 and len in
the R-code.
74
finite-sample discrete convolution results 29 and 30. The infinite peaks of the amplitude
function in the seasonal frequencies means that the corresponding frequency components are
magnified ‘very heavily’: as can be seen in the upper right panel, red line, the periodicity
is strongly marked. Letting the data-size grow unboundedly would lead to asymptotically
unbounded seasonal patterns i.e. the difference between consecutive/different months would
diverge asymptotically. This typical non-stationary feature is reflected by the infinite peaks
of the amplitude function. Of course, any finite sample of the non-stationary seasonal process
yt must be finite and therefore its DFT or periodogram must be finite too.
The above exercises confirme that Our discrete finite sample convolution results 29 and 30 hold
remarkably well over a broad range of filters – the approximation error is small/negligible – even in
situations where the standard theory (equation 31) fails, because input and/or output signals are
integrated. However, We must warn against uncautious application because the approximation
error may become ‘large’ – sufficiently large to interfer with Our later optimization – if the data
is trending: recall that a trend strongly contradicts the implicit periodicity assumption of the
DFT (see exercise 8, p.31, and fig.14). In the following section We propose an extension of the
convolution results to non-stationary integrated processes.
3.3.3
Non-stationary Integrated I(1)-Processes
We mainly discuss the practically relevant case of a non-stationary integrated input process xt ∈
I(1) which is stationary after ordinary differences
xt − xt−1 = ut ∈ I(0)
In principle xt can be viewed as the output of an unstable AR(1)-filter with input ut :
xt = xt−1 + ut
whose transfer function
1
1 − exp(−iω)
has a singularity in frequency zero: low-frequency components are heavily magnified by the (unstable) filter or, stated otherwise, xt is trending, see section 921 in the SARIMA-script. Our discrete
convolution results suggest that
Γ(ω) =
ΞT X (ωk ) ≈
IT X (ωk ) ≈
ΞT U (ωk )
1 − exp(−iωk )
IT U (ωk )
|1 − exp(−iωk )|2
(36)
(37)
Unfortunately, the singularity of the transferfunction leads to an unreconciliable mismatch in
frequency ω0 = 0 since the left-hand side is finite (the data x1 , ..., xT is finite) whereas the righthand side is generally infinite in frequency zero. A similar mismatch was observed in exercise
3, p.71, see fig.28: the periodogram of the output signal (red line) was finite in the seasonal
frequencies vs. an infinite convolution (green line). Besides this obvious mismatch in the unit-root
frequency zero, one can show that IT X (ωk ) is also biased for all k > 0 whereby the amount of
distortion depends on the input process see the exercise below and Wildi (2008) for the theory.
The approximation errors in 36 and 37 are no more negligible, in general, though they are often
found to be negligible for typical economic data, see the exercise below. In order to eliminate the
bias We recommend usage of the pseudo-DFT and of the pseudo-periodogram statistics
Ξpseudo
(ωk )
TX
:=
ITpseudo
(ωk )
X
:=
ΞT U (ωk )
1 − exp(−iωk )
IT U (ωk )
|1 − exp(−iωk )|2
21 ???
75
(38)
(39)
in lieu of the ‘direct’ sample estimates ΞT X (ωk ) and IT X (ωk ).
3.3.4
Exercise
We here illustrate that the periodogram of an integrated process is generally biased. Since the magnitude of the bias depends on the Data Generating Process (DGP) 22 We also attempt to convey
an intuitive feeling of the problem by analyzing three simple processes which reflect characteristics
of typical economic data. Specifically, let yt be the output of the MA(1) ordinary difference filter
yt
= xt − xt−1
(40)
and assume the input is a non-stationary process
xt
= xt−1 + ut
where the stationary differences are an AR(1)-process
ut
= a1 ut−1 + t
(41)
Note that yt = xt − xt−1 = ut . Thus the periodogram of yt should coincide with the periodogram
of ut :
IT Y (ωk ) = IT U (ωk )
We now check this trivial requirement by computing the periodogram IT Y (ωk ) of yt in two different
ways:
ITpseudo
(ωk )
Y
ITdirect
(ωk )
Y
:= |1 − exp(−iωk )|2
IT U (ωk )
= IT U (ωk )
|1 − exp(−iωk )|2
:= |1 − exp(−iωk )|2 IT X (ωk ) ≈ IT U (ωk )
(42)
(43)
where 1 − exp(−iωk ) is the transfer function of the difference filter in 40. The first periodogram
estimate ITpseudo
(ωk ) relies on 30 where We insert the pseudo-periodogram 39 of the non-stationary
Y
xt . This equates trivially to IT U (ωk ), as desired, which happens to be IT Y (ωk ) also23 . The second
periodogram estimate 43 relies on a direct computation of the periodogram IT X (ωk ). We now
(ωk ) in 43. As We shall see, the
analyze the quality of the approximation of IT U (ωk ) by ITdirect
Y
magnitude of the approximation error depends on a1 in 41: We therefore analyze three settings –
data samples – corresponding to a1 = −0.9, 0 and 0.9.
1. Consider the above filter 40 where xt = xt−1 + ut is based on 41. Generate three different
realizations of length 1000 of yt , xt based on a1 = −0.9, a1 = 0 and a1 = 0.9 in 41 and analyze
(ωk ) and IT U (ωk ) graphically, see
the quality of the approximation 43 by comparing ITdirect
Y
fig.29. Hint: use the same setseed argument for all three realizations.
>
>
>
>
>
>
>
>
>
len<-1000
set.seed(10)
u1<-arima.sim(list(ar=-0.9),n=len)
set.seed(10)
u2<-arima.sim(list(ar=0.),n=len)
set.seed(10)
u3<-arima.sim(list(ar=0.9),n=len)
# Compute transferfunction of difference filter
len1<-length(per(u1,plot_T)$per)-1
22 The
bias is larger if the differenced stationary process is positively autocorrelated, see Wildi (2008) for details.
practice, applying the difference operator to xt means that one looses one observation i.e. the sample
becomes y2 , ..., yT whereas the periodogram of ut could rely on u1 , ..., uT : We here ignore this artifact and assume
that y1 = u1 is known.
23 In
76
>
>
>
>
>
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
trffkt_diff<-(1-exp(1.i*(0:len1)*pi/len1))
# Amplitude function of difference filter
amp_diff<-abs(trffkt_diff)
file = paste("z_convo_bias.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
plot_T<-F
par(mfrow=c(3,1))
per_pseudo<-per(u1,plot_T)$per
# compute non-stationary x
x1<-cumsum(u1)
per_direct<-amp_diff^2*per(x1,plot_T)$per
plot(per_pseudo,type="l",main="Bias effect: a1=-0.9",
axes=F,xlab="Frequency",ylab="periodograms",col="black",ylim=c(0,max(per_direct)))
lines(per_direct,col="blue")
mtext("Direct (biased)", side = 3, line = -1,at=len1/2,col="blue")
mtext("Pseudo (unbiased)", side = 3, line = -2,at=len1/2,col="black")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
per_pseudo<-per(u2,plot_T)$per
x2<-cumsum(u2)
per_direct<-amp_diff^2*per(x2,plot_T)$per
plot(per_pseudo,type="l",main="Bias effect: a1=0",
axes=F,xlab="Frequency",ylab="periodograms",col="black",ylim=c(0,max(per_direct)))
lines(per_direct,col="blue")
mtext("Direct (biased)", side = 3, line = -1,at=len1/2,col="blue")
mtext("Pseudo (unbiased)", side = 3, line = -2,at=len1/2,col="black")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
per_pseudo<-per(u3,plot_T)$per
x3<-cumsum(u3)
per_direct<-amp_diff^2*per(x3,plot_T)$per
plot(per_pseudo,type="l",main="Bias effect: a1=0.9",
axes=F,xlab="Frequency",ylab="periodograms",col="black",ylim=c(0,max(per_direct)))
lines(per_direct,col="blue")
mtext("Direct (biased)", side = 3, line = -1,at=len1/2,col="blue")
mtext("Pseudo (unbiased)", side = 3, line = -2,at=len1/2,col="black")
axis(1,at=c(0,1:6*len1/6+1),labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
77
10
20
Direct (biased)
Pseudo (unbiased)
0
periodograms
Bias effect: a1=−0.9
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
5pi/6
pi
5pi/6
pi
Frequency
1.0
Direct (biased)
Pseudo (unbiased)
0.0
periodograms
Bias effect: a1=0
0
pi/6
2pi/6
3pi/6
4pi/6
Frequency
40
80
Direct (biased)
Pseudo (unbiased)
0
periodograms
Bias effect: a1=0.9
0
pi/6
2pi/6
3pi/6
4pi/6
Frequency
Figure 29: Bias effect depending on DGP: a1=-0.9 (top), a1=0 (middle) and a1=0.9 (bottom)
We can see that ‘direct’ and ‘pseudo’ periodograms are almost indistinguishable for a1 = −0.9
(because the strong negative autocorrelation of ut nearly ‘cancels’ the unit-root of xt ); for
a1 = 0 We can observe differences but nothing ‘systematic’ yet24 ; for a1 = 0.9, however, the
difference between both periodograms is substantial and the bias of ITdirect
(ωk ) is marked for
Y
the higher frequencies whose contributions to the sample variance are ‘massively’ exagerated:
We observe a strong positive bias of ITdirect
(ωk ). Note that a1 = 0.9 means that a typical path
Y
of xt ressembles a realization of an I(2)-process: We here deliberately magnify the unit-root
distortion in order to make the problem palpable.
We infer from the above exercise that a direct computation of the periodogram IT X (ωk ) of a nonstationary series xt is nearly unbiased if the (stationary) first differences ut = xt − xt−1 do not
24 One can show that the periodogram of x retains all relevant information in this case (random-walk), see Wildi
t
(2008).
78
show evidence of a strong positive autocorrelation (a1 ‘small’) which applies to typical economic
data25 . In such a case the difference between the pseudo-periodogram and the periodogram is
negligible.
3.3.5
Non-Stationary Processes: Additional Unit-Roots
If xt ∈ I(d) is of higher integration order d ≥ 2 or if the unit-roots are seasonal (not in frequency
zero) then xt could be differenced accordingly and the pseudo-DFT or the pseudo-periodogram
could be obtained. As an example
Ξpseudo
(ωk )
TX
:=
ITpseudo
(ωk )
X
:=
ΞT U (ωk )
(1 − exp(−iωk ))2
IT U (ωk )
|1 − exp(−iωk )|4
for an I(2)-process
(1 − B)2 xt ∈ I(0)
or
Ξpseudo
(ωk )
TX
:=
(ωk )
ITpseudo
X
:=
ΞT U (ωk )
1 − exp(−i12ωk )
IT U (ωk )
|1 − exp(−i12ωk )|2
for a process with seasonal roots
(1 − B 12 )xt ∈ I(0)
However We did not find the above extensions to be useful for ‘typical’ economic data and therefore
We here restrict ourselves to the the simple I(1)-case with ordinary (first) differences. We recommend usage of the pseudo-DFT/pseudo-periodogram if first differences of the data are strongly
positively autocorrelated. It should be emphasized that log-returns are often more interesting than
the original levels because the former emphasize the relevant growth-dynamics: in such a case one
can apply ordinary DFT and periodogram statistics to the (non-trending) log-transformed data.
4
Direct Filter Approach (DFA)
In the previous section We analyzed extensively filters (scaling/shift/convolution) and We proposed tools for quantifying their effects (transfer function, amplitude, phase). We now attempt to
optimize filter coefficients in view of a particular task: forecasting, nowcasting or backcasting the
output of a (possibly bi-infinite) target filter 14 based on a finite sample x1 , ..., xT of xt .
4.1
Mean-Square Paradigm
According to section 3.1.1 We assume a general target specification
yt =
∞
X
γk xt−k
(44)
k=−∞
For practical relevance as well as for simplicity We assume stability and symmetry of the target
filter γk = γ−k . We now seek filter coefficients bkh , k = h, ..., L − 1 + h such that the finite sample
estimate
L−1+h
X
ŷth :=
bkh xt−k
(45)
k=h
25 Differences or log-returns of important macro-series (GDP, IPI, employment,...) or of financial data (stock
prices, futures,...) are generally weakly autocorrelated or even close to white noise.
79
is closest possible to yt , h ∈ ZZ, in mean-square
E (yt − ŷth )2 → min
(46)
bh
where bh = (bhh , ..., bL−1+h,h ).
• If h = 0 We use data xt , ..., xt−(L−1) for estimating yt : this is a nowcast and bk0 , k =
0, ..., L − 1 is a real-time filter.
• If h = 1 We use data xt−1 , ..., xt−L for estimating yt : this is a forecast and bk1 , k = 1, ..., L
is a forecast filter.
• If h = −1 We use data xt+1 , ..., xt−(L−2) for estimating yt : this is a backcast and bk,−1 ,
k = −1, ..., L − 2 is a smoother.
For simplicity of notation (as well as practical relevance) We now fix attention to the real-time
estimate (nowcast) ŷT of yT and drop the index h = 0 in sub- and superscripts.
As usual, in applications, the expectation is unknown and therefore We could try to replace
46 by its sample estimate
T
2π
1X
(yt − ŷt )2 =
T t=1
T
[T /2]
X
IT ∆Y (ωk )
(47)
k=−[T /2]
where IT ∆Y (ωk ) is the periodogram of ∆yt := yt − ŷt and where the identity follows from 13.
Unfortunately, the output yt of the generally bi-infinite filter isn’t observed and therefore IT ∆Y (ωk )
is unknown too. But We could try to approximate the periodogram by relying on the finite-sample
discrete convolution 30:
IT ∆Y (ωk ) ≈ ∆ΓIT X (ωk )
P∞
where ∆Γ(ωk ) = Γ(ωk )− Γ̂(ωk ) = j=−∞ ∆γj exp(−ijωk ) is the difference of target and real-time
transfer functions (recall that We assume h = 0, for simplicity). Then
T
1X
(yt − ŷt )2
T t=1
=
≈
2π
T
2π
T
[T /2]
X
IT ∆Y (ωk )
(48)
k=−[T /2]
[T /2]
X
k=−[T /2]
2
|∆Γ(ωk )| IT X (ωk ) → min
b
(49)
In contrast to 47 or 46, the frequency-domain criterion 49 can be computed: since filter coefficients
b0 , ..., bL−1 are optimized ‘directly’ We named this method Direct Filter Approach (DFA). We can
see that the periodogram IT X (ωk ) weights the approximation error ∆Γ(ωk ) between target and
real-time filters: the latter must be close to the former if IT X (ωk ) is large, in relative terms.
Formally, one can show that the approximation error in 49 is ‘unusually’ small26 . Furthermore,
the time-domain MSE (left-hand side of 48) is itself an asymptotically efficient estimate of 46, see
Wildi (2008). Therefore, minimizing 49 is indeed pertinent. If xt is integrated (trending) then one
could plug the pseudo-periodogram 39 of xt as an alternative.
From a computational perspective the above criterion 49 is convenient because it is a squared
function of the unknown coefficients. Therefore a unique solution exists and can be computed
analytically, in closed-form (interested readers are referred to Wildi (2013)27 ).
26 The
term ‘unusual’√here means that the error is hidden by ordinary sample fluctuations whose magnitude is
typically of order O(1/ T ): the error in 49 is of smaller magnitude asymptotically: this property is commonly
referred to as ‘superconsistency’. The interested reader is referred to Wildi (2008) for formal results.
27 http://blog.zhaw.ch/idp/sefblog/index.php?/archives/259-Elements-of-Forecasting-and-Signal-Extraction.
html
80
4.1.1
Exercises
We here compute real-time estimates of the ideal lowpass
1 |ω| < cutoff
Γ(ω, cutoff) =
0 otherwise
with filter weights
∞
cutoff
2 X sin(k · cutoff)
Γ(ω) =
+
cos(kω)
π
π
k
k=1
see 3. The following DFA-code can perform typical mean-square optimization based on criterion
49:
>
>
>
>
>
>
>
>
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# This function computes mean-square DFA-solutions
# L is the length of the MA filter,
# periodogram is the frequency weighting function in the DFA
# Gamma is the transferfunction of the symmetric filter (target) and
# Lag is the lag-parameter: Lag=0 implies real-time filtering, Lag=L/2
#
implies symmetric filter
# The function returns optimal coefficients as well as the transfer function of the
#
optimized real-time filter
dfa_ms<-function(L,periodogram,Lag,Gamma)
{
K<-length(periodogram)-1
X<-exp(-1.i*Lag*pi*(0:(K))/(K))*rep(1,K+1)*sqrt(periodogram)
X_y<-exp(-1.i*Lag*pi*(0:(K))/(K))*rep(1,K+1)
for (l in 2:L)
#l<-L<-21
{
X<-cbind(X,(cos((l-1-Lag)*pi*(0:(K))/(K))+
1.i*sin((l-1-Lag)*pi*(0:(K))/(K)))*sqrt(periodogram))
X_y<-cbind(X_y,(cos((l-1-Lag)*pi*(0:(K))/(K))+
1.i*sin((l-1-Lag)*pi*(0:(K))/(K))))
}
xtx<-t(Re(X))%*%Re(X)+t(Im(X))%*%Im(X)
# MA-Filtercoefficients
b<-as.vector(solve(xtx)%*%(t(Re(X_y))%*%(Gamma*periodogram)))
# Transferfunction
trffkt<-1:(K+1)
trffkt[1]<-sum(b)
for (k in 1:(K))#k<-1
{
trffkt[k+1]<-(b%*%exp(1.i*k*(0:(length(b)-1))*pi/(K)))
}
return(list(b=b,trffkt=trffkt))
}
The following inputs are required in the head of the function-call
• L: the filter length. Larger L require more coefficients to be estimated and the resulting
filter will be more flexible (which is welcome) but potentially prone to overfitting (which is
unwelcome).
• weight func: the frequency weighting-function. We will use mainly the periodogram (experienced users know why). But We will also plug-in model-based spectra in section 8 (in order
to replicate and to customize model-based approaches).
81
• Lag: corresponds to −h i.e. it allows for estimation of yT −Lag : A forecast, nowcast (realtime filter) or backcast (smoother) is obtained depending on Lag < 0, Lag = 0 or Lag > 0.
A finite symmetric filter is obtained if L is an odd integer and Lag = (L − 1)/2.
• Gamma: the target symmetric filter.
1. We estimate optimal real-time filters (h = Lag = 0) of length L = 12 for three different
stationary processes
xt = 0.9xt−1 + t
xt =
t
(50)
xt = −0.9xt−1 + t
by applying the above DFA-function to approximate the ideal lowpass with cutoff π/6. Since
the processes are different We expect the solutions of 49 to be different too.
• Generate realizations of length T = 120 for the above three processes and compute
real-time estimates ŷt of yt . Plot the data and the filtered series see fig.30.
>
>
>
>
>
>
>
>
>
>
>
+
+
+
+
>
>
>
>
>
>
>
+
+
+
+
+
+
+
+
+
+
>
>
>
>
+
# Generate series
set.seed(10)
len<-120
a_vec<-c(0.9,0,-0.9)
x<-matrix(nrow=len,ncol=3)
plot_T<-F
yhat<-x
periodogram<-matrix(ncol=3,nrow=len/2+1)
trffkt<-periodogram
# Generate series
for (i in 1:3)
{
set.seed(10)
x[,i]<-arima.sim(list(ar=a_vec[i]),n=len)
}
# Specify filter settings
L<-12
Lag<-0
Gamma<-c(1,(1:(len/2))<len/12)
b<-matrix(nrow=L,ncol=3)
# Compute real-time filters
for (i in 1:3)
{
periodogram[,i]<-per(x[,i],plot_T)$per
# Optimize filters
filt<-dfa_ms(L,periodogram[,i],Lag,Gamma)
trffkt[,i]<-filt$trffkt
b[,i]<-filt$b
# Compute outputs
for (j in L:len)
yhat[j,i]<-filt$b%*%x[j:(j-L+1),i]
}
file = paste("z_dfa_ar1_output.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(3,1))
for (i in 1:3)
{
82
+
ts.plot(x[,i],main=paste("a1 = ",a_vec[i],sep=""),col="blue")
+
lines(yhat[,i],col="red")
+ }
> dev.off()
null device
1
0 2 4
−4
x[, i]
a1 = 0.9
0
20
40
60
80
100
120
80
100
120
80
100
120
Time
0 1 2
−2
x[, i]
a1 = 0
0
20
40
60
Time
0
−4
x[, i]
4
a1 = −0.9
0
20
40
60
Time
Figure 30: Inputs (blue) and real-time outputs (red) for a1=0.9 (top), a1=0 (middle) and a1=-0.9
(bottom)
We can see that the filter effect is weakest for the top-DGP (a1 = 0.9) and strongest
for the bottom process (a1 = −0.9).
• Compare amplitude and time-shift functions of the three real-time filters graphically,
see fig.31.
83
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
>
+
>
>
>
+
+
>
>
>
>
>
>
>
>
+
>
>
>
+
+
>
>
>
>
>
>
+
>
>
>
omega_k<-pi*0:(len/2)/(len/2)
file = paste("z_dfa_ar1_amp_shift.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,2))
amp<-abs(trffkt)
shift<-Arg(trffkt)/omega_k
plot(amp[,1],type="l",main="Amplitude functions",
axes=F,xlab="Frequency",ylab="Amplitude",col="black",ylim=c(0,1))
lines(amp[,2],col="orange")
lines(amp[,3],col="green")
lines(Gamma,col="violet")
mtext("Amplitude a1=0.9", side = 3, line = -1,at=len/4,col="black")
mtext("Amplitude a1=0", side = 3, line = -2,at=len/4,col="orange")
mtext("Amplitude a1=-0.9", side = 3, line = -3,at=len/4,col="green")
mtext("Target", side = 3, line = -4,at=len/4,col="violet")
axis(1,at=c(0,1:6*len/12+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
plot(shift[,1],type="l",main="Time-shifts",
axes=F,xlab="Frequency",ylab="Shift",col="black",
ylim=c(0,max(na.exclude(shift[,3]))))
lines(shift[,2],col="orange")
lines(shift[,3],col="green")
lines(rep(0,len/2+1),col="violet")
mtext("Shift a1=0.9", side = 3, line = -1,at=len/4,col="black")
mtext("Shift a1=0", side = 3, line = -2,at=len/4,col="orange")
mtext("Shift a1=-0.9", side = 3, line = -3,at=len/4,col="green")
mtext("Target", side = 3, line = -4,at=len/4,col="violet")
axis(1,at=c(0,1:6*len/12+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
plot(periodogram[,1],type="l",main="Periodograms",
axes=F,xlab="Frequency",ylab="Periodogram",col="black",
ylim=c(0,max(periodogram[,3])/6))
lines(periodogram[,2],col="orange")
lines(periodogram[,3],col="green")
mtext("Periodogram a1=0.9", side = 3, line = -1,at=len/4,col="black")
mtext("Periodogram a1=0", side = 3, line = -2,at=len/4,col="orange")
mtext("Periodogram a1=-0.9", side = 3, line = -3,at=len/4,col="green")
axis(1,at=c(0,1:6*len/12+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
84
0
pi/6
3pi/6
5pi/6
0.0 0.5 1.0 1.5 2.0
Shift a1=0.9
Shift a1=0
Shift a1=−0.9
Target
Shift
Amplitude a1=0.9
Amplitude a1=0
Amplitude a1=−0.9
Target
0.4
0.8
Time−shifts
0.0
Amplitude
Amplitude functions
0
Frequency
pi/6
3pi/6
5pi/6
Frequency
Periodograms
3
2
1
0
Periodogram
4
Periodogram a1=0.9
Periodogram a1=0
Periodogram a1=−0.9
0
pi/6
3pi/6
5pi/6
Frequency
Figure 31: Amplitude (top left), time-shifts (top-right) and periodograms (bottom left) for a1=0.9
(black), a1=0 (orange) and a1=-0.9 (green)
The amplitude function (top left panel) of the black filter (corresponding to the positively
autocorrelated series a1 = 0.9) is the farest away from the target in the stop-band – the
filter damps high-frequency components the least – but it is closest to the target in in
the passband ω < π/6: it sacrifices to some extent high-frequency damping against better
passband properties. The converse applies to the green filter, corresponding to a1 = −0.9
and the orange filter (white noise a1 = 0) lies in between. The very strong (relative) damping
of the green filter shows up in a larger time-shift (top right panel). This strong damping
towards the highest frequencies is due to a large green periodogram (bottom left panel)
towards ω = π (We decided to truncate black and green periodograms for ease of visual
inspection). In contrast, the large black periodogram towards the lowest frequencies implies
that the fit of of Γ(ωk ) (violet) by Γ̂(ωk ) (black) in the top panels must be improved: both the
amplitude (left) as well as the shift (right) are closest to the target in the passband. These
observations match very well the structure of the optimization criterion 49, as expected.
85
2. We now briefly verify that the optimized coefficients are indeed optimal
• Plug Γ(ωk ) and Γ̂(ωk ) into 49 and compute the criterion values for all three processes.
• Exchange Γ̂(ωk ) and periodograms corresponding to the three processes in 49 and verify that any process-specific solution is suboptimal for the other two processes (as an
example: the white-noise solution should not be optimal for the two autocorrelated
processes).
>
>
>
+
+
+
+
+
+
+
+
>
>
+
# Compute criterion values for all (3*3) combinations of filters and periodograms
perf_mat<-matrix(nrow=3,ncol=3)
for (i in 1:3)
{
for (j in 1:3)
{
# Criterion value
perf_mat[j,i]<-(2*pi/length(Gamma))*
abs(Gamma-trffkt[,i])^2%*%periodogram[,j]
}
}
dimnames(perf_mat)[[2]]<-c("filter: a1=0.9","filter: a1=0","filter: a1=-0.9")
dimnames(perf_mat)[[1]]<-c("periodogram: a1=0.9",
" periodogram: a1=0","periodogram: a1=-0.9")
The criterion values for all combinations of periodograms and filters are summarized in
table 3. For a fixed periodogram (row i) the smallest criterion value is achieved for the
periodogram: a1=0.9
periodogram: a1=0
periodogram: a1=-0.9
filter: a1=0.9
0.260
0.153
1.003
filter: a1=0
0.489
0.074
0.078
filter: a1=-0.9
0.940
0.093
0.025
Table 3: Criterion values for all 3*3 combinations of periodograms and filters
corresponding filter in column j = i, as expected.
• Compare frequency-domain criterion values 49 and time-domain mean-square errors 47.
Hint: in order to perform time-domain MSE’s We must observe y1 , ..., y120 . For this
purpose We generate a long series x−1000 , ..., x1000 of length T = 2001 and apply a
truncated symmetric lowpass of length 2001 − 120 for estimating y1 , ..., y120 28 .
>
>
>
>
>
>
>
>
>
>
>
>
>
>
+
28 Fig.3
# Define all relevant variables
set.seed(10)
lenh<-2000
len<-120
a_vec<-c(0.9,0,-0.9)
xh<-matrix(nrow=lenh,ncol=length(a_vec))
x<-matrix(nrow=len,ncol=length(a_vec))
plot_T<-F
yhat<-x
y<-x
periodogram<-matrix(ncol=3,nrow=len/2+1)
trffkt<-periodogram
# Generate series for each process
for (i in 1:length(a_vec))
{
in section 2.1.2 suggests that an approximation of order 2000 should be good.
86
+
+
+
>
>
>
>
>
>
>
>
>
>
+
+
+
+
+
+
+
>
>
>
>
>
>
>
+
+
+
+
+
+
+
+
+
+
+
+
>
>
>
>
>
>
+
+
+
+
+
+
+
+
+
set.seed(10)
xh[,i]<-arima.sim(list(ar=a_vec[i]),n=lenh)
}
# We extract 120 observations in the midddle of xh: these will be used
# for real-time filtering
x<-xh[lenh/2+(-len/2):((len/2)-1),]
# Compute the coefficients of the symmetric target filter
cutoff<-pi/6
# Order of approximation
ord<-1000
gamma<-c(cutoff/pi,(1/pi)*sin(cutoff*1:ord)/(1:ord))
# Compute the outputs yt of the symmetric target filter
for (i in 1:length(a_vec))
{
for (j in 1:120)
{
y[j,i]<-gamma[1:900]%*%xh[lenh/2+(-len/2)-1+(j:(j-899)),i]+
gamma[2:900]%*%xh[lenh/2+(-len/2)+(j:(j+898)),i]
}
}
# Specify real-time filter settings
L<-12
Lag<-0
Gamma<-c(1,(1:(len/2))<len/12)
b<-matrix(nrow=L,ncol=3)
# Compute real-time filters
for (i in 1:3)
{
periodogram[,i]<-per(x[,i],plot_T)$per
# Optimize filters
filt<-dfa_ms(L,periodogram[,i],Lag,Gamma)
trffkt[,i]<-filt$trffkt
b[,i]<-filt$b
# Compute outputs: We can use the longer series in order to obtain
# outputs for j=1,...,len
for (j in 1:len)
yhat[j,i]<-filt$b%*%xh[lenh/2+(-len/2)-1+j:(j-L+1),i]
perf_mat[i,i]<-(2*pi/length(Gamma))*abs(Gamma-trffkt[,i])^2%*%periodogram[,i]
}
# Compute time-domain MSE
mse<-apply(na.exclude((yhat-y))^2,2,mean)
file = paste("z_dfa_ar1_sym_output.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(3,1))
for (i in 1:3)
{
ymin<-min(min(y[,i]),min(na.exclude(yhat)[,i]))
ymax<-max(max(y[,i]),max(na.exclude(yhat)[,i]))
ts.plot(yhat[,i],main=paste("Time-domain MSE = ",
round(mse[i],3)," , Frequency-domain MSE = ",
round(perf_mat[i,i],3),", a1 = ",a_vec[i],sep=""),col="blue",ylim=c(ymin,ymax))
lines(y[,i],col="red")
mtext("Real-time", side = 3, line = -1,at=len/2,col="blue")
mtext("target", side = 3, line = -2,at=len/2,col="red")
87
+ }
> dev.off()
null device
1
Time−domain MSE = 0.322 , Frequency−domain MSE = 0.315, a1 = 0.9
−2
−6
yhat[, i]
2
Real−time
target
0
20
40
60
80
100
120
Time
0.5
Real−time
target
−0.5
yhat[, i]
Time−domain MSE = 0.053 , Frequency−domain MSE = 0.047, a1 = 0
0
20
40
60
80
100
120
Time
0.0
Real−time
target
−0.6
yhat[, i]
0.6
Time−domain MSE = 0.028 , Frequency−domain MSE = 0.028, a1 = −0.9
0
20
40
60
80
100
120
Time
Figure 32: Real-time filter output (blue) vs. targets (red) for a1=0.9 (top), a1=0 (middle) and
a1=-0.9 (bottom)
We can see that the real-time estimates (blue) are substantially noisier than the target
(red) and that they lag. The remaining (undesirable) stop-band noise is due to the
leaking amplitude functions in fig.31, top-left panel; the lag corresponds to the positive
time-shifts in fig.31, top-right panel. The time-domain MSE’s
T
1X
(yt − ŷt )2
T t=1
88
are very close to the criterion values 49, as can be seen in the headers of the above figure:
minimizing the observable frequency-domain MSE is virtually the same as minimizing
the (generally) unobservable time-domain MSE.
3. We now analyze the effect of h (h = −Lag) on the real-time filters. Compute optimal
finite sample filters for Lag = 0, ..., L/2 for the above three processes and plot the resulting
amplitude and time-shift functions, see fig.33. Hint: We now use L = 13 in order to obtain
a symmetric filter in Lag = 6
>
>
>
>
>
>
+
+
+
+
+
+
+
+
+
+
+
+
+
>
>
>
>
>
>
>
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
L<-13
yhat_Lag<-array(dim=c(len,3,L/2+2))
trffkt<-array(dim=c(len/2+1,3,L/2+2))
b<-array(dim=c(L,3,L/2+2))
# Compute real-time filters for Lag=,...,L/2 and for the above three AR-processes
for (i in 1:3)
{
periodogram[,i]<-per(x[,i],plot_T)$per
for (Lag in 0:((L/2)+1))
{
# Optimize filters
filt<-dfa_ms(L,periodogram[,i],Lag,Gamma)
trffkt[,i,Lag+1]<-filt$trffkt
b[,i,Lag+1]<-filt$b
# Compute outputs
for (j in L:len)
yhat_Lag[j,i,Lag+1]<-filt$b%*%x[j:(j-L+1),i]
}
}
omega_k<-pi*0:(len/2)/(len/2)
colo<-rainbow(L/2+2)
file = paste("z_dfa_ar1_amp_shift_Lag.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(3,4))
amp<-abs(trffkt)
shift<-Arg(trffkt)/omega_k
for (i in 1:3)
{
ymin<-min(amp[,i,],na.rm=T)
ymax<-max(amp[,i,],na.rm=T)
plot(amp[,i,1],type="l",main=paste("Amplitude functions, a1 = ",a_vec[i],sep=""),
axes=F,xlab="Frequency",ylab="Amplitude",col=colo[1],ylim=c(ymin,ymax))
mtext("Lag=0", side = 3, line = -1,at=len/4,col=colo[1])
for (j in 2:(L/2+2))
{
lines(amp[,i,j],col=colo[j])
mtext(paste("Lag=",j-1,sep=""), side = 3, line = -j,at=len/4,col=colo[j])
}
axis(1,at=c(0,1:6*len/12+1),labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
ymin<-min(shift[,i,],na.rm=T)
ymax<-max(shift[,i,],na.rm=T)
plot(shift[,i,1],type="l",main=paste("Time-Shifts, a1 = ",a_vec[i],sep=""),
axes=F,xlab="Frequency",ylab="Shift",col=colo[1],ylim=c(ymin,ymax))
mtext("Lag=0", side = 3, line = -1,at=len/4,col=colo[1])
89
+
for (j in 2:(L/2+2))
+
{
+
lines(shift[,i,j],col=colo[j])
+
mtext(paste("Lag=",j-1,sep=""), side = 3, line = -j,at=len/4,col=colo[j])
+
}
+
axis(1,at=c(0,1:6*len/12+1),labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
+
axis(2)
+
box()
+
ymin<-min(b[,i,],na.rm=T)
+
ymax<-max(b[,i,],na.rm=T)
+
plot(b[,i,1],col=colo[1],ylim=c(ymin,ymax),main=paste("Filter coefficients"),
+
ylab="Output",xlab="lag",axes=F,typ="l")
+
for (j in 2:(L/2+2))
+
{
+
lines(b[,i,j],col=colo[j],type="l")
+
mtext(paste("Lag=",j-1,sep=""), side = 3, line = -j,at=L/2,col=colo[j])
+
}
+
axis(1,at=1:L,labels=-1+1:L)
+
axis(2)
+
box()
+
ymin<-min(yhat_Lag[,i,],na.rm=T)
+
ymax<-max(yhat_Lag[,i,],na.rm=T)
+
ts.plot(yhat_Lag[,i,1],col=colo[1],ylim=c(ymin,ymax),main=paste("Output series"),
+
ylab="Output")
+
mtext("Lag=0", side = 3, line = -1,at=len/4,col=colo[1])
+
for (j in 2:(L/2+2))
+
{
+
lines(yhat_Lag[,i,j],col=colo[j])
+
mtext(paste("Lag=",j-1,sep=""), side = 3, line = -j,at=len/4,col=colo[j])
+
}
+
+ }
> dev.off()
null device
1
90
Frequency
0
2
−2
−6
0.5
−0.5
Output
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
0 Lag=7
3 6 9
Lag=0
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
0 40 100
Lag=7
Time
Filter coefficients
Output series
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
0 Lag=7
3 6 9
lag
0.0 0.4
lag
−0.05
Frequency
Output
0.5
0.2
−0.1
Lag=0
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
3pi/6 pi
Lag=7
Output
4
0
−6
Shift
1.2
0.6
0.0
Amplitude
0
Output series
Frequency
Amplitude functions, a1 = −0.9
Time−Shifts, a1 = −0.9
Lag=0
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
3pi/6 pi
Lag=7
Filter coefficients
−0.6
Frequency
Output
4
0
−6
0
Lag=0
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
3pi/6 pi
Lag=7
Lag=0
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
0 40 100
Lag=7
Time
Output
0
Lag=0
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
3pi/6 pi
Lag=7
Shift
0.6
0.0
Amplitude
1.2
Amplitude functions, a1 = 0Time−Shifts, a1 = 0
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
0 Lag=7
3 6 9
Output series
lag
0.10
Frequency
−0.05
Frequency
Output
4
0
−6
0
Lag=0
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
3pi/6 pi
Lag=7
Filter coefficients
0.10
0
Lag=0
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
3pi/6 pi
Lag=7
Shift
0.8
0.4
0.0
Amplitude
Amplitude functions, a1 = 0.9
Time−Shifts, a1 = 0.9
Lag=0
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
0 40 100
Lag=7
Time
Figure 33: Amplitude (left) and time-shift (right) functions as a function of Lag (rainbow) for
a1=0.9 (top), a1=0 (middle) and a1=-0.9 (bottom)
For better visual inspection We here focus attention on the ‘white noise’ filter (DGP with
a1 = 0), see fig.34.
>
>
>
>
>
>
+
+
+
+
file = paste("z_dfa_ar1_amp_shift_Lag_0.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,2))
amp<-abs(trffkt)
shift<-Arg(trffkt)/omega_k
for (i in 2:2)
{
ymin<-min(amp[,i,],na.rm=T)
ymax<-max(amp[,i,],na.rm=T)
plot(amp[,i,1],type="l",main=paste("Amplitude functions, a1 = ",a_vec[i],sep=""),
91
+
axes=F,xlab="Frequency",ylab="Amplitude",col=colo[1],ylim=c(ymin,ymax))
+
mtext("Lag=0", side = 3, line = -1,at=len/4,col=colo[1])
+
for (j in 2:(L/2+2))
+
{
+
lines(amp[,i,j],col=colo[j])
+
mtext(paste("Lag=",j-1,sep=""), side = 3, line = -j,at=len/4,col=colo[j])
+
}
+
axis(1,at=c(0,1:6*len/12+1),labels=c("0","pi/6","2pi/6","3pi/6",
+
"4pi/6","5pi/6","pi"))
+
axis(2)
+
box()
+
ymin<-min(shift[,i,],na.rm=T)
+
ymax<-max(shift[,i,],na.rm=T)
+
plot(shift[,i,1],type="l",main=paste("Time-Shifts, a1 = ",a_vec[i],sep=""),
+
axes=F,xlab="Frequency",ylab="Shift",col=colo[1],ylim=c(ymin,ymax))
+
mtext("Lag=0", side = 3, line = -1,at=len/4,col=colo[1])
+
for (j in 2:(L/2+2))
+
{
+
lines(shift[,i,j],col=colo[j])
+
mtext(paste("Lag=",j-1,sep=""), side = 3, line = -j,at=len/4,col=colo[j])
+
}
+
axis(1,at=c(0,1:6*len/12+1),labels=c("0","pi/6","2pi/6","3pi/6",
+
"4pi/6","5pi/6","pi"))
+
axis(2)
+
box()
+
ymin<-min(b[,i,],na.rm=T)
+
ymax<-max(b[,i,],na.rm=T)
+
plot(b[,i,1],col=colo[1],ylim=c(ymin,ymax),main=paste("Filter coefficients"),
+
ylab="Output",xlab="lag",axes=F,typ="l")
+
for (j in 2:(L/2+2))
+
{
+
lines(b[,i,j],col=colo[j],type="l")
+
mtext(paste("Lag=",j-1,sep=""), side = 3, line = -j,at=L/2,col=colo[j])
+
}
+
axis(1,at=1:L,labels=-1+1:L)
+
axis(2)
+
box()
+
+
ymin<-min(yhat_Lag[,i,],na.rm=T)
+
ymax<-max(yhat_Lag[,i,],na.rm=T)
+
ts.plot(yhat_Lag[,i,1],col=colo[1],ylim=c(ymin,ymax),
+
main=paste("Output series"),ylab="Output")
+
for (j in 2:(L/2+2))
+
{
+
lines(yhat_Lag[,i,j],col=colo[j])
+
mtext(paste("Lag=",j-1,sep=""), side = 3, line = -j,at=len/4,col=colo[j])
+
}
+
+ }
> dev.off()
null device
1
92
Lag=0
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
Lag=7
pi/6
−2
3pi/6
5pi/6
0
3pi/6
5pi/6
Filter coefficients
Output series
4
6
0.5
−0.5
Output
0.05
2
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
Lag=7
0.0
0.15
Frequency
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
Lag=7
0
pi/6
Frequency
−0.05
Output
−6
0.8
0.4
0.0
Amplitude
0
2 4 6
Lag=0
Lag=1
Lag=2
Lag=3
Lag=4
Lag=5
Lag=6
Lag=7
Shift
Time−Shifts, a1 = 0
1.2
Amplitude functions, a1 = 0
8
10
12
0
lag
20
40
60
80
120
Time
Figure 34: Amplitude (left) and time-shift (right) functions as a function of Lag (rainbow colors)
for the white noise process (a1=0)
As expected, the time-shift (top-right) increases with increasing Lag (decreasing h). For
Lag = (L − 1)/2 = 6 the filter is symmetric and therefore the corresponding time-shift
(violet line) is constant29 . The shift does not vanish because the filter is causal: coefficients
are symmetric about Lag 6 (not zero), see the violet line in the bottom-left panel. We can see
that the output series (bottom-right panel) are shifted accordingly: the larger the shift, the
smoother the series. Indeed, We can observe, also, that the amplitude functions get closer to
zero in the stop-band, as Lag = −h increases. The stronger noise suppression is obtained by
assigning more weight to past realizations as can be seen in the bottom left panel: whereas
the real-time filter (red line bottom left panel) emphasizes the last observation, the Lag = 6
symmetric filter assigns a more regular symmetric weighting scheme centered around the
29 The shift is constant (flat line) in the passband. The variable shift in the stopband is an artifact of the Argfunction: the physical shift must be constant since the filter weights (violet line bottom left panel) are symmetric.
93
middle coefficient b(L−1)/2 = b6 . The effect is that the real-time filter will be much faster
(much smaller time shift, see top-right panel) but noisier (the amplitude is leaking in the
stop-band, top-left panel).
4. To conclude this series of exercises We compute finite-sample distributions of filter coefficients, of amplitude and of time-shift functions and We analyze overfitting issues by comparing in-sample and out-of-sample characteristics of the optimized filter as a function of
the filter length L. For this purpose We focus on properties of the practically relevant realtime filters Lag = −h = 0 and We rely on the white noise process. Specifically We fit
filters of lengths L = 3, 6, 12, 24 and L = 48 and analyze MSE’s both in-sample as well as
out-of-sample.
• Generate a simulation sample of 100 realizations of length 2000+2*120
• For each realization: apply a symmetric filter of length 1999 to the data for t = 1000 :
1239
• Compute the periodogram on the sample t = 1000 : 1119 (in-sample length T = 120)
• Estimate real-time filters of lengths L = 3, 6, 12, 24 and L = 48
• Compute real-time filter outputs for t = 1000 : 1239 (total sample-length 240: the last
120 observations are out-of-sample)
P1119
1
2
i
• Determine in-sample mean-square errors 120
t=1000 (ŷt − yt ) as well as out-of-sample
P
1239
1
2
i
i
mean-square errors 120
t=1120 (ŷt − yt ) where yt is the finite symmetric filter and ŷt ,
i = 1, ..., 5 are the outputs of the real-time filters of length L = 3, 6, 12, 24 and L = 48
• Store filter-coefficients and transfer functions in order to compute empirical distributions.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
+
+
+
# Compute real-time filters of length 3,6,12,24 and 48
Lag<-0
L_vec<-c(3,6,12,24,48)
# Compute the coefficients of the symmetric target filter
cutoff<-pi/6
# Order of approximation
ord<-999
gamma<-c(cutoff/pi,(1/pi)*sin(cutoff*1:ord)/(1:ord))
# Determine full-length and in-sample length
len<-120
lenh<-2240
set.seed(10)
anzsim<-100
perf_outsample<-matrix(nrow=anzsim,ncol=length(L_vec))
perf_insample<-perf_outsample
b_sim<-as.list(1:anzsim)
b<-as.list(1:length(L_vec))
trffkt<-array(dim=c(len/2+1,length(L_vec),anzsim))
ymin<-1:length(L_vec)
ymax<-1:length(L_vec)
# Target in frequency-domain
Gamma<-c(1,(1:(len/2))<len/12)
#
# Start simulation
for (k in 1:anzsim)
{
# Full length data
xh<-rnorm(lenh)
94
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
>
>
>
# in-sample data-set: used for estimation of periodogram
x<-xh[(lenh/2-len):(lenh/2-1)]
y<-x
# compute output of symmetric filter
for (j in 1:(2*len))
{
y[j]<-gamma%*%xh[lenh/2-len-1+(j:(j-(ord)))]+
gamma[2:ord]%*%xh[lenh/2-len+(j:(j+ord-2))]
}
yhat_insample<-array(dim=c(2*len,length(L_vec)))
# Compute Periodogram based on in-sample data
per_wn<-per(x,plot_T)$per
for (i in 1:length(L_vec))
{
# Optimize filters in sample
filt<-dfa_ms(L_vec[i],per_wn,Lag,Gamma)
trffkt[,i,k]<-filt$trffkt
b[[i]]<-filt$b
if (k==1)
{
ymin[i]<-min(b[[i]])
ymax[i]<-max(b[[i]])
} else
{
ymin[i]<-min(ymin[i],min(b[[i]]))
ymax[i]<-max(ymax[i],max(b[[i]]))
}
# Compute the outputs in and out-of-sample
for (j in 1:(2*len))#j<-1
yhat_insample[j,i]<-b[[i]]%*%xh[lenh/2-len-1+(j:(j-(L_vec[i])+1))]
}
# Store filter coefficients
b_sim[[k]]<-b
# MSE performances: in and out-of-sample
perf_insample[k,]<-apply(na.exclude(y[1:len]-yhat_insample[1:len,])^2,2,mean)
perf_outsample[k,]<apply(na.exclude(y[len+1:len]-yhat_insample[len+1:len,])^2,2,mean)
}
perf_mat<-rbind(apply(perf_insample,2,mean),apply(perf_outsample,2,mean))
dimnames(perf_mat)[[2]]<-paste("L=",L_vec,sep="")
dimnames(perf_mat)[[1]]<-c("In-sample","Out-of-sample")
In-sample
Out-of-sample
L=3
0.093
0.097
L=6
0.075
0.081
L=12
0.068
0.080
L=24
0.064
0.084
L=48
0.062
0.100
Table 4: In- and out-of-sample MSE-performances of real-time trend extraction filters of length
3-48
MSE-performances of the simulation-study as summarized in table 4 suggest that the
optimal filter length is L = 12: for larger lengths overfitting affects (out-of-sample)
performances. As expected, in-sample MSE’s decrease with increasing L30 . As a result,
30 In
fact this statement is not trivial since the DFA-optimization criterion is implemented in the frequency-
95
the gap between in-sample and out-of-sample performances opens for increasing L.
However, out-of-sample performances of the filter with length L = 24 are very close to
the best filter L = 12 and therefore the design seems quite robust since We have only
120 observations (10 years of monthly data) available.
• Plot the empirical distribution of the filter coefficients, see fig.35.
>
>
+
>
>
+
+
+
+
+
+
+
+
+
>
file = paste("z_dfa_wn_b_dist.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(2,2))
for (i in 2:length(L_vec))
{
b_opt<-dfa_ms(L_vec[i],rep(1,length(Gamma)),Lag,Gamma)$b
ts.plot(b_sim[[1]][[i]],ylim=c(ymin[i],ymax[i]),
main=paste("Filter coefficients L = ",L_vec[i],sep=""),xlab="lag",
ylab="coefficients")
for (j in 2:anzsim)
lines(b_sim[[j]][[i]])
lines(b_opt,col="red",lwd=2)
}
dev.off()
null device
1
domain, whereas Our performance measure is implemented in the time-domain. We just confirmed, once again, the
close correspondence between 47 and 49.
96
1
2
3
4
5
0.15
6
2
4
6
8
10
12
Filter coefficients L = 24
Filter coefficients L = 48
−0.10
0.05
coefficients
0.05
0.15
lag
0.15
lag
−0.05
coefficients
0.05
−0.05
0.10
coefficients
0.20
Filter coefficients L = 12
0.00
coefficients
Filter coefficients L = 6
5
10
15
20
0
10
lag
20
30
40
lag
Figure 35: Empirical distribution of filter coefficients as a function of the filter length L: DGP is
white noise (a1=0)
The above figure illustrates the empirical distributions of the coefficients around the
theoretical best real-time estimates (red lines) assuming knowledge of the GDP (white
noise). We observe that the estimates are unbiased. Also, coefficients are not significantly different from zero for lags larger than six (zero lies in the ±2σ band for higher
lags): this result is in conformity with the above out-of-sample results (increased discrepancy between in-sample and out-of-sample performances for L > 6: overfitting).
Interestingly, a damped periodic ‘structure’ is built into the estimates as L increases31 .
• Plot the empirical distribution of amplitude and time-shift functions, see figs.36 and
37.
> file = paste("z_dfa_wn_amp_dist.pdf", sep = "")
31 The coefficients of the symmetric target filter are also a damped sinusoid of frequency π/6 which coincides quite
well with the above figure.
97
>
+
>
>
+
+
+
+
+
+
+
+
+
>
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
par(mfrow=c(2,2))
for (i in 2:length(L_vec)) #i<-2
{
trffkt_opt<-dfa_ms(L_vec[i],rep(1,length(Gamma)),Lag,Gamma)$trffkt
ts.plot(abs(trffkt[,i,1]),ylim=c(min(abs(trffkt[,i,])),max(abs(trffkt[,i,]))),
main=paste("Amplitude: L = ",
L_vec[i],sep=""),xlab="lag",ylab="coefficients")
for (j in 2:anzsim)
lines(abs(trffkt[,i,j]))
lines(abs(trffkt_opt),col="red",lwd=2)
}
dev.off()
null device
1
98
coefficients
10
20
30
40
50
60
0
10
20
30
40
50
lag
lag
Amplitude: L = 24
Amplitude: L = 48
60
1.0
0.0
0.5
coefficients
0.8
0.4
0.0
coefficients
1.5
0
0.0 0.2 0.4 0.6 0.8
Amplitude: L = 12
0.0 0.2 0.4 0.6 0.8
coefficients
Amplitude: L = 6
0
10
20
30
40
50
60
0
lag
10
20
30
40
50
60
lag
Figure 36: Empirical distribution of amplitude functions as a function of the filter length L: DGP
is white noise (a1=0)
We observe that the variance of the distribution of the empirical amplitude-function
increases substantially with increasing L. This result certainly explains poorer out-ofsample properties of filters whose length equals or exceeds L = 24.
>
>
+
>
>
>
+
+
+
file = paste("z_dfa_wn_shift_dist.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special",
width = 6, height = 6)
omega_k<-pi*0:(len/2)/(len/2)
par(mfrow=c(2,2))
for (i in 2:length(L_vec)) #i<-2
{
trffkt_opt<-dfa_ms(L_vec[i],rep(1,length(Gamma)),Lag,Gamma)$trffkt
ts.plot(Arg(trffkt[,i,1])/omega_k,ylim=c(min(na.exclude(Arg(trffkt[,i,])/omega_k)),m
99
+
main=paste("Shift: L = ",L_vec[i],sep=""),xlab="lag",
+
ylab="coefficients")
+
for (j in 2:anzsim)
+
lines(Arg(trffkt[,i,j])/omega_k)
+
lines(Arg(trffkt_opt)/omega_k,col="red",lwd=2)
+ }
> dev.off()
null device
1
Shift: L = 12
2
−2
−10
−6
coefficients
1.0
0.0
coefficients
2.0
Shift: L = 6
10
20
30
40
50
60
0
10
20
30
40
lag
lag
Shift: L = 24
Shift: L = 48
50
60
50
60
10
−30
−10
coefficients
0
−20
coefficients
10
0
0
10
20
30
40
50
60
0
lag
10
20
30
40
lag
Figure 37: Empirical distribution of time-shift functions as a function of the filter length L: DGP
is white noise (a1=0)
The empirical distribution of the time-shift confirms previous findings: the variance
increases for L ≥ 12.
100
In general, neither the theoretical MSE-criterion nor the time-domain sample criterion 47 are
observed32 , but the frequency-domain MSE 49 can be computed and We verified that the latter
is very close to the time-domain criterion 47 (superconsistency). Also, We could observe the rich
interaction between filter-characteristics and −h (Lag parameter in the R-code) which addresses
the problem of smoothing and revisions, see next section. Finally, We emphasized and quantified
the well-known overfitting problem and We analyzed the empirical distribution of filter coefficients
as well as of amplitude and time-shift functions, depending on the filter length L. The MSE-filter
is sensitive to overfitting for L ≥ 12.
4.2
4.2.1
Revisions: Releases, Vintage Triangle, Revision Error
Introduction
Readers mainly interested in financial applications may skip this section without loss of information. The topic to be developped here addresses publications of economic macro-indicators
because the corresponding time series – vintages, see below – are subject to a ‘particular’ nonstationarity which is likely to mask ‘poor’ real-time performances of such designs. Let’s start then!
GDP-growth rates as released by the BEA33 are summarized in table 5:
> US_GDP<-read.csv(paste(path.dat,"US_GDP.csv",sep=""),header=T)
> US_GDP_wp<-read.csv(paste(path.dat,"US_GDP_wp.csv",sep=""),header=T,sep=";")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
US.GDP
2007:Q4
2008:Q1
2008:Q2
2008:Q3
2008:Q4
2009:Q1
2009:Q2
2009:Q3
2009:Q4
2010:Q1
2010:Q2
2010:Q3
2010:Q4
2011:Q1
2011:Q2
2011:Q3
2011:Q4
2012:Q1
2012:Q2
2012:Q3
2012:Q4
X09Q1
-0.04%
0.22%
0.70%
-0.13%
-0.96%
X10Q1
0.53%
-0.18%
0.36%
-0.68%
-1.37%
-1.65%
-0.18%
0.55%
1.40%
X11Q1
0.72%
-0.18%
0.15%
-1.01%
-1.74%
-1.24%
-0.18%
0.40%
1.23%
0.92%
0.43%
0.63%
0.78%
X12Q1
0.42%
-0.44%
0.33%
-0.93%
-2.30%
-1.71%
-0.17%
0.42%
0.94%
0.97%
0.93%
0.62%
0.58%
0.09%
0.33%
0.45%
0.68%
X13Q1
0.42%
-0.44%
0.33%
-0.93%
-2.30%
-1.34%
-0.08%
0.36%
0.99%
0.58%
0.56%
0.64%
0.59%
0.02%
0.61%
0.32%
1.01%
0.49%
0.31%
0.77%
-0.04%
Table 5: US-GDP: yearly vintages starting in Q1 2009 and ending in Q1 2013
Columns correspond to publication dates: the first column was published in the first quarter 2009
and the last column in the first quarter 2013. Rows correspond to historical time. The fifth row
32 In
order to approximate the time-domain criterion We had to extended the sample on both sides, recall exercise
2.
33 Bureau of Economic Analysis.
The real-time data can be accessed via the Philadelphia FED: http:
//www.philadelphiafed.org/research-and-data/real-time-center/real-time-data/data-files/ROUTPUT/ (we
computed growth-rates based on the original level-data).
101
(2008:Q4) addresses GDP in the last quarter 2008: We see how the initial estimate or first release
−0.96% is revised as new information in subsequent years flows in, ending in a substantial negative
growth of −2.3% according to data up to the first quarter 2013. We learn from the above example
that
• Revisions of typical economic data may be substantial. In general We observe that the level
of aggregation affects the magnitude of revisions: GDP (strongly aggregated) is ordinarily
less heavily revised than IPI (industrial production index), for example.
• Revisions can extend over long time spans: in the above example We see that revisions are
still ‘substantial’ between year ‘two’ and year ‘three’ after the initial release.
The origins of revisions are multiple. One of them is related to ‘filters’: GDP-data is seasonally
adjusted and early estimates rely on ‘forecasts’ of components which are not available at time of
publishing. We here focus specifically on filter-induced revisions.
4.2.2
Filter Revisions
In analogy to the above GDP-table We want to estimate a target yt (say ‘true’ GDP) based on
data x1 , ..., xt−h : the index t − h corresponds to the publication-date (the columns in the above
table) and t is historical time to which the target refers: t shifts along the rows. To be clear,
hopefully, let us emphasize that t and h allow to ‘move’ along rows and columns (diagonals) in
the table:
• For fixed t, a changing h allows to move along the t-th row:
– for h = 0 the initial release (real-time estimate, nowcast) of yt is obtained based on
data x1 , ..., xt up to t;
– for h = −1 the second release of yt is obtained based on data x1 , ..., xt+1 up to t + 1:
one future observation xt+1 is used and We shift from column t to column t + 1 but We
stay in row t.
– for arbitrary h the |h|-th release of yt is obtained based on data x1 , ..., xt+|h| up to
t + |h|: |h| future observations xt+1 , ..., xt+|h| are used. We stay in row t but We shifted
to column t + |h|.
• For fixed h, a changing t allows to move along the |h|-diagonal of the matrix:
– For h = 0 fixed, the target yt , t = 1, ..., T is estimated based on data x1 , ..., xt : We
obtain the time series of first releases (real-time estimates) along the first diagonal of
the matrix.
– For h = −1 fixed, the target yt , t = 1, ..., T − 1 is estimated based on data x1 , ..., xt+1 :
We obtain the time series of second releases along the second diagonal of the matrix.
– For arbitrary but fixed h, the target yt , t = 1, ..., T − |h| is estimated based on data
x1 , ..., xt+|h| : We obtain the time series of |h|-releases along the |h|-th diagonal of the
matrix.
• Moving along columns is also possible by changing t and h simultaneously such that t − h
is fixed:
– For t − h = 1 fixed, the target yt is restricted to t = 1: y1 then relies on x1 . Note
that We do not compute forecasts y2 , y3 , ... based on x1 and therefore all corresponding
column-elements are NA’s.
– For t − h = 2 fixed, the target yt is restricted to t = 1, 2: y1 and y2 both rely on x1 , x2 .
The estimate for y1 can rely on a future x2 : it is therefore the second release of y1 . The
estimate of y2 is the first (real-time) release. All other elements in the second column
are NA’s.
102
– For arbitrary but fixed t−h = k, the target yt is restricted to t = 1, 2, ..., k: y1 , ..., yk rely
on data x1 , x2 , ..., xk . The estimate for y1 can rely on future x2 , ..., xk : it is therefore
the k-th release of y1 . The estimate of yk is the first (real-time) release. All other
elements in the k-th column are NA’s.
The column time series are called vintages. Vintages are important because many important
economic series are revised: the users observes vintages of GDP or IPI or employment, for
example.
• The triangular shape of the table is due to the fact that We do not perform forecasts of the
target.
Let’s now explain how We obtain these estimates in Our filter framework i.e. how We access
rows and columns in the table.
The Initial Release
For h = 0 We want to estimate yt based on x1 , ..., xt (nowcast, real-time estimate). For this
purpose We optimize coefficients bk0 , k = 0, ..., L − 1 of the real-time filter
ŷt0
:=
L−1
X
bk0 xt−k
k=0
The case h = 0 corresponds to Lag = 0 in fig.34. The resulting time series ŷt0 corresponds to the
first diagonal in table 5.
The Second Release
For h = −1 (Lag = 1 in Our R-code) We want to estimate yt based on data x1 , ..., xt+1 up
to t + 1: We use one future observation xt+1 . For this purpose We optimize coefficients bk,−1 ,
k = −1, ..., L − 2 of the real-time filter
ŷt−1 :=
L−2
X
bk,−1 xt−k
k=−1
The case h = −1 corresponds to Lag = 1 in fig.34. The resulting time series ŷt−1 corresponds to
the second diagonal in table 5.
The |h|-th Release
For arbitrary h < 0 (Lag = −h > 0 in Our code) We want to estimate yt based on data x1 , ..., xt+|h|
up to t + |h|: We use future observations xt+1 , ..., xt+|h| . For this purpose We optimize coefficients
bkh , k = h, ..., L − 1 + h of the real-time filter
ŷth :=
L−1+h
X
bkh xt−k
k=h
This corresponds to the case Lag = −h in fig.34, whereby the maximal considered Lag was
(L + 1)/2 = 7. The resulting time series ŷth corresponds to the |h|-th diagonal in table 5.
The Final Release
The filter (revision-) sequence Lag = 0, ..., 7 could have been stopped in Lag = (L − 1)/2 = 6
because the resulting filter is symmetric, see fig.34, violet line, bottom-left panel. The output
−(L−1)/2
of the symmetric filter Lag = (L − 1)/2 is called ‘final’ release34 . In the above GDPŷt
table 5, estimates are stabilized after a revision-span of three years: the resulting estimates are
34 The terminology ‘final’ is borrowed from the fact that characteristics of filters whose Lag-parameter exceeds
L/2 are generally suboptimal designs and therefore We refrain from increasing Lag or −h beyond L/2.
103
‘final’; note however that ‘true’ GDP (whatever this theoretical construct might be) does not have
−(L−1)/2
to coincide with this final number. Accordingly, the final estimate ŷt
is not identical with
the target yt because the latter is the (unobservable) output of a bi-infinite filter.
Vintages
The j-th vintage (the j-th column in table 5) is obtained by estimating yt , t = 1, ..., j by
ŷtt−j :=
L−1+t−j
X
bk,t−j xt−k
(51)
k=t−j
The resulting time series, the j-th vintage, is a non-stationary time series because the filters
bk,t−j depend on t: as an example, the last observation ŷj0 is generally noisier than any previous
observation ŷtt−j because bk0 is the real-time filter (the amplitude of the real-time filter damps
high-frequency noise less effectively than filters with Lag > 0, see fig.34, top-left panel).
4.2.3
Examples/Exercices
In analogy to the US-GDP table 5, vintage-data can be arranged in the so-called vintage triangle.
For illustration We here compute the vintage-triangle for the three AR(1)-processes 50 based on
expression 51, whereby we us the filters for Lag = 0, ..., 6 as computed in exercise 3, p.89, and
plotted in figs.33 and 34.
> vintage<-array(dim=c(len,3,len))
> dim(vintage)
[1] 120
>
>
+
+
+
+
+
+
+
+
>
>
>
>
>
3 120
# For each of the three AR(1)-processes We compute the vintage series
for (i in 1:3)
{
for (j in L:len)#j<-L
{
vintage[(j-as.integer(L/2)):j,i,j]<-yhat_Lag[j,i,(as.integer(L/2)+1):1]
vintage[1:(j-as.integer(L/2)-1),i,j]<yhat_Lag[(as.integer(L/2)+1):(j-1),i,as.integer(L/2)+1]
}
}
# We select the third DGP with a1=-0.9
i<-3
vintage_triangle<-vintage[,i,]
dimnames(vintage_triangle)[[2]]<-paste("Publ. ",1:len,sep="")
dimnames(vintage_triangle)[[1]]<-paste("Target ",1:len,sep="")
Table 6 shows the last six vintages (last six columns and rows) for t = 115, ..., 120 for the third
h
process (a1 = −0.9). In the last column on the right We see the last vintage y120+h
for h =
0
0, −1, −2, −3, −4: y120 is the real-time estimate (first release) of the target y120 based on data
−1
x1 , ..., x120 ; y119
is the second release of the target y119 based on data x1 , ..., x120 and so on. In
analogy to table 5, the column-date in table 6 refers to the publication date and the row-date refers
to the target time i.e. the index t of yt . The initial release in the first column (publication date 115)
is 0.177; the second release of the same target value y115 in the second column is 0.176; the third
release in the third column is 0.197, and so on. The differences between the various releases are
due to revisions: previous estimates of y115 are up-dated when new information becomes available.
We can observe that the initial release 0.177 is first revised upwards and then downwards, ending
in the slightly smaller value 0.106 in the last column.
104
Target
Target
Target
Target
Target
Target
115
116
117
118
119
120
Publ. 115
0.177
Publ. 116
0.176
0.092
Publ. 117
0.197
0.127
0.067
Publ. 118
0.218
0.142
0.074
0.022
Publ. 119
0.126
0.024
-0.057
-0.113
-0.138
Publ. 120
0.106
-0.023
-0.135
-0.216
-0.260
-0.266
Table 6: Last 5 vintages of finite sample filter for the AR(1)-process with a1=-0.9: columns
correspond to vintages and are indexed by corresponding publication dates; rows correspond to
revisions of estimates for a fixed historical target date
Tentacle Plot
We now plot the vintages obtained for the three AR(1)-processes 50, see fig.38: the resulting
graph is called a tentacle plot.
>
>
>
>
>
+
+
+
+
+
+
+
+
+
+
+
+
>
colo<-rainbow(len)
file = paste("z_vintages.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(3,1))
for (i in 1:3)
{
ymin<-min(vintage[,i,],na.rm=T)
ymax<-max(vintage[,i,],na.rm=T)
ts.plot(vintage[,i,L],col=colo[1],ylim=c(ymin,ymax),
main=paste("Tentacle plot: vintages and full revision sequence,
a1 = ",a_vec[i],sep=""),ylab="Vintages")
for (j in (L+1):len)
{
lines(vintage[,i,j],col=colo[j])
}
lines(vintage[,i,len],col="red",lwd=2)
}
dev.off()
null device
1
105
−2
−6
Vintages
2
Tentacle plot: vintages and full revision sequence,
a1 = 0.9
0
20
40
60
80
100
120
Time
0.5
−0.5
Vintages
Tentacle plot: vintages and full revision sequence,
a1 = 0
0
20
40
60
80
100
120
Time
0.0 0.4
−0.6
Vintages
Tentacle plot: vintages and full revision sequence,
a1 = −0.9
0
20
40
60
80
100
120
Time
Figure 38: Tentacle plot: full historical revision sequence for a1=0.9 (top), a1=0 (middle) and
a1=-0.9 (bottom). Final release is emphasized in bold red
By illustrating the stepwise convergence of initial to final releases, the main revision effects are
summarized in a handy and very effective way. Ideally, the revision error would vanish resulting
in a single line in the tentacle plot. Obviously this is not the case for the three AR(1)-processes
in the above plot: the larger the revisions – the more difficult the real-time problem – the wider
apart the tentacles. We first observe that the magnitude of the revision error seems to depend
on the DGP: it is smallest for the positively autocorrelated process (a1 = 0.9) and largest for
the negatively autocorrelated DGP (a1 = −0.9) although We should emphasize that We here
effectively address a relative effect, namely the magnitude of the revisions relative to the strength
of the signal. This result should not come as a surprise since We know that the filter for the
first process does not damp high-frequency noise as strongly as the filter for the third process, see
fig.33: the signal-extraction task is less demanding when the process is positively autocorrelated,
see fig.30. In order to discuss the topic more thoroughly We focus on the second (white noise)
106
process, see fig.39 whose specification is close to typical finance data.
>
>
>
>
>
>
>
+
>
+
+
+
>
>
>
>
>
+
+
>
+
+
+
>
>
file = paste("z_vintages_2.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
i<-2
ymin<-min(vintage[,i,],na.rm=T)
ymax<-max(vintage[,i,],na.rm=T)
ts.plot(vintage[,i,L],col=colo[1],ylim=c(ymin,ymax),
main="Vintages: full revision sequence and final release (black)",ylab="Vintages")
for (j in (L+1):len)
{
lines(vintage[,i,j],col=colo[j])
}
lines(vintage[,i,len],col="black",lwd=2)
i<-2
ymin<-min(vintage[,i,],na.rm=T)
ymax<-max(vintage[,i,],na.rm=T)
ts.plot(vintage[,i,L],col=colo[1],ylim=c(ymin,ymax),
main="Vintages: full revision sequence and real-time initial release (black)",
ylab="Vintages")
for (j in (L+1):len)
{
lines(vintage[,i,j],col=colo[j])
}
lines(yhat_Lag[,i,1],col="black",lty=1)
dev.off()
null device
1
107
0.5
−0.5
Vintages
Vintages: full revision sequence and final release (black)
0
20
40
60
80
100
120
Time
0.5
−0.5
Vintages
Vintages: full revision sequence and real−time initial release (black)
0
20
40
60
80
100
120
Time
Figure 39: Vintages: full historical revision sequence in the case of the white noise process
The two graphs differ in the sense that We emphasize in bold (black) either the last vintage (top
graph) or the first release (bottom graph). Otherwise both plots are identical. Convergence to the
final release is achieved after (L − 1)/2 = 6 time steps in Our setting. For typical macro-data the
revision span is generally longer: as an example US-GDP in table 5 is still substantial revised after
after two years or eight quarters. The real-time initial release emphasized in the bottom graph
(black) is obtained by linking the end-points of the tentacles. The second release would be obtained
by linking the next-to-last endpoints, and so on. Typically, early releases are noisier (weaker
noise suppression: leaking amplitude function) and delayed (positive time-shift), as confirmed and
quantified by Our earlier amplitude and time-shift plots figs.33 and 34. Therefore turning-points
cannot be detected accurately in real-time: one has to wait several time-units (days, weeks,
months, quarters) until a trend reversal can be assessed with sufficient confidence. As an example,
the revised history of most economic indicators dates the great recession (Dec07-June09) timely
and accurately; in real-time, however, indicators were substantially delayed, some designs by
108
more than a year, and early warnings were heavily revised i.e. pretty unreliable.
4.3
Customization
The above examples and in particular fig.34 illustrated a fundamental tradeoff between the ability
of suppressing noise and the magnitude of the time-shift of a filter35 . In fact We used this interaction between amplitude and time-shift functions when implementing revision-sequences since
higher-lag filters are able to suppress noise better: therefore the history of a filtered time series
could be ‘cosmetically enhanced’ (smoothed).
The ordinary mean-square paradigm – the optimization criterion 49 – proposes a particular
option for the tradeoff between ‘speed’ and ‘smoothness’, as illustrated in Our previous examples.
However, in practice users may assign priorities differently: a manager of a pension-fund may
prefer ‘reliability’ (strong noise suppression) whereas a high-frequency trader might favour ‘speed’
(small time-shift), instead. In terms of revisions-sequences: the former user might be willing
to wait until a clear ‘revised’ signal emerges (loosing on early but potentially risky opportunities) whereas the latter user might jump on ‘early releases’ in order to take profit of potential
rebounds (at higher-volatility risk levels). Instead of the somehow rigid (mean-square) revision
framework We here propose novel estimation algorithms which can account specifically for a broad
range of practically relevant user priorities by emphasizing specifically the observed ‘speed-noise’
or timeliness-smoothness dilemma. In fact, We shall propose a much richer three dimensional
tradeoff, the so-called Accuracy-Timeliness-Smootness trilemma (ATS for short) which will allow
to improve on any single or any pair of ATS-components, at costs of the remaining one(s): as
an example We will show how to improve on Timeliness and Smoothness simultaneously, when
benchmarked against the ordinary MSE-design.
In short: Customization will allow to implement user-preferences directly into the optimization
criterion, through a suitable interface, in order to match performances and research priorities,
better than by the ordinary and somehow rigid MSE-paradigm.
4.3.1
Decomposition of the MS-Criterion
The following identity holds for general transfer functions Γ and Γ̂:
= A(ω)2 + Â(ω)2 − 2A(ω)Â(ω) cos Φ̂(ω) − Φ(ω)
|Γ(ω) − Γ̂(ω)|2
=
(A(ω) − Â(ω))2
h
i
+2A(ω)Â(ω) 1 − cos Φ̂(ω) − Φ(ω)
(52)
If We assume that Γ is symmetric and positive, then Φ(ω) ≡ 0. Inserting 52 into 49 and using
1 − cos(Φ̂(ω)) = 2 sin(Φ̂(ω)/2)2 then leads to
2π
T
=
2π
T
+
[T /2]
2
Γ(ωk ) − Γ̂(ωk ) IT X (ωk )
X
k=−[T /2]
T /2
X
(A(ωk ) − Â(ωk ))2 IT X (ωk )
(53)
k=−T /2
2π
T
T /2
X
4A(ωk )Â(ωk ) sin(Φ̂(ωk )/2)2 IT X (ωk )
(54)
k=−T /2
35 One can derive an analytic link between phase and amplitude functions which shows that either function can
be derived explicitly from knowing the other. We here omit discussion presentation and discussion of this result
because it would take us too far away from the main topic: forecasting and real-time signal extraction.
109
The first summand 53 is the distinctive part of the total mean-square filter error which is attributable to the amplitude function of the real-time filter (the MS-amplitude error). The second
summand 54 measures the distinctive contribution of the phase or time-shift to the total meansquare error (the MS-time-shift error). The term A(ωk )Â(ωk ) in 54 is a ‘scaling’ factor which
accounts for the fact that the phase function is dimensionless i.e. it does not convey level information.
4.3.2
Accuracy, Timeliness and Smoothness (ATS-) Error-Components
The above decomposition into amplitude and time-shift error contributions can be refined further
by splitting each term into contributions from pass and stopbands. For ease of exposition We
assume an ideal lowpass target with a specified cutoff-frequency delimiting both frequency-bands36 :
|ωk | < cutoff then corresponds to the passband and its complement is the stop- or rejection-band.
A(ccuracy)
S(moothness)
T(imeliness)
R(esidual)
:=
:=
:=
:=
2π
T
2π
T
P
P
(A(ωk ) − Â(ωk ))2 IT X (ωk )
PPassband
2
Stopband (A(ωk ) − Â(ωk )) IT X (ωk )
2π
2
T P Passband 4A(ωk )Â(ωk ) sin(Φ̂(ωk )/2) IT X (ωk )
2π
2
Stopband 4A(ωk )Â(ωk ) sin(Φ̂(ωk )/2) IT X (ωk )
T
(55)
• Accuracy measures the contribution to the MSE-norm if the time-shift (in the passband)
and the noise suppression (in the stop-band) are ignored. This would correspond to the
performance of a symmetric filter (no time-shift) with perfect noise suppression (Â(·) = 0 in
the stopband) and with the same amplitude as the considered real-time filter in the passband.
Such a design could be easily constructed by the techniques presented in the first section
(apply the inverse Fourier-transform to the specified function).
• Smoothness measures the contribution to total MSE of the undesirable high-frequency noise,
leaking through the imperfect amplitude function (convolution theorem) in the stopband of
the real-time filter. As We shall see, this statistic is closely linked to a well-known ‘curvature’ or smoothness measure in the time-domain (mean-square second order differences), see
section 7.1.
• Timeliness measures the MSE-contribution generated by the time-shift. As We shall see,
this ‘measure’ is closely linked to a well-known time-domain concept referred to as ‘peakcorrelation’, see section 7.1.
• The Residual is that part of the MSE which is not attributable to any of the above errorcomponents: it corresponds to a time-shift contribution from the stopband which is generally
irrelevant (it cannot be identified with a well-known user-priority) and negligible. In Our
case – ideal lowpass target – this error term vanishes because Γ(ωk ) = A(ωk ) = 0 in the
stopband.
From now on We ignore the Residual and consider the ATS-decomposition of the MSE-norm.
4.3.3
General Customized Criterion
Based on the above ATS-decomposition
MSE=Accuracy+Timeliness+Smoothness
(56)
We are in a position to generalize the mean-square optimization criterion 49 by assigning weights
to the ATS-components:
MSE-Cust(λ1 , λ2 ) = Accuracy + (1 + λ1 )Timeliness + (1 + λ2 )Smoothness → min
b
(57)
36 Pass- and stopbands can be defined similarly for ideal bandpass filters or for any interesting target such as, for
example, HP- or CF-filters or more general model-based designs.
110
Selecting λ1 > 0 would emphasize the contribution by the Timeliness component: the resulting
optimal filter would have a smaller Timeliness error contribution; selecting λ2 > 0 would magnify
Smoothness issues and the resulting filter would have a smaller Smoothness error; finally, selecting λ1 > 0, λ2 > 0 would emphasize both dimensions simultaneously: depending on the relative
magnitudes of λ1 , λ2 either or both error contributions could be reduced; at costs of the Accuracycomponent whose loss must overcompensate potential gains of Timeliness and/or Smoothness.
To be clear, let us emphasize the latter point: the MSE-filter minimizes 56; therefore any other design must lead to a higher criterion value (uniqueness of the minimum of a quadratic function); as
a result, the Accuracy component of an alternative filter with smaller Timeliness and Smoothness
error-contributions must necessarily over compensate the latter gains. This disproportionate contribution might put the Accuracy-term ‘under stress’ and therefore arbitrary performance-gains
– by immoderate disequilibria (large λ1 , λ2 ) – are in the realm of fiction and desire; nonetheless,
effective true out-of-sample gains are permissible in terms of Smoothness and Timeliness simultaneously, in the frequency-domain, as well as in terms of improved peak-correlation and curvature
performances, as measured in the time-domain.
We now briefly generalize the above schematic criterion 57 by introducing weighting functions
W1 (ωk ) ≥ 0 and W2 (ωk ) ≥ 0 in 56:
2π X
(A(ωk ) − Â(ωk ))2 IT X (ωk )
T
Passband
2π X
+
(A(ωk ) − Â(ωk ))2 W2 (ωk )IT X (ωk )
T
Stopband
2π
+
T
X
4A(ωk )Â(ωk ) sin(Φ̂(ωk )/2)2 W1 (ωk )IT X (ωk ) → min
b
Passband
where We omitted the (vanishing or negligible) Residual-component. The schematic criterion 57
could be replicated by setting
W1 (ωk , λ1 )
=
1 + λ1
W2 (ωk , λ2 )
=
1 + λ2
Note, however, that W2 as defined above introduces an undesirable discontinuity in the cutofffrequency since frequency-components on the left (in the passband) are unweighted (weight ‘one’)
whereas components on the right (stopband) are magnified by 1 + λ2 (this effect does not apply
to W1 because We neglected the Residual). We now depart from the schematic simplification 57
and propose the following refined weighting scheme
W1 (ωk , λ) =
1+λ
(58)
W2 (ωk , η) = (1 + |ωk | − cutoff)η
The new function W2 proposes a continuous weighting scheme whose importance increases monotonically as a function of ωk : higher frequencies are affected more heavily than lower frequencies
in the stopband if η > 0: this is a welcome asset in many real-time applications37 . Note that We
re-labelled λ1 , λ2 by λ, η in order to distinguish symbolically both effects: λ > 0 emphasizes the
Timeliness-component whereas η > 0 magnifies Smoothness-issues. The above criterion can be
re-written in its original (‘historical’) more compact form as
X
2π
(A(ωk ) − Â(ωk ))2 W (ωk , η)IT X (ωk )
T
All Frequencies
+(1 + λ)
2π
T
X
4A(ωk )Â(ωk ) sin(Φ̂(ωk )/2)2 W (ωk )IT X (ωk ) → min
b
All Frequencies
(59)
37 The derivative of a trigonometric signal is proportional to frequency. Therefore the impact of undesirable
high-frequency components (noise) on ‘smoothness’ is dependent upon frequency. The proposed weighting scheme
specifically accounts for corresponding user-requirements; better than 57.
111
where
W (ωk , η, cutoff) =
1 , if |ωk | < cutoff
(1 + |ωk | − cutoff)η , otherwise
(60)
Since Γ(·) = 0, the stopband contributions of the phase-error in the second sum (Residual) vanishes; also, We could skip W (ωk ) in this expression since the weighting function is one in the
passband. The above expression 59 was first proposed in Wildi (2005); we here wanted to establish a link to the ATS-decomposition 56 of the MSE-norm, as proposed in McElroy and Wildi
(2012).
• Classical mean-square optimization is obtained for λ = η = 0: the revision error is addressed.
This setting is ideal when implementing a revision-sequence (filling a vintage triangle).
• For λ > 0 the user can emphasize the contribution of the time-shift error. As a result, the
customized filter output will gain in ‘speed’ (improved peak-correlation performances).
• The parameter η emphasizes noise-suppression in the stopband. As a result, the customized
filter output will gain in smoothness (smaller curvature).
It incumbes upon the user to address specific research priorities, in terms of ATS-components, by
suitable choices of λ and η. Mean-square performances are obtained by selecting λ = η = 0. The
general optimization principle 59 is called a Customized Criterion. In Our applications We
invariably rely on weighting functions as defined by 60 though experienced users might shape the
weighting-scheme according to more sophisticated or more specific priorities.
I-DFA: Numerically Tractable Customization∗
4.3.4
The mean-square error criterion is a quadratic function of the filter parameters and therefore the
solution can be obtained analytically. Unfortunately, 59 is a non-linear function of the coefficients
if λ > 0. Therefore, We here propose an alternative customized criterion which is tractable
analytically. Consider the following expression:
2π
T
[T /2]
X
n o2
p
Γ(ωk ) − < Γ̂(ωk ) + i 1 + 4λΓ(ωk )= Γ̂(ωk ) W (ωk , η)IT X (ωk ) → min (61)
k=−[T /2]
where <(·) and =(·) denote real and imaginary parts and i2 = −1 is the imaginary unit. We
call the resulting approach I-DFA38 . Obviously, the above expression is quadratic in the filter
coefficients. In analogy to 59, the weighting function W (ωk , η) emphasizes the fit in the stop
band. The term λΓ(ωk ) emphasizes the imaginary part of the real-time filter in the pass band: for
λ > 0 the imaginary part is artificially inflated and therefore the phase is affected. The following
38 The
capital I in the acronym stands for the imaginary part which is emphasized by λ.
112
development allows for a direct comparison of 59 and 61:
2π
T
=
2π
T
[T /2]
k=−[T /2]
[T /2]
2π
T
X
2
2 Γ(ωk ) − < Γ̂(ωk )
+ = Γ̂(ωk )
W (ωk , η)IT X (ωk )
k=−[T /2]
+4λ
=
2
p
Γ(ωk ) − < Γ̂(ωk ) + i 1 + 4λΓ(ωk )= Γ̂(ωk ) W (ωk , η)IT X (ωk )(62)
X
2π
T
[T /2]
X
2
Γ(ωk )= Γ̂(ωk ) W (ωk , η)IT X (ωk )
k=−[T /2]
[T /2]
X
|Γ(ωk ) − Γ̂(ωk )|2 W (ωk , η)IT X (ωk )
k=−[T /2]
2π
+4λ
T
[T /2]
X
A(ωk )Â(ωk )2 sin(Φ̂(ωk ))2 W (ωk , η)IT X (ωk )
(63)
k=−[T /2]
A direct comparison of 59 and 63 reveals that Φ̂(ωk )/2 is replaced by Φ̂(ωk ) and a supernumerary
weighting-term Â(ωk ) appears in the latter expression. Expression 63 can be solved analytically
for arbitrary λ and/or weighting functions W (ωk , η) because Â(ωk )2 sin(Φ̂(ωk ))2 is simply the
squared imaginary part of the real-time filter (i.e. it is a quadratic function of the filter coefficients). For λ = η = 0 the original (DFA) mean-square criterion 49 is obtained. Overemphasizing
the imaginary part of the real-time filter in the pass-band by augmenting λ > 0 results in filters
with smaller time-shifts, as desired.
Summary
The I-DFA criterion 61 replicates perfectly the ordinary MSE-criterion 49 when λ = η = 0.
In contrast to 59, it can be solved analytically, in closed form, for any (λ, η)-specification: the
resulting algorithm is fast and solutions are unique. It sligthly differs from 59 but the effects of
λ and η on Timeliness and Smoothness are similar. Therefore, from a practical perspective We
assign preference to the customized I-DFA criterion 61 or 63.
4.3.5
R-code: I-DFA
We implement the generalized criterion 61 or, equivalently, 63 in R and define a corresponding
new function called df a analytic():
>
>
>
>
>
>
>
>
>
>
>
>
>
+
+
# This function computes analytic DFA-solutions
# L is the length of the MA-filter,
# weight_func is the periodogram,
# lambda emphasizes phase artifacts in the customized criterion,
# eta emphasizes noise-suppression/smoothness
# Gamma is the transferfunction of the symmetric filter (target) and
# Lag is the lag-parameter: Lag=0 implies real-time filtering, Lag=L/2
#
implies symmetric filter
# i1 and i2 allow for filter restrictions in frequency zero
# The function returns the weights of the MA-Filter as well as its transferfunction
#
#
dfa_analytic<-function(L,lambda,weight_func,Lag,Gamma,eta,cutoff,i1,i2)
{
K<-length(weight_func)-1
113
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# Define the amplitude weighting function weight_h (W(omega_k))
omega_Gamma<-as.integer(cutoff*K/pi)
if ((K-omega_Gamma+1)>0)
{
weight_h<-weight_func*(c(rep(1,omega_Gamma),(1:(K-omega_Gamma+1))^(eta)))
} else
{
weight_h<-weight_func*rep(1,K+1)
}
# First order filter restriction: assigning a `large' weight to frequency zero
if (i1)
weight_h[1]<-max(1.e+10,weight_h[1])
X<-exp(-1.i*Lag*pi*(0:(K))/(K))*rep(1,K+1)*sqrt(weight_h)
X_y<-exp(-1.i*Lag*pi*(0:(K))/(K))*rep(1,K+1)
if (i2)
{
# Second order restriction: time shift in frequency zero vanishes
for (l in 2:(L-1))
{
X<-cbind(X,(cos((l-1-Lag)*pi*(0:(K))/(K))-((l-1)/(L-1))*
cos((L-1-Lag)*pi*(0:(K))/(K))+
sqrt(1+Gamma*lambda)*1.i*(sin((l-1-Lag)*pi*(0:(K))/(K))-((l-1)/(L-1))*
sin((L-1-Lag)*pi*(0:(K))/(K))))*sqrt(weight_h))
X_y<-cbind(X_y,(cos((l-1-Lag)*pi*(0:(K))/(K))-((l-1)/(L-1))*
cos((L-1-Lag)*pi*(0:(K))/(K))+
1.i*(sin((l-1-Lag)*pi*(0:(K))/(K))-((l-1)/(L-1))*sin((L-1-Lag)*pi*(0:(K))/(K)))))
}
xtx<-t(Re(X))%*%Re(X)+t(Im(X))%*%Im(X)
# MA-Filterweights
b<-as.vector(solve(xtx)%*%(t(Re(X_y))%*%(Gamma*weight_h)))
# the last weight is a function of the previous ones through the second order restriction
b<-c(b,-sum(b*(0:(length(b)-1)))/(length(b)))
} else
{
for (l in 2:L)
{
X<-cbind(X,(cos((l-1-Lag)*pi*(0:(K))/(K))+
sqrt(1+Gamma*lambda)*1.i*sin((l-1-Lag)*pi*(0:(K))/(K)))*sqrt(weight_h))
X_y<-cbind(X_y,(cos((l-1-Lag)*pi*(0:(K))/(K))+
1.i*sin((l-1-Lag)*pi*(0:(K))/(K))))
}
xtx<-t(Re(X))%*%Re(X)+t(Im(X))%*%Im(X)
# MA-Filterweights
b<-as.vector(solve(xtx)%*%(t(Re(X_y))%*%(Gamma*weight_h)))
}
# Transferfunction
trffkt<-1:(K+1)
trffkt[1]<-sum(b)
for (k in 1:(K))#k<-1
{
trffkt[k+1]<-(b%*%exp(1.i*k*(0:(length(b)-1))*pi/(K)))
}
return(list(b=b,trffkt=trffkt))
114
+ }
5
ATS-Trilemma
When addressing complex decision problems, people often face bipolar choices based on fundamental (‘natural’) tradeoffs. One cannot expect to progress on two desirable but antagonistic
dimensions at the same time: the ‘debt’ vs. ‘economic-growth’ debate stigmatizes such a dilemma
in politics (I did not say ‘economics’). In sciences in general and in statistics specifically such
fundamental tradeoffs (uncertainty-principle, bias variance dilemma) offer exciting structural and
philosophical insights into the considered subject matter and beyond. Time series analysis brings
its own ‘home-brew’ tradeoff, the timeliness-smoothness dilemma encountered in previous examples. Interestingly, all precited dilemma are linked: the same universal ‘human incapacity’ is
addressed though in different contexts and by different technical slangs. So let’s try to go beyond
this cramped bipolar perspective and try to address more sophisticated priorities.
Adding dimensions is a well-known strategy to circumvent apparently impossible tasks (Klein’s
bottel). We do not depart from this receipt and consider adding dimension(s) to the original meansquare paradigm. The ATS(R)-decomposition proposed in section 4.3.2 and concretized in 56 and
in the customized criterion 59 or in the numerically (much) more attractive variant 63, adds an
Accuracy-component as well as a (generally negligible) Residual. Therefore, the bulck of the meansquare mass (the energy of the filter error) can be shifted among three (neglecting the Residual)
instead of two ‘recipients’. We can relieve any single or any pair of components by assigning the
additional burden to the remaining one(s). If We want to improve Timeliness and Smoothness,
We must be willing to afflict Accuracy: the affliction might be ‘heavy’ because as We depart from
the optimal MSE-solution, the MSE-mass inflates. The ATS-Trilemma adds flexibility in order to
match research priorities by optimization criteria.
We now apply the DFA-apparatus to two ‘standard’ tasks, namely seasonal adjustment and
trend extraction and take profit of the additional opportunities unfolded by customization and the
ATS-trilemma39 .
6
Seasonal Adjustment
We now apply the above function to real-time seasonal adjustment. We analyze the structure
of the estimation problem, derive filter characteristics and apply a simple customization scheme.
We augment the filter length and analyze overfitting issues by relying on out-of-sample performances. We compute vintages, analyze revisions and obtain tentacle plots. Finally, We compute
finite sample distributions of filter coefficients as well as finite sample distributions of real-time
amplitude and time-shift functions (as far as We know the latter are a novelty). In order to illustrate potentially interesting issues We first analyze a very simple periodic (trigonometric) seasonal
component. After that We propose SA for a series with a complex mix of components, including
deterministic, stationary stochastic and non-stationary stochastic seasonal patterns.
6.1
Narrow Seasonal Peak: Seasonal Line Spectrum
We here analyze a particular monthly ‘seasonal’ series of large sample length T = 600 and a simple
deterministic (trigonometric) seasonal of frequency π/6: the experimental design is conceived such
as to reveal some of the salient features of seasonal adjustment as well as to illustrate the flexibility
of the DFA as compared to the ubiquitous and rigid seasonal difference filter 1 − B 12 .
39 We do not explicitly emphasize cycle extraction (bandpass filters) but since Our proceeding is generic the
former could be straightforwardly implemented.
115
6.1.1
The DGP: AR(1) plus Single Line Spectrum
We generate a realization of length T = 600 of an AR(1)-process and add a determinsistic trigonometric signal of frequency π/6
zt
=
0.9zt−1 + t
xt
= zt + cos(tπ/6)
with σ 2 = 1. The AR(1)-process zt is the signal and cos(tπ/6) is the (undesirable) seasonal
component. The aggregate xt , its acf and its periodogram are plotted in fig.40.
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
>
>
>
>
>
# Simulation of the AR(1)+cos series
len<-600
set.seed(10)
eps<-rnorm(len)
ar1<-0.9
z<-eps
for (i in 2:len)
z[i]<-ar1*z[i-1]+eps[i]
x<-z+cos((1:len)*pi/6)
plot_T<-F
file = paste("z_seas_a.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(3,1))
ts.plot(x)
acf(x)
plot(per(x,plot_T)$per,type="l",axes=F,ylab="Periodogram")
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
116
5
0
−5
x
0
100
200
300
400
500
600
Time
0.4
0.0
ACF
0.8
Series x
0
5
10
15
20
25
25
10
0
Periodogram
Lag
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Index
Figure 40: Seasonal series (top), acf (middle) and periodogram (bottom)
In contrast to the acf, the periodogram is very explicit about the presence of a seasonal component
with a single spectral peak in π/6: efficiency of the DFA is closely linked to the resolution ability
of the periodogram. We now attempt to seasonally adjust the data by damping the seasonal peak
and by leaving all other components ‘intact’40 . Obviously, a time series with a single seasonal
peak cannot be tackled by the classical seasonal difference filter 1 − B 12 whose amplitude function
was shown in fig.25. Therefore, We first customize the target signal Γ in view of the seasonal
adjustment (SA) task.
40 Since the seasonal component in Our example is a deterministic trigonometric signal (a line spectrum) We
could remove the undesirable term by simple regression methods. In practice, however, seasonal components are
never deterministic and therefore this approach is not to be recommended, in general.
117
6.1.2
Manual Gamma-Interface
We now specify the transfer function Γ(·) of a symmetric target filter which proceeds to SA of xt
by eliminating the seasonal component in π/6 without affecting (noticeably) the interesting signal,
namely the AR(1)-component zt :
1 ω 6= π/6
Γ(ω) =
0 ω = π/6
This target filter is plotted together with the amplitude of the classical seasonal adjustment filter
1 − B 12 in fig.41.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
# assigning the periodogram
weight_func<-per(x,plot_T)$per
K<-length(weight_func)-1
# Define target Gamma
Gamma<-rep(1,K+1)
Gamma[1+(length(Gamma)/6):(length(Gamma)/6)]<-0
# Compute amplitude of seasonal difference
omega_k<-(0:K)*pi/K
b1<-1
b12<--1
trffkt<-1+b12*complex(arg=12*omega_k)
amplitude<-abs(trffkt)
file = paste("z_seas_a_a.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
plot(Gamma,type="l",axes=F,col="black",ylim=c(0,2),ylab="",xlab="")
lines(amplitude,lty=1,col="red")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
mtext("Amplitude seasonal differences", side = 3, line = -2,at=K/2,col="red")
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
118
2.0
0.0
0.5
1.0
1.5
Target
Amplitude seasonal differences
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Figure 41: Seasonal adjustment: target (blue) vs. traditional seasonal adjustment filter (black)
The target Γ(ωk ) (black) removes the spectral peak in π/6 and leaves all other components intact41 .
In contrast, the classical seasonal adjustment filter seems rather ill-suited (heavily distorted) for
the task at hand.
Remark (practical hint)
• When working with monthly seasonal data We recommend to select the sample length T as
a multiple of the seasonal periodicity twelve (skip the first few observations of the sample
until the resulting T is a multiple of twelve).
• This way, the discrete frequency grid ωk = k ∗ 2π/T tracks the seasonal peaks since ωjT /12 =
jπ/6 for j = 1, ..., 6.
41 Strictly speaking We remove components in a narrow interval centered in π/6 since in practice pure (deterministic) line spectra are unlikely to be observed at least in the context of economic data.
119
6.1.3
A ‘Short’ Real-Time MSE (SA-)Filter
We now compute a MSE real-time filter of length L = 24 (again a multiple of 12) based on 49.
Amplitude and time-shift functions of the filter are plotted and compared to the target in fig.42.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
+
>
>
>
>
>
>
>
# Length of Moving-Average:
# Trick: selecting L=24 to be a multiple of 6 (the quotient in the
#
frequency pi/6 of the cosine) allows
#
the filter to damp/eliminate the component more easily!
L<-24
# Customization: lambda=eta=0 implies minimal mean-square revisions
lambda<-0
eta<-0
# cutoff frequency: this parameter is inactive if eta=0
cutoff<-pi/6
# Real-time filter
Lag<-0
# We do not impose filter restrictions: see exercises below
i1<-F
i2<-F
# Compute DFA
#
dfa_mse<-dfa_analytic(L,lambda,weight_func,Lag,Gamma,eta,cutoff,i1,i2)
#
b_ms<-dfa_mse$b
trffkt_ms<-dfa_mse$trffkt
# Amplitude and time shift
amp_analytic_ms<-abs(trffkt_ms)
pha_analytic_ms<-Arg(trffkt_ms)/(pi*(0:(K))/(K))
file = paste("z_seas_a_a_at.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
plot(Gamma,type="l",axes=F,col="black",ylim=c(0,max(amp_analytic_ms)),ylab="",
xlab="",main="Amplitude")
lines(amp_analytic_ms,lty=1,col="red")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
mtext("Real-time amplitude MSE-filter", side = 3, line = -2,at=K/2,col="red")
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(rep(0,K+1),type="l",axes=F,col="black",ylim=c(min(na.exclude(pha_analytic_ms)),
max(na.exclude(pha_analytic_ms))),ylab="",xlab="",main="Time-shift")
lines(pha_analytic_ms,lty=1,col="red")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
mtext("Real-time amplitude MSE-filter", side = 3, line = -2,at=K/2,col="red")
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
120
1.2
Amplitude
0.0
0.6
Target
Real−time amplitude MSE−filter
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
5pi/6
pi
1.0
Time−shift
−1.0
0.0
Target
Real−time amplitude MSE−filter
0
pi/6
2pi/6
3pi/6
4pi/6
Figure 42: Seasonal adjustment: real-time MSE-filter (red) vs. target (black): amplitude (top)
and time-shift (bottom)
We observe that the amplitude function of the MSE real-time filter attempts to damp – not eliminate – the seasonal component. We now apply the filter to the data xt and compare periodograms
before/after filtering, see fig.43.
>
>
>
+
+
+
>
>
>
# Filtering time series
xf_ms<-x
for (i in L:length(x))
{
xf_ms[i]<-b_ms%*%x[i:(i-L+1)]
}
file = paste("z_seas_a_a_afbe.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
121
>
>
>
>
>
+
>
>
>
>
+
>
>
>
ts.plot(xf_ms,col="red",ylab="")
lines(x,col="blue")
mtext("Input", side = 3, line = -1,at=K,col="blue")
mtext("Real-time output", side = 3, line = -2,at=K,col="red")
plot((per(xf_ms[L:len],plot_T)$per),type="l",axes=F,col="red",
ylab="Periodograms",xlab="Frequency")
lines((per(x[L:len],plot_T)$per),lty=2,col="blue")
mtext("Input", side = 3, line = -1,at=K/2,col="blue")
mtext("Real-time output", side = 3, line = -2,at=K/2,col="red")
axis(1,at=1+0:6*(len-L)/12,labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
122
−5
0
5
Input
Real−time output
0
100
200
300
400
500
600
5pi/6
pi
10 20 30
Input
Real−time output
0
Periodograms
Time
0
pi/6
2pi/6
3pi/6
4pi/6
Frequency
Figure 43: Filter effect: original (blue) and filtered (red) series (top graph) and periodograms
(bottom graph)
As expected, the seasonal peak is damped but not entirely removed. The other components do not
seem to be affected by the filtering, as desired. We now attempt to improve the attenuation of the
seasonal peak by the real-time design, possibly without affecting the other components noticeably.
6.1.4
Customizing the Real-Time (SA-)Filter
We just learned how to customize the target signal Γ(·) in order to perform seasonal adjustment
(lowpass and bandpass filtering were discussed in previous sections; highpass is generally uninteresting). We now customize the amplitude fit in the stopband by relying on the general (analytically
tractable) criterion 63. Specifically, We assign an artificially large weight W (π/6) = 100 to frequency π/6 such that Γ̂(π/6) must be close to Γ(π/6) = 0 (otherwise the value of the criterion 63
would become excessively large). This way We force the real-time filter to damp effectively the
seasonal peak. We set λ = 0. This is a ‘true’ customization in the sense that the user prioritizes
123
an ‘effective’ seasonal adjustment over the plain mean-square solution, as provided by criterion 49.
We set
W (ωk ) =
100 ωk = π/6
1 otherwise
(64)
and compute the corresponding customized real-time filter42 : outputs, amplitude and time-shift
functions of the customized and of the previous MSE-filter are plotted and compared in figs.45
and 44. Note that We can interpret W (ωk , η)IT X (ωk ) in 63 as a customized spectrum estimate
IT X 0 (ωk ) of a fictious series x0t with a very strong seasonal component in π/6 i.e. We are performing
ordinary mean-square optimization for a ‘suitably distorted’ DGP x0t which fits Our assigned
priority.
>
>
>
>
>
>
>
>
>
>
>
>
>
+
+
+
>
>
>
>
+
+
>
>
>
>
>
>
+
>
>
>
>
+
+
+
>
>
>
weight_func_c<-weight_func
# Here We customize
weight_func_c[(length(weight_func)/6+1)]<-10^6*weight_func[length(weight_func)/6+1]
# Compute customized filter
dfa_c<-dfa_analytic(L,lambda,weight_func_c,Lag,Gamma,eta,cutoff,i1,i2)
b_c<-dfa_c$b
trffkt_c<-dfa_c$trffkt
# Amplitude and time shift
amp_analytic_c<-abs(trffkt_c)
pha_analytic_c<-Arg(trffkt_c)/(pi*(0:(K))/(K))
# Filter series
xf_c<-x
for (i in L:length(x))
{
xf_c[i]<-b_c%*%x[i:(i-L+1)]
}
file = paste("z_seas_per_ms_c.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
plot((per(xf_ms[L:len],plot_T)$per),type="l",axes=F,col="red",
ylab="Periodogram",xlab="Frequency",
main="Comparisons of periodograms of input and output signals")
lines((per(x[L:len],plot_T)$per),col="blue")
lines((per(xf_c[L:len],plot_T)$per),col="green")
mtext("Input", side = 3, line = -1,at=K/2,col="blue")
mtext("Output mean-square", side = 3, line = -2,at=K/2,col="red")
mtext("Output customized", side = 3, line = -3,at=K/2,col="green")
axis(1,at=1+0:6*(len-L)/12,labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
hl<-10
plot((per(xf_ms[L:len],plot_T)$per)[((len-L)/12)+(-hl:hl)],type="l",
axes=F,col="red",ylab="Periodogram",xlab="Frequency",
main="Magnifying glass on pi/6",
ylim=c(0,max((per(x[L:len],plot_T)$per)[((len-L)/12)+(-hl:hl)])))
lines((per(x[L:len],plot_T)$per)[((len-L)/12)+(-hl:hl)],col="blue")
lines((per(xf_c[L:len],plot_T)$per)[((len-L)/12)+(-hl:hl)],col="green")
mtext("Input", side = 3, line = -1,at=K/2,col="blue")
42 Recall that We selected T to be a multiple of the seasonal periodicity 12 such that ω
T /12 = π/6 i.e. frequency
π/6 is an element of the set (frequency-grid) ωk , k = 0, ..., T /2.
124
>
>
>
>
>
>
mtext("Output mean-square", side = 3, line = -2,at=K/2,col="red")
mtext("Output customized", side = 3, line = -3,at=K/2,col="green")
axis(1,at=hl+2,labels="pi/6")
axis(2)
box()
dev.off()
null device
1
10 20 30
Input
Output mean−square
Output customized
0
Periodogram
Comparisons of periodograms of input and output signals
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Frequency
15
0 5
Periodogram
Magnifying glass on pi/6
pi/6
Frequency
Figure 44: Periodograms of input (blue), output MSE (red) and output customized (green): full
bandwith (top) and vicinity of pi/6 (bottom)
We can observe that the periodograms of filtered (green and red) and orifinal data are almost
identical in the passband. In π/6 the periodogram of the customized filter is vanishingly small, as
desired.
>
>
>
>
+
>
>
>
>
>
>
file = paste("z_seas_a_ms_c.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
plot(Gamma,type="l",axes=F,col="black",ylim=c(0,max(amp_analytic_ms)),
ylab="",xlab="",main="Amplitude")
lines(amp_analytic_ms,lty=1,col="red")
lines(amp_analytic_c,lty=1,col="green")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
mtext("Real-time amplitude MSE", side = 3, line = -2,at=K/2,col="red")
mtext("Real-time amplitude customized", side = 3, line = -3,at=K/2,col="green")
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
125
>
>
>
+
>
>
>
>
>
>
>
>
>
axis(2)
box()
plot(rep(0,K+1),type="l",axes=F,col="black",ylim=c(min(na.exclude(pha_analytic_c)),
max(na.exclude(pha_analytic_c))),ylab="",xlab="",main="Time-shift")
lines(pha_analytic_ms,lty=1,col="red")
lines(pha_analytic_c,lty=1,col="green")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
mtext("Real-time amplitude MSE", side = 3, line = -2,at=K/2,col="red")
mtext("Real-time amplitude customized", side = 3, line = -3,at=K/2,col="green")
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
126
1.2
Amplitude
0.0
0.6
Target
Real−time amplitude MSE
Real−time amplitude customized
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
5pi/6
pi
Time−shift
−3
−1
1
Target
Real−time amplitude MSE
Real−time amplitude customized
0
pi/6
2pi/6
3pi/6
4pi/6
Figure 45: Amplitude (top) and time-shifts (bottom) of MSE (red) and customized filters (green)
Customizing the real-time filter by assigning a large weight to frequency π/6 in 64 pulls the ‘green’
amplitude function down in order to match Γ(π/6) = 0. As We can see, this is almost a ‘free lunch’
since amplitude and time-shift functions are not substantially affected by this customization.
6.1.5
A High-Order (SA-) Filter
We now propose an alternative approach which hopefully provides deeper insights into the structure of the estimation problem. We first note that the undesirable spectral peak in Our example is
narrow, as is frequently the case for economic data with regular but not necessarily deterministic
seasonal patterns. The above fig.45, top-graph, illustrated that the dip of the amplitude function
in π/6 is unnecessarily wide: as an undesirable side-effect, the filter removes spectral power on the
left and on the right of π/6 as can be seen by comparing periodograms of filterd (red and green)
outputs vs. input series (blue) in fig.44, bottom-graph. This is because a MA-filter of length
L = 24 is a polynomial of order 24 in exp(−ijωk ) which has at most 24 roots or zeroes in [−π, π]:
127
as can be seen in fig.45, top-graph, We count L/2 = 12 ‘ondulations’ of the amplitude function
in the half-width [0, π]. Since the number of potential roots is‘small’, the resulting polynomial
transfer function is unable to generate a very narrow dip in π/6. Thus We could try to augment
the filter order.
We now set L = 60 and L = 120 and compute corresponding mean-square real-time filters.
Amplitude functions as well as periodograms of input and output signals are plotted in figs.46 and
47 together with our previous filters.
>
>
>
>
+
+
+
+
+
+
+
+
+
+
+
+
>
>
>
>
+
>
>
>
>
>
>
>
+
+
+
+
>
>
>
>
>
+
+
>
>
>
>
>
>
# Length of Moving-Averages:
L_vec<-c(60,120)
# Compute analytical DFA: MSE-filters (no customization)
for (i in 1:length(L_vec))
{
assign(paste("dfa_mse_",L_vec[i],sep=""),
dfa_analytic(L_vec[i],lambda,weight_func,Lag,Gamma,eta,cutoff,i1,i2))
assign(paste("b_ms_",L_vec[i],sep=""),
get(paste("dfa_mse_",L_vec[i],sep=""))$b)
assign(paste("trffkt_ms_",L_vec[i],sep=""),
get(paste("dfa_mse_",L_vec[i],sep=""))$trffkt)
assign(paste("amp_analytic_ms_",L_vec[i],sep=""),
abs(get(paste("trffkt_ms_",L_vec[i],sep=""))))
assign(paste("pha_analytic_ms_",L_vec[i],sep=""),
Arg(get(paste("trffkt_ms_",L_vec[i],sep="")))/(pi*(0:(K))/(K)))
}
file = paste("z_seas_a_mse_c_mse.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
plot(Gamma,type="l",axes=F,col="black",ylim=c(0,max(amp_analytic_c)),
ylab="",xlab="",main="Amplitude")
lines(amp_analytic_ms,lty=1,col="red")
lines(amp_analytic_c,lty=1,col="green")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
mtext("MSE-filter: L=24", side = 3, line = -2,at=K/2,col="red")
mtext("Customized filter: L=24", side = 3, line = -3,at=K/2,col="green")
colo<-c("violet","orange")
for (i in 1:length(L_vec))
{
lines(get(paste("amp_analytic_ms_",L_vec[i],sep="")),col=colo[i])
mtext(paste("MSE-Filter: L=",L_vec[i],sep=""), side = 3, line = -3-i,at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
hl<-30
plot(Gamma[(K/6)+(-hl:hl)],type="l",axes=F,col="black",
ylim=c(0,max(amp_analytic_c)),ylab="",xlab="",
main="Amplitude: magnifying-glass in pi/6")
lines(amp_analytic_ms[(K/6)+(-hl:hl)],lty=1,col="red")
lines(amp_analytic_c[(K/6)+(-hl:hl)],lty=1,col="green")
mtext("Target", side = 3, line = -1,at=hl,col="black")
mtext("MSE-filter: L=24", side = 3, line = -2,at=hl,col="red")
mtext("Customized filter: L=24", side = 3, line = -3,at=hl,col="green")
for (i in 1:length(L_vec))
128
+
+
+
+
>
>
>
>
{
lines(get(paste("amp_analytic_ms_",L_vec[i],sep=""))[(K/6)+(-hl:hl)],col=colo[i])
mtext(paste("MSE-Filter: L=",L_vec[i],sep=""), side = 3, line = -3-i,at=hl,col=colo[i])
}
axis(1,at=hl+2,labels="pi/6")
axis(2)
box()
dev.off()
null device
1
Amplitude
0.0
0.6
1.2
Target
MSE−filter: L=24
Customized filter: L=24
MSE−Filter: L=60
MSE−Filter: L=120
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Target
MSE−filter: L=24
Customized filter: L=24
MSE−Filter: L=60
MSE−Filter: L=120
0.0
0.6
1.2
Amplitude: magnifying−glass in pi/6
pi/6
Figure 46: Amplitude functions full bandwith (top) and magnifying glass in pi/6 (bottom): MSE
L=24 (red), customized L=24 (green), MSE L=60 (violet) and MSE L=120 (orange)
A closer look to frequency π/6 in the bottom graph illustrates that the highest order filter L = 120
129
(orange) matches Our intention quite well: the dip is ‘deep’ (the damping will be strong) and
its width is substantially reduced as compared to the customized filter (green). The top-graph
confirms that the high-order filter (orange) is close to an identity in the passband, as desired. Remarkably, overfitting does not seem to be an issue here, since the filter matches all requirements
for an effective (real-time) SA.
We now filter the data with the available designs and compare periodograms before and after
filtering, see fig.47.
>
>
>
+
+
+
+
+
+
>
>
>
>
+
+
>
>
>
>
+
+
+
+
+
>
+
>
>
>
>
+
+
>
>
>
>
+
+
+
+
>
>
>
>
# Filter series
xf<-matrix(ncol=length(L_vec),nrow=length(x))
for (j in 1:length(L_vec))
{
for (i in L_vec[j]:length(x))
{
xf[i,j]<-get(paste("b_ms_",L_vec[j],sep=""))%*%x[i:(i-L_vec[j]+1)]
}
}
file = paste("z_seas_per_ms_c_ms.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
plot((per(xf_ms[max(L_vec):len],plot_T)$per),type="l",axes=F,col="red",
ylab="Periodogram",xlab="Frequency",
main="Comparisons of periodograms of input and output signals")
lines((per(xf_c[max(L_vec):len],plot_T)$per),col="green")
mtext("MSE-Filter: L=24", side = 3, line = -3,at=K/2,col="red")
mtext("Output customized", side = 3, line = -2,at=K/2,col="green")
for (i in 1:length(L_vec))
{
lines((per(xf[max(L_vec):len,i],plot_T)$per),col=colo[j])
mtext(paste("MSE-Filter: L=",L_vec[i],sep=""), side = 3, line = -3-i,
at=K/2,col=colo[i])
}
axis(1,at=1+0:6*(len-max(L_vec))/12,labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
hl<-30
plot((per(xf_ms[max(L_vec):len],plot_T)$per)[(len-max(L_vec))/12+(-hl:hl)],type="l",axes=F,
col="red",ylab="Periodogram",xlab="Frequency",
main="Magnifying glass on pi/6")
lines((per(xf_c[max(L_vec):len],plot_T)$per)[(len-max(L_vec))/12+(-hl:hl)],col="green")
mtext("MSE-Filter: L=24", side = 3, line = -3,at=hl,col="red")
mtext("Output customized", side = 3, line = -2,at=hl,col="green")
for (i in 1:length(L_vec))
#i<-2
{
lines((per(xf[max(L_vec):len,i],plot_T)$per)[(len-max(L_vec))/12+(-hl:hl)],col=colo[i])
mtext(paste("MSE-Filter: L=",L_vec[i],sep=""), side = 3, line = -3-i,at=hl,col=colo[i])
}
axis(1,at=hl+2,labels="pi/6")
axis(2)
box()
dev.off()
null device
130
1
20
10
Output customized
MSE−Filter: L=24
MSE−Filter: L=60
MSE−Filter: L=120
0
Periodogram
Comparisons of periodograms of input and output signals
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Frequency
10 15
5
Output customized
MSE−Filter: L=24
MSE−Filter: L=60
MSE−Filter: L=120
0
Periodogram
Magnifying glass on pi/6
pi/6
Frequency
Figure 47: Periodograms of MSE L=24 (red), output customized L=24 (green), output MSE L=60
(violet) and output MSE L=120 (orange) : full bandwith (top) and vicinity of pi/6 (bottom)
To conclude We compare the periodogram of the input signal and of the MSE-filter with L = 120,
see fig.48.
>
>
>
>
+
+
>
file = paste("z_seas_per_ms_120_i.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
plot((per(x[max(L_vec):len],plot_T)$per),type="l",axes=F,col="blue",
ylab="Periodogram",xlab="Frequency",
main="Comparisons of periodograms of input and output signals")
lines(per(xf[max(L_vec):len,i],plot_T)$per,col="orange")
131
>
>
>
+
>
>
>
>
+
+
>
>
>
>
>
>
>
mtext("Input", side = 3, line = -1,at=K/2,col="blue")
mtext("Output MSE 120", side = 3, line = -2,at=K/2,col="orange")
axis(1,at=1+0:6*(len-max(L_vec))/12,labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
hl<-30
plot((per(x[max(L_vec):len],plot_T)$per)[(len-max(L_vec))/12+(-hl:hl)],
type="l",axes=F,col="blue",ylab="Periodogram",xlab="Frequency",
main="Comparisons of periodograms of input and output signals")
lines((per(xf[max(L_vec):len,i],plot_T)$per)[(len-max(L_vec))/12+(-hl:hl)],col="orange")
mtext("Input", side = 3, line = -1,at=hl,col="blue")
mtext("Output MSE 120", side = 3, line = -2,at=hl,col="orange")
axis(1,at=hl+2,labels="pi/6")
axis(2)
box()
dev.off()
null device
1
132
10
20
Input
Output MSE 120
0
Periodogram
Comparisons of periodograms of input and output signals
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Frequency
5
10
Input
Output MSE 120
0
Periodogram
Comparisons of periodograms of input and output signals
pi/6
Frequency
Figure 48: Periodograms of input (blue) and ouput MSE L=120 (orange): full bandwith (top)
and vicinity of pi/6 (bottom)
As expected, the highest-order filter (L = 120) does a remarkable task in damping the seasonal
component: almost without affecting the non-seasonal AR(1)-component. Despite its large order,
the filter should be more or less immune against overfitting because the time-shift is close to zero
and because the amplitude is close to one except in π/6: clearly, these characteristics should be
useful out-of-sample too. We now check these claims.
6.1.6
Out-of-Sample Performances and Finite Sample Distributions of Filter Coefficients, Amplitude and Time-Shift Functions
We analyze overfitting effects, out-of-sample performances and finite-sample empirical distribution
of coefficients, amplitude and time-shift functions of filters with lengths L = 24, 60 and 120. MSE-
133
performances in- and out-of-sample are computed with respect to the true signal zt in
zt
=
0.9zt−1 + t
xt
= zt + cos(tπ/6)
(65)
We can thus avoid computation of a possibly cumbersome high-order symmetric target filter. We
generate 100 realizations of length 360 of the above seasonal process: the data is splitted into the
first 180 observations, used for estimation (in-sample performances), and the final 180 observations,
used for out-of-sample evaluation. MSE’s are reported in table 7 and the empirical distributions
of filter coefficients, of real-time amplitude and of time-shift functions are plotted in figs.49, 50
and 51.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Lag<-0
anzsim<-100
len1<-360
len_sim<-180
K<-len_sim/2
set.seed(10)
L_vec<-c(24,60,120)
# Define target Gamma
Gamma_sim<-rep(1,K+1)
Gamma_sim[1+(length(Gamma_sim)/6):(length(Gamma_sim)/6)]<-0
b_sim<-as.list(1:anzsim)
b_sim<-as.list(1:anzsim)
amp_sim<-b_sim
shift_sim<-b_sim
b<-as.list(1:length(L_vec))
amp<-matrix(ncol=length(L_vec),nrow=K+1)
shift<-amp
mse_in_sample<-matrix(ncol=length(L_vec),nrow=anzsim)
mse_out_sample<-mse_in_sample
ymin<-rep(10^6,length(L_vec))
ymax<--ymin
# Start simulation
for (i in 1:simanz)
{
z1<-arima.sim(list(ar=0.9),n=len1+max(L_vec))
x1<-z1+cos((1:(len1+max(L_vec)))*pi/6)
z_sim<-z1[max(L_vec)-1+1:len_sim]
x_sim<-x1[max(L_vec)-1+1:len_sim]
weight_func_sim<-per(x_sim,plot_T)$per
# Compute MSE-filters
for (j in 1:length(L_vec))
{
dfa<-dfa_analytic(L_vec[j],lambda,weight_func_sim,Lag,Gamma_sim,eta,cutoff,i1,i2)
b[[j]]<-dfa$b
ymin[j]<-min(ymin[j],min(b[[j]]))
ymax[j]<-max(ymax[j],max(b[[j]]))
amp[,j]<-abs(dfa$trffkt)
shift[,j]<-Arg(dfa$trffkt)/((0:K)*pi/K)
xf<-x1
for (k in 1:len1)
{
xf[max(L_vec)-1+k]<-b[[j]]%*%x1[max(L_vec)-1+k:(k-L_vec[j]+1)]
}
134
+
+
+
+
+
+
+
+
>
>
>
>
>
>
>
+
+
+
+
+
+
+
+
+
+
+
+
>
mse_in_sample[i,j]<-mean((z1-xf)[max(L_vec)-1+1:len_sim]^2)
mse_out_sample[i,j]<-mean((z1-xf)[max(L_vec)-1+(len_sim+1):len1]^2)
}
b_sim[[i]]<-b
amp_sim[[i]]<-amp
shift_sim[[i]]<-shift
}
perf_mat<-rbind(apply(mse_in_sample,2,mean),apply(mse_out_sample,2,mean))
dimnames(perf_mat)[[2]]<-paste("L=",L_vec,sep="")
dimnames(perf_mat)[[1]]<-c("In-sample","Out-of-sample")
file = paste("z_idfa_dist_SA_coef.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(3,1))
for (j in 1:length(L_vec))
{
b<-b_sim[[1]][[j]]
ts.plot(b_sim[[1]][[j]],ylim=c(ymin[j],ymax[j]),
main=paste("Empirical distribution of coefficients: L = ",L_vec[j],sep=""),
xlab="lag",ylab="coefficients")
for (i in 2:anzsim)
{
lines(b_sim[[i]][[j]])
b<-b+b_sim[[i]][[j]]
}
lines(b/anzsim,col="red",lwd=2)
}
dev.off()
null device
1
135
0.0 0.4 0.8
coefficients
Empirical distribution of coefficients: L = 24
5
10
15
20
lag
0.0 0.4 0.8
coefficients
Empirical distribution of coefficients: L = 60
0
10
20
30
40
50
60
100
120
lag
0.8
0.4
0.0
coefficients
Empirical distribution of coefficients: L = 120
0
20
40
60
80
lag
Figure 49: Empirical distribution of real-time filter coefficients of SA-filters of length 24, 60 and
120: mean of distribution highlighted in red
>
>
>
>
+
+
+
+
+
+
+
+
file = paste("z_idfa_dist_SA_amp.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(3,1))
for (j in 1:length(L_vec))
{
amp<-amp_sim[[1]][,j]
ts.plot(amp_sim[[1]][,j],ylim=c(0,1.8),
main=paste("Empirical distribution of amplitude: L = ",L_vec[j],sep=""),
xlab="lag",ylab="coefficients")
for (i in 2:anzsim)
{
lines(amp_sim[[i]][,j])
136
+
amp<-amp+amp_sim[[i]][,j]
+
}
+
lines(amp/anzsim,col="red",lwd=2)
+ }
> dev.off()
null device
1
1.0
0.0
coefficients
Empirical distribution of amplitude: L = 24
0
20
40
60
80
lag
1.0
0.0
coefficients
Empirical distribution of amplitude: L = 60
0
20
40
60
80
lag
1.0
0.0
coefficients
Empirical distribution of amplitude: L = 120
0
20
40
60
80
lag
Figure 50: Empirical distribution of real-time amplitude functions of SA-filters of length 24, 60
and 120: mean of distribution is highlighted in red
> file = paste("z_idfa_dist_SA_shift.pdf", sep = "")
> pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
> par(mfrow=c(3,1))
137
>
+
+
+
+
+
+
+
+
+
+
+
+
>
for (j in 1:length(L_vec))
{
shift<-shift_sim[[1]][,j]
ts.plot(shift_sim[[1]][,j],ylim=c(-2,2),
main=paste("Empirical distribution of time-shift: L = ",L_vec[j],sep=""),
xlab="lag",ylab="coefficients")
for (i in 2:anzsim)
{
lines(shift_sim[[i]][,j])
shift<-shift+shift_sim[[i]][,j]
}
lines(shift/anzsim,col="red",lwd=2)
}
dev.off()
null device
1
138
1
0
−2
coefficients
2
Empirical distribution of time−shift: L = 24
0
20
40
60
80
lag
1
0
−2
coefficients
2
Empirical distribution of time−shift: L = 60
0
20
40
60
80
lag
1
0
−2
coefficients
2
Empirical distribution of time−shift: L = 120
0
20
40
60
80
lag
Figure 51: Empirical distribution of time-shift of SA-filters of length 24, 60 and 120: mean of
distribution is highlighted in red
In-sample
Out-of-sample
L=24
0.200
0.220
L=60
0.109
0.122
L=120
0.065
0.073
Table 7: In- and out-of-sample MSE-performances of real-time SA-filters of length 24, 60 and 120
Table 7 confirms that in-sample and out-of-sample performances are close to a tie and that out-ofsample performances of the highest-order filter (L = 120) are better than in-sample performances
of the shorter filters involved: as claimed, overfitting is not an issue. Damping or removing narrow
spectral peaks is an easy estimation task ! As an additional confirmation fig.49 illustrates that the
empirical distribution of filter coefficients is very tight: as expected, the filters are pretty close
139
to identities since b0 ≈ 1 and bj ≈ 0 if j > 0. In contrast, the empirical distribution of coefficients of real-time trend -extraction filters in fig.35 appears substantially noisier which reflects the
complexity of this problem: damping components in a broad stop-band is much more difficult
than tackling narrow (seasonal) peaks. Accordingly, overfitting was a serious issue, recall MSEperformances reported in table 4 as compared to table 7 and compare the filter-lengths involved.
Recommendation
Although I-DFA could perform seasonal adjustment and trend extraction at once, based on a
single filter, the previous results suggest the following proceeding in applications:
• first seasonally adjust a series based on a real-time SA-filter of possibly high order, which is
immanently immune to overfitting
• then apply a ‘specialized’ trend-extraction filter of much smaller order – to contain overfitting
– to the previously adjusted series.
The empirical distribution of the amplitude function in fig.50 suggests that higher order filters
L = 120 are proner to ‘outliers’ of the amplitude function in the passband ωk 6= π/6 (Gibbs
phenomenon) but they are more robust in the stop-band i.e. the distribution is more tightly
concentrated in ωk = π/6. The empirical distribution of the time-shift in fig.51 suggests that the
time-shift especially of higher-order filters is fairly tightly concentrated around zero in most of the
passband.
6.1.7
Revision Sequence: First, Final and Last Releases
To conclude, We here analyze revision-sequences and vintages. Since real-time SA-filters are close
to an identity (up to narrow dips in potential seasonal frequencies43 ) we expect real-time estimates
to be fairly close to final releases. In order to check this claim we rely on the above SA-problem
based on the realization of length len = 600 of
zt
=
0.9zt−1 + t
xt
= zt + cos(tπ/6)
with σ 2 = 1 and target signal Γ(·) as defined and computed in the previous exercises.
We set L = 12144 and compute SA-filters for Lag = 0, 1, ..., L − 1 = 120 – We here go beyond
the symmetric filter for reasons to be explained below –.
>
>
>
>
>
>
>
>
+
+
+
+
+
+
K<-length(weight_func)-1
L<-121
yhat_Lag<-array(dim=c(len,L))
trffkt<-array(dim=c(len/2+1,L))
b<-array(dim=c(L,L))
# Compute real-time filters for Lag=,...,L/2 and for the above three AR-processes
weight_func<-per(x,plot_T)$per
for (Lag in 0:(L-1))
{
# Optimize filters
filt<-dfa_ms(L,weight_func,Lag,Gamma)
trffkt[,Lag+1]<-filt$trffkt
b[,Lag+1]<-filt$b
# Compute outputs
43 Amplitude functions are close to an identity and time-shifts are nearly vanishing, see figs.50 and 51: filter
coefficients are close to the identity too: b0 = 1 and bk = 0 for k > 0, see fig.49.
44 If L is odd, then the filter corresponding to Lag = (L − 1)/2 is symmetric.
140
+
for (j in L:len)
+
yhat_Lag[j,Lag+1]<-filt$b%*%x[j:(j-L+1)]
+ }
We are now able to compute and plot amplitude and time-shift functions as well as filter-weights
of Lag = 0 (real-time), Lag = (L − 1)/2 = 60 (final or symmetric filter) and Lag = L = 120 (last
filter), see fig.52.
>
>
>
>
>
>
>
>
>
>
+
>
>
>
+
+
+
+
+
>
+
>
>
>
>
>
+
>
>
+
+
+
+
+
+
+
+
>
+
>
>
>
>
>
+
+
>
omega_k<-pi*0:(len/2)/(len/2)
colo<-rainbow(L)
file = paste("z_idfa_SA_Lag02L.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(3,1))
amp<-abs(trffkt)
shift<-Arg(trffkt)/omega_k
ymin<-min(amp,na.rm=T)
ymax<-max(amp,na.rm=T)
plot(amp[,1],type="l",main="Amplitude functions",
axes=F,xlab="Frequency",ylab="Amplitude",col="blue",ylim=c(ymin,ymax))
mtext("Lag=0", side = 3, line = -1,at=len/4,col="blue")
select_i<-c(as.integer(L/2+1),L)
for (j in 1:length(select_i))
{
lines(amp[,select_i[j]],col=colo[select_i[j]])
mtext(paste("Lag=",select_i[j]-1,sep=""), side = 3, line = -j-1,
at=len/4,col=colo[select_i[j]])
}
axis(1,at=c(0,1:6*len/12+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
ymin<-min(shift,na.rm=T)
ymax<-max(shift,na.rm=T)
plot(shift[,1],type="l",main="Time-Shifts",
axes=F,xlab="Frequency",ylab="Shift",col="blue",ylim=c(-1,ymax))
mtext("Lag=0", side = 3, line = -1,at=len/4,col="blue")
for (j in 1:length(select_i))
{
# We here recompute the shift because the function Arg has troubles
#
when dealing with the periodicity of the phase
shift_s<-Arg(trffkt[,select_i[j]]*exp(-1.i*select_i[j]*omega_k))/omega_k
lines(shift_s+select_i[j],col=colo[select_i[j]])
mtext(paste("Lag=",select_i[j]-1,sep=""), side = 3,
line = -j-1,at=len/4,col=colo[select_i[j]])
}
axis(1,at=c(0,1:6*len/12+1),labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
ymin<-min(b,na.rm=T)
ymax<-max(b,na.rm=T)
plot(b[,1],type="l",col="blue",ylim=c(ymin,ymax),main="Filter coefficients",
ylab="Output",xlab="lag",
axes=F)
mtext("Lag=0", side = 3, line = -1,at=L/2,col="blue")
141
>
+
+
+
+
+
>
>
>
>
for (j in 1:length(select_i))
{
lines(b[,select_i[j]],col=colo[select_i[j]])
mtext(paste("Lag=",select_i[j]-1,sep=""), side = 3, line = -j-1,
at=L/2,col=colo[select_i[j]])
}
axis(1,at=20*(1:(L/20)),labels=20*(1:(L/20))-1)
axis(2)
box()
dev.off()
null device
1
0.8
Lag=0
Lag=60
Lag=120
0.2
Amplitude
Amplitude functions
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
4pi/6
5pi/6
pi
79
99
Frequency
40
80
Lag=0
Lag=60
Lag=120
0
Shift
Time−Shifts
0
pi/6
2pi/6
3pi/6
Frequency
0.4
0.8
Lag=0
Lag=60
Lag=120
0.0
Output
Filter coefficients
19
39
59
119
lag
Figure 52: Amplitude (top), time-shift (middle) and coefficients (bottom) of filters with Lags 0
(blue), 60 (cyan) and 120 (red)
142
Amplitude functions of initial (dark blue: Lag = 0) and of the ‘last’ filter (red: Lag = 120) are
identical which might be a bit surprising: the explanation is given by the bottom graph where
We see that both filters are identical up to exchanging b0 and bL−1 . The time-shifts (middle-plot)
are therefore clearly different since the initial release assigns most weight to the latest observation
b0 ≈ 1 whereas the last filter (Lag = L − 1) reverts time ordering, thus assigning most weight
b120 ≈ 1 to the first observation, lagged by L − 1 = 120 time units. Both asymmetric amplitude
functions (top graph: red and blue are overlapping) are very close to the amplitude of the final
symmetric filter (light blue) which, together with the nearly vanishing time-shift (middle graph,
dark blue) suggests that the initial release should be very close to the final (output of symmetric
filter) release i.e. We expect the magnitude of revisions to be small.
6.1.8
Revision Sequence: Vintages and Tentacle Plot
The following R-chunk computes vintages of filters with Lag = 0, ..., L − 1 = 120 and sets-up the
the vintage triangle for the tentacle plot, see fig.53.
> vintage<-array(dim=c(len,len))
> dim(vintage)
[1] 600 600
>
+
+
+
+
+
+
+
+
+
>
>
>
for (j in L:len)#j<-L
{
# first L/2 releases
vintage[(j-as.integer(L/2)):j,j]<-yhat_Lag[j,(as.integer(L/2)+1):1]
# symmetric filter
vintage[1:(j-as.integer(L/2)-1),j]<-yhat_Lag[(as.integer(L/2)+1):(j-1),
as.integer(L/2)+1]
# last L/2 releases
vintage[1:as.integer(L/2),j]<-yhat_Lag[L,L:(as.integer(L/2)+2)]
}
vintage_triangle<-vintage
dimnames(vintage_triangle)[[2]]<-paste("Publ. ",1:len,sep="")
dimnames(vintage_triangle)[[1]]<-paste("Target ",1:len,sep="")
>
>
>
>
>
>
>
+
>
+
+
+
>
>
>
>
>
>
+
+
colo<-rainbow(len)
file = paste("z_vintages_sa.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
ymin<-min(vintage,na.rm=T)
ymax<-max(vintage,na.rm=T)
ts.plot(vintage[,L],col=colo[1],ylim=c(ymin,ymax),
main="Tentacle plot: vintages and full revision sequence",ylab="Vintages")
for (j in (L+1):len)
{
lines(vintage[,j],col=colo[j])
}
abline(v=c(L,len-L+1),col="black",lty=2)
mtext("Start of symmetric (final) filter", side = 3, line = -1,at=L,col="black")
mtext("End of symmetric (final) filter", side = 3, line = -1,at=len-L+1,col="black")
ymin<-min(vintage,na.rm=T)
ymax<-max(vintage,na.rm=T)
ts.plot(yhat_Lag[,1],col="blue",ylim=c(ymin,ymax),
main="Initial release (blue), last vintage (red) and true signal (green)",
ylab="Vintages")
143
>
>
>
>
>
>
lines(vintage[,len],col="red")
lines(z,col="green")
abline(v=c(L,len-L+1),col="black",lty=2)
mtext("Start of symmetric (final) filter", side = 3, line = -1,at=L,col="black")
mtext("End of symmetric (final) filter", side = 3, line = -1,at=len-L+1,col="black")
dev.off()
null device
1
5
End of symmetric (final) filter
0
Start of symmetric (final) filter
−5
Vintages
Tentacle plot: vintages and full revision sequence
0
100
200
300
400
500
600
Time
5
End of symmetric (final) filter
0
Start of symmetric (final) filter
−5
Vintages
Initial release (blue), last vintage (red) and true signal (green)
0
100
200
300
400
500
600
Time
Figure 53: Tentacle plot (top) and initial release vs. last vintage and true signal (bottom)
The tentacle plot in the upper graph is fairly close to a line – no visisble tentacles actually –
which implies that revisions are negligible. In comparison, the plots in figs.38 and 39 obtained
in the context of trend -extraction, showed evidence of ‘tentacles’ in particular in the vicinity of
144
turning-points. A comparison of the initial release (blue) and the final vintage (red) as well as
the true signal (zt in 65) in the bottom graph of fig.53 confirms Our initial claim: initial and
‘final’ releases, as obtained between the two vertical shaded lines, are almost indistinguishable
(the green line dominates because it is printed last) and in particular the initial release (blue) is
not delayed when compared to the output of the symmetric filter (red) or the true signal (green).
Note that observations on the left of the first vertical (dashed) line are obtained by filters with
Lag = (L + 1)/2, (L + 1)/2 + 1, ..., L − 1. This facility is of practical relevance when L is ‘large’
because the first L − 1 observations of the initial (real-time) filter are unobservable (NA’s); thus
in the extreme case L = T We would have only one single observation available: by allowing Lag
to vary from Lag = 0 to Lag = L − 1, as We did above, We thus obtain a SA-series of full length
T . Interestingly, therefore, a full revision-sequence might still be useful: not for improving initial
releases (which was the original purpose and intention) but for computing full-length SA.
6.2
General Composite Seasonal Spectrum
We now allow for a much richer seasonal structure, than the previous single line spectrum in π/6,
by generating a ‘mixed-bag’ spectrum.
6.2.1
The DGP: Deterministic, Stochastic, Stationary and Non-Stationary Seasonal
‘Mixed-Bag’
We here consider a more plausible (but still artificial) design based on shorter sample length (ten
years of monthly data: T = 120) and a more complex seasonal pattern based on a mix of a
deterministic seasonal in π/6, a non-stationary stochastic seasonal with peaks in π/2 and π and
a less regular stationary seasonal with a peak in frequency 4π/6: the latter peak is a bit broader
because a stationary seasonal component is ‘less stable’45 . The data xt is generated as follows:
zt
=
0.9zt−1 + 1t
yt
= yt−4 + 2t
wt
= −0.995wt−1 − 0.990025wt−2 + 3t
xt
= cos(tπ/6) + zt + yt + wt
where cos(tπ/6) is the line-spectrum in π/6, yt is the non-stationary seasonal with peaks in π/2, π,
wt is the stationary seasonal with a peak in 4π/646 and zt adds low-frequency mass frequently
found in economic data. This generic empirical setting allows to replicate much richer seasonal
structures, as typically found in applications, than ‘simple’ SARIMA-models based on the seasonal
1
difference 1−B
12 AR(12)-operator (as an example, the latter would generate peaks in all seasonal
frequencies kπ/6, k = 1, ..., 6 which is a rigid pattern).
The following R-chunk generates all of the above series, computes the aggregate xt as well as its
periodogram, see fig.54. Note that We scaled (standardized) all stochastic seasonal components,
for graphical convenience, and that We generated series of length T = 120 (as intended: 10 years
of monthly data) as well as 1000: the shorter sample is for estimation whereas the longer sample
will be used for out-of-sample evaluation.
>
>
>
>
>
>
# Simulation of the `complex' seasonal series
len<-120
len1<-1000
set.seed(10)
ar1<-0.9
z<-arima.sim(list(ar=ar1),n=len1)
45 Economic data often shows evidence of broader peaks in frequency 4π/6 because of the potential existence of
additional calendar effects.
p
46 The coefficients a , a were determined according to a = −(0.9952 ), a = 2 ∗ cos(4π/6) ( − a ) which,
1 2
2
1
2
according to the ARIMA-script (script number 1) generates a cycle peaking in frequency 4π/6.
145
>
>
>
+
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
eps<-rnorm(3000)
yh<-eps
for (i in 5:length(eps))
yh[i]<-yh[i-4]+eps[i]
y<-scale(yh[(length(eps)-len1+1):length(eps)])
a_2<--0.995^2
a_1<-2*cos(4*pi/6)*sqrt(-a_2)
w<-scale(arima.sim(list(ar=c(a_1,a_2)),n=len1))
xh<-z+cos((1:len1)*pi/6)+y+w
x<-xh[1:len]
plot_T<-F
file = paste("z_seas_a_g.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(3,1))
ts.plot(x)
acf(x)
plot(per(x,plot_T)$per,type="l",axes=F,ylab="Periodogram")
axis(1,at=1+0:6*len/12,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
−6 −2
x
2
6
null device
1
0
20
40
60
80
100
120
Time
0.4
−0.2
ACF
1.0
Series x
0
5
10
15
20
12
8
4
0
Periodogram
Lag
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Index
Figure 54: Seasonal series (top), acf (middle) and periodogram (bottom)
146
As expected, the periodogram reflects all seasonal components (peaks). Note that We do not care
about the essence of a seasonal component: whether a peak is generated by a deterministic (π/6) or
a stochastic, stationary (4π/6) or non-stationary (π/2, π) component is irrelevant. We ultimately
just care about matching location, height (power/magnitude) and width (regularity/stability) of
dominant peaks; in SA, in particular, as well as in signal extraction, in general.
6.2.2
The Gamma-Interface
We associate ‘naturally’ spectral peaks in the seasonal frequencies kπ/6, k = 1, ..., 6 of a monthly
series with a seasonal component and We don’t care whether this component is a mixed-bag –
a heterogeneous aggregate of different components – or a single homogenous process. SA of xt
requires a filter which matches location, height and width of the seasonal peaks, as revealed in
fig.54, bottom plot. We could now specify a symmetric target filter Γ(·) manually, by imposing
zeroes at the relevant frequencies, as We did in section 6.1. Alternatively, one could think about an
automatic procedure which would design Γ(·) accordingly. The function in the following R-chunk
is a first attempt in this direction: it specifies a symmetric target Γ(·) based on the periodogram
as well as a list of pre-specified seasonal frequencies47 where potential peaks could (or not) occur.
It allows also to tackle calendar effects by specifying a corresponding list of candidate-frequencies.
We would like to emphasize that the following code is prototypical and thus subject to (multiple)
improvements: but We are not interested in pushing this project further. We invite interested
readers to ‘go through’ the code; in case of desinterest you may simply skip the following chunk.
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Gamma_interface<-function(list_freq_seasonal,list_freq_calendar,spect)
{
K<-length(spect)-1
# determine asymmetrical width of seasonal peaks
#
(calendar peaks are assumed to be line spectra)
# Two rules are used:
#
The monotonic decay on both sides of the peak (as long as its decaying
#
it's still part of the peak)
#
The absolute value of the peak (which must be larger than
#
med_times the medians on both sides)
med_times<-4
spec_inflate<-4
med_spec_u<-1:(length(list_freq_seasonal)-1)
med_spec_l<-1:(length(list_freq_seasonal)-1)
len_u<-list_freq_seasonal
len_l<-len_u
for (i in 1:(length(list_freq_seasonal)))#i<-6
{
med_spec_l[i]<-2*ifelse(i==1,NA,median(spect[(list_freq_seasonal[i]-1):
(list_freq_seasonal[i-1]+1)]))
med_spec_u[i]<-2*ifelse(i==length(list_freq_seasonal),
NA,median(spect[(list_freq_seasonal[i]+1):(list_freq_seasonal[i+1]-1)]))
if (i<length(list_freq_seasonal))
{
# median rule on the right half of the peak (peaks can be asymmetric)
med_u<-which(!(spect[list_freq_seasonal[i]:list_freq_seasonal[i+1]]>
med_times*med_spec_u[i]))[1]-1
med_u<-ifelse(length(med_u)==0,list_freq_seasonal[i+1]-list_freq_seasonal[i],med_u)
# monotonic decay rule on the right half of the peak
47 The function doesn’t ‘know’ a priori at which rate a series is sampled: monthly, daily, quarterly,...: therefore
the user has to supply this information.
147
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff_u<-which(!diff(spect[list_freq_seasonal[i]:list_freq_seasonal[i+1]])<0)[1]-1
diff_u<-ifelse(length(diff_u)==0,list_freq_seasonal[i+1]-list_freq_seasonal[i],diff_u)
len_u[i]<-min(diff_u,med_u)
} else
{
len_u[i]<-0
}
if (i>1)
{
# same as above but on the left side of the peak: median and monotonic decay rules
med_l<-which(!(spect[list_freq_seasonal[i]:list_freq_seasonal[i-1]]>
med_times*med_spec_l[i]))[1]-1
med_l<-ifelse(length(med_l)==0,list_freq_seasonal[i]-list_freq_seasonal[i-1],med_l)
diff_l<-which(!diff(spect[list_freq_seasonal[i]:list_freq_seasonal[i-1]])<0)[1]-1
diff_l<-ifelse(length(diff_l)==0,list_freq_seasonal[i]-list_freq_seasonal[i-1],diff_l)
len_l[i]<-min(diff_l,med_l)
} else
{
len_l[i]<-0
}
# which(diff(which(spect[list_freq[i]:list_freq[i-1]]>med_spec[i-1]))>1)[1]
}
# Formatting Gamma based on location, width and height of peaks as determined above
Gamma<-rep(1,K+1)
for (i in 1:(length(list_freq_seasonal))) #i<-6
{
# If the width of the peak is not null (location problem: where do I have peaks)
if (len_l[i]+len_u[i]>0)
{
# determining the width
width_peak<-(list_freq_seasonal[i]-max(0,len_l[i]-1)):
(list_freq_seasonal[i]+max(0,len_u[i]-1))
# determining the height (deepness of target trough/dip)
Gamma[width_peak]<-sqrt(min(na.exclude(c(med_spec_l[i],med_spec_u[i]))))/
(spec_inflate*sqrt(spect[width_peak]))
# We dot not allow for amplitudes larger than one
Gamma[which(Gamma>1)]<-1
# We drill a zero in the seasonal frequency (if it is loaded by a peak)
Gamma[list_freq_seasonal[i]]<-0
}
}
if (length(list_freq_calendar)>0)
Gamma[list_freq_calendar]<-0
#
#
#
#
#
#
plot_T<-F
plot(Gamma,type="l",axes=F,ylim=c(0,1))
lines(per(x_data,plot_T)$per/max(per(x_data,plot_T)$per),col="red")
axis(1,at=1+(0:6)*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
return(list(Gamma=Gamma))
}
148
The function requires the following inputs:
• list f req seasonal: a list of seasonal frequencies: the function checks whether the frequencies
are ‘loaded’ by spectral peaks and assigns dips to Γ(·) if affirmative48 .
• list f req calendar: a list of calendar frequencies. The function does not check the presence
or not of spectral peaks: a single zero is automatically assigned to Γ(·) in each frequency of
the submitted list49 .
• spect: a spectral estimate. In Our case the periodogram.
6.2.3
Automatic Seasonal Adjustment
We now feed Our data xt to the above automatic Gamma-interface and then proceed to real-time
SA. Fig.55 compares the generated target filter and the periodogram of xt .
>
>
>
>
>
>
>
>
>
>
+
>
>
>
>
>
weight_func<-per(x,plot_T)$per
spect<-weight_func
K<-length(weight_func)-1
list_freq_seasonal<-round(1+K*c((1:6)/6))
list_freq_calendar<-NULL#round(1+K*(4/6+0.1/pi))
Gamma<-Gamma_interface(list_freq_seasonal,list_freq_calendar,weight_func)$Gamma
file = paste("z_seas_agi.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
plot_T<-F
plot(Gamma,type="l",axes=F,ylim=c(0,1),
main="Periodogram of input (red) and automatic target (black)")
lines(per(x,plot_T)$per/max(per(x,plot_T)$per),col="red")
axis(1,at=1+(0:6)*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
48 We deliberately ignore statistical tests about the significance of a periodogram peak because classical inferential
tools do not perform well in this particular descriptive/explorative application. We are aware of the fact that Our
‘rule-based’ proecdure is rather ad hoc and might be subject to substantial improvement. Interested readers are
welcome to do so.
49 Calendar effects are generally deterministic with narrow line spectra: therefore a single zero of Γ(·) is generally
sufficient.
149
0.6
0.4
0.0
0.2
Gamma
0.8
1.0
Periodogram of input (red) and automatic target (black)
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
Index
Figure 55: Automatic Gamma-interface
The dips of the target filter match location, height and width of the seasonal components quite
well: We can see that the dip of the potentially unstable stationary seasonal in 4π/6 is treated
differently by receiving a broader dip. The next fig.56 plots amplitude and time-shift functions of
two mean-square real-time filters of lengths L = 24 and L = 60.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
# Length of Moving-Average:
# Trick: selecting L=24 to be a multiple of 6 (the quotient in the
#
frequency pi/6 of the cosine) allows
#
the filter to damp/eliminate the component more easily!
L_vec<-c(24,len/2)
b_list<-as.list(1:length(L_vec))
xf<-matrix(nrow=len1,ncol=length(L_vec))
trffkt<-matrix(nrow=K+1,ncol=length(L_vec))
amp<-trffkt
shift<-trffkt
# Customization: lambda=eta=0 implies minimal mean-square revisions
lambda<-0
eta<-0
# cutoff frequency: this parameter is inactive if eta=0
cutoff<-pi/6
# Lag: Lag=0: real-time filter;
Lag<-0
# We do not impose filter restrictions: see exercises below
i1<-F
i2<-F
# Compute analytical DFA
150
>
+
+
+
+
+
+
+
+
+
+
+
>
>
>
>
>
>
>
+
+
+
>
>
>
>
>
>
>
+
+
+
+
>
>
>
>
+
>
>
+
+
+
+
>
>
>
>
for (i in 1:length(L_vec))
{
dfa_mse<-dfa_analytic(L_vec[i],lambda,weight_func,Lag,Gamma,eta,cutoff,i1,i2)
b_list[[i]]<-dfa_mse$b
trffkt[,i]<-dfa_mse$trffkt
amp[,i]<-abs(trffkt[,i])
shift[,i]<-Arg(trffkt[,i])/(pi*(0:(K))/(K))
for (j in L_vec[i]:len1)
{
xf[j,i]<-b_list[[i]]%*%xh[j:(j-L_vec[i]+1)]
}
}
# Final Symmetric filter
L<-61
Lag<-(L-1)/2
dfa_symmetric<-dfa_analytic(L,lambda,weight_func,Lag,Gamma,eta,cutoff,i1,i2)
b_symmetric<-dfa_symmetric$b
xf_symmetric<-rep(NA,len1)
for (j in ((L-1)/2+1):(len1-(L-1)/2))
{
xf_symmetric[j]<-b_symmetric%*%xh[(j+(L-1)/2):(j-(L-1)/2)]
}
colo<-rainbow(2*length(L_vec))
file = paste("z_seas_a_a_asag.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
plot(Gamma,type="l",axes=F,col="black",ylim=c(0,max(amp)),ylab="",xlab="",main="Amplitude")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
for (i in 1:length(L_vec))
{
lines(amp[,i],lty=1,col=colo[i])
mtext(paste("Amplitude: L=",L_vec[i],sep=""), side = 3, line = -1-i,at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(rep(0,K+1),type="l",axes=F,col="black",ylim=c(min(na.exclude(shift)),
max(na.exclude(shift))),ylab="",xlab="",main="Time-shift")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
for (i in 1:length(L_vec))
{
lines(shift[,i],lty=1,col=colo[i])
mtext(paste("Shift: L=",L_vec[i],sep=""), side = 3, line = -1-i,at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
151
Amplitude
0.0
0.6
1.2
Target
Amplitude: L=24
Amplitude: L=60
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
pi
4pi/6
5pi/6
pi
Time−shift
−1.0
0.5
Target
Shift: L=24
Shift: L=60
0
pi/6
2pi/6
3pi/6
Figure 56: Real-time SA-filters: amplitude (top) and shift (bottom)
Both real-time filters damp the undesirable seasonal components in the automatically assigned
stop-bands and both filters are reasonably close to the identity in the passband. We therefore
expect real-time estimates to perform quite well and We expect revision errors to be small.
6.2.4
Out-of-Sample Performances: Amplitude Effect
In order to verify Our claims We first plot the periodograms of input and output signals for a long
out-of-sample period, see fig.57.
>
>
>
+
+
file = paste("z_seas_per_oos_sa.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
plot(per(xh[max(L_vec):len1],plot_T)$per,type="l",axes=F,col="blue",
ylab="Periodogram",xlab="Frequency",
main="Comparisons of periodograms of input and output signals")
152
>
>
+
+
+
+
>
+
>
>
>
mtext("Input", side = 3, line = -1,at=len1/4,col="blue")
for (i in 1:length(L_vec))
{
lines(per(xf[max(L_vec):len1,i],plot_T)$per,col=colo[i])
mtext(paste("Output: L=",L_vec[i],sep=""), side = 3, line = -1-i,at=len1/4,col=colo[i])
}
axis(1,at=1+0:6*(len1-max(L_vec))/12,labels=c("0","pi/6","2pi/6","3pi/6",
"4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
Comparisons of periodograms of input and output signals
30
20
10
0
Periodogram
40
50
Input
Output: L=24
Output: L=60
0
pi/6
2pi/6
3pi/6
4pi/6
5pi/6
Frequency
Figure 57: Periodograms of input and real-time outputs: out-of-sample
153
pi
The periodograms are almost indistinguishable in the passband, as desired. In the stopband the
seasonal peaks of the input do not appear in the out-of-sample filter outputs: they have been
effectively damped50 . We infer from this analysis that the SA-task seems to be effective in terms
of amplitude effects (removal of seasonal components). We now check whether the filter outputs
are delayed or not: this effect cannot be quantified by the periodogram plots (the DFT’s would
be informative though).
6.2.5
Out-of-Sample Performances: Time-Shift and Revision Error
We now compare outputs of final symmetric filter and of the above real-time filters out-of-sample,
see fig.58.
>
>
>
>
>
>
>
+
>
>
+
+
+
+
+
>
>
>
+
>
>
>
>
>
>
+
+
>
>
+
+
+
+
+
>
>
>
>
file = paste("z_sym_rt_sa_oos.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
mplot<-cbind(xf_symmetric,xf)
ymin<-min(mplot,na.rm=T)
ymax<-max(mplot,na.rm=T)
ts.plot(mplot[,3],col="blue",ylim=c(ymin,ymax),
main="Final and real-time filter outputs (out-of-sample)",ylab="Vintages")
mtext("Final (symmetric) filter",col="blue", side = 3, line = -1,at=dim(mplot)[1]/2)
for (j in 1:length(L_vec))
{
lines(mplot[,j],col=colo[j])
mtext(paste("Real-time filter: L=",L_vec[j],sep=""),col=colo[j], side = 3,
line = -1-j,at=dim(mplot)[1]/2)
}
abline(v=c(L,len1-L+1),col="black",lty=2)
mtext("Start of symmetric (final) filter", side = 3, line = -1,at=L,col="black")
mtext("End of symmetric (final) filter", side = 3, line = -1,
at=dim(mplot)[1]-L+1,col="black")
anf<-400
enf<-600
mplot<-cbind(xf_symmetric,xf)[400:600,]
ymin<-min(mplot,na.rm=T)
ymax<-max(mplot,na.rm=T)
plot(mplot[,3],type="l",col="blue",ylim=c(ymin,ymax),
main="Final and real-time filter outputs (out-of-sample)",
ylab="Outputs",xlab="", axes=F)
mtext("Final (symmetric) filter",col="blue", side = 3, line = -1,at=dim(mplot)[1]/2)
for (j in 1:length(L_vec))
{
lines(mplot[,j],col=colo[j])
mtext(paste("Real-time filter: L=",L_vec[j],sep=""),col=colo[j], side = 3,
line = -1-j,at=dim(mplot)[1]/2)
}
axis(1,at=c(1,as.integer(((enf-anf)/4)*1:4)),labels=anf+c(0,as.integer(((enf-anf)/4)*1:4)))
axis(2)
box()
dev.off()
50 We could ‘eliminate’ any residual power in the seasonal frequencies by customization i.e. by artificially overemphasizing the height of the seasonal peaks, recall Our proceeding in section 6.1, p.6.1.4.
154
null device
1
Final and real−time filter outputs (out−of−sample)
5
0
−5
Vintages
Start of symmetric (final) filter Final (symmetric) filter End of symmetric (final) filter
Real−time filter: L=24
Real−time filter: L=60
0
200
400
600
800
1000
Time
−2
2
Final (symmetric) filter
Real−time filter: L=24
Real−time filter: L=60
−6
Outputs
Final and real−time filter outputs (out−of−sample)
400
450
500
550
600
Figure 58: Comparison of real-time (green: L=60; red: L=24) and final (blue) out-of-sample
outputs
The out-of-sample outputs of the real-time filters (green and red) are pretty close to the final filter
output (blue), as expected. A closer view to the out-of-sample period from t = 400 : 600 in the
lower graph confirms that neither real-time filter is delayed, as was to be expected from the timeshift plots in fig.56. Let us emphasize, once again, that real-time SA is not a difficult estimation
problem because the stopband is invariably narrow: the amplitude function is close to an identity
up to a finite set of (generally) narrow seasonal dips. Therefore, revisions could be ignored by all
practical means. To be more specific: the revision error due to SA-filtering (increasing Lag) is
likely to be negligible when compared to the magnitude of ‘ordinary’ data-revisions.
155
6.3
Real-Time Seasonal Adjustment and Misspecification
Real-time SA is invariably an easy estimation task – a breeze when compared to trend extraction –. Interestingly, data can be effectively adjusted even under deliberate (severe) modelmisspecification. The interested reader is referred to a comprehensive SEFBlog-tutorial on the
topic: http://blog.zhaw.ch/idp/sefblog/index.php?/archives/309-Seasonal-Adjustment-The-Epilogue.
html.
7
Trend Extraction
Real-time trend extraction is generally (much) challenging than real-time seasonal adjustment
because one attempts to remove or damp components in a broad/wide/large high-frequency stopband. Therefore both the amplitude as well as the time-shift of the real-time filter will more or
less heavily deviate from the idealized lowpass target, in contrast to real-time SA-filters, which
are invariably close to the target filter (by transitivity since both are close to the identity). As
a result, customization of the amplitude-fit in the stop-band (Smoothness) by η as well as the
customization of the phase or time-shift function in the passband (Timeliness) by λ, in criterion
63, will affect noticeably real-time filter characteristics. The following sections are devoted to the
topic.
7.1
Performance Measures
We here propose a set of four performances measures, two classical time-domain and two frequencydomain statistics, which emphasize timeliness and smoothness issues but differently than (complementary to) the ATS-decomposition 56. Our intention here is to provide additional evidence that
customization obtained by 57 or, more generally, by 63 indeed tackles user-priorities ‘the right
way’.
7.1.1
Time-Domain: Curvature and Peak-Correlation
In contrast to SA, performances of real-time trend filters can substantially deviate from the target.
In order to compare filter-designs We therefore propose a set of well-known and well-documented
time-domain performance measures which can be linked to Selectivity and Timeliness as defined
in section 4.3.2. The first measure computes relative mean-square second-order differences of a
filter-output ŷt :
2 2
PT 2
E (1 − B) ŷt
t=3 ŷt − 2ŷt−1 + ŷt−2
≈
(66)
Curvature :=
PT
2
V ar(yˆt )
t=1 (ŷt − ŷ)
where ŷ is the (arithmetic) mean of ŷt . Note that We now identify ‘Curvature’ with the sampleestimate on the right hand-side. Mean-square second-order differences emphasize the geometric
curvature: if the filter-output ŷt appears smooth then Curvature is small. As an extreme example,
if ŷt is a linear function (of time), then Curvature vanishes. Note that the squared second-order
2
differences ŷt − 2ŷt−1 + ŷt−2 could be made arbitrarily small by simple scaling of the filter output. In order to avoid easy ‘cheating’ We therefore divide by the variance of the signal. Curvature
does not explicitly refer to Timeliness but it is related to Selectivity, as shown below.
The concept of peak-correlation is another well-established performance-measure which is defined by
T
−j
X
max(cor(yt , ŷt+j )) ≈ max
(yk − y)(ŷk+j − ŷ)
(67)
j
j
156
k=1
where yt is the target (in our case it is the output of the final symmetric filter) and ŷt is the
estimate (in our case a real-time filter output). Note that We are not primarily interested in the
magnitude of the correlations, but in the lead or lag j0 at which the correlation between the target
yt and the shifted (real-time) estimate ŷt+j0 is maximized: this will be called ‘Peak Correlation’.
A positive Peak Correlation j0 means a lag/delay by the real-time filter and turning-points are
delayed and conversely for negative j0 . Obviously, j0 addresses directly Timeliness since a higher
time-shift of the filter affects the lag at which the above correlation ‘peaks’.
7.1.2
Frequency-Domain: Selectivity and Mean-Shift
Filter characteristics are uniquely described by amplitude und time-shift functions. We here propose two measures which summarize potentially relevant effects in a way complementary (but not
identical) to Timeliness and Smoothness error components. Selectivity relates pass- and stopband
amplitude characteristics
R
P
Â(ω)2 h(ω)dω
Â(ωk )2 IT X (ωk )
Passband
≈ P Passband
(68)
Selectivity(α) := R
2
α
Â(ω)2 h(ω)|ω|α ω
Stopband Â(ωk ) IT X (ωk )|ωk |
Stopband
For α = 0 this number can be interpreted as the ratio of the spectral mass of the filter-output in the
passband relative to the spectral mass of the filter-output in the stopband : if a filter separates passband and stopband components better, then the Selectivity improves i.e. Selectivity(α) increases.
In practice, We have found that a broad user-community tends to prefer trend-estimates which
appear ‘smooth’ in visual terms i.e. with less noisy high-frequency ripples. Since high-frequency
noise components contaminate more heavily the filter-output (the derivative of a trigonometric
signal is proportional to frequency) We therefore propose to set α = 2 in 68: noisy high-frequency
components are then leveraged by their derivative (the square exponent reflects the fact that
Â(ωk )2 IT X (ωk ) addresses a mean-square term). Selectivity(2) matches preferences of a broad
user-community better than Selectivity(0). We now drop α = 2 in the above appellation and call
the resulting performance measure ‘Selectivity’, for short. In contrast to Smoothness, Selectivity
is immune to scaling effects of the amplitude i.e. it is invariant to a constant multiplying the
amplitude function.
With respect to time-shift performances We propose the following Mean-Shift statistic
X
1
Mean-Shift :=
φ̂(ωk )
Number of ωk in passband
(69)
Passband
ˆ is the time-shift function. Our focus on the passband in this latter measure is due to
where φ(·)
the fact that potentially interesting turning-points of a series are linked to passband-components:
therefore the Mean-Shift is an approximate measure of the relevant delay of a real-time filter. In
contrast to Timeliness, in which the amplitude and the time-shift are entangled, the Mean-Shift
is insensitive to the amplitude function.
In contrast to Timeliness and Smoothness components all presented measures are insensitive
to scaling effects of the output signal (multiplying the output by a positive constant), as desired.
7.1.3
A Link Between Curvature and Smoothness∗
A link between Smoothness and Curvature could be obtained by noting that
2
PT ŷ
−
2ŷ
+
ŷ
t
t−1
t−2
t=3
Curvature =
PT
2
t=1 (ŷt − ŷ)
PT /2
4
k=−T /2 |1 − exp(−iωk )| IT Ŷ (ωk )
≈
PT /2
k=−T /2 IT Ŷ (ωk )
157
where We used the decomposition 13 for the denominator and the convolution result 30 together
with the decomposition 13 for the numerator in the above quotient, noting that ŷt − 2ŷt−1 + ŷt−2
is the output of the second-order difference filter (applied to ŷt ) whose transferfunction is (1 −
exp(−iωk ))2 .
The customized Smoothness-term is defined as
2π X
(A(ωk ) − Â(ωk ))2 W2 (ωk )IT X (ωk )
S(moothness) :=
T
Stopband
:=
2π
T
≈
2π
T
X
Â(ωk )2 W2 (ωk )IT X (ωk )
Stopband
X
W2 (ωk )IT Ŷ (ωk )
Stopband
where We used the fact that A(ωk ) = 0 in the stopband and where Â(ωk )2 IT X (ωk ) ≈ IT Ŷ (ωk ) by
convolution 30. The numerator of Curvature differs from Smoothness by the respective weightingfunctions assigned to IT Ŷ (ωk )51 . Obviously, there is a link between both expressions.
7.1.4
R-Code: Performance Measures
The following function computes the ATS-components as well as the above time-domain and
frequency-domain performance measures: Curvature, Peak-Correlation, Selectivity and MeanShift. The periodogram will be based on a sample-length T = 120 (10 years of monthly data) but
time-domain performances will be computed on a much longer series (x1) of length 1000 such that
We can compute and compare in-sample and out-of-sample performances. The function computes
a whole bunch of results useful for evaluation:
• Real-time filters (Lag = 0) for designs specified in the vectors lambda vec and eta vec (We
can evaluate several designs at once).
• A symmetric (final) MSE-filter which is our reference for deriving peak-correlations.
• A theoretically best mean-square real-time filter, assuming knowledge of the true DGP, which
allows to benchmark customized designs in terms of out-of-sample performances.
• ATS-components and our four performance measures: Selectivity, Mean-Shift, Curvature
and Peak-Correlation.
>
>
>
>
>
>
>
>
>
+
+
+
+
+
+
+
# This function computes:
# 1. real-time and symmetric filters,
# 2. in- and out-of-sample performances: Selectivity, Mean-Shift, Curvature
#
and Peak-Correlation
# 3. the ATS error components
#
#----------#
Performance_func<-function(lambda_vec,eta_vec,len1,len,x1,weight_func,Gamma,
cutoff,L,L_sym,a1,mba)
{
K<-length(weight_func)-1
omega_k<-(0:K)*pi/K
#
amp<-matrix(ncol=length(lambda_vec)+1,nrow=K+1)
shift<-amp
51 Note
that both weighting-functions are monotonically increasing with frequency.
158
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
selectivity_insamp<-rep(NA,dim(amp)[2])
mean_shift_insamp<-rep(NA,dim(amp)[2])
curvature_insamp<-rep(NA,dim(amp)[2])
selectivity_outsamp<-rep(NA,dim(amp)[2])
mean_shift_outsamp<-rep(NA,dim(amp)[2])
curvature_outsamp<-rep(NA,dim(amp)[2])
b<-matrix(ncol=dim(amp)[2],nrow=L)
# Determine passband
omega_Gamma<-as.integer(cutoff*K/pi)+1
passband<-1:omega_Gamma
stopband<-(omega_Gamma+1):(K+1)
Accuracy<-rep(NA,dim(amp)[2])
Smoothness<-Accuracy
Timeliness<-Accuracy
Residual<-Accuracy
lag_cor<-0:10
peak_cor_insamp<-matrix(ncol=length(lag_cor),nrow=dim(amp)[2])
peak_cor_outsamp<-matrix(ncol=length(lag_cor),nrow=dim(amp)[2])
lag_max_insamp<-rep(NA,dim(amp)[2])
lag_max_outsamp<-rep(NA,dim(amp)[2])
xf<-matrix(nrow=len1,ncol=dim(amp)[2])
# Final symmetric MSE-filter
Lag_sym<-(L_sym-1)/2
lambda<-0
eta<-0
filt_sym<-dfa_analytic(L_sym,lambda,weight_func,Lag_sym,Gamma,eta,cutoff,i1,i2)
trffkt_sym<-filt_sym$trffkt
amp_sym<-abs(trffkt_sym)
shift_sym<-Arg(trffkt_sym)/omega_k
b_sym<-filt_sym$b
# Compute outputs on long sample
xf_sym<-rep(NA,len1)
for (j in (1+(L_sym-1)/2):(len1-(L_sym-1)/2))
xf_sym[j]<-b_sym%*%x1[(L_sym-1)/2+j:(j-L_sym+1)]
weight_func_best<-rep(1,K+1)/abs(1-a1*exp(1.i*omega_k))^2
#a1<-0
#
# Estimation loop for all eta/lambda values
for (i in 0:(dim(amp)[2]-1))
#i<-1
{
if (i==0)
{
if (mba)
{
dfa<-dfa_analytic(L,lambda,weight_func,Lag,Gamma,eta,cutoff,i1,i2)
} else
{
dfa<-dfa_analytic(L,lambda,weight_func_best,Lag,Gamma,eta,cutoff,i1,i2)
}
} else
{
dfa<-dfa_analytic(L,lambda_vec[i],weight_func,Lag,Gamma,eta_vec[i],cutoff,i1,i2)
}
159
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#
#
#
#
#
b[,i+1]<-dfa$b
#
amp[,i+1]<-abs(dfa$trffkt)
Selectivity: immunized against scaling effects
selectivity_insamp[i+1]<-(amp[1:(K*cutoff/pi),i+1]^2%*%weight_func[1:(K*cutoff/pi)])/
(amp[(K*cutoff/pi+1):(K+1),i+1]^2%*%(weight_func[(K*cutoff/pi+1):(K+1)]*
(1+(0:(K-K*cutoff/pi)))^2))
shift[1+1:K,i+1]<-Arg(dfa$trffkt)[1+1:K]/((pi*1:K)/K)
Shift in frequency zero
shift[1,i+1]<-b[,i+1]%*%(0:(L-1))/amp[1,i+1]
Mean-shift statistic: immunized against scaling effects
mean_shift_insamp[i+1]<-mean(shift[1:(K*cutoff/pi),i+1])
amp_error<-((Gamma-amp[,i+1]))^2*weight_func
shift_error<-4*Gamma*amp[,i+1]*sin(shift[,i+1]*omega_k/2)^2*weight_func
Accuracy[i+1]<-sum(amp_error[passband])
Smoothness[i+1]<-sum(amp_error[stopband])
Timeliness[i+1]<-sum(shift_error[passband])
Residual[i+1]<-sum(shift_error[stopband])
yhat<-rep(NA,len1)
for (j in L:len1)
yhat[j]<-b[,i+1]%*%x1[j:(j-L+1)]
xf[,i+1]<-yhat
Relative Curvature (immunized against scaling effects)
curvature_insamp[i+1]<-mean(diff(yhat[1:len],diff=2)^2,na.rm=T)/
var(yhat[1:len],na.rm=T)
curvature_outsamp[i+1]<-mean(diff(yhat[(len+1):len1],diff=2)^2,na.rm=T)/
var(yhat[(len+1):len1],na.rm=T)
for (j in lag_cor)
#j<-0
{
if (!mba)
peak_cor_insamp[i+1,j+1]<-cor(xf_sym[(1+(L_sym-1)/2):len],
yhat[j+((L_sym-1)/2+1):len])
peak_cor_outsamp[i+1,j+1]<-cor(xf_sym[(len+1):(len1-L_sym)],
yhat[j+(len+1):(len1-L_sym)])
}
if (!mba)
lag_max_insamp[i+1]<-which(peak_cor_insamp[i+1,]==max(peak_cor_insamp[i+1,]))-1
lag_max_outsamp[i+1]<-which(peak_cor_outsamp[i+1,]==max(peak_cor_outsamp[i+1,]))-1
}
Rownames
if (!mba)
{
dim_names<-c("Theoretical best MSE",paste("Lambda=",lambda_vec,", eta=",eta_vec,sep=""))
if (prod(lambda_vec*eta_vec)==0)
{
dim_names[1+which(lambda_vec==0&eta_vec==0)]<-"DFA-MSE"
}
} else
{
dim_names<-c("MBA-MSE",paste("Lambda=",lambda_vec,", eta=",eta_vec,sep=""))
}
dimnames(xf)[[2]]<-dim_names
dimnames(amp)[[2]]<-dim_names
dimnames(shift)[[2]]<-dim_names
160
+
dimnames(b)[[2]]<-dim_names
+ #
+ # We collect all frequency-domain performance statistics in corresponding tables
+
if (!mba)
+
{
+
amp_shift_mat_insamp<-cbind(selectivity_insamp,mean_shift_insamp,
+
curvature_insamp,lag_max_insamp)
+
dimnames(amp_shift_mat_insamp)[[2]]<-c("Selectivity","Mean-shift",
+
"Curvature","Peak-Correlation lag")
+
dimnames(amp_shift_mat_insamp)[[1]]<-dim_names
+
} else
+
{
+
amp_shift_mat_insamp<-cbind(selectivity_insamp,mean_shift_insamp)
+
dimnames(amp_shift_mat_insamp)[[2]]<-c("Selectivity","Mean-shift")
+
dimnames(amp_shift_mat_insamp)[[1]]<-dim_names
+
}
+
amp_shift_mat_outsamp<-cbind(curvature_outsamp,lag_max_outsamp)
+
dimnames(amp_shift_mat_outsamp)[[1]]<-dim_names
+
if (mba)
+
{
+
dimnames(amp_shift_mat_outsamp)[[2]]<-c("Curvature","Peak-Correlation")
+
} else
+
{
+
dimnames(amp_shift_mat_outsamp)[[2]]<-c("Curvature (out-of-sample)",
+
"Peak-Correlation (out-of-sample)")
+
dimnames(amp_shift_mat_outsamp)[[1]]<-dim_names
+
}
+
+
ats_mat<-cbind(Accuracy,Timeliness,Smoothness,Residual,
+
Accuracy+Timeliness+Smoothness+Residual)
+
dimnames(ats_mat)[[2]][dim(ats_mat)[2]]<-"Total MSE"
+
dimnames(ats_mat)[[1]]<-dim_names
+
return(list(xf=xf,amp_shift_mat_insamp=amp_shift_mat_insamp,
+
amp_shift_mat_outsamp=amp_shift_mat_outsamp,
+
ats_mat=ats_mat,amp=amp,shift=shift,b=b,xf_sym=xf_sym))
+ }
7.2
MSE-Criterion
The material on this topic has been presented in sections 4.1.1 (real-time performances, smoothing,
overfitting and finite-sample distributions of filter-coefficients, amplitude and time-shift functions)
and 4.2 (revisions, vintage triangle, tentacle plot). For this purpose we relied on a simpler DFAMSE estimation routine df a ms, proposed in section 4.1.1, which can be replicated perfectly by
the new more general function df a analytic.
Therefore we here limit Ourself to computing two MSE-filters which will be used as benchmarks
for evaluating customized designs: the ordinary DFA MSE-solution (λ = η = 0 in 59 or 63) and the
best theoretical MSE-filter, assuming knowledge of the true DGP: the latter in particular should
be an irrefutable (because slightly unfair) candidate for out-of-sample evaluation of customized
designs.
161
7.2.1
Empirical setting
In order to comply with the problem structure of some practically relevant and challenging
real-time applications (real-time economic indicators, financial trading) We here rely on a ‘flatspectrum’ white-noise input process: something that will not be too far away from log-returns of
typical (seasonally adjusted) macro- or financial data:
xt
= t
Targeting the low-frequency trend-growth in log-returns of economic data allows to track turningpoints, if done properly. For simplicity We here assume monthly data and track the synthetic
output of a bi-infinite ideal lowpass with cutoff π/12
1 |ωk | < π/12
Γ(ωk ) =
0 otherwise
in real-time. The cutoff-frequency π/12 means that We attempt to eliminate components whose
2π
= 24 time-units: this is a reasonable setting for economic-monitoring since
duractions exceeds π/12
the duration of business-cycles is typically above 2 years52 . This is a very tough but practically
relevant estimation problem!
In the following R-chunk We generate a realization of length 1000 of a standardized white
noise: the first T = 120 observations are used for in-sample estimation. We also define the target
signal.
>
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
>
>
>
>
>
>
>
>
>
# Generate series
gen_ser<-function(setseed,len,len1,cutoff_period)
{
set.seed(setseed)
# The longer sample is used for implementing the symmetric filter and
# for computing peak-correlations
x1<-rnorm(len1)
# The shorter sample of length 120 is used for estimating the real-time filter
x<-x1[1:len]
plot_T<-F
yhat<-x
Gamma<-c(1,(1:(len/2))<len/(2*cutoff_period))
# Compute periodogram (in-sample)
weight_func<-per(x,plot_T)$per
K<-length(weight_func)-1
omega_k<-(0:K)*pi/K
return(list(omega_k=omega_k,x1=x1,x=x,Gamma=Gamma,weight_func=weight_func))
}
#
setseed<-10
len<-120
len1<-1000
cutoff_period<-12
cutoff<-pi/cutoff_period
#
gen_obj<-gen_ser(setseed,len,len1,cutoff_period)
#
52 Omitting the double-dip in the early 80’s We observe that recessions are generally separated by more than two
years in historical data.
162
>
>
>
>
>
>
x1<-gen_obj$x1
x<-gen_obj$x
omega_k<-gen_obj$omega_k
Gamma<-gen_obj$Gamma
weight_func<-gen_obj$weight_func
K<-length(weight_func)-1
7.2.2
Unconstrained MSE-Solution
We compute a real-time MSE estimate ŷt based on the MSE-criterion 49, applying a real-time
filter of length L = 2453 . We also compute a symmetric (final) MSE-filter of length L = 61
(for computing peak-correlations) as well as the theoretically best real-time MSE-filter of length
L = 24 (assuming knowledge of the true DGP: white noise). The following R-chunk initializes the
filter design.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
# Generate series
L_sym<-61
L<-24
# Specify filter settings
Lag<-0
# No filter restrictions
i1<-i2<-F
# Optimize unconstrained real-time MSE-filter
eta_vec<-0
lambda_vec<-0
# True DGP: white noise spectrum
a1<-0
# mba<-T is used when replicating model-based approaches later on
mba<-F
We can now proceed to estimation and evaluation of the MSE-solution.
>
>
>
+
>
>
>
>
>
>
# Start processing
#
perf<-Performance_func(lambda_vec,eta_vec,len1,len,x1,weight_func,
Gamma,cutoff,L,L_sym,a1,mba)
xf<-perf$xf
amp_shift_mat_insamp<-perf$amp_shift_mat_insamp
amp_shift_mat_outsamp<-perf$amp_shift_mat_outsamp
ats_mat<-perf$ats_mat
amp<-perf$amp
shift<-perf$shift
Input and output series as well as periodograms thereof and amplitude/time-shift functions are
plotted in fig.59.
>
>
>
>
>
>
>
colo<-rainbow(dim(xf)[2])
file = paste("z_dfa_ar1_output_e.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,2))
ts.plot(x,main="DFA (red) and theoretical MSE (cyan) vs. input (black)",col="black")
mtext("Input", side = 3, line = -1,at=len/2,col="black",ylab="series")
for (i in 1:dim(xf)[2])
53 Shorter filters are unable to damp sufficiently well components of frequency close to the cutoff π/12 and longer
filters are possibly subject to overfitting, recall table 4.
163
+
+
+
+
>
+
>
>
>
>
>
>
>
+
>
>
+
+
+
+
>
>
>
>
+
>
>
+
+
+
+
>
>
>
>
{
lines(xf[,i],col=colo[i])
mtext(dimnames(xf)[[2]][i], side = 3, line = -i-1,at=len/2,col=colo[i])
}
plot(per(x[L:len],plot_T)$per,type="l",axes=F,col="black",ylim=c(0,max(amp)),
ylab="Periodogram",xlab="",main="Periodograms")
mtext("Input", side = 3, line = -1,at=(K-L/2)/2,col="black")
lines(per(xf[L:len,2],plot_T)$per,lty=1,col="red")
mtext("MSE-Output", side = 3, line = -2,at=(K-L/2)/2,col="red")
axis(1,at=1+0:6*(K-L/2)/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(Gamma,type="l",axes=F,col="black",ylim=c(0,max(amp,1)),ylab="",xlab="",
main=paste("Amplitude MSE-Filter: L=",L,sep=""))
mtext("Target", side = 3, line = -1,at=K/2,col="black")
for (i in 1:dim(xf)[2])
{
lines(amp[,i],col=colo[i])
mtext(dimnames(amp)[[2]][i], side = 3, line = -i-1,at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(rep(0,K+1),type="l",axes=F,col="black",ylim=c(0,max(na.exclude(shift[2:(K+1),]))),
ylab="",xlab="",main=paste("Shift MSE-Filter: L=",L,sep=""))
mtext("Target", side = 3, line = -1,at=K/2,col="black")
for (i in 1:dim(xf)[2])
{
lines(shift[,i],col=colo[i])
mtext(dimnames(shift)[[2]][i], side = 3, line = -i-1,at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
164
Input
MSE−Output
0.4
0.0
0.2
1
0
−2
−1
x
0.6
Input
Theoretical best MSE
DFA−MSE
Periodogram
Periodograms
2
DFA (red) and theoretical MSE (cyan) vs. input (black)
0
20
40
60
80
120
0
pi/6
3pi/6
5pi/6
Time
Target
Theoretical best MSE
DFA−MSE
Target
Theoretical best MSE
DFA−MSE
0
0.0
1
2
0.4
3
4
5
Shift MSE−Filter: L=24
0.8
Amplitude MSE−Filter: L=24
0
pi/6
3pi/6
5pi/6
0
pi/6
3pi/6
5pi/6
Figure 59: Inputs (blue) and real-time lowpass MSE output (red) (top left); periodograms (top
right); amplitude functions (bottom left) and time-shifts (bottom right): the theoretically best
filter (blue) assumes knowledge of the DGP (white noise)
We observe that the rea-time amplitude functions (bottom left) are noticeably smaller than one in
the passband. As an effect, the periodogram of the filtered output (top right) is smaller than the
periodogram of the input in the passband. The time-shift (bottom right) is somewhere between 2.4
and 4.7 time-units in the passband. As an effect, the output (top left) is delayed. The amplitude
(bottom left) attempts to ‘eliminate’ undesirable high-frequency components: the damping is not
excessively heavy, though marked, in the stopband. As a result We still observe tiny spectral mass
in the stop-band of the periodogram (top right) and the output series (top left) is still slightly
noisy (undesirable high-frequency ripples). These issues can and will be addressed by systematic
customization of Timeliness and Smoothness error components, see below.
165
7.2.3
Constrained MSE-Solutions: i1 and i2 Constraints
The input parameters i1 and i2 in the head of the function df a analytic allow to impose filter
constraints in frequency zero:
• i1 < −T imposes an amplitude-match Â(0) = Γ(0)
• i2 < −T imposes a vanishing time-shift φ̂(0) = 0.
Both constraints can be combined, too, and We now estimate filters for all four combinations.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
# i1 restriction only (not i2)
i1<-T
i2<-F
# Compute filter and performances
perf<-Performance_func(lambda_vec,eta_vec,len1,len,x1,weight_func,Gamma,cutoff,L,L_sym,a1,mba)
xf_i1<-perf$xf
amp_i1<-perf$amp
shift_i1<-perf$shift
#
# i2 restriction only (not (i1)
i1<-F
i2<-T
perf<-Performance_func(lambda_vec,eta_vec,len1,len,x1,weight_func,Gamma,cutoff,L,L_sym,a1,mba)
xf_i2<-perf$xf
amp_i2<-perf$amp
shift_i2<-perf$shift
#
# i1 and i2 restrictions
i1<-T
i2<-T
perf<-Performance_func(lambda_vec,eta_vec,len1,len,x1,weight_func,Gamma,cutoff,L,L_sym,a1,mba)
xf_i1i2<-perf$xf
amp_i1i2<-perf$amp
shift_i1i2<-perf$shift
We now plot and compare amplitude and time-shift functions54 , see fig.60.
>
>
>
>
>
>
+
>
>
>
>
>
>
>
>
>
#
# Generate graphs
file = paste("z_dfa_ar1_output_ee.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(1,2))
plot(Gamma,type="l",axes=F,col="black",ylim=c(0,max(amp_i1i2,1)),
ylab="",xlab="",main="Amplitude")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
lines(amp[,2],lty=1,col="red")
lines(amp_i1[,2],lty=1,col="orange")
lines(amp_i2[,2],lty=1,col="green")
lines(amp_i1i2[,2],lty=1,col="violet")
mtext("Amplitude i1=i2=F", side = 3, line = -2,at=K/2,col="red")
mtext("Amplitude i1=T,i2=F", side = 3, line = -3,at=K/2,col="orange")
mtext("Amplitude i1=F,i2=T", side = 3, line = -4,at=K/2,col="green")
mtext("Amplitude i1=i2=T", side = 3, line = -5,at=K/2,col="violet")
54 The
time-shift in frequency zero is computed according to 24.
166
>
>
>
>
+
>
>
>
>
>
>
>
>
>
>
>
>
>
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(rep(0,K+1),type="l",axes=F,col="black",ylim=c(0,max(na.exclude(shift_i1))),
ylab="",xlab="",main="Shift")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
lines(shift[,2],lty=1,col="red")
lines(shift_i1[,2],lty=1,col="orange")
lines(shift_i2[,2],lty=1,col="green")
lines(shift_i1i2[,2],lty=1,col="violet")
mtext("Shift i1=i2=F", side = 3, line = -2,at=K/2,col="red")
mtext("Shift i1=T,i2=F", side = 3, line = -3,at=K/2,col="orange")
mtext("Shift i1=F,i2=T", side = 3, line = -4,at=K/2,col="green")
mtext("Shift i1=i2=T", side = 3, line = -5,at=K/2,col="violet")
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
Shift
Target
Amplitude i1=i2=F
Amplitude i1=T,i2=F
Amplitude i1=F,i2=T
Amplitude i1=i2=T
Target
Shift i1=i2=F
Shift i1=T,i2=F
Shift i1=F,i2=T
Shift i1=i2=T
5
6
Amplitude
0
0.0
1
0.2
0.4
2
0.6
3
0.8
4
1.0
1.2
null device
1
0
2pi/6
4pi/6
pi
0
2pi/6
4pi/6
pi
Figure 60: Effect of Filter restrictions in frequency zero on amplitude and time-shifts. Input:
white noise.
The amplitude functions of the filters with i1<-T (orange and violet) start in Γ(0) = 1, as desired,
and the shifts of the two filters with i2<-T (green and violet) start in zero, as expected. These
features – restrictions – were less effective in the context of SA because unrestricted filters are close
167
to identities in the passband and therefore both restrictions are closed to be satisfied anyway. In
the context of real-time trend extraction, however, real-time filters can substantially deviate from
the target in frequency zero. Depending on the particular application, frequency zero may (or may
not) deserve special care and attention by imposing i1 and/or i2: as an example, tracking the level
of the trend of a non-stationary series might benefit from these restrictions55 . In most applications
We find the i2-restriction (vanishing time-shift) potentially more interesting because it complies
with a faster detection of turning-points. All the following examples are based on unconstrained
filters i1 = i2 = F .
7.2.4
Revision Sequence: Vintage Triangle
We did not found any relevant practical application of revision sequences in the context of trendextraction so far and therefore We skip this topic. Interested readers are referred to sections 4.2
and 4.2.3 for corresponding empirical material.
7.3
Customization: Enhancing Either Speed or Noise-suppression (TimelinessSmoothness Dilemma)
Now that We have Our benchmark MSE-filter at disposal, We can proceed to customization of
the real-time trend filter by selecting λ > 0 or η > 0 in the general criterion 63. We first illustrate
the effect of η, fixing λ = 0: this is the ‘Smoothness only’ experiment. The ‘Timeliness only’
experiment is then obtained by fixing η = 0 and increasing λ. By addressing a single dimension
only We allow the MSE-mass to ‘circulate freely’ among the other two error components in the
ATS-trilemma: therefore, We expect to observe classical dilemma at work.
7.3.1
Emphasizing Smoothness Only
We fix λ = 0 and compute real-time filters for η from 0 to 1.5 by incremental steps of 0.25.
>
>
>
>
>
>
>
>
>
>
>
>
>
eta_vec<-(0:6)/4
lambda_vec<-rep(0,length(eta_vec))
i1<-F
i2<-F
# Compute in/out-of-sample performances
perf<-Performance_func(lambda_vec,eta_vec,len1,len,x1,weight_func,Gamma,cutoff,L,L_sym,a1,mba)
xf<-perf$xf
amp_shift_mat_insamp<-perf$amp_shift_mat_insamp
amp_shift_mat_outsamp<-perf$amp_shift_mat_outsamp
ats_mat<-perf$ats_mat
amp<-perf$amp
shift<-perf$shift
Filter outputs, amplitude and time-shift functions are plotted in fig.61.
>
>
>
>
>
>
#
# Plots
colo<-rainbow(2*dim(amp)[2])
file = paste("z_dfa_cust_amp.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(1,2))
55 Formally, i1 < −T is necessary to ensure a finite mean-square filter error when the DGP of the input signal
is I(1) with a single unit-root in frequency zero. Both restrictions i1 < −i2 < −T are necessary when the DGP is
I(2) with a double root in frequency zero. However, We are not interested in ‘unit-roots’ or DGP’s and therefore
We impose these restrictions, in any possible combination, when felt useful or practically relevant.
168
>
>
>
+
+
+
+
>
>
>
>
+
>
>
+
+
+
+
>
>
>
>
plot(Gamma,type="l",axes=F,col="black",ylim=c(0,1),ylab="",xlab="",main="Amplitude")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
for (i in 1:dim(amp)[2])
{
lines(amp[,i],lty=1,col=colo[i])
mtext(dimnames(amp)[[2]][i], side = 3, line = -1-i,at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(rep(0,K+1),type="l",axes=F,col="black",ylim=c(0,max(na.exclude(shift))),
ylab="",xlab="",main="Shift")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
for (i in 1:dim(amp)[2])
{
lines(shift[,i],lty=1,col=colo[i])
mtext(dimnames(shift)[[2]][i], side = 3, line = -1-i,at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
Shift
Target
Theoretical best MSE
DFA−MSE
Lambda=0, eta=0.25
Lambda=0, eta=0.5
Lambda=0, eta=0.75
Lambda=0, eta=1
Lambda=0, eta=1.25
Lambda=0, eta=1.5
Target
Theoretical best MSE
DFA−MSE
Lambda=0, eta=0.25
Lambda=0, eta=0.5
Lambda=0, eta=0.75
Lambda=0, eta=1
Lambda=0, eta=1.25
Lambda=0, eta=1.5
6
8
Amplitude
0
0.0
0.2
2
0.4
4
0.6
0.8
1.0
null device
1
0
2pi/6
4pi/6
pi
0
2pi/6
4pi/6
pi
Figure 61: Customized filters: the effect of eta (strength of noise supression/smoothness) on
amplitude and time-shifts (delays)
169
The amplitude functions decrease (approach zero) monotonically in the stopband with increasing
η, as desired. An undesirable side-effect is that the amplitudes are also slightly pulled-down in the
passband but this effect could be compensated either by rescaling the output series (for example
by 1/Â(0)) or by imposing i1<-T: in applications, We generally prefer the former scaling because
it does not affect the effective filter properties. Note that the performance measures proposed in
section 7.1 were explicitly immunized against ‘amplitude-shrinkage’: either by computing relative
numbers or by disentangling the time-shift from the amplitude.
7.3.2
Dilemma: Timeliness vs. Smoothness, Selectivity vs. Mean-Shift and Curvature vs. Peak-Correlation
Table 8 reports the ATS-components, based on 55. The Residual vanishes because the target
Theoretical best MSE
DFA-MSE
Lambda=0, eta=0.25
Lambda=0, eta=0.5
Lambda=0, eta=0.75
Lambda=0, eta=1
Lambda=0, eta=1.25
Lambda=0, eta=1.5
Accuracy
0.137
0.099
0.132
0.173
0.221
0.272
0.321
0.366
Timeliness
0.118
0.133
0.149
0.167
0.186
0.208
0.232
0.251
Smoothness
0.140
0.138
0.100
0.072
0.050
0.033
0.021
0.013
Residual
0.000
0.000
0.000
0.000
0.000
0.000
0.000
0.000
Total MSE
0.395
0.370
0.381
0.412
0.457
0.514
0.574
0.631
Table 8: ATS-components: emphasizing Smoothness only
filter vanishes in the stop-band. As expected, the Smoothness error-component decreases and
the Timeliness-component increases with increasing η. Also, Accuracy increases monotonically
because larger η shrink the amplitude function in the passband, see fig.61. Finally, the total MSE
(the sum of the ATS-components) increases because stronger customization takes us ‘farther away’
from the MSE-filter. Note that ‘Total MSE’ of the DFA filter is smaller than for the best possible
MSE-design because We optimized Our criterion accordingly: We thus observe overfitting. Also,
the ‘total MSE’ of the customized designs could be significantly reduced by simple scaling in order to compensate for the observed amplitude-shrinkage in the passband (but since We are not
interested in MSE-performances of these designs We left this an exercise).
Table 9 provides additional in-sample evidence based on Our set of performance-measures:
larger η lead to better Selectivity at costs of larger Mean-Shift or, alternatively, smaller curvature
at costs of increasing peak-correlation lag: three different dilemma anchored in the same fundamental tradeoff. As expected, the Mean-Shift is closely linked to Peak-Correlation. Out-of-sample
Theoretical best MSE
DFA-MSE
Lambda=0, eta=0.25
Lambda=0, eta=0.5
Lambda=0, eta=0.75
Lambda=0, eta=1
Lambda=0, eta=1.25
Lambda=0, eta=1.5
Selectivity
0.021
0.018
0.033
0.059
0.107
0.203
0.392
0.734
Mean-shift
3.126
2.535
3.166
3.975
4.941
6.005
7.079
8.065
Curvature
0.197
0.238
0.132
0.074
0.041
0.021
0.011
0.005
Peak-Correlation lag
4.000
3.000
4.000
5.000
5.000
6.000
7.000
8.000
Table 9: In-sample performance measures: Selectivity vs. Mean-Shift and Curvature vs. PeakCorrelation: emphasizing Smoothness only
170
performances in table 10 confirm consistently the previous findings. We now briefly compare the
Theoretical best MSE
DFA-MSE
Lambda=0, eta=0.25
Lambda=0, eta=0.5
Lambda=0, eta=0.75
Lambda=0, eta=1
Lambda=0, eta=1.25
Lambda=0, eta=1.5
Curvature (out-of-sample)
0.234
0.379
0.216
0.123
0.068
0.036
0.018
0.009
Peak-Correlation (out-of-sample)
4.000
4.000
4.000
5.000
5.000
6.000
7.000
8.000
Table 10: Out-of-sample performance measures: Selectivity vs. Mean-Shift and Curvature vs.
Peak-Correlation: emphasizing Smoothness only
filter outputs of MSE (η = 0) and strongly customized (η = 1.5) filters, see fig.62.
>
>
>
>
>
>
>
+
+
+
>
>
>
+
>
#------------------# Compare MSE and heavily customized filter
xf0<-xf[L+1:len,1]
xf1<-xf[L+1:len,dim(amp)[2]]
file = paste("z_dfa_cust_amp_out_iut.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
ts.plot(as.ts(xf0),type="l",axes=F,col=colo[1],ylim=c(min(na.exclude(xf0)),
max(na.exclude(xf0))),
ylab="",xlab="",main=paste("Filter outputs: MSE (eta=0) vs. customized (eta=",
eta_vec[length(eta_vec)],")",sep=""))
mtext("MSE (eta=0)", side = 3, line = -1,at=len/2,col=colo[1])
lines(as.ts(xf1),col=colo[dim(amp)[2]])
mtext(paste("Customized (eta=",eta_vec[length(eta_vec)],")",sep=""),
side = 3, line = -2,at=len/2,col=colo[dim(amp)[2]])
dev.off()
null device
1
171
0.4
Filter outputs: MSE (eta=0) vs. customized (eta=1.5)
−0.6
−0.4
−0.2
0.0
0.2
MSE (eta=0)
Customized (eta=1.5)
0
20
40
60
80
100
120
Figure 62: Filter outputs: MSE vs. customized
As expected, the output of the customized filter is substantially smoother but turning-points are
delayed in comparison to the MSE-filter (table 9 suggests a time differential of approximately 5
time-units) which confirms, once again, the Timeliness-Smoothness dilemma. We notice the different scales as a consequence of the amplitude-shrinkage (which explains part of the larger ‘total
MSE’ of customized filters).
7.3.3
Emphasizing Timeliness Only
We here fix η = 0 and compute real-time filters for λ = 0, 1, 2, 4, 8, 16. Since η is fixed We expect
to observe the classical dilemma between Smoothness and Timeliness (Selectivity and Mean-Shift,
Curvature and Peak-Correlation): still no use of the full potential beared in the trilemma!
>
>
>
>
>
>
>
>
>
>
>
>
>
lambda_vec<-c(0,2^(0:4))
eta_vec<-rep(0,length(lambda_vec))
i1<-F
i2<-F
# Compute in/out-of-sample performances
perf<-Performance_func(lambda_vec,eta_vec,len1,len,x1,weight_func,Gamma,cutoff,L,L_sym,a1,mba)
xf<-perf$xf
amp_shift_mat_insamp<-perf$amp_shift_mat_insamp
amp_shift_mat_outsamp<-perf$amp_shift_mat_outsamp
ats_mat<-perf$ats_mat
amp<-perf$amp
shift<-perf$shift
172
Filter outputs, amplitude and time-shift functions are plotted in fig.63.
>
>
>
>
>
>
>
>
>
+
+
+
+
+
>
>
>
>
+
>
>
+
+
+
+
+
>
>
>
>
#
# Plots
colo<-rainbow(2*dim(amp)[2])
file = paste("z_dfa_cust_shift.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(1,2))
plot(Gamma,type="l",axes=F,col="black",ylim=c(0,1),ylab="",xlab="",main="Amplitude")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
for (i in 1:dim(amp)[2])
{
lines(amp[,i],lty=1,col=colo[i])
mtext(dimnames(amp)[[2]][i], side = 3, line = -1-i,
at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(rep(0,K+1),type="l",axes=F,col="black",ylim=c(min(shift),max(na.exclude(shift))),
ylab="",xlab="",main="Shift")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
for (i in 1:dim(amp)[2])
{
lines(shift[,i],lty=1,col=colo[i])
mtext(dimnames(shift)[[2]][i], side = 3,
line = -1-i,at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
173
Target
Theoretical best MSE
DFA−MSE
Lambda=1, eta=0
Lambda=2, eta=0
Lambda=4, eta=0
Lambda=8, eta=0
Lambda=16, eta=0
Target
Theoretical best MSE
DFA−MSE
Lambda=1, eta=0
Lambda=2, eta=0
Lambda=4, eta=0
Lambda=8, eta=0
Lambda=16, eta=0
4
5
Shift
0.0
−1
0
0.2
1
0.4
2
3
1.0
0.8
0.6
Amplitude
0
2pi/6
4pi/6
pi
0
2pi/6
4pi/6
pi
Figure 63: Customized filters: emphasize timeliness
As λ increases, the time-shift decreases, as desired. The effect on the amplitude functions is
interesting: whereas the stopband remains more or less unaffected, the amplitudes are shrunken
in the passband56 . As a result, Selectivity must worsen (with increasing λ).
7.3.4
Dilemma: Selectivity vs. Mean-Shift and Timeliness vs.
Curvature vs. Peak-Correlation
Smoothness and
Table 11 reports the ATS-components. As expected, the Timeliness error-component decreases
Theoretical best MSE
DFA-MSE
Lambda=1, eta=0
Lambda=2, eta=0
Lambda=4, eta=0
Lambda=8, eta=0
Lambda=16, eta=0
Accuracy
0.137
0.099
0.162
0.206
0.263
0.324
0.376
Timeliness
0.118
0.133
0.083
0.059
0.035
0.017
0.007
Smoothness
0.140
0.138
0.139
0.142
0.149
0.160
0.172
Residual
0.000
0.000
0.000
0.000
0.000
0.000
0.000
Total MSE
0.395
0.370
0.384
0.407
0.447
0.501
0.555
Table 11: ATS-components: emphasizing Timeliness only
and the Smoothness-component increases with increasing λ. Also, Accuracy increases because the
amplitude functions are shrunken in the passband, see fig.63. Finally, total MSE (sum of ATScomponents) increases because stronger customization takes us ‘farther away’ from the MSE-filter
56 This is because λ in 63 magnifies the imaginary part of the real-time filter: by shrinking the amplitude, the
imaginary part is automatically shrunken, too.
174
(part of this undesirable MSE-increase could be avoided by simple scaling in order to compensate
for the shrinkage-phenomenon but We do not address this topic because customized filters are not
explicitly designed for MSE-performances).
Table 12 confirms these in-sample findings: larger λ lead to worse Selectivity at the benefit of
smaller Mean-Shift or worse Curvature at the benefit of smaller Peak-Correlation lag. Once again,
We sollicited dichotomic tradeoffs. Out-of-sample performances in table 13 confirm consistently
Theoretical best MSE
DFA-MSE
Lambda=1, eta=0
Lambda=2, eta=0
Lambda=4, eta=0
Lambda=8, eta=0
Lambda=16, eta=0
Selectivity
0.021
0.018
0.013
0.010
0.008
0.006
0.004
Mean-shift
3.126
2.535
1.709
1.295
0.909
0.647
0.512
Curvature
0.197
0.238
0.309
0.365
0.446
0.540
0.623
Peak-Correlation lag
4.000
3.000
3.000
3.000
2.000
1.000
0.000
Table 12: In-sample performances measures: Selectivity vs. Mean-Shift and Curvature vs. PeakCorrelation: emphasizing Timeliness only
in-sample findings.
Theoretical best MSE
DFA-MSE
Lambda=1, eta=0
Lambda=2, eta=0
Lambda=4, eta=0
Lambda=8, eta=0
Lambda=16, eta=0
Curvature (out-of-sample)
0.234
0.379
0.498
0.592
0.730
0.891
1.029
Peak-Correlation (out-of-sample)
4.000
4.000
3.000
3.000
2.000
1.000
1.000
Table 13: Out-of-sample performances measures: Selectivity vs. Mean-Shift and Curvature vs.
Peak-Correlation: emphasizing Timeliness only
We now briefly compare the filter outputs of MSE (η = λ = 0) and heavily customized
(λ = 16, η = 0) filters, see fig.64.
>
>
>
>
>
>
>
+
>
>
>
>
#------------------# Compare MSE and heavily customized filter
xf0<-xf[L+1:len,1]
xf1<-xf[L+1:len,dim(amp)[2]]
file = paste("z_dfa_cust_amp_out_puti.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
ts.plot(as.ts(xf0),type="l",axes=F,col=colo[1],ylim=c(min(na.exclude(xf1)),max(na.exclude(xf1))
main="Filter outputs: MSE (lambda=0) vs. customized (lambda=16)")
mtext("MSE (lambda=0)", side = 3, line = -1,at=len/2,col=colo[1])
lines(as.ts(xf1),col=colo[dim(amp)[2]])
mtext("Customized (lambda=16)", side = 3, line = -2,at=len/2,col=colo[dim(amp)[2]])
dev.off()
null device
1
175
Filter outputs: MSE (lambda=0) vs. customized (lambda=16)
−0.4
−0.2
0.0
0.2
0.4
MSE (lambda=0)
Customized (lambda=16)
0
20
40
60
80
100
120
Figure 64: Filter outputs: MSE vs. customized
As expected, the customized filter (green) is faster but noisier than the MSE-filter (red). We
now proceed to a more sophisticated estimation problem, namely tackling the time-shift in the
passband and the amplitude function in the stop-band simultaneously: we’ll make use of the full
potential of the ATS-Trilemma.
7.4
7.4.1
Customization: Enhancing Speed And Smoothness in the ATSTrilemma
Experimental Design
We here select η > 0 and λ > 0, compute corresponding real-time filters of length L = 24 and
compare performances with the previously obtained MSE-design η = λ = 0 (L = 24). Specifically
We analyze the following three customized filters
• λ = 32, η = 1: a filter which emphasizes Timeliness as well as Smoothness more or less
heavily.
• λ = 100, η = 0.7: a filter which prioritizes strongly Timeliness, though Smoothness is
emphasized too.
• λ = 8, η = 1.5: a filter which prioritizes Smoothness over Timeliness.
We then compute in-sample as well as ‘true’ out-of-sample performances as referenced against the
DFA-MSE and the best theoretical MSE-filter (assuming knowledge of the DGP).
7.4.2
In-Sample Analysis: Frequency-Domain Statistics
We proceed to estimation:
176
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
# Filter length
L<-24
# No filter restrictions
i1<-F
i2<-F
# Designs: MSE and two customized filters
lambda_vec<-c(0,32,100,8)
eta_vec<-c(0,1,0.7,1.5)
mba<-F
# Compute in/out-of-sample performances
perf<-Performance_func(lambda_vec,eta_vec,len1,len,x1,weight_func,Gamma,cutoff,L,L_sym,a1,mba)
xf<-perf$xf
amp_shift_mat_insamp<-perf$amp_shift_mat_insamp
amp_shift_mat_outsamp<-perf$amp_shift_mat_outsamp
ats_mat<-perf$ats_mat
amp<-perf$amp
shift<-perf$shift
xf_sym<-perf$xf_sym
Amplitude and time-shift functions of the real-time filters are plotted in fig.65.
>
>
>
>
>
>
>
>
>
+
+
+
+
+
>
>
>
>
+
>
>
+
+
+
+
+
>
>
>
>
#
# Plots
colo<-rainbow(dim(amp)[2])
file = paste("z_dfa_cust_ats.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(1,2))
plot(Gamma,type="l",axes=F,col="black",ylim=c(0,1),ylab="",xlab="",main="Amplitude")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
for (i in 1:dim(amp)[2])
{
lines(amp[,i],lty=1,col=colo[i])
mtext(dimnames(amp)[[2]][i], side = 3,
line = -1-i,at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(rep(0,K+1),type="l",axes=F,col="black",ylim=c(min(shift),max(na.exclude(shift))),
ylab="",xlab="",main="Shift")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
for (i in 1:dim(amp)[2])
{
lines(shift[,i],lty=1,col=colo[i])
mtext(dimnames(shift)[[2]][i], side = 3,
line = -1-i,at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
177
Target
Theoretical best MSE
DFA−MSE
Lambda=32, eta=1
Lambda=100, eta=0.7
Lambda=8, eta=1.5
6
Target
Theoretical best MSE
DFA−MSE
Lambda=32, eta=1
Lambda=100, eta=0.7
Lambda=8, eta=1.5
4
1.0
Shift
0.0
0
0.2
0.4
2
0.6
0.8
Amplitude
0
2pi/6
4pi/6
pi
0
2pi/6
4pi/6
pi
Figure 65: MSE vs. customized filters: emphasize timeliness and smoothness simultaneously
The relatively strong Timeliness-Smoothness weights λ, η assigned to all three customized filters shrinks their amplitudes towards zero in the passband which is not really an issue since We
could easily re-scale all outputs by the inverse amplitude functions 1/Âi (0) in frequency zero.
As explained previously, Our performance measures were specifically immunized against this customization effect.
7.4.3
Trilemma: Improving Selectivity and Mean-Shift; Timeliness and Smoothness;
Curvature and Peak-Correlation
Table 14 reports the ATS-components. Unlike the previous dilemma in sections 7.3.1 and 7.3.3
Theoretical best MSE
DFA-MSE
Lambda=32, eta=1
Lambda=100, eta=0.7
Lambda=8, eta=1.5
Accuracy
0.137
0.099
0.732
0.718
0.701
Timeliness
0.118
0.133
0.008
0.001
0.038
Smoothness
0.140
0.138
0.014
0.030
0.007
Residual
0.000
0.000
0.000
0.000
0.000
Total MSE
0.395
0.370
0.754
0.750
0.747
Table 14: ATS-components: emphasizing Timeliness only
We now observe that the customized filters can outperform the benchmark MSE-design in terms
of Timeliness and Smoothness but at costs of Accuracy. However... We know that the amplitude
shrinkage in the passband can distord Timeliness and Smoothness since both depend upon the
amplitude function. Therefore We look at Our alternative performance measures which are immunized against amplitude-shrinkage, see tables 15 (in-sample) and 16 (out-of-sample). We can
178
Theoretical best MSE
DFA-MSE
Lambda=32, eta=1
Lambda=100, eta=0.7
Lambda=8, eta=1.5
Selectivity
0.021
0.018
0.033
0.011
0.180
Mean-shift
3.126
2.535
0.606
0.464
3.415
Curvature
0.197
0.238
0.078
0.179
0.017
Peak-Correlation lag
4.000
3.000
2.000
0.000
4.000
Table 15: In-sample performances measures: Selectivity vs. Mean-Shift and Curvature vs. PeakCorrelation: emphasizing Smoothness and Timeliness
appreciate the double-scoring in terms of Selectivity and Mean-Shift or, alternatively, in terms of
Curvature57 and Peak-Correlation, of the ‘balanced’ customized filter λ = 32, η = 1 over the DFA
MSE-filter (η = λ = 0). The best theoretical MSE-design is beaten too. The two ‘extreme’ designs
(last two rows) perform as desired: they strongly outperform the theoretically best MSE-filter in
their stronger attributes and the loss incurred in their weaker dimension is mild. Out-of-sample
Theoretical best MSE
DFA-MSE
Lambda=32, eta=1
Lambda=100, eta=0.7
Lambda=8, eta=1.5
Curvature (out-of-sample)
0.234
0.379
0.139
0.315
0.029
Peak-Correlation (out-of-sample)
4.000
4.000
2.000
1.000
4.000
Table 16: Out-of-sample performances measures: Selectivity vs. Mean-Shift and Curvature vs.
Peak-Correlation: emphasizing Smoothness and Timeliness
performances confirm consistently Our in-sample findings.
We now briefly compare the four different out-of-sample real-time filter outputs and reference
them against the symmetric filter, see fig.66.
>
>
>
>
>
>
>
>
>
+
+
>
>
+
+
+
+
>
+
>
colo<-rainbow(dim(amp)[2]+1)
file = paste("z_dfa_cust_amp_out_ats.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
# Select out-of-sample period
anf<-4*len#len+1
enf<-5*len
sel<-1:dim(amp)[2]
mplot<-scale(cbind(xf_sym,xf[,sel])[anf:enf,])
plot(as.ts(mplot[,1]),type="l",axes=F,col="black",ylim=c(min(na.exclude(mplot)),
max(na.exclude(mplot))),ylab="",xlab="",
main="Out-of-sample final symmetric vs. real-time MSE and customized",lwd=2)
mtext("Final symmetric", side = 3, line = -1,at=(enf-anf)/2,col="black")
for (i in 1:length(sel))
{
lines(as.ts(mplot[,i+1]),col=colo[sel[i]],lwd=2)
mtext(dimnames(amp)[[2]][i], side = 3, line = -1-i,at=(enf-anf)/2,col=colo[sel[i]])
}
axis(1,at=c(1,rep(0,6))+as.integer((0:6)*(enf-anf)/6),
labels=as.integer(anf+(0:6)*(enf-anf)/6))
axis(2)
57 Recall
that We use a relative measure which is immune to scaling effects such as entailed by amplitude shrinkage.
179
> box()
> dev.off()
null device
1
Out−of−sample final symmetric vs. real−time MSE and customized
−2
−1
0
1
2
Final symmetric
Theoretical best MSE
DFA−MSE
Lambda=32, eta=1
Lambda=100, eta=0.7
Lambda=8, eta=1.5
480
500
520
540
560
580
600
Figure 66: Standardized filter outputs out-of-sample: final symmetric vs. real-time MSE and
customized designs
All series are standardized in order to match scales (overcome the amplitude shrinkage). We can
recognize the difficulty of the estimation problem by the fact that the output of the symmetric filter of length L = 61 (black line) is still subject to noisy random high-frequency noise which leakes
the filter despite its substantial length of 5 years. We observe that the λ = 100, η = 0.7-filter
(cyan) systematically lies on the left58 of the other real-time filters (it is faster) but the residual
58 Not
all of the noisy local peaks and troughs can be anticipated by this filter, of course, because they belong to
180
noise is important.
The filter with λ = 8, η = 1.5 (violet) is much smoother than the MSE-filter (red) without being
systematically delayed thus confirming reported performance numbers. The filter λ = 32, η = 1
lies slightly on the left of the MSE filter (smaller Peak-Correlation lag) and it is slightly ‘un-noisier’
(smaller Curvature), as desired.
7.4.4
In- and Out-of-Sample Empirical Distributions of Curvature and Peak-Correlation
We here replicate the above experiment 200-times and report box-plots of in- and out-of-sample
distributions of Curvature and Peak-Correlation measures, see figs.67 and 68.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
+
>
+
>
+
>
+
+
+
+
+
+
+
+
+
+
+
+
+
# Filter length
L<-24
# No filter restrictions
i1<-F
i2<-F
# Designs: MSE and two customized filters
lambda_vec<-c(0,32,100,8)
eta_vec<-c(0,1,0.7,1.5)
# Compute in/out-of-sample performances
setseed<-10
len<-120
len1<-1000
cutoff_period<-12
cutoff<-pi/cutoff_period
anzsim<-200
amp_shift_mat_insamp_array<-array(dim=c(dim(amp_shift_mat_insamp),anzsim))
amp_shift_mat_outsamp_array<-array(dim=c(dim(amp_shift_mat_outsamp),anzsim))
ats_mat_array<-array(dim=c(dim(ats_mat),anzsim))
amp_array<-array(dim=c(dim(amp),anzsim))
shift_array<-array(dim=c(dim(shift),anzsim))
dimnames(amp_shift_mat_insamp_array)<-list(dimnames(amp_shift_mat_insamp)[[1]],
dimnames(amp_shift_mat_insamp)[[2]],1:anzsim)
dimnames(amp_shift_mat_outsamp_array)<-list(dimnames(amp_shift_mat_outsamp)[[1]],
dimnames(amp_shift_mat_outsamp)[[2]],1:anzsim)
dimnames(ats_mat_array)<-list(dimnames(ats_mat)[[1]],
dimnames(ats_mat)[[2]],1:anzsim)
for (i in 1:anzsim)
#i<-1
{
setseed<-setseed+1
# generate series and in-sample periodogram
gen_obj<-gen_ser(setseed,len,len1,cutoff_period)
#
x1<-gen_obj$x1
x<-gen_obj$x
omega_k<-gen_obj$omega_k
Gamma<-gen_obj$Gamma
weight_func<-gen_obj$weight_func
#
# Compute real-time filters
perf<-Performance_func(lambda_vec,eta_vec,len1,len,x1,weight_func,
the stopband (We control the time-shift in the passband) and because the input series is white noise; as claimed:
this is a tough estimation problem.
181
+
+
+
+
+
+
+
+
+ }
>
>
>
>
>
>
+
+
+
+
>
+
+
+
+
>
Gamma,cutoff,L,L_sym,a1,mba)
xf<-perf$xf
amp_shift_mat_insamp_array[,,i]<-perf$amp_shift_mat_insamp
amp_shift_mat_outsamp_array[,,i]<-perf$amp_shift_mat_outsamp
ats_mat_array[,,i]<-perf$ats_mat
amp_array[,,i]<-perf$amp
shift_array[,,i]<-perf$shift
colo<-rainbow(dim(amp)[2]+1)[1:dim(amp)[2]]
file = paste("z_box_plot_in.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
boxplot(list(amp_shift_mat_insamp_array[1,3,],amp_shift_mat_insamp_array[2,3,],
amp_shift_mat_insamp_array[3,3,],amp_shift_mat_insamp_array[4,3,],
amp_shift_mat_insamp_array[5,3,]),outline=F,
names=c("Best MSE",paste("DFA(",lambda_vec,",",eta_vec,")",sep="")),
main="Curvature in-sample",cex.axis=0.8,col=colo)
boxplot(list(amp_shift_mat_insamp_array[1,4,],amp_shift_mat_insamp_array[2,4,],
amp_shift_mat_insamp_array[3,4,],amp_shift_mat_insamp_array[4,4,],
amp_shift_mat_insamp_array[5,4,]),outline=F,
names=c("Best MSE",paste("DFA(",lambda_vec,",",eta_vec,")",sep="")),
main="Peak-correlation in-sample",cex.axis=0.8,col=colo)
dev.off()
null device
1
182
0.0 0.2 0.4 0.6
Curvature in−sample
Best MSE
DFA(0,0)
DFA(32,1)
DFA(100,0.7) DFA(8,1.5)
0 2 4 6 8
Peak−correlation in−sample
Best MSE
DFA(0,0)
DFA(32,1)
DFA(100,0.7) DFA(8,1.5)
Figure 67: Box-plots of in-of-sample empirical distributions of Curvature (top) and PeakCorrelation (bottom)
>
>
>
>
+
+
+
+
>
+
+
+
file = paste("z_box_plot_out.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
boxplot(list(amp_shift_mat_outsamp_array[1,1,],amp_shift_mat_outsamp_array[2,1,],
amp_shift_mat_outsamp_array[3,1,],amp_shift_mat_outsamp_array[4,1,],
amp_shift_mat_outsamp_array[5,1,]),outline=F,names=c("Best MSE",paste("DFA(",
lambda_vec,",",eta_vec,")",sep="")),#dimnames(amp_shift_mat_outsamp_array)[[1]],
main="Curvature out-of-sample",cex.axis=0.8,col=colo)
boxplot(list(amp_shift_mat_outsamp_array[1,2,],amp_shift_mat_outsamp_array[2,2,],
amp_shift_mat_outsamp_array[3,2,],amp_shift_mat_outsamp_array[4,2,],
amp_shift_mat_outsamp_array[5,2,]),outline=T,names=c("Best MSE",paste("DFA(",
lambda_vec,",",eta_vec,")",sep="")),#dimnames(amp_shift_mat_outsamp_array)[[1]],
183
+ main="Peak-correlation out-of-sample",cex.axis=0.8,col=colo)
> dev.off()
null device
1
0.0
0.4
0.8
Curvature out−of−sample
Best MSE
DFA(0,0)
DFA(32,1)
DFA(100,0.7) DFA(8,1.5)
Peak−correlation out−of−sample
0 2 4 6 8
●
●
●
●
●
●
●
Best MSE
●
DFA(0,0)
DFA(32,1)
DFA(100,0.7) DFA(8,1.5)
Figure 68: Box-plots of out-of-sample empirical distributions of Curvature (top) and PeakCorrelation (bottom)
Since Curvature and Peak-Correlation are antagonistic we expect that designs which perform
well in one-dimension loose in the other attribute. Therefore it would be interesting to compute
some ‘aggregate’ measure. Fig.69 shows the empirical out-of-sample distributions of two simple
aggregates: the product (top) and the weighted sum (10 ∗ Curvature) + (P eak − Correlation):
the scaling of the Curvature-term is derived from visual inspection of the plots in fig.68 where we
can see that the scales of both measures differ roughly by a factor of ten.
184
>
>
>
>
+
+
+
+
+
+
+
>
+
+
+
+
+
+
+
+
>
file = paste("z_box_plot_agg.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
boxplot(list(amp_shift_mat_outsamp_array[1,1,]*amp_shift_mat_outsamp_array[1,2,],
amp_shift_mat_outsamp_array[2,1,]*amp_shift_mat_outsamp_array[2,2,],
amp_shift_mat_outsamp_array[3,1,]*amp_shift_mat_outsamp_array[3,2,],
amp_shift_mat_outsamp_array[4,1,]*amp_shift_mat_outsamp_array[4,2,],
amp_shift_mat_outsamp_array[5,1,]*amp_shift_mat_outsamp_array[5,2,]),
outline=F,names=c("Best MSE",paste("DFA(",
lambda_vec,",",eta_vec,")",sep="")),#dimnames(amp_shift_mat_outsamp_array)[[1]],
main="Aggregate performance: Curvature*Peakcorr out-of-sample",cex.axis=0.8,col=colo)
boxplot(list(10*amp_shift_mat_outsamp_array[1,1,]+amp_shift_mat_outsamp_array[1,2,],
10*amp_shift_mat_outsamp_array[2,1,]+amp_shift_mat_outsamp_array[2,2,],
10*amp_shift_mat_outsamp_array[3,1,]+amp_shift_mat_outsamp_array[3,2,],
10*amp_shift_mat_outsamp_array[4,1,]+amp_shift_mat_outsamp_array[4,2,],
10*amp_shift_mat_outsamp_array[5,1,]+amp_shift_mat_outsamp_array[5,2,]),
outline=F,names=c("Best MSE",paste("DFA(",
lambda_vec,",",eta_vec,")",sep="")),#dimnames(amp_shift_mat_outsamp_array)[[1]],
main="Aggregate performance: 10*Curvature+Peakcorr out-of-sample",
cex.axis=0.8,col=colo)
dev.off()
null device
1
185
0.0
1.0
2.0
Aggregate performance: Curvature*Peakcorr out−of−sample
Best MSE
DFA(0,0)
DFA(32,1)
DFA(100,0.7) DFA(8,1.5)
0
4
8
12
Aggregate performance: 10*Curvature+Peakcorr out−of−sample
Best MSE
DFA(0,0)
DFA(32,1)
DFA(100,0.7) DFA(8,1.5)
Figure 69: Box-plots of product (top) and sum (bottom) of Curvature and Peak-Correlation:
out-of-sample
One could deduce a lot of information from the above plots but the main message is simple and
clear: suitably customized filters (green) outperform the theoretically best MSE-filter (red) in both
dimensions, as measured by Curvature and Peak-Correlation, simultaneously out-of-sample; ‘extreme’ designs (cyan/blue) outperform the MSE-filter markedly in their stronger attribute without
giving-up too much (or not at all...) in their weaker dimension. Performances by the DFA-MSE
filter (yellow) are more ambiguous: it seems to outperform the best MSE-filter in terms of PeakCorrelation but it is outperformed in terms of Curvature (but it does not loose on both counts
simultaneously).
We now derive some other potentially useful conclusions from the above results. We first focus
on the disaggregated measures in figs.67 and 68. We note that the out-of-sample box-plots of the
best MSE-filter (red) are narrower (the distributions are tighter) than in-sample plots because
186
the former evaluation period is much longer (1000-120=880 observations) than the in-sample span
(T = 120). We remark, also, that the first three DFA-filters (yellow, green, cyan) are subject
to slight overfitting since out-of-sample performances are slightly worse. In contrast, the ‘extreme’ filter (blue) is remarkably immune against overfitting: the strong customization entailed by
η = 1.5 implicitly ‘freezes’ degrees of freedom by shrinking the amplitude function towards zero in
the stopband (kind of implicit regularization). This strong regularization tightens noticeably the
Curvature-distribution. The tradeoff is a flatter Peak-Correlation distribution (higher entropy).
In contrast, the two ‘fastest’ filters have a tighter Peak-Correlation distribution. In general, We
observe that customized filters have tighter distributions than the DFA MSE-filter: emphasizing
Timeliness, through λ, tightens the distribution of the Peak-Correlation; emphasizing Smoothness,
via η, concentrates the distribution of Curvature. In contrast, the DFA-MSE filter is ‘unrestricted’
and therefore it is also more sensitive to overfitting, recall Our results in section 4.1.1, table 4 and
the finite-sample distributions of filter coefficients, amplitude and time-shift functions in figs. 35,
36 and 37.
When looking at the aggregate measures in fig.69 we see that the customized filters strongly
outperform both MSE-filters when looking at the combined product (top): this is to be expected
especially for the two extreme filters (cyan/blue) because of the marked performance-disequilibria
(in such a case the product ought to be smaller). Interestingly, the outperformance is still marked
when looking at the additive aggregation scheme (bottom graph). We now see that the balanced
design (green) outperforms the other designs, as expected. Finally, the DFA-MSE filter (yellow) is outperformed by all other filters which was to be expected, too. Of course, our proposed
aggregate-measures are to some extent arbitrary but given the empirical distributions of the individual performance-measures we expect our conclusions to be fairly robust against alternative
aggregation- and/or weighting-schemes: we expect the balanced design (green) to outperform the
(theoretically best) MSE-filter (red) systematically out-of-sample.
Summary
The ‘balanced’ customized filter λ = 32, η = 1 outperforms the (DFA) MSE-filter both in terms
of Timeliness and Smoothness, Curvature and Peak-Correlation, Selectivity and Mean-Shift and
its out-of-sample performances are remarkably consistent (robust against overfitting), despite the
fact that We estimated L = 24 coefficients based on T = 120 (10 years) in-sample data only.
In particular, the customized filter outperforms the best theoretical MSE-filter out-of-sample in
both dimensions (Curvature/Peak-Correlation) simultaneously. The two ‘unbalanced’ filters, prioritizing either Timeliness (λ = 100, η = 0.7) or Smoothness (λ = 8, η = 1.5), clearly outperform
the MSE-design in their stronger disciplin without giving-up ‘too much’ in their weaker attribute.
Suitably customized filters are less prone to overfitting than the ordinary MSE-design: emphasizing Timeliness, through λ, tightens the distribution of the Peak-Correlation and emphasizing
Smoothness, via η, concentrates the distribution of Curvature.
8
Replication and Customization of Model-Based and Classic (HP/CF/Henderson) Filters by DFA
Until yet We used the DFT (the periodogram) as a natural spectral estimate. But We could plugin any ‘reasonable’ or interesting alternative statistic, instead. We call this possibility ‘Spectrum
Interface’ since We establish a natural link between the user and the optimization criterion by
means of the spectrum estimate: the DFA is a completely agnostic approach though his author
has strong subjective preferences (let Us confess that ‘the periodogram and We’ are a love affair).
By opening Our mind, We are now in a position to replicate and, more interestingly, to customize
classic filter-designs.
187
8.1
8.1.1
Replication
True Spectrum when the DGP is Known
Model-based approaches such as implemented in TRAMO/SEATS, X-13 or Stamp rely on ARIMAmodels for fitting/forecasting the data. A general ARIMA-model is a one-sided filter applied to
white noise. For illustration We here assume that the DGP is a stationary AR(1)-process but Our
generic approach readily extends to arbitrary ARIMA-models. Let
xt = a1 xt−1 + t
where t is a white noise process with variance V ar(t ) = σ 2 . The spectral density of white noise
is a flat line
σ2
h (ω) =
2π
with the property that the autocovariance satisfies the following system of equations
2
Z π
σ k=0
R(k) =
h(ω) exp(−ikω)dω =
0 k 6= 0
−π
Since the amplitude function of the AR(1)-filter is
1
1 − a1 exp(−iω)
We deduce that the spectrum of the AR(1)-process xt is
hx (ω) =
σ2
2π|1 − a1 exp(−iω)|2
(70)
(convolution theorem). Straightforward generalizations apply to arbitrary (S)ARIMA-processes59 .
Until yet, We plugged the periodogram IT X (ωk ), k = −T /2, ..., T /2 into DFA. But We could
have used hx (ω) instead: if a1 is unknown then We could supply an estimate and obtain a corresponding empirical spectrum. In fact We could rely on the whole SARIMA-apparatus (identification, estimation, diagnostics) and derive corresponding empirical spectral estimates. By doing so
We would just replicate the traditional model-based approach as shown below.
8.1.2
Model-Based Solution
Estimating the output yT of a (possibly bi-infinite) target filter γk
yT =
∞
X
γk xT −k
k=−∞
entails estimation of future observations xT +1 , xT +2 , ...60 . Cleveland proposed to forecast the
missing data and then to apply the target filter to the artificially extended time series61 . We here
59 Unit-roots lead to singularities and the resulting h (ω) is called-pseudo-spectral density, see section
x
3.3.3. Nothing wrong with that, see Wildi (2008) http://blog.zhaw.ch/idp/sefblog/index.php?/archives/
168-RTSE-My-Good-Old-Book.html and McElroy-Wildi (2012) for technical details: http://blog.zhaw.ch/idp/
sefblog/index.php?/archives/271-Trilemma-Paper-Latest-Sweaved-Version-Available.html.
60 Note that we do not assume symmetry of the filter. Therefore We could easily replicate a pure forecasting
1
k = −h
problem: h-step ahead forecasting is obtained by specifying γk =
. The resulting target transfer
0 otherwise
function Γ(ω) = exp(ihωk ) is an anticipative allpass. Note that the phase Φ(ω) = hω of the target filter would not
vanish anymore but who cares? Just plug that phase into DFA by specifying Lag = −h: a breeze!
61 Backcasts of x , x
0
−1 , ... could be provided as well but in general filter weights γk decay sufficiently rapidly to
zero such that We could ignore this issue. Recall that We tackled the problem in the SA-section by implementing
full revision sequencies in DFA.
188
briefly verify that this (model-based) approach is fully compatible with DFA when supplying the
corresponding model-based spectrum, as proposed above. We provide purely empirical evidences
by comparing amplitude functions of corresponding real-time filters (the literature is sufficiently
enriched by elegant mathematical proofs).
In order to pursue We need a target filter: We here propose the ideal lowpass with cutoff π/12,
as used in Our previous framework. Since Our approach is generic we could also provide any
model-based (symmetric) trend-extraction filter (as generated by SEATS or STAMP for example)
or any of the classic HP (Hodrick-Prescott) or CF (Christiano Fitzgerald) or H (Henderson) filters:
We really don’t care about this choice in the sense that we could replicate any target. The filter
weights γk of Our target were derived in 2
sin(j · cutoff)
j 6= 0
jπ
γj =
cutoff
j=0
π
Let’s now derive the model-based real-time filter for estimating yT whereby missing (future) data
is replaced by forecasts:
ŷT
=
−1
X
γk x̂T −k +
−1
X
γk x̂T −k +
k=−∞
=
−1
X
T
−1
X
∞
X
γk x̂T −k
k=T
γk xT −k
k=0
|k|
γk a1 xT +
0
X
T
−1
X
γk xT −k
k=0
k=−∞
=
γk xT −k +
k=0
k=−∞
≈
T
−1
X
!
|k|
γk a1
xT +
k=−∞
T
−1
X
γk xT −k
(71)
k=1
|k|
where a1 xT is the forecast of xT +|k| . For simplicity We assumed that T is sufficiently large such
that the above approximation applies i.e. backcasts are neglected. This proceeding is generic,
too, and therefore it straightforwardly extends to arbitrary (S)ARIMA-processes. Expression 71
is the optimal model-based real-time MSE-filter and We now compare these coefficients with those
obtained by DFA, when plugging 70 into Our function df a analytic, see fig.70. Note that We
don’t need to generate artificial data since We are just interested in confirming the equality of
two filters (for an arbitrary AR(1)-parameter a1 ) and note also that We can rely on an arbitrarily
tight frequency-grid ωk since We do not rely on the perioodgram anymore.
8.1.3
DFA Replicates MBA
We first specify the target (symmetric) lowpass (We assume a relatively high resolution K = 1200
of the discrete frequency-grid):
>
>
>
>
>
>
>
>
# Frequency resolution
K<-1200
# Hypothetical sample length
len<-120
# Symmetric lowpass target
cutoff<-pi/12
# Order of approximation : 10, 100, 1000, 10000
ord<-len
189
>
>
>
>
>
# Compute coefficients gamma
gamma_k<-c(cutoff/pi,(1/pi)*sin(cutoff*1:ord)/(1:ord))
#sum(gamma_k)+sum(gamma_k[2:ord])
# Target in frequency-domain
Gamma<-(0:K)<as.integer(cutoff*K/pi)+1
We now compute the real-time model-based filter:
>
>
>
>
>
>
>
>
>
+
+
+
+
>
omega_k<-(0:K)*pi/K
# AR(1)-coefficient
a1<-0.5
# Model-based filter
gamma_0<-gamma_k%*%a1^(0:ord)
gamma_mba_rt<-c(gamma_0,gamma_k[2:(ord)])
trffkt_mba<-rep(NA,K+1)
weight_func<-trffkt_mba
for (i in 0:K)
{
trffkt_mba[i+1]<-gamma_mba_rt%*%exp(1.i*omega_k[i+1]*(0:(ord-1)))
}
amp_mba<-abs(trffkt_mba)
Finally We proceed to replication by DFA: We compute a filter of lengths L = 120 and L = 12 in
order to inspect finite-(short) sample issues.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
L<-len
# model-based spectrum
weight_func<-1/abs(1-a1*exp(1.i*omega_k))^2
# MSE-filter
lambda<-0
eta<-0
# Real-time design
Lag<-0
# Unconstrained filter
i1<-F
i2<-F
dfa_ar1_long<-dfa_analytic(L,lambda,weight_func,Lag,Gamma,eta,cutoff,i1,i2)
# Much shorter sample length
L<-len/10
lambda<-0
eta<-0
Lag<-0
i1<-F
i2<-F
dfa_ar1_short<-dfa_analytic(L,lambda,weight_func,Lag,Gamma,eta,cutoff,i1,i2)
The amplitude functions of MBA- and DFA-filters are plotted in fig.70.
>
>
>
>
+
+
>
file = paste("z_mbaedfa.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(2,1))
plot(dfa_ar1_long$b,type="l",axes=F,col="blue",ylim=c(min(dfa_ar1_long$b),
max(dfa_ar1_long$b)),ylab="",xlab="",main=paste("Filter coefficients of real-time
model-based (red) and DFA-MSE (blue): a1=",a1,", T=120",sep=""),lwd=2)
mtext("DFA", side = 3, line = -1,at=len/2,col="blue")
190
>
>
>
+
>
>
>
+
+
>
>
>
>
>
>
>
lines(gamma_mba_rt,col="red",lwd=1)
mtext("Model-based", side = 3, line = -2,at=len/2,col="red")
axis(1,at=c(1,rep(0,6))+as.integer((0:6)*len/6),
labels=as.integer(0+(0:6)*(len)/6))
axis(2)
box()
plot(dfa_ar1_short$b,type="l",axes=F,col="blue",ylim=c(min(dfa_ar1_short$b),
max(dfa_ar1_short$b)),ylab="",xlab="",main=paste("Filter coefficients of real-time
model-based (red) and DFA-MSE (blue): a1=",a1,", T=12",sep=""),lwd=2)
mtext("DFA", side = 3, line = -1,at=len/20,col="blue")
lines(gamma_mba_rt[1:12],col="red",lwd=1)
mtext("Model-based", side = 3, line = -2,at=len/20,col="red")
axis(1,at=1:12,labels=0:11)
axis(2)
box()
dev.off()
null device
1
191
Filter coefficients of real−time
model−based (red) and DFA−MSE (blue): a1=0.5, T=120
0.00
0.10
DFA
Model−based
0
20
40
60
80
100
120
Filter coefficients of real−time
model−based (red) and DFA−MSE (blue): a1=0.5, T=12
0.00
0.10
DFA
Model−based
0
1
2
3
4
5
6
7
8
9
10
11
Figure 70: Filter coefficients of real-time model-based (red) and DFA-MSE (blue)
One can run the above code for arbitrary a1 , T (sample length) and K (resolution of frequencygrid) and verify the claimed identity. For small T (bottom graph, T = 12) one notices small
differences between 71 and DFA because the latter computes best finite sample filters whereas
Our approximation 71 ignores backcasts i.e. it assumes a semi-infinite sample (which is contradicted by relying on a short sample T = 12). The resolution of the frequency-grid has an impact
too but for K sufficiently large (say K > 100) the differences are negligible by all practical means.
Finally, let us emphasize here that We can safely estimate filters of length L = T because a modelbased (empirical) spectrum is smooth, assuming the model does not suffer overfitting.
Summary
If We ignore backcasts (large sample size T ) and if We assume that the frequency-resolution is
sufficiently tight, then the DFA replicates the MBA arbitrarily well. This replication would still
hold for (very) small sample sizes but then We would have to account explicitly for the possibility
192
of backcasts in the MBA (which was ignored merely for convenience).
8.2
Customization: Improving Timeliness and Smoothness, Selectivity and Mean-Shift, Curvature and Peak-Correlation of Real-Time
Model-Based Filters
Obviously there is no direct benefit to expect from a pure replication of the classic time-domain
model-based approach (MBA) by DFA. But once replicated, We could be tempted to customize
the MBA. We acknowledge that many users rely on models; also, We are aware that many users are
not unconditionally happy with the outcome of the MBA (say in terms of classic Curvature and/or
Peak-Correlation measures); therefore We here provide an original contribution for model-based
proponents: enhance real-time characteristics of pure model-based approaches without
leaving the maximum-likelihood paradigm!
We here apply the previously defined P erf ormance f unc to artificial data generated by an
AR(1) model-specification and compare real-time MBA-designs – MSE and customized MBA – ,
assuming knowledge of the true DGP (therefore We do not distinguish in-sample and out-of-sample
time spans). We first generate the data:
>
>
>
>
>
>
>
>
>
>
>
set.seed(10)
len<-120
len1<-1000
# The longer sample is used for implementing the symmetric filter and
# for computing peak-correlations
x1<-arima.sim(list(ar=a1),n=len1)
# In previous sections the shorter sample of length 120 was used for
# estimating the real-time DFA-filters
# We do not use in-sample data here because we know the DGP
#
(but we still have to define x in the head of the function)
x<-x1[1:len]
We now compute model-based MSE and model-based customized filters by relying on our workhorse P erf ormance f unc-function. Model-based AR(1)-spectra are obtained by specifying mba <
−T (otherwise the periodogram will be used).
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
# Length of symmetric target filter
L_sym<-61
# Length of model-based filters
L<-120
# Real-time
Lag<-0
# No filter restrictions
i1<-i2<-F
# Designs: three customized filters (the MSE is automatically computed)
lambda_vec<-c(32,100,500)
eta_vec<-c(0.5,1,0.3)
# Use model-based spectrum
mba<-T
# Compute in/out-of-sample performances
perf<-Performance_func(lambda_vec,eta_vec,len1,len,x1,weight_func,Gamma,cutoff,L,L_sym,a1,mba)
xf<-perf$xf
amp_shift_mat<-cbind(perf$amp_shift_mat_insamp,perf$amp_shift_mat_outsamp)
ats_mat<-perf$ats_mat
amp<-perf$amp
193
> shift<-perf$shift
> xf_sym<-perf$xf_sym
Amplitude and time-shift functions are plotted in fig.71.
>
>
>
>
>
>
>
>
>
+
+
+
+
+
>
>
>
>
+
>
>
+
+
+
+
+
>
>
>
>
#
# Plots
colo<-rainbow(dim(amp)[2]+1)
file = paste("z_dfa_cust_ats_mba.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
par(mfrow=c(1,2))
plot(Gamma,type="l",axes=F,col="black",ylim=c(0,1),ylab="",xlab="",main="Amplitude")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
for (i in 1:dim(amp)[2])
{
lines(amp[,i],lty=1,col=colo[i])
mtext(dimnames(amp)[[2]][i], side = 3,
line = -1-i,at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
plot(rep(0,K+1),type="l",axes=F,col="black",ylim=c(min(shift),max(na.exclude(shift))),
ylab="",xlab="",main="Shift")
mtext("Target", side = 3, line = -1,at=K/2,col="black")
for (i in 1:dim(amp)[2])
{
lines(shift[,i],lty=1,col=colo[i])
mtext(dimnames(shift)[[2]][i], side = 3,
line = -1-i,at=K/2,col=colo[i])
}
axis(1,at=1+0:6*K/6,labels=c("0","pi/6","2pi/6","3pi/6","4pi/6","5pi/6","pi"))
axis(2)
box()
dev.off()
null device
1
194
Target
MBA−MSE
Lambda=32, eta=0.5
Lambda=100, eta=1
Lambda=500, eta=0.3
Target
MBA−MSE
Lambda=32, eta=0.5
Lambda=100, eta=1
Lambda=500, eta=0.3
6
1.0
Shift
0.0
0
0.2
2
0.4
4
0.6
0.8
Amplitude
0
2pi/6
4pi/6
pi
0
2pi/6
4pi/6
pi
Figure 71: MBA vs. customized filters: amplitude and time-shifts
The amplitude functions are shrunken by the more or less heavy customization: so We need to look
at Our (normalized) performance measures in order to get a better feeling of the resulting ‘noisesuppression’. Increasing λ pulls the time-shift down in the passband, as desired. We expect that
Timeliness, Peak-Correlation and Mean-Shift should be positively affected. Performance measures
are reported in table 17: note that We do not distinguish in- and out-of-sample performances since
the DGP is known. The customized designs generally beat the ‘plain-vanilla’ MSE-design in all
MBA-MSE
Lambda=32, eta=0.5
Lambda=100, eta=1
Lambda=500, eta=0.3
Selectivity
0.000044
0.000086
0.000345
0.000030
Mean-shift
2.348114
0.995862
1.349925
0.024777
Curvature
0.219023
0.073286
0.017756
0.167471
Peak-Correlation
3.000000
2.000000
2.000000
1.000000
Table 17: In-sample performances measures: MBA-MSE vs. MBA-customized
dimensions (except for Selectivity of the extreme design in the last row).
Remark
Since the DGP is known, fiddling and tweaking (λ, η) is not subject to overfitting (at least with
respect to the frequency-domain measures Selectivity and Mean-Shift). Therefore performances
apply to the DGP rather than to a singular realization. As a result, one could experiment with
‘extreme’ customization-settings. Also, one can compute filters of arbitrary length (We selected
L = 120).
To conclude, We briefly compare the obtained model-based filter outputs and reference them
195
against the symmetric filter, see fig.72.
>
>
>
>
>
>
>
>
+
+
>
>
+
+
+
+
>
+
>
>
>
file = paste("z_dfa_cust_amp_out_ats_mba.pdf", sep = "")
pdf(file = paste(path.out,file,sep=""), paper = "special", width = 6, height = 6)
# Select out-of-sample period
anf<-3*len
enf<-5*len
sel<-1:dim(amp)[2]
mplot<-scale(cbind(xf_sym,xf)[anf:enf,])
plot(as.ts(mplot[,1]),type="l",axes=F,col="black",ylim=c(min(na.exclude(mplot)),
max(na.exclude(mplot))),ylab="",xlab="",
main="Final symmetric vs. real-time MBA: MSE and customized",lwd=2)
mtext("Final symmetric", side = 3, line = -1,at=(enf-anf)/2,col="black")
for (i in 1:length(sel))
{
lines(as.ts(mplot[,i+1]),col=colo[sel[i]],lwd=2)
mtext(dimnames(amp)[[2]][i], side = 3, line = -1-i,at=(enf-anf)/2,col=colo[sel[i]])
}
axis(1,at=c(1,rep(0,6))+as.integer((0:6)*(enf-anf)/6),
labels=as.integer(anf+(0:6)*(enf-anf)/6))
axis(2)
box()
dev.off()
null device
1
196
Final symmetric vs. real−time MBA: MSE and customized
−2
−1
0
1
2
Final symmetric
MBA−MSE
Lambda=32, eta=0.5
Lambda=100, eta=1
Lambda=500, eta=0.3
360
400
440
480
520
560
600
Figure 72: Filter outputs out-of-sample: final symmetric vs. real-time MSE and customized
designs
All series are standardized in order to match scales. We can observe that the customized filters
tend to lie ‘on the left’ of the MSE-filter, as measured by Peak-Correlations, and that the series
are smoother (except the extreme design), as measured by Curvature or Selectivity.
8.3
Replication of HP- and CF-Filters
HP and CF-filters can be replicated by model-based designs and therefore they can be replicated
and customized by the DFA (transitivity). We refer the interested reader to SEFBlog:
• HP-filter: http://blog.zhaw.ch/idp/sefblog/index.php?/archives/261-Replication-of-the-Hodrickhtml
197
• CF-filter: http://blog.zhaw.ch/idp/sefblog/index.php?/archives/264-Replication-of-the-Christian
html
Obviously, any classic (or otherwise extravagant) filter can be customized.
9
Multivariate Direct Filter Approach: MDFA
The additional M... I don’t have time to put this stuff into a unifying format right now. The
interested reader is referred to SEFBlog for code, paper and tutorials on the topic.
10
10.1
Appendix
A Proof
Proposition 1 The periodogram of a sequence x1 , ..., xT satisfies
T
−1
X
1
R̂(j) exp(−ijωk ) , |k| = 1, ..., T /2
2π
IT X (ωk ) =
j=−(T −1)
T 2
x
,
k=0
2π
(72)
Furthermore, for |t| = 0, ..., T − 1 the following holds
2π
T
T /2
X
wk exp(−itωk )IT X (ωk ) =
k=−T /2
R̂(t) + R̂(T − t) ,
t 6= 0
R̂(0)
, otherwise
(73)
Proof
A proof of the first claim is proposed in Brockwell and Davis [?], proposition 10.1.2. The
second assertion follows from
2π
T
=
=
=
=
=
2π
T
1
T
1
T
1
T
T /2
X
wk exp(−itωk )IT X (ωk )
k=−T /2
T /2
X
wk exp(−itωk )
k=−T /2
T
−1
X
j=−(T −1)
T
−1
X
R̂(j)
T /2
X
1
2π
T
−1
X
wk exp(−i(t + j)ωk )
k=−T /2
R̂(j) exp(−i(j + t)ω−T /2 )
j=−(T −1)
T
−1
X
R̂(j) exp(−ijωk )
j=−(T −1)
T
X
wk exp(−i(j + t)ωk )
k=0
R̂(j) exp(−i(j + t)ω−T /2 )
j=−(T −1)
T
X
exp(−i(j + t)ωk )
k=1
R̂(t) + R̂(T − t) ,
t 6= 0
R̂(0)
, otherwise
where the last equality follows from the orthogonality relations ??, noting that j +t = 0 ‘generates’
R̂(−t) or, equivalently, R̂(t) and that j + t = T ‘generates’ R̂(T − t) if t 6= 0.
198
Note also that 73 is a consequence of the implicit periodicity of the data assumed by the
periodogram-construct. To see this assume t = 1 and let X0 = XT (‘cyclical’ data). Then
2π
T
T /2
X
wk exp(−iωk )IT X (ωk )
=
R̂(1) + R̂(T − 1)
=
T −1
1 X
1
Xk Xk+1 + X1 XT
T
T
k=−T /2
k=1
=
=
1
T
1
T
T
−1
X
Xk Xk+1 +
k=1
T
−1
X
1
X1 X0
T
Xk Xk+1
k=0
which is the ‘natural’ estimate of R(1) (if E[Xt ] = 0).
10.2
A Bad ‘Smart’ Idea
An utterly simple proceeding:
• Transform the data xt to the frequency-domain via DFT.
• Multiply the DFT by the transferfunction Γ(·) of the target filter.
• Transform the obtained DFT back to the time-domain, by means of the IDFT.
If this worked We could have skipped everything past section 2.2. So: what could be wrong with
Fourier? See exercise 8, p.31 and a SEFBlog-entry devoted to the topic http://blog.zhaw.ch/
idp/sefblog/index.php?/archives/145-Filtering-in-the-Frequency-Domain-a-Bad-Smart-Idea.
html. The resulting filtering could work well for smoothing historical data but real-time performances for typical econonomic data are likely to be intolerable.
199
© Copyright 2026 Paperzz