mvspectrum {ForeCA} | R Documentation |
Estimates spectrum of multivariate time series
Description
The spectrum of a multivariate time series is a matrix-valued function of the
frequency \lambda \in [-\pi, \pi]
, which is symmetric/Hermitian around
\lambda = 0
.
mvspectrum
estimates it and returns a 3D array of dimension
num.freqs \times K \times K
. Since the spectrum is symmetric/Hermitian around
\lambda = 0
it is sufficient to store only positive frequencies.
In the implementation in this package we thus usually
consider only positive frequencies (omitting 0
); num.freqs
refers
to the number of positive frequencies only.
normalize_mvspectrum
normalizes the spectrum such that
it adds up to 0.5
over all positive frequencies (by symmetry it will
add up to 1 over the whole range – thus the name normalize).
For a K
-dimensional time series it adds
up to a Hermitian K \times K
matrix with 0.5 in the diagonal and
imaginary elements (real parts equal to 0
) in the off-diagonal.
Since it is Hermitian the mvspectrum will add up to the identity matrix
over the whole range of frequencies, since the off-diagonal elements
are purely imaginary (real part equals 0) and thus add up to 0.
check_mvspectrum_normalized
checks if the spectrum is normalized
(see normalize_mvspectrum
for the requirements).
mvpgram
computes the multivariate periodogram estimate using
bare-bone multivariate fft (mvfft
). Use
mvspectrum(..., method = 'pgram')
instead of mvpgram
directly.
This function is merely included to have one method that does not require the astsa nor the sapa R packages. However, it is strongly encouraged to install either one of them to get (much) better estimates. See Details.
get_spectrum_from_mvspectrum
extracts the spectrum of one time series from an
"mvspectrum"
object by taking the i-th diagonal entry for each frequency.
spectrum_of_linear_combination
computes the spectrum of the linear
combination \mathbf{y}_t = \mathbf{X}_t \boldsymbol \beta
of K
time series \mathbf{X}_t
. This can be efficiently computed by the
quadratic form
f_{y}(\lambda) = \boldsymbol \beta' f_{\mathbf{X}}(\lambda) \boldsymbol \beta \geq 0,
for each \lambda
. This holds for any \boldsymbol \beta
(even \boldsymbol \beta = \boldsymbol 0
– not only for
||\boldsymbol \beta ||_2 = 1
.
For \boldsymbol \beta = \boldsymbol e_i
(the i-th basis vector)
this is equivalent to get_spectrum_from_mvspectrum(..., which = i)
.
Usage
mvspectrum(
series,
method = c("mvspec", "pgram", "pspectrum", "ar"),
normalize = FALSE,
smoothing = FALSE,
...
)
normalize_mvspectrum(mvspectrum.output)
check_mvspectrum_normalized(f.U, check.attribute.only = TRUE)
mvpgram(series)
get_spectrum_from_mvspectrum(
mvspectrum.output,
which = seq_len(dim(mvspectrum.output)[2])
)
spectrum_of_linear_combination(mvspectrum.output, beta)
Arguments
series |
a |
method |
string; method for spectrum estimation: use |
normalize |
logical; if |
smoothing |
logical; if |
... |
additional arguments passed to |
mvspectrum.output |
an object of class |
f.U |
multivariate spectrum of class |
check.attribute.only |
logical; if |
which |
integer(s); the spectrum of which series whould be extracted. By default, it returns all univariate spectra as a matrix (frequencies in rows). |
beta |
numeric; vector |
Details
For an orthonormal time series \mathbf{U}_t
the raw periodogram adds up
to I_K
over all (negative and positive) frequencies. Since we only consider
positive frequencies, the normalized multivariate spectrum should add up to
0.5 \cdot I_K
plus a Hermitian imaginary matrix (which will add up to zero
when combined with its symmetric counterpart.)
As we often use non-parametric smoothing for less variance, the spectrum estimates
do not satisfy this identity exactly. normalize_mvspectrum
thus adjust the
estimates so they satisfy it again exactly.
mvpgram
has no options for improving spectrum estimation whatsoever.
It thus yields very noisy (in fact, inconsistent) estimates of the
multivariate spectrum f_{\mathbf{X}}(\lambda)
.
If you want to obtain better estimates then please use other method
s in
mvspectrum
(this is highly recommended to obtain more
reasonable/stable estimates).
Value
mvspectrum
returns a 3D array of dimension num.freqs \times K \times K
, where
num.freqs is the number of frequencies
K is the number of series (columns in
series
).
It also has an "normalized"
attribute, which is
FALSE
if normalize = FALSE
; otherwise TRUE
.
See normalize_mvspectrum
for details.
normalize_mvspectrum
returns a normalized spectrum over
positive frequencies, which:
- univariate:
adds up to
0.5
,- multivariate:
adds up to Hermitian
K \times K
matrix with 0.5 in the diagonal and purely imaginary elements in the off-diagonal.
check_mvspectrum_normalized
throws an error if spectrum is not
normalized correctly.
get_spectrum_from_mvspectrum
returns either a matrix of all univariate spectra,
or one single column (if which
is specified.)
spectrum_of_linear_combination
returns a vector with length equal to
the number of rows of mvspectrum.output
.
References
See References in spectrum
, pspectrum
,
mvspec
.
Examples
set.seed(1)
XX <- cbind(rnorm(100), arima.sim(n = 100, list(ar = 0.9)))
ss3d <- mvspectrum(XX)
dim(ss3d)
ss3d[2,,] # at omega_1; in general complex-valued, but Hermitian
identical(ss3d[2,,], Conj(t(ss3d[2,,]))) # is Hermitian
## Not run:
ss <- mvspectrum(XX[, 1], method="pspectrum", smoothing = TRUE)
mvspectrum(XX, normalize = TRUE)
## End(Not run)
ss <- mvspectrum(whiten(XX)$U, normalize = TRUE)
xx <- scale(rnorm(100), center = TRUE, scale = FALSE)
var(xx)
sum(mvspectrum(xx, normalize = FALSE, method = "pgram")) * 2
sum(mvspectrum(xx, normalize = FALSE, method = "mvspec")) * 2
## Not run:
sum(mvspectrum(xx, normalize = FALSE, method = "pspectrum")) * 2
## End(Not run)
## Not run:
xx <- scale(rnorm(100), center = TRUE, scale = FALSE)
ss <- mvspectrum(xx)
ss.n <- normalize_mvspectrum(ss)
sum(ss.n)
# multivariate
UU <- whiten(matrix(rnorm(40), ncol = 2))$U
S.U <- mvspectrum(UU, method = "mvspec")
mvspectrum2wcov(normalize_mvspectrum(S.U))
## End(Not run)
XX <- matrix(rnorm(1000), ncol = 2)
SS <- mvspectrum(XX, "mvspec")
ss1 <- mvspectrum(XX[, 1], "mvspec")
SS.1 <- get_spectrum_from_mvspectrum(SS, 1)
plot.default(ss1, SS.1)
abline(0, 1, lty = 2, col = "blue")
XX <- matrix(arima.sim(n = 1000, list(ar = 0.9)), ncol = 4)
beta.tmp <- rbind(1, -1, 2, 0)
yy <- XX %*% beta.tmp
SS <- mvspectrum(XX, "mvspec")
ss.yy.comb <- spectrum_of_linear_combination(SS, beta.tmp)
ss.yy <- mvspectrum(yy, "mvspec")
plot(ss.yy, log = TRUE) # using plot.mvspectrum()
lines(ss.yy.comb, col = "red", lty = 1, lwd = 2)