mavats.factormodel
1from typing import Tuple, Union 2 3import numpy as np 4from numpy import linalg as LA 5from scipy.linalg import eigh 6 7 8def estimate_factor_model( 9 X: np.ndarray, h0: int, k1: Union[int, None] = None, k2: Union[int, None] = None 10) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: 11 r""" 12 Estimates the high-dimensional matrix factor model in Wang, Liu, Chen 2019 (https://doi.org/10.1016/j.jeconom.2018.09.013) 13 where $X_t = R F_t C^T + E_t = Q_1 Z_t Q_2^T + E_t$ 14 15 Parameters 16 ---------- 17 X : (T, p1, p2) ndarray 18 The observed data. 19 h0 : int 20 Lag parameter. 21 k1 : int, optional 22 Rank of the front loading matrix. If None, the rank is estimated. 23 k2 : int, optional 24 Rank of the back loading matrix. If None, the rank is estimated. 25 26 Returns 27 ------- 28 Z : (T, k1, k2) ndarray 29 The estimated transformed factor matrix. 30 S : (T, p1, p2) ndarray 31 The estimated dynamic signal $S_t = Q_1 Z_t Q_2^T$. 32 Q1 : (p1, k1) ndarray 33 The estimated front loading matrix. 34 Q2 : (p2, k2) ndarray 35 The estimated back loading matrix. 36 37 """ 38 M1 = _compute_M(X, h0) 39 Q1 = _compute_Q(M1, k1) 40 M2 = _compute_M(X.transpose(0, 2, 1), h0) 41 Q2 = _compute_Q(M2, k2) 42 Z = Q1.T @ X @ Q2 43 S = Q1 @ Z @ Q2.T 44 return Z, S, Q1, Q2 45 46 47def _compute_omega_hat(X: np.ndarray, h: int) -> np.ndarray: 48 T, p1, p2 = X.shape 49 omega_hat = np.zeros((p2, p2, p1, p1)) 50 X_t = X[: T - h] 51 X_th = X[h:T] 52 for i in range(p2): 53 for j in range(p2): 54 omega_hat[i, j] = np.einsum("tk,tl->kl", X_t[:, :, i], X_th[:, :, j]) 55 return omega_hat / (T - h) 56 57 58def _compute_M(X: np.ndarray, h0: int) -> np.ndarray: 59 T, p1, p2 = X.shape 60 M = np.zeros((p1, p1)) 61 for h in range(1, h0 + 1): 62 omega_hat = _compute_omega_hat(X, h) 63 for i in range(p2): 64 for j in range(p2): 65 M += omega_hat[i, j] @ omega_hat[i, j].T 66 return M 67 68 69def _compute_Q(M: np.ndarray, k: Union[int, None]) -> np.ndarray: 70 if k is None: 71 w, v = eigh(M) 72 k = _estimate_k(w) 73 w, v = w[-k:], v[:, -k:] 74 else: 75 w, v = eigh(M, subset_by_index=(M.shape[0] - k, M.shape[0] - 1)) 76 v = _ensure_positive_eigenvecs(v) 77 return v 78 79 80def _estimate_k(w: np.ndarray) -> int: 81 w = np.flipud(w)[: len(w) // 2 + 1] 82 ratios = w[1:] / w[:-1] 83 return int(np.argmin(ratios)) + 1 84 85 86def _ensure_positive_eigenvecs(v: np.ndarray) -> np.ndarray: 87 v_summed = np.sum(v, axis=0) 88 lt_zero = v_summed < 0 89 v[:, lt_zero] *= -1 90 return v
def
estimate_factor_model( X: numpy.ndarray, h0: int, k1: Optional[int] = None, k2: Optional[int] = None) -> Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, numpy.ndarray]:
9def estimate_factor_model( 10 X: np.ndarray, h0: int, k1: Union[int, None] = None, k2: Union[int, None] = None 11) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: 12 r""" 13 Estimates the high-dimensional matrix factor model in Wang, Liu, Chen 2019 (https://doi.org/10.1016/j.jeconom.2018.09.013) 14 where $X_t = R F_t C^T + E_t = Q_1 Z_t Q_2^T + E_t$ 15 16 Parameters 17 ---------- 18 X : (T, p1, p2) ndarray 19 The observed data. 20 h0 : int 21 Lag parameter. 22 k1 : int, optional 23 Rank of the front loading matrix. If None, the rank is estimated. 24 k2 : int, optional 25 Rank of the back loading matrix. If None, the rank is estimated. 26 27 Returns 28 ------- 29 Z : (T, k1, k2) ndarray 30 The estimated transformed factor matrix. 31 S : (T, p1, p2) ndarray 32 The estimated dynamic signal $S_t = Q_1 Z_t Q_2^T$. 33 Q1 : (p1, k1) ndarray 34 The estimated front loading matrix. 35 Q2 : (p2, k2) ndarray 36 The estimated back loading matrix. 37 38 """ 39 M1 = _compute_M(X, h0) 40 Q1 = _compute_Q(M1, k1) 41 M2 = _compute_M(X.transpose(0, 2, 1), h0) 42 Q2 = _compute_Q(M2, k2) 43 Z = Q1.T @ X @ Q2 44 S = Q1 @ Z @ Q2.T 45 return Z, S, Q1, Q2
Estimates the high-dimensional matrix factor model in Wang, Liu, Chen 2019 (https://doi.org/10.1016/j.jeconom.2018.09.013) where $X_t = R F_t C^T + E_t = Q_1 Z_t Q_2^T + E_t$
Parameters
- X ((T, p1, p2) ndarray): The observed data.
- h0 (int): Lag parameter.
- k1 (int, optional): Rank of the front loading matrix. If None, the rank is estimated.
- k2 (int, optional): Rank of the back loading matrix. If None, the rank is estimated.
Returns
- Z ((T, k1, k2) ndarray): The estimated transformed factor matrix.
- S ((T, p1, p2) ndarray): The estimated dynamic signal $S_t = Q_1 Z_t Q_2^T$.
- Q1 ((p1, k1) ndarray): The estimated front loading matrix.
- Q2 ((p2, k2) ndarray): The estimated back loading matrix.