def model_local_level(endog=None, params=None, direct=False): if endog is None: y1 = 10.2394 endog = np.r_[y1, [1] * 9] if params is None: params = [1.993, 8.253] sigma2_y, sigma2_mu = params if direct: mod = None # Construct the basic representation ssm = KalmanSmoother(k_endog=1, k_states=1, k_posdef=1) ssm.bind(endog) init = Initialization(ssm.k_states, initialization_type='diffuse') ssm.initialize(init) # ssm.filter_univariate = True # should not be required # Fill in the system matrices for a local level model ssm['design', :] = 1 ssm['obs_cov', :] = sigma2_y ssm['transition', :] = 1 ssm['selection', :] = 1 ssm['state_cov', :] = sigma2_mu else: mod = UnobservedComponents(endog, 'llevel') mod.update(params) ssm = mod.ssm ssm.initialize(Initialization(ssm.k_states, 'diffuse')) return mod, ssm
def test_irrelevant_state(): # This test records a case in which exact diffuse initialization leads to # numerical problems, because the existence of an irrelevant state # initialized as diffuse means that there is never a transition to the # usual Kalman filter. endog = macrodata.infl spec = { 'freq_seasonal': [{'period': 8, 'harmonics': 6}, {'period': 36, 'harmonics': 6}] } # Approximate diffuse version mod = UnobservedComponents(endog, 'llevel', **spec) mod.ssm.initialization = Initialization(mod.k_states, 'approximate_diffuse') res = mod.smooth([3.4, 7.2, 0.01, 0.01]) # Exact diffuse version mod2 = UnobservedComponents(endog, 'llevel', **spec) mod2.ssm.filter_univariate = True mod2.ssm.initialization = Initialization(mod2.k_states, 'diffuse') res2 = mod2.smooth([3.4, 7.2, 0.01, 0.01]) # Check that e.g. the filtered state for the level is equal assert_allclose(res.filtered_state[0, 25:], res2.filtered_state[0, 25:], atol=1e-5)
def model_local_linear_trend(endog=None, params=None, direct=False): if endog is None: y1 = 10.2394 y2 = 4.2039 y3 = 6.123123 endog = np.r_[y1, y2, y3, [1] * 7] if params is None: params = [1.993, 8.253, 2.334] sigma2_y, sigma2_mu, sigma2_beta = params if direct: mod = None # Construct the basic representation ssm = KalmanSmoother(k_endog=1, k_states=2, k_posdef=2) ssm.bind(endog) init = Initialization(ssm.k_states, initialization_type='diffuse') ssm.initialize(init) # ssm.filter_univariate = True # should not be required # Fill in the system matrices for a local level model ssm['design', 0, 0] = 1 ssm['obs_cov', 0, 0] = sigma2_y ssm['transition'] = np.array([[1, 1], [0, 1]]) ssm['selection'] = np.eye(2) ssm['state_cov'] = np.diag([sigma2_mu, sigma2_beta]) else: mod = UnobservedComponents(endog, 'lltrend') mod.update(params) ssm = mod.ssm ssm.initialize(Initialization(ssm.k_states, 'diffuse')) return mod, ssm
def setup_class(cls, **kwargs): k_states = 2 init = Initialization(k_states) init.set(0, 'diffuse') init.set(1, 'stationary') if kwargs.pop('approx', False): init_approx = Initialization(k_states) init_approx.set(0, 'approximate_diffuse') init_approx.set(1, 'stationary') kwargs['init_approx'] = init_approx super(CheckVAR1Mixed, cls).setup_class(init=init, **kwargs)
def test_global_stationary(): # Test for global approximate diffuse initialization # - 1-dimensional - endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(1, 0, 0), trend='c') # no intercept intercept = 0 phi = 0.5 sigma2 = 2. mod.update(np.r_[intercept, phi, sigma2]) init = Initialization(mod.k_states, 'stationary') check_initialization(mod, init, [0], np.diag([0]), np.eye(1) * sigma2 / (1 - phi**2)) # intercept intercept = 1.2 phi = 0.5 sigma2 = 2. mod.update(np.r_[intercept, phi, sigma2]) init = Initialization(mod.k_states, 'stationary') check_initialization(mod, init, [intercept / (1 - phi)], np.diag([0]), np.eye(1) * sigma2 / (1 - phi**2)) # - n-dimensional - endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(2, 0, 0), trend='c') # no intercept intercept = 0 phi = [0.5, -0.2] sigma2 = 2. mod.update(np.r_[intercept, phi, sigma2]) init = Initialization(mod.k_states, 'stationary') T = np.array([[0.5, 1], [-0.2, 0]]) Q = np.diag([sigma2, 0]) desired_cov = solve_discrete_lyapunov(T, Q) check_initialization(mod, init, [0, 0], np.diag([0, 0]), desired_cov) # intercept intercept = 1.2 phi = [0.5, -0.2] sigma2 = 2. mod.update(np.r_[intercept, phi, sigma2]) init = Initialization(mod.k_states, 'stationary') desired_intercept = np.linalg.inv(np.eye(2) - T).dot([intercept, 0]) check_initialization(mod, init, desired_intercept, np.diag([0, 0]), desired_cov)
def test_global_diffuse(): # Test for global diffuse initialization # - 1-dimensional - endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(1, 0, 0)) init = Initialization(mod.k_states, 'diffuse') check_initialization(mod, init, [0], np.eye(1), np.diag([0])) # - n-dimensional - endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(2, 0, 0)) init = Initialization(mod.k_states, 'diffuse') check_initialization(mod, init, [0, 0], np.eye(2), np.diag([0, 0]))
def model_common_level(endog=None, params=None, restricted=False): if endog is None: y11 = 10.2394 y21 = 8.2304 endog = np.column_stack([np.r_[y11, [1] * 9], np.r_[y21, [1] * 9]]) if params is None: params = [0.1111, 3.2324] theta, sigma2_mu = params # sigma2_1 = 1 # sigma_12 = 0 # sigma2_2 = 1 if not restricted: # Construct the basic representation ssm = KalmanSmoother(k_endog=2, k_states=2, k_posdef=1) ssm.bind(endog.T) init = Initialization(ssm.k_states, initialization_type='diffuse') ssm.initialize(init) # ssm.filter_univariate = True # should not be required # Fill in the system matrices for a common trend model ssm['design'] = np.array([[1, 0], [theta, 1]]) ssm['obs_cov'] = np.eye(2) ssm['transition'] = np.eye(2) ssm['selection', 0, 0] = 1 ssm['state_cov', 0, 0] = sigma2_mu else: # Construct the basic representation ssm = KalmanSmoother(k_endog=2, k_states=1, k_posdef=1) ssm.bind(endog.T) init = Initialization(ssm.k_states, initialization_type='diffuse') ssm.initialize(init) # ssm.filter_univariate = True # should not be required # Fill in the system matrices for a local level model ssm['design'] = np.array([[1, theta]]).T ssm['obs_cov'] = np.eye(2) ssm['transition', :] = 1 ssm['selection', :] = 1 ssm['state_cov', :] = sigma2_mu return ssm
def test_global_approximate_diffuse(): # Test for global approximate diffuse initialization # - 1-dimensional - endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(1, 0, 0)) init = Initialization(mod.k_states, 'approximate_diffuse') check_initialization(mod, init, [0], np.diag([0]), np.eye(1) * 1e6) init = Initialization(mod.k_states, 'approximate_diffuse', constant=[1.2]) check_initialization(mod, init, [1.2], np.diag([0]), np.eye(1) * 1e6) init = Initialization(mod.k_states, 'approximate_diffuse', approximate_diffuse_variance=1e10) check_initialization(mod, init, [0], np.diag([0]), np.eye(1) * 1e10) # - n-dimensional - endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(2, 0, 0)) init = Initialization(mod.k_states, 'approximate_diffuse') check_initialization(mod, init, [0, 0], np.diag([0, 0]), np.eye(2) * 1e6) init = Initialization(mod.k_states, 'approximate_diffuse', constant=[1.2, -0.2]) check_initialization(mod, init, [1.2, -0.2], np.diag([0, 0]), np.eye(2) * 1e6) init = Initialization(mod.k_states, 'approximate_diffuse', approximate_diffuse_variance=1e10) check_initialization(mod, init, [0, 0], np.diag([0, 0]), np.eye(2) * 1e10)
def model_dfm(endog=None, params=None, factor_order=2): if endog is None: levels = macrodata[['realgdp', 'realcons']] endog = np.log(levels).iloc[:21].diff().iloc[1:] * 400 if params is None: params = np.r_[0.5, 1., 1.5, 2., 0.9, 0.1] # Model mod = DynamicFactor(endog, k_factors=1, factor_order=factor_order) mod.update(params) ssm = mod.ssm ssm.filter_univariate = True init = Initialization(ssm.k_states, 'diffuse') ssm.initialize(init) return mod, ssm
def setup_class(cls, *args, **kwargs): init_approx = kwargs.pop('init_approx', None) super(CheckApproximateDiffuseMixin, cls).setup_class(*args, **kwargs) # Get the approximate diffuse results kappa = cls.approximate_diffuse_variance if init_approx is None: init_approx = Initialization(cls.ssm.k_states, 'approximate_diffuse', approximate_diffuse_variance=kappa) cls.ssm.initialize(init_approx) cls.results_b = cls.ssm.smooth() # Instruct the tests not to test against the first d values cls.rtol_diffuse = np.inf
def model_var1(endog=None, params=None, measurement_error=False, init=None): if endog is None: levels = macrodata[['realgdp', 'realcons']] endog = np.log(levels).iloc[:21].diff().iloc[1:] * 400 if params is None: params = np.r_[0.5, 0.3, 0.2, 0.4, 2**0.5, 0, 3**0.5] if measurement_error: params = np.r_[params, 4, 5] # Model mod = VARMAX(endog, order=(1, 0), trend='n', measurement_error=measurement_error) mod.update(params) ssm = mod.ssm if init is None: init = Initialization(ssm.k_states, 'diffuse') ssm.initialize(init) return mod, ssm
def test_global_known(): # Test for global known initialization # - 1-dimensional - endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(1, 0, 0)) # Known, mean init = Initialization(mod.k_states, 'known', constant=[1.5]) check_initialization(mod, init, [1.5], np.diag([0]), np.diag([0])) # Known, covariance init = Initialization(mod.k_states, 'known', stationary_cov=np.diag([1])) check_initialization(mod, init, [0], np.diag([0]), np.diag([1])) # Known, both init = Initialization(mod.k_states, 'known', constant=[1.5], stationary_cov=np.diag([1])) check_initialization(mod, init, [1.5], np.diag([0]), np.diag([1])) # - n-dimensional - endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(2, 0, 0)) # Known, mean init = Initialization(mod.k_states, 'known', constant=[1.5, -0.2]) check_initialization(mod, init, [1.5, -0.2], np.diag([0, 0]), np.diag([0, 0])) # Known, covariance init = Initialization(mod.k_states, 'known', stationary_cov=np.diag([1, 4.2])) check_initialization(mod, init, [0, 0], np.diag([0, 0]), np.diag([1, 4.2])) # Known, both init = Initialization(mod.k_states, 'known', constant=[1.5, -0.2], stationary_cov=np.diag([1, 4.2])) check_initialization(mod, init, [1.5, -0.2], np.diag([0, 0]), np.diag([1, 4.2]))
def test_mixed_stationary(): # More specific tests when one or more blocks are initialized as stationary endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(2, 1, 0)) phi = [0.5, -0.2] sigma2 = 2. mod.update(np.r_[phi, sigma2]) init = Initialization(mod.k_states) init.set(0, 'diffuse') init.set((1, 3), 'stationary') desired_cov = np.zeros((3, 3)) T = np.array([[0.5, 1], [-0.2, 0]]) Q = np.diag([sigma2, 0]) desired_cov[1:, 1:] = solve_discrete_lyapunov(T, Q) check_initialization(mod, init, [0, 0, 0], np.diag([1, 0, 0]), desired_cov) init.clear() init.set(0, 'diffuse') init.set(1, 'stationary') init.set(2, 'approximate_diffuse') T = np.array([[0.5]]) Q = np.diag([sigma2]) desired_cov = np.diag([0, np.squeeze(solve_discrete_lyapunov(T, Q)), 1e6]) check_initialization(mod, init, [0, 0, 0], np.diag([1, 0, 0]), desired_cov) init.clear() init.set(0, 'diffuse') init.set(1, 'stationary') init.set(2, 'stationary') desired_cov[2, 2] = 0 check_initialization(mod, init, [0, 0, 0], np.diag([1, 0, 0]), desired_cov) # Test with a VAR model endog = np.zeros((10, 2)) mod = varmax.VARMAX(endog, order=(1, 0), ) intercept = [1.5, -0.1] transition = np.array([[0.5, -0.2], [0.1, 0.8]]) cov = np.array([[1.2, -0.4], [-0.4, 0.4]]) tril = np.tril_indices(2) params = np.r_[intercept, transition.ravel(), np.linalg.cholesky(cov)[tril]] mod.update(params) # > stationary, global init = Initialization(mod.k_states, 'stationary') desired_intercept = np.linalg.solve(np.eye(2) - transition, intercept) desired_cov = solve_discrete_lyapunov(transition, cov) check_initialization(mod, init, desired_intercept, np.diag([0, 0]), desired_cov) # > diffuse, global init.set(None, 'diffuse') check_initialization(mod, init, [0, 0], np.eye(2), np.diag([0, 0])) # > stationary, individually init.unset(None) init.set(0, 'stationary') init.set(1, 'stationary') a, Pinf, Pstar = init(model=mod) desired_intercept = [intercept[0] / (1 - transition[0, 0]), intercept[1] / (1 - transition[1, 1])] desired_cov = np.diag([cov[0, 0] / (1 - transition[0, 0]**2), cov[1, 1] / (1 - transition[1, 1]**2)]) check_initialization(mod, init, desired_intercept, np.diag([0, 0]), desired_cov)
def test_mixed_stationary(): # More specific tests when one or more blocks are initialized as stationary endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(2, 1, 0)) phi = [0.5, -0.2] sigma2 = 2. mod.update(np.r_[phi, sigma2]) init = Initialization(mod.k_states) init.set(0, 'diffuse') init.set((1, 3), 'stationary') desired_cov = np.zeros((3, 3)) T = np.array([[0.5, 1], [-0.2, 0]]) Q = np.diag([sigma2, 0]) desired_cov[1:, 1:] = solve_discrete_lyapunov(T, Q) check_initialization(mod, init, [0, 0, 0], np.diag([1, 0, 0]), desired_cov) init.clear() init.set(0, 'diffuse') init.set(1, 'stationary') init.set(2, 'approximate_diffuse') T = np.array([[0.5]]) Q = np.diag([sigma2]) desired_cov = np.diag([0, np.squeeze(solve_discrete_lyapunov(T, Q)), 1e6]) check_initialization(mod, init, [0, 0, 0], np.diag([1, 0, 0]), desired_cov) init.clear() init.set(0, 'diffuse') init.set(1, 'stationary') init.set(2, 'stationary') desired_cov[2, 2] = 0 check_initialization(mod, init, [0, 0, 0], np.diag([1, 0, 0]), desired_cov) # Test with a VAR model endog = np.zeros((10, 2)) mod = varmax.VARMAX( endog, order=(1, 0), ) intercept = [1.5, -0.1] transition = np.array([[0.5, -0.2], [0.1, 0.8]]) cov = np.array([[1.2, -0.4], [-0.4, 0.4]]) tril = np.tril_indices(2) params = np.r_[intercept, transition.ravel(), np.linalg.cholesky(cov)[tril]] mod.update(params) # > stationary, global init = Initialization(mod.k_states, 'stationary') desired_intercept = np.linalg.solve(np.eye(2) - transition, intercept) desired_cov = solve_discrete_lyapunov(transition, cov) check_initialization(mod, init, desired_intercept, np.diag([0, 0]), desired_cov) # > diffuse, global init.set(None, 'diffuse') check_initialization(mod, init, [0, 0], np.eye(2), np.diag([0, 0])) # > stationary, individually init.unset(None) init.set(0, 'stationary') init.set(1, 'stationary') a, Pinf, Pstar = init(model=mod) desired_intercept = [ intercept[0] / (1 - transition[0, 0]), intercept[1] / (1 - transition[1, 1]) ] desired_cov = np.diag([ cov[0, 0] / (1 - transition[0, 0]**2), cov[1, 1] / (1 - transition[1, 1]**2) ]) check_initialization(mod, init, desired_intercept, np.diag([0, 0]), desired_cov)
def test_nested(): endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(6, 0, 0)) phi = [0.5, -0.2, 0.1, 0.0, 0.1, 0.0] sigma2 = 2. mod.update(np.r_[phi, sigma2]) # Create the initialization object as a series of nested objects init1_1 = Initialization(3) init1_1_1 = Initialization(2, 'stationary') init1_1_2 = Initialization(1, 'approximate_diffuse', approximate_diffuse_variance=1e9) init1_1.set((0, 2), init1_1_1) init1_1.set(2, init1_1_2) init1_2 = Initialization(3) init1_2_1 = Initialization(1, 'known', constant=[1], stationary_cov=[[2.]]) init1_2.set(0, init1_2_1) init1_2_2 = Initialization(1, 'diffuse') init1_2.set(1, init1_2_2) init1_2_3 = Initialization(1, 'approximate_diffuse') init1_2.set(2, init1_2_3) init = Initialization(6) init.set((0, 3), init1_1) init.set((3, 6), init1_2) # Check the output desired_cov = np.zeros((6, 6)) T = np.array([[0.5, 1], [-0.2, 0]]) Q = np.array([[sigma2, 0], [0, 0]]) desired_cov[:2, :2] = solve_discrete_lyapunov(T, Q) desired_cov[2, 2] = 1e9 desired_cov[3, 3] = 2. desired_cov[5, 5] = 1e6 check_initialization(mod, init, [0, 0, 0, 1, 0, 0], np.diag([0, 0, 0, 0, 1, 0]), desired_cov)
def test_invalid(): # Invalid initializations (also tests for some invalid calls to set) assert_raises(ValueError, Initialization, 5, '') assert_raises(ValueError, Initialization, 5, 'stationary', constant=[1, 2]) assert_raises(ValueError, Initialization, 5, 'stationary', stationary_cov=[1, 2]) assert_raises(ValueError, Initialization, 5, 'known') assert_raises(ValueError, Initialization, 5, 'known', constant=[1]) assert_raises(ValueError, Initialization, 5, 'known', stationary_cov=[0]) # Invalid set() / unset() calls init = Initialization(5) assert_raises(ValueError, init.set, -1, 'diffuse') assert_raises(ValueError, init.unset, -1) assert_raises(ValueError, init.set, 5, 'diffuse') assert_raises(ValueError, init.set, 'x', 'diffuse') assert_raises(ValueError, init.unset, 'x') assert_raises(ValueError, init.set, (1, 2, 3), 'diffuse') assert_raises(ValueError, init.unset, (1, 2, 3)) init.set(None, 'diffuse') assert_raises(ValueError, init.set, 1, 'diffuse') init.clear() init.set(1, 'diffuse') assert_raises(ValueError, init.set, None, 'stationary') init.clear() assert_raises(ValueError, init.unset, 1) # Invalid __call__ init = Initialization(2) assert_raises(ValueError, init) init = Initialization(2, 'stationary') assert_raises(ValueError, init)
def test_mixed_basic(): # Performs a number of tests for setting different initialization for # different blocks # - 2-dimensional - endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(2, 0, 0)) phi = [0.5, -0.2] sigma2 = 2. mod.update(np.r_[phi, sigma2]) # known has constant init = Initialization(mod.k_states) init.set(0, 'known', constant=[1.2]) # > known has constant init.set(1, 'known', constant=[-0.2]) check_initialization(mod, init, [1.2, -0.2], np.diag([0, 0]), np.diag([0, 0])) # > diffuse init.unset(1) init.set(1, 'diffuse') check_initialization(mod, init, [1.2, 0], np.diag([0, 1]), np.diag([0, 0])) # > approximate diffuse init.unset(1) init.set(1, 'approximate_diffuse') check_initialization(mod, init, [1.2, 0], np.diag([0, 0]), np.diag([0, 1e6])) # > stationary init.unset(1) init.set(1, 'stationary') check_initialization(mod, init, [1.2, 0], np.diag([0, 0]), np.diag([0, 0])) # known has cov init = Initialization(mod.k_states) init.set(0, 'known', stationary_cov=np.diag([1])) init.set(1, 'diffuse') check_initialization(mod, init, [0, 0], np.diag([0, 1]), np.diag([1, 0])) # known has both init = Initialization(mod.k_states) init.set(0, 'known', constant=[1.2], stationary_cov=np.diag([1])) init.set(1, 'diffuse') check_initialization(mod, init, [1.2, 0], np.diag([0, 1]), np.diag([1, 0])) # - 3-dimensional - endog = np.zeros(10) mod = sarimax.SARIMAX(endog, order=(3, 0, 0)) # known has constant init = Initialization(mod.k_states) init.set((0, 2), 'known', constant=[1.2, -0.2]) init.set(2, 'diffuse') check_initialization(mod, init, [1.2, -0.2, 0], np.diag([0, 0, 1]), np.diag([0, 0, 0])) # known has cov init = Initialization(mod.k_states) init.set((0, 2), 'known', stationary_cov=np.diag([1, 4.2])) init.set(2, 'diffuse') check_initialization(mod, init, [0, 0, 0], np.diag([0, 0, 1]), np.diag([1, 4.2, 0])) # known has both init = Initialization(mod.k_states) init.set((0, 2), 'known', constant=[1.2, -0.2], stationary_cov=np.diag([1, 4.2])) init.set(2, 'diffuse') check_initialization(mod, init, [1.2, -0.2, 0], np.diag([0, 0, 1]), np.diag([1, 4.2, 0]))