예제 #1
0
    def test_ma1(self):
        b = [0.6]
        ma1 = Arma([], b)
        zeros = ma1.calculate_zeros()

        self.assertEqual(len(zeros), 1)
        self.assertAlmostEqual(zeros[0], -b[0])
예제 #2
0
    def test_number_of_poles_matches_ar_order(self):
        p = 6
        rng = default_rng(4)
        ar = Arma(rng.normal(size=p), [])
        poles = ar.calculate_poles()

        self.assertEqual(len(poles), p)
예제 #3
0
    def test_ar1(self):
        a = [0.7]
        ar1 = Arma(a, [])
        poles = ar1.calculate_poles()

        self.assertEqual(len(poles), 1)
        self.assertAlmostEqual(poles[0], a[0])
예제 #4
0
    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)
예제 #5
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)
예제 #6
0
    def test_default_initial_conditions_are_zero(self):
        n1 = 5
        n2 = 8

        usage_seq = np.hstack((np.ones(n2, dtype=int), np.zeros(n1,
                                                                dtype=int)))

        seqs = []
        for i in range(2):
            if i == 0:
                ic = ([0.0], [0.0, 0.0])
            else:
                ic = None

            arma1 = Arma(
                [0.9],
                [0.1, -0.2],
                default_source=sources.GaussianNoise(),
            )
            arma2 = Arma(
                [0.1, -0.2],
                [0.3, 0.4, 0.5],
                default_source=sources.GaussianNoise(),
            )

            seq = sample_switching_models([arma1, arma2],
                                          usage_seq,
                                          initial_conditions=ic)
            seqs.append(seq)

        np.testing.assert_allclose(seqs[0], seqs[1])
예제 #7
0
    def test_number_of_zeros_matches_ma_order(self):
        q = 5
        rng = default_rng(3)
        ma = Arma([], rng.normal(size=q))
        zeros = ma.calculate_zeros()

        self.assertEqual(len(zeros), q)
예제 #8
0
    def test_model_histories_do_not_matter(self):
        n1 = 5
        n2 = 8

        usage_seq = np.hstack((np.ones(n2, dtype=int), np.zeros(n1,
                                                                dtype=int)))

        seqs = []
        for i in range(2):
            if i == 0:
                ic1 = ([0.3], [-0.2, 0.2])
                ic2 = ([0.2, 0.1], [-0.1, 0.2, 0.0])
            else:
                ic1 = None
                ic2 = None

            arma1 = Arma(
                [0.9],
                [0.1, -0.2],
                default_source=sources.GaussianNoise(),
                initial_conditions=ic1,
            )
            arma2 = Arma(
                [0.1, -0.2],
                [0.3, 0.4, 0.5],
                default_source=sources.GaussianNoise(),
                initial_conditions=ic2,
            )

            seq = sample_switching_models([arma1, arma2], usage_seq)
            seqs.append(seq)

        np.testing.assert_allclose(seqs[0], seqs[1])
예제 #9
0
    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)
예제 #10
0
    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)
예제 #11
0
    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)
예제 #12
0
    def test_inverse_arma_switches_orders(self):
        arma = Arma([-1.1, -0.6, -0.1], [0.5, 0.3])
        inv_arma = arma.inverse()

        self.assertEqual(inv_arma.p, arma.q)
        self.assertEqual(inv_arma.q, arma.p)

        self.assertEqual(len(inv_arma.a), inv_arma.p)
        self.assertEqual(len(inv_arma.b), inv_arma.q)
예제 #13
0
    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)
예제 #14
0
    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)
예제 #15
0
    def test_ma2(self):
        b = [-0.5, -0.3]
        ma2 = Arma([], b)
        zeros = ma2.calculate_zeros()

        self.assertEqual(len(zeros), 2)

        zero_prod = np.prod(zeros)
        zero_sum = np.sum(zeros)

        np.testing.assert_allclose(zero_sum, -b[0], atol=1e-8)
        np.testing.assert_allclose(zero_prod, b[1], atol=1e-8)
예제 #16
0
    def test_ar2(self):
        a = [0.5, -0.7]
        ar2 = Arma(a, [])
        poles = ar2.calculate_poles()

        self.assertEqual(len(poles), 2)

        pole_prod = np.prod(poles)
        pole_sum = np.sum(poles)

        np.testing.assert_allclose(pole_sum, a[0], atol=1e-8)
        np.testing.assert_allclose(pole_prod, -a[1], atol=1e-8)
예제 #17
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)
예제 #18
0
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_)
예제 #19
0
    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_)
예제 #20
0
 def createArma(default_source: Optional[Callable] = None):
     return Arma(
         [-1.1, -0.6, -0.1],
         [0.5, 0.3],
         bias=-0.41,
         default_source=default_source,
     )
예제 #21
0
    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)
예제 #22
0
    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)
예제 #23
0
    def test_product_of_monomials_based_on_zeros_recovers_ma_coeffs(self):
        p = 4
        q = 4
        rng = default_rng(2)
        arma = Arma(rng.normal(size=p), rng.normal(size=q))

        zeros = arma.calculate_zeros()
        coeffs = np.polynomial.polynomial.polyfromroots(zeros)

        # make sure the coefficients are real, up to tolerance
        self.assertLess(np.max(np.abs(np.imag(coeffs))), 1e-6)

        # ensure that the coefficients are ordered in the proper way
        coeffs = np.flip(coeffs.real)

        np.testing.assert_allclose(coeffs[1:], arma.b)
예제 #24
0
    def test_transform_only_one_retval_by_default(self):
        arma_hsmm = ArmaHSMM(self.armas)

        n = 16
        y_exp, _, _ = arma_hsmm.transform(n,
                                          return_input=True,
                                          return_usage_seq=True)

        arma1 = Arma([0.9], [], default_source=sources.GaussianNoise())
        arma2 = Arma([0.2, -0.1], [0.3],
                     default_source=sources.GaussianNoise())
        arma_hsmm2 = ArmaHSMM([arma1, arma2])

        y = arma_hsmm2.transform(n)

        np.testing.assert_allclose(y, y_exp)
예제 #25
0
    def test_multiple_models(self):
        n1 = 13
        n2 = 23

        rng = np.random.default_rng(2)
        X = rng.normal(size=n1 + n2)

        arma1 = Arma([0.9], [0.1, -0.2])
        arma2 = Arma([0.1, -0.2], [0.3])
        _, X_ret = sample_switching_models(
            [arma1, arma2],
            np.hstack((np.zeros(n1, dtype=int), np.ones(n2, dtype=int))),
            X=X,
            return_input=True,
        )

        np.testing.assert_allclose(X, X_ret)
예제 #26
0
    def test_multiple_models_callable_source(self):
        n1 = 13
        n2 = 23

        seed = 12
        src = sources.GaussianNoise(seed)

        X_exp = src(size=n1 + n2)

        arma1 = Arma([0.9], [0.1, -0.2])
        arma2 = Arma([0.1, -0.2], [0.3])
        _, X_ret = sample_switching_models(
            [arma1, arma2],
            np.hstack((np.zeros(n1, dtype=int), np.ones(n2, dtype=int))),
            X=sources.GaussianNoise(seed),
            return_input=True,
        )

        np.testing.assert_allclose(X_exp, X_ret)
예제 #27
0
    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)
예제 #28
0
    def test_correct_history_used_at_switch_point(self):
        n1 = 13
        n2 = 5

        arma1 = Arma([0.9], [0.1, -0.2],
                     default_source=sources.GaussianNoise())

        a2 = [0.1, -0.2]
        b2 = [0.3]
        arma2 = Arma(a2, b2, default_source=sources.GaussianNoise())

        seq, X = sample_switching_models(
            [arma1, arma2],
            np.hstack((np.zeros(n1, dtype=int), np.ones(n2, dtype=int))),
            return_input=True,
        )

        exp_ar = np.dot(np.flip(a2), seq[n1 - len(a2):n1])
        exp_ma = np.dot(np.flip(b2), X[n1 - len(b2):n1]) + X[n1]

        self.assertAlmostEqual(exp_ar + exp_ma, seq[n1])
예제 #29
0
    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)
예제 #30
0
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)