Ejemplo n.º 1
0
def test_DiscreteMarkovChain_point():
    test_Gammas = at.as_tensor_variable(np.array([[[1.0, 0.0], [0.0, 1.0]]]))

    with pm.Model():
        # XXX: `draw_values` won't use the `Deterministic`s values in the `point` map!
        # Also, `Constant` is only for integer types (?!), so we can't use that.
        test_gamma_0 = pm.Dirichlet("gamma_0", np.r_[1.0, 1000.0], shape=2)
        test_point = {"gamma_0": np.r_[1.0, 0.0]}
        assert np.all(
            DiscreteMarkovChain.dist(test_Gammas, test_gamma_0,
                                     shape=10).random(point=test_point) == 0)
        assert np.all(
            DiscreteMarkovChain.dist(test_Gammas, 1.0 -
                                     test_gamma_0, shape=10).random(
                                         point=test_point) == 1)
Ejemplo n.º 2
0
def test_DiscreteMarkovChain_logp(Gammas, gamma_0, obs, exp_res):
    aesara.config.compute_test_value = "warn"
    test_dist = DiscreteMarkovChain.dist(Gammas, gamma_0, shape=obs.shape[-1])
    test_logp_tt = test_dist.logp(obs)
    test_logp_val = test_logp_tt.eval()

    if exp_res is None:

        def logp_single_chain(Gammas, gamma_0, obs):
            state_transitions = np.stack([obs[:-1], obs[1:]]).T

            p_S_0_to_1 = gamma_0.dot(Gammas[0])

            p_S_obs = np.empty_like(obs, dtype=np.float64)
            p_S_obs[0] = p_S_0_to_1[obs[0]]

            for t, (S_tm1, S_t) in enumerate(state_transitions):
                p_S_obs[t + 1] = Gammas[t, S_tm1, S_t]

            return np.log(p_S_obs)

        logp_fn = np.vectorize(logp_single_chain,
                               signature="(n,m,m),(m),(n)->(n)")

        Gammas = np.broadcast_to(Gammas, (obs.shape[0], ) + Gammas.shape[-2:])
        exp_res = logp_fn(Gammas, gamma_0, obs)

        exp_res = exp_res.sum(-1)

    assert np.allclose(test_logp_val, exp_res)
Ejemplo n.º 3
0
def test_DiscreteMarkovChain_random():
    # A single transition matrix and initial probabilities vector for each
    # element in the state sequence
    test_Gamma = np.array([[[1.0, 0.0], [0.0, 1.0]]])
    test_gamma_0 = np.r_[0.0, 1.0]
    test_sample = DiscreteMarkovChain.dist(test_Gamma, test_gamma_0,
                                           shape=10).random()
    assert np.all(test_sample == 1)

    test_sample = DiscreteMarkovChain.dist(test_Gamma,
                                           1.0 - test_gamma_0,
                                           shape=10).random()
    assert np.all(test_sample == 0)
    test_sample = DiscreteMarkovChain.dist(test_Gamma, test_gamma_0,
                                           shape=10).random(size=12)
    assert test_sample.shape == (
        12,
        10,
    )

    test_sample = DiscreteMarkovChain.dist(test_Gamma, test_gamma_0,
                                           shape=10).random(size=2)
    assert np.array_equal(test_sample,
                          np.stack([np.ones(10), np.ones(10)], 0).astype(int))

    # Now, the same set-up, but--this time--generate two state sequences
    # samples
    test_Gamma = np.array([[[0.8, 0.2], [0.2, 0.8]]])
    test_gamma_0 = np.r_[0.2, 0.8]
    test_sample = DiscreteMarkovChain.dist(test_Gamma, test_gamma_0,
                                           shape=10).random(size=2)
    # TODO: Fix the seed, and make sure there's at least one 0 and 1?
    assert test_sample.shape == (2, 10)

    # Two transition matrices--for two distinct state sequences--and one vector
    # of initial probs.
    test_Gamma = np.stack([
        np.array([[[1.0, 0.0], [0.0, 1.0]]]),
        np.array([[[1.0, 0.0], [0.0, 1.0]]])
    ])
    test_gamma_0 = np.r_[0.0, 1.0]
    test_dist = DiscreteMarkovChain.dist(test_Gamma,
                                         test_gamma_0,
                                         shape=(2, 10))
    test_sample = test_dist.random()
    assert np.array_equal(test_sample,
                          np.stack([np.ones(10), np.ones(10)], 0).astype(int))
    assert test_sample.shape == (2, 10)

    # Now, the same set-up, but--this time--generate three state sequence
    # samples
    test_sample = test_dist.random(size=3)
    assert np.array_equal(
        test_sample,
        np.tile(
            np.stack([np.ones(10), np.ones(10)], 0).astype(int), (3, 1, 1)),
    )
    assert test_sample.shape == (3, 2, 10)

    # Two transition matrices and initial probs. for two distinct state
    # sequences
    test_Gamma = np.stack([
        np.array([[[1.0, 0.0], [0.0, 1.0]]]),
        np.array([[[1.0, 0.0], [0.0, 1.0]]])
    ])
    test_gamma_0 = np.stack([np.r_[0.0, 1.0], np.r_[1.0, 0.0]])
    test_dist = DiscreteMarkovChain.dist(test_Gamma,
                                         test_gamma_0,
                                         shape=(2, 10))
    test_sample = test_dist.random()
    assert np.array_equal(test_sample,
                          np.stack([np.ones(10), np.zeros(10)], 0).astype(int))
    assert test_sample.shape == (2, 10)

    # Now, the same set-up, but--this time--generate three state sequence
    # samples
    test_sample = test_dist.random(size=3)
    assert np.array_equal(
        test_sample,
        np.tile(
            np.stack([np.ones(10), np.zeros(10)], 0).astype(int), (3, 1, 1)),
    )
    assert test_sample.shape == (3, 2, 10)

    # "Time"-varying transition matrices with a single vector of initial
    # probabilities
    test_Gamma = np.stack(
        [
            np.array([[0.0, 1.0], [1.0, 0.0]]),
            np.array([[0.0, 1.0], [1.0, 0.0]]),
            np.array([[1.0, 0.0], [0.0, 1.0]]),
        ],
        axis=0,
    )
    test_gamma_0 = np.r_[1, 0]

    test_dist = DiscreteMarkovChain.dist(test_Gamma, test_gamma_0, shape=3)
    test_sample = test_dist.random()
    assert np.array_equal(test_sample, np.r_[1, 0, 0])

    # Now, the same set-up, but--this time--generate three state sequence
    # samples
    test_sample = test_dist.random(size=3)
    assert np.array_equal(test_sample,
                          np.tile(np.r_[1, 0, 0].astype(int), (3, 1)))

    # "Time"-varying transition matrices with two initial
    # probabilities vectors
    test_Gamma = np.stack(
        [
            np.array([[0.0, 1.0], [1.0, 0.0]]),
            np.array([[0.0, 1.0], [1.0, 0.0]]),
            np.array([[1.0, 0.0], [0.0, 1.0]]),
        ],
        axis=0,
    )
    test_gamma_0 = np.array([[1, 0], [0, 1]])

    test_dist = DiscreteMarkovChain.dist(test_Gamma,
                                         test_gamma_0,
                                         shape=(2, 3))
    test_sample = test_dist.random()
    assert np.array_equal(test_sample, np.array([[1, 0, 0], [0, 1, 1]]))

    # Now, the same set-up, but--this time--generate three state sequence
    # samples
    test_sample = test_dist.random(size=3)
    assert np.array_equal(
        test_sample,
        np.tile(np.array([[1, 0, 0], [0, 1, 1]]).astype(int), (3, 1, 1)))

    # Two "Time"-varying transition matrices with two initial
    # probabilities vectors
    test_Gamma = np.stack(
        [
            [
                np.array([[0.0, 1.0], [1.0, 0.0]]),
                np.array([[0.0, 1.0], [1.0, 0.0]]),
                np.array([[1.0, 0.0], [0.0, 1.0]]),
            ],
            [
                np.array([[1.0, 0.0], [0.0, 1.0]]),
                np.array([[1.0, 0.0], [0.0, 1.0]]),
                np.array([[0.0, 1.0], [1.0, 0.0]]),
            ],
        ],
        axis=0,
    )
    test_gamma_0 = np.array([[1, 0], [0, 1]])

    test_dist = DiscreteMarkovChain.dist(test_Gamma,
                                         test_gamma_0,
                                         shape=(2, 3))
    test_sample = test_dist.random()
    assert np.array_equal(test_sample, np.array([[1, 0, 0], [1, 1, 0]]))

    # Now, the same set-up, but--this time--generate three state sequence
    # samples
    test_sample = test_dist.random(size=3)
    assert np.array_equal(
        test_sample,
        np.tile(np.array([[1, 0, 0], [1, 1, 0]]).astype(int), (3, 1, 1)))
Ejemplo n.º 4
0
def test_DiscreteMarkovChain_logp():
    theano.config.compute_test_value = "warn"

    # A single transition matrix and initial probabilities vector for each
    # element in the state sequence
    test_Gammas = np.array([[[0.0, 1.0], [1.0, 0.0]]])
    test_gamma_0 = np.r_[1.0, 0.0]
    test_obs = np.r_[1, 0, 1, 0]

    test_dist = DiscreteMarkovChain.dist(test_Gammas,
                                         test_gamma_0,
                                         shape=test_obs.shape[-1])
    test_logp_tt = test_dist.logp(test_obs)
    assert test_logp_tt.eval() == 0

    # "Time"-varying transition matrices with a single vector of initial
    # probabilities
    test_Gammas = np.stack(
        [
            np.array([[0.0, 1.0], [1.0, 0.0]]),
            np.array([[0.0, 1.0], [1.0, 0.0]]),
            np.array([[0.0, 1.0], [1.0, 0.0]]),
            np.array([[0.0, 1.0], [1.0, 0.0]]),
        ],
        axis=0,
    )

    test_gamma_0 = np.r_[1.0, 0.0]

    test_obs = np.r_[1, 0, 1, 0]

    test_dist = DiscreteMarkovChain.dist(test_Gammas,
                                         test_gamma_0,
                                         shape=test_obs.shape[-1])

    test_logp_tt = test_dist.logp(test_obs)

    assert test_logp_tt.eval() == 0

    # Static transition matrix and two state sequences
    test_Gammas = np.array([[[0.0, 1.0], [1.0, 0.0]]])

    test_obs = np.array([[1, 0, 1, 0], [0, 1, 0, 1]])

    test_gamma_0 = np.r_[0.5, 0.5]

    test_dist = DiscreteMarkovChain.dist(test_Gammas,
                                         test_gamma_0,
                                         shape=test_obs.shape[-1])

    test_logp_tt = test_dist.logp(test_obs)

    test_logp = test_logp_tt.eval()
    assert test_logp[0] == test_logp[1]

    # Time-varying transition matrices and two state sequences
    test_Gammas = np.stack(
        [
            np.array([[0.0, 1.0], [1.0, 0.0]]),
            np.array([[0.0, 1.0], [1.0, 0.0]]),
            np.array([[0.0, 1.0], [1.0, 0.0]]),
            np.array([[0.0, 1.0], [1.0, 0.0]]),
        ],
        axis=0,
    )

    test_obs = np.array([[1, 0, 1, 0], [0, 1, 0, 1]])

    test_gamma_0 = np.r_[0.5, 0.5]

    test_dist = DiscreteMarkovChain.dist(test_Gammas,
                                         test_gamma_0,
                                         shape=test_obs.shape[-1])

    test_logp_tt = test_dist.logp(test_obs)

    test_logp = test_logp_tt.eval()
    assert test_logp[0] == test_logp[1]

    # Two sets of time-varying transition matrices and two state sequences
    test_Gammas = np.stack(
        [
            [
                np.array([[0.0, 1.0], [1.0, 0.0]]),
                np.array([[0.0, 1.0], [1.0, 0.0]]),
                np.array([[0.0, 1.0], [1.0, 0.0]]),
                np.array([[0.0, 1.0], [1.0, 0.0]]),
            ],
            [
                np.array([[1.0, 0.0], [0.0, 1.0]]),
                np.array([[1.0, 0.0], [0.0, 1.0]]),
                np.array([[1.0, 0.0], [0.0, 1.0]]),
                np.array([[1.0, 0.0], [0.0, 1.0]]),
            ],
        ],
        axis=0,
    )

    test_obs = np.array([[1, 0, 1, 0], [0, 0, 0, 0]])

    test_gamma_0 = np.r_[0.5, 0.5]

    test_dist = DiscreteMarkovChain.dist(test_Gammas,
                                         test_gamma_0,
                                         shape=test_obs.shape[-1])

    test_logp_tt = test_dist.logp(test_obs)

    test_logp = test_logp_tt.eval()
    assert test_logp[0] == test_logp[1]

    # Two sets of time-varying transition matrices--via `gamma_0`
    # broadcasting--and two state sequences
    test_gamma_0 = np.array([[0.5, 0.5], [0.5, 0.5]])

    test_dist = DiscreteMarkovChain.dist(test_Gammas,
                                         test_gamma_0,
                                         shape=test_obs.shape[-1])

    test_logp_tt = test_dist.logp(test_obs)

    test_logp = test_logp_tt.eval()
    assert test_logp[0] == test_logp[1]

    # "Time"-varying transition matrices with a single vector of initial
    # probabilities, but--this time--with better test values
    test_Gammas = np.stack(
        [
            np.array([[0.1, 0.9], [0.5, 0.5]]),
            np.array([[0.2, 0.8], [0.6, 0.4]]),
            np.array([[0.3, 0.7], [0.7, 0.3]]),
            np.array([[0.4, 0.6], [0.8, 0.2]]),
        ],
        axis=0,
    )

    test_gamma_0 = np.r_[0.3, 0.7]

    test_obs = np.r_[1, 0, 1, 0]

    test_dist = DiscreteMarkovChain.dist(test_Gammas,
                                         test_gamma_0,
                                         shape=test_obs.shape[-1])

    test_logp_tt = test_dist.logp(test_obs)

    logp_res = test_logp_tt.eval()

    logp_exp = np.concatenate(
        [
            test_gamma_0.dot(test_Gammas[0])[None, ...],
            test_Gammas[(np.ogrid[1:4], test_obs[:-1])],
        ],
        axis=-2,
    )
    logp_exp = logp_exp[(np.ogrid[:4], test_obs)]
    logp_exp = np.log(logp_exp).sum()
    assert np.allclose(logp_res, logp_exp)