def test_second_model_history_is_not_default(self): n1 = 13 n2 = 23 # these will get overridden seq = [0] seq1_exp = [1] seq2_exp = [2] for i in range(2): arma1 = Arma([0.9], [0.1, -0.2], default_source=sources.GaussianNoise()) arma2 = Arma([0.1, -0.2], [0.3], default_source=sources.GaussianNoise()) if i == 0: seq1_exp = arma1.transform(n1) seq2_exp = arma2.transform(n2) else: seq = sample_switching_models( [arma1, arma2], np.hstack((np.zeros(n1, dtype=int), np.ones(n2, dtype=int))), ) np.testing.assert_allclose(seq[:n1], seq1_exp) self.assertGreater(np.max(np.abs(seq[n1:] - seq2_exp)), 0)
class TestArmaSourceScaling(unittest.TestCase): def setUp(self): self.source_scaling = 1.3 self.rng = np.random.default_rng(1) self.n = 1000 self.source_data = self.rng.normal(size=self.n) self.a = [-1.1, -0.6, -0.1] self.b = [0.5, 0.3] self.arma = Arma(self.a, self.b, source_scaling=self.source_scaling) self.arma_alt = Arma(self.a, self.b, source_scaling=1) self.y, self.x = self.arma.transform(X=self.source_data, return_input=True) self.y_alt, self.x_alt = self.arma_alt.transform(X=self.source_data, return_input=True) def test_output_scaled_by_appropriate_factor(self): np.testing.assert_allclose(self.y, self.source_scaling * self.y_alt) def test_input_not_scaled(self): np.testing.assert_allclose(self.x_alt, self.x) def test_default_scaling_is_one(self): arma_def = Arma(self.a, self.b) y_def = arma_def.transform(X=self.source_data) np.testing.assert_allclose(y_def, self.y_alt)
class TestArmaMonitor(unittest.TestCase): def setUp(self): self.rng = np.random.default_rng(1) self.n = 253 self.source_data = self.rng.normal(size=self.n) self.a = [-1.1, -0.6, -0.1] self.b = [0.5, 0.3] self.arma = Arma(self.a, self.b) def test_monitor_output_matches_transform_retval(self): monitor = AttributeMonitor(["output_"]) y_out = self.arma.transform(X=self.source_data, monitor=monitor) self.assertTrue(hasattr(monitor.history_, "output_")) np.testing.assert_allclose(monitor.history_.output_, y_out) def test_monitor_input_matches_actual_input(self): monitor = AttributeMonitor(["input_"]) self.arma.transform(X=self.source_data, monitor=monitor) self.assertTrue(hasattr(monitor.history_, "input_")) np.testing.assert_allclose(monitor.history_.input_, self.source_data) def test_monitor_is_initialized_on_zero_n_samples(self): monitor = AttributeMonitor(["input_", "output_"]) self.arma.transform(0, monitor=monitor) self.assertTrue(hasattr(monitor.history_, "input_")) self.assertTrue(hasattr(monitor.history_, "output_")) def test_monitor_is_initialized_on_empty_U(self): monitor = AttributeMonitor(["input_", "output_"]) self.arma.transform(X=[], monitor=monitor) self.assertTrue(hasattr(monitor.history_, "input_")) self.assertTrue(hasattr(monitor.history_, "output_")) def test_chunk_hint_does_not_affect_monitoring(self): names = ["input_", "output_"] monitor1 = AttributeMonitor(names) self.arma.transform(X=self.source_data, monitor=monitor1, chunk_hint=11) monitor2 = AttributeMonitor(names) arma2 = Arma(self.a, self.b) arma2.transform(X=self.source_data, monitor=monitor2, chunk_hint=23) np.testing.assert_allclose(monitor1.history_.input_, monitor2.history_.input_) np.testing.assert_allclose(monitor1.history_.output_, monitor2.history_.output_)
def test_chunk_hint_does_not_affect_monitoring(self): names = ["input_", "output_"] monitor1 = AttributeMonitor(names) self.arma.transform(X=self.source_data, monitor=monitor1, chunk_hint=11) monitor2 = AttributeMonitor(names) arma2 = Arma(self.a, self.b) arma2.transform(X=self.source_data, monitor=monitor2, chunk_hint=23) np.testing.assert_allclose(monitor1.history_.input_, monitor2.history_.input_) np.testing.assert_allclose(monitor1.history_.output_, monitor2.history_.output_)
def test_trivial_arma_with_bias_no_noise(self): bias = 0.75 arma = Arma([], [], bias=bias) y = arma.transform(X=np.zeros(15)) np.testing.assert_allclose(y, bias)
def test_inverse_recovers_input_with_nonzero_bias(self): arma = Arma([1.3, -0.8, 0.2, -0.1], [-0.3, 0.5], bias=0.6) inv_arma = arma.inverse() y = arma.transform(X=self.u) u_again = inv_arma.transform(X=y) np.testing.assert_allclose(self.u, u_again)
def test_inverse_recovers_input_with_zero_bias(self): arma = Arma([-1.1, -0.6, -0.1], [0.5, 0.3]) inv_arma = arma.inverse() y = arma.transform(X=self.u) u_again = inv_arma.transform(X=y) np.testing.assert_allclose(self.u, u_again)
def test_ar1_zero_input(self): alpha = 0.78 y0 = 1.0 ar = Arma([alpha], [], initial_conditions=([y0], [])) n = 10 y = ar.transform(n, X=lambda size: np.zeros(size)) y_exp = y0 * alpha**np.arange(1, n + 1) np.testing.assert_allclose(y, y_exp)
def test_single_model(self): n = 20 a = [0.9] b = [0.1, -0.2] arma1 = Arma(a, b, default_source=sources.GaussianNoise()) seq_exp = arma1.transform(n) arma2 = Arma(a, b, default_source=sources.GaussianNoise()) seq = sample_switching_models([arma2], np.zeros(n, dtype=int)) np.testing.assert_allclose(seq, seq_exp)
class TestArmaTransformZeroSamples(unittest.TestCase): def setUp(self): # this also implicitly tests that this works without default_source self.arma = Arma([1, 0.5], [-0.3]) def test_zero_samples_returns_empty_output(self): y = self.arma.transform(0) self.assertEqual(len(y), 0) def test_zero_samples_returns_empty_output_and_input_when_return_input_true( self): y, x = self.arma.transform(0, return_input=True) self.assertEqual(len(y), 0) self.assertEqual(len(x), 0) def test_empty_x_returns_empty(self): y, x = self.arma.transform(X=[], return_input=True) self.assertEqual(len(y), 0) self.assertEqual(len(x), 0)
def test_asymptotic_value_constant_noise(self): bias = 0.32 arma = Arma([-1.1, -0.6, -0.1], [0.5, 0.3], bias=bias) # the asymptotic value y0 should be given by # y0 * (1 - sum(a)) = bias + x0 * (1 + sum(b)) # so: y0 = (bias + x0 * (1 + sum(b))) / (1 - sum(a)) x0 = -0.5 # give it enough time to converge n = 1000 y = arma.transform(X=x0 * np.ones(n)) y0 = (bias + x0 * (1 + np.sum(arma.b))) / (1 - np.sum(arma.a)) self.assertAlmostEqual(y[-1], y0)
def test_ma_is_convolution(self): rng = default_rng(1) q = 3 b = rng.normal(size=q) ma = Arma([], b) n = 52 x = rng.normal(size=n) y = ma.transform(X=x) x_padded = np.hstack((np.zeros(q), x)) b_ext = np.hstack(([1], b)) y_exp = np.convolve(x_padded, b_ext, mode="valid") np.testing.assert_allclose(y, y_exp)
def test_initial_conditions_parameter_is_obeyed(self): a = [0.8] b = [0.1, 0.2] n = 32 ic = ([-0.5], [-0.5, 0.3]) arma = Arma(a, b, default_source=sources.GaussianNoise(), initial_conditions=ic) seq_exp = arma.transform(n) arma = Arma(a, b, default_source=sources.GaussianNoise()) seq = sample_switching_models([arma], np.zeros(n, dtype=int), initial_conditions=ic) np.testing.assert_allclose(seq, seq_exp)
def test_default_scaling_is_one(self): arma_def = Arma(self.a, self.b) y_def = arma_def.transform(X=self.source_data) np.testing.assert_allclose(y_def, self.y_alt)