예제 #1
0
def test_SwitchingProcess_random():
    test_states = np.r_[0, 0, 1, 1, 0, 1]
    mu_zero_nonzero = [Constant.dist(0), Constant.dist(1)]
    test_dist = SwitchingProcess.dist(mu_zero_nonzero, test_states)
    assert np.array_equal(test_dist.shape, test_states.shape)
    test_sample = test_dist.random()
    assert test_sample.shape == (test_states.shape[0],)
    assert np.all(test_sample[test_states > 0] > 0)

    test_sample = test_dist.random(size=5)
    assert np.array_equal(test_sample.shape, (5,) + test_states.shape)
    assert np.all(test_sample[..., test_states > 0] > 0)

    test_states = np.r_[0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0]
    test_dist = SwitchingProcess.dist(mu_zero_nonzero, test_states)
    assert np.array_equal(test_dist.shape, test_states.shape)
    test_sample = test_dist.random(size=1)
    assert np.array_equal(test_sample.shape, (1,) + test_states.shape)
    assert np.all(test_sample[..., test_states > 0] > 0)

    test_states = np.r_[0, 0, 1, 1, 0, 1]
    test_mus = [Constant.dist(i) for i in range(6)]
    test_dist = SwitchingProcess.dist(test_mus, test_states)
    assert np.array_equal(test_dist.shape, test_states.shape)
    test_sample = test_dist.random()
    assert np.array_equal(test_sample.shape, test_states.shape)
    assert np.all(test_sample[..., test_states > 0] > 0)

    test_states = np.c_[0, 0, 1, 1, 0, 1].T
    test_mus = np.arange(1, 6).astype(float)
    # One of the states has emissions that are a sequence of five Dirac delta
    # distributions on the values 1 to 5 (i.e. the one with values
    # `test_mus`), and the other is just a single delta at 0.  A single state
    # sample from this emissions mixture is a length five array of zeros or the
    # values 1 to 5.
    # Instead of specifying a state sequence containing only one state, we use
    # six state sequences--each of length one.  This should give us six samples
    # of either five zeros or the values 1 to 5.
    test_dist = SwitchingProcess.dist(
        [Constant.dist(0), Constant.dist(test_mus)], test_states
    )
    assert np.array_equal(test_dist.shape, (6, 5))
    test_sample = test_dist.random()
    assert np.array_equal(test_sample.shape, test_dist.shape)
    assert np.all(test_sample[np.where(test_states > 0)[0]] == test_mus)

    test_states = np.c_[0, 0, 1, 1, 0, 1]
    test_mus = np.arange(1, 7).astype(float)
    test_dist = SwitchingProcess.dist(
        [Constant.dist(0), Constant.dist(test_mus)], test_states
    )
    assert np.array_equal(test_dist.shape, test_states.shape)

    test_states = np.r_[0, 0, 1, 1, 0, 1]
    test_sample = SwitchingProcess.dist(
        [Constant.dist(0), Constant.dist(test_mus)], test_states
    ).random(size=3)
    assert np.array_equal(test_sample.shape, (3,) + test_mus.shape)
    assert np.all(test_sample.sum(0)[..., test_states > 0] > 0)
def test_PoissonZeroProcess_point():
    test_states = np.r_[0, 0, 1, 1, 0, 1]

    with pm.Model():
        test_mean = Constant("c", 1000.0)
        test_point = {"c": 100.0}
        test_sample = PoissonZeroProcess.dist(
            test_mean, test_states).random(point=test_point)

    assert np.all(0 < test_sample[..., test_states > 0])
    assert np.all(test_sample[..., test_states > 0] < 200)
    assert np.all(test_sample[..., test_states == 0] == 0)
예제 #3
0
def test_only_positive_state():
    number_of_draws = 50
    S = 2
    mu = 10
    y_t = np.repeat(0, 100)

    with pm.Model():
        p_0_rv = pm.Dirichlet("p_0", np.r_[1, 1], shape=2)
        p_1_rv = pm.Dirichlet("p_1", np.r_[1, 1], shape=2)

        P_tt = at.stack([p_0_rv, p_1_rv])
        Gammas_tt = pm.Deterministic("P_tt", at.shape_padleft(P_tt))

        gamma_0_rv = pm.Dirichlet("gamma_0", np.ones((S, )), shape=S)

        V_rv = DiscreteMarkovChain("V_t",
                                   Gammas_tt,
                                   gamma_0_rv,
                                   shape=y_t.shape[0])
        V_rv.tag.test_value = (y_t > 0) * 1

        _ = SwitchingProcess(
            "Y_t",
            [Constant.dist(np.array(0, dtype=np.int64)),
             Constant.dist(mu)],
            V_rv,
            observed=y_t,
        )

        posterior_trace = pm.sample(
            chains=1,
            draws=number_of_draws,
            return_inferencedata=True,
            step=FFBSStep([V_rv]),
        )

        posterior_pred_trace = pm.sample_posterior_predictive(
            posterior_trace.posterior, var_names=["Y_t"])
        assert np.all(posterior_pred_trace["Y_t"] == 0)
예제 #4
0
def create_dirac_zero_hmm(X, mu, xis, observed):
    S = 2
    z_tt = at.stack([at.dot(X, xis[..., s, :]) for s in range(S)], axis=1)
    Gammas_tt = pm.Deterministic("Gamma", multilogit_inv(z_tt))
    gamma_0_rv = pm.Dirichlet("gamma_0", np.ones((S, )), shape=S)

    if type(observed) == np.ndarray:
        T = X.shape[0]
    else:
        T = X.get_value().shape[0]

    V_rv = DiscreteMarkovChain("V_t", Gammas_tt, gamma_0_rv, shape=T)
    if type(observed) == np.ndarray:
        V_rv.tag.test_value = (observed > 0) * 1
    else:
        V_rv.tag.test_value = (observed.get_value() > 0) * 1
    Y_rv = SwitchingProcess(
        "Y_t",
        [Constant.dist(np.array(0, dtype=np.int64)),
         Constant.dist(mu)],
        V_rv,
        observed=observed,
    )
    return Y_rv
def test_subset_args():

    test_dist = Constant.dist(c=np.r_[0.1, 1.2, 2.3])
    test_idx = np.r_[0, 2]
    res = distribution_subset_args(test_dist, shape=[3], idx=test_idx)
    assert np.array_equal(res["c"].eval(), np.r_[0.1, 2.3])

    test_dist = pm.Normal.dist(mu=np.r_[0.1, 1.2, 2.3], sigma=np.r_[10.0])
    test_idx = np.r_[0, 2]
    res = distribution_subset_args(test_dist, shape=[3], idx=test_idx)
    assert np.array_equal(res["mu"].eval(), np.r_[0.1, 2.3])
    assert np.array_equal(res["sigma"].eval(), np.r_[10.0, 10.0])

    test_dist = pm.Poisson.dist(mu=np.r_[0.1, 1.2, 2.3])
    test_idx = np.r_[0, 2]
    res = distribution_subset_args(test_dist, shape=[3], idx=test_idx)
    assert np.array_equal(res["mu"].eval(), np.r_[0.1, 2.3])

    test_dist = pm.NegativeBinomial.dist(mu=np.r_[0.1, 1.2, 2.3], alpha=2)
    test_idx = np.r_[0, 2]
    res = distribution_subset_args(test_dist, shape=[3], idx=test_idx)
    assert np.array_equal(res["mu"].eval(), np.r_[0.1, 2.3])
    assert np.array_equal(res["alpha"].eval(), np.r_[2.0, 2.0])
def test_SwitchingProcess():

    np.random.seed(2023532)

    test_states = np.r_[2, 0, 1, 2, 0, 1]
    test_dists = [
        Constant.dist(0),
        pm.Poisson.dist(100.0),
        pm.Poisson.dist(1000.0)
    ]
    test_dist = SwitchingProcess.dist(test_dists, test_states)
    assert np.array_equal(test_dist.shape, test_states.shape)

    test_sample = test_dist.random()
    assert test_sample.shape == (test_states.shape[0], )
    assert np.all(test_sample[test_states == 0] == 0)
    assert np.all(0 < test_sample[test_states == 1])
    assert np.all(test_sample[test_states == 1] < 1000)
    assert np.all(100 < test_sample[test_states == 2])

    test_mus = np.r_[100, 100, 500, 100, 100, 100]
    test_dists = [
        Constant.dist(0),
        pm.Poisson.dist(test_mus),
        pm.Poisson.dist(10000.0),
    ]
    test_dist = SwitchingProcess.dist(test_dists, test_states)
    assert np.array_equal(test_dist.shape, test_states.shape)

    test_sample = test_dist.random()
    assert test_sample.shape == (test_states.shape[0], )
    assert np.all(200 < test_sample[2] < 600)
    assert np.all(0 < test_sample[5] < 200)
    assert np.all(5000 < test_sample[test_states == 2])

    test_dists = [
        Constant.dist(0),
        pm.Poisson.dist(100.0),
        pm.Poisson.dist(1000.0)
    ]
    test_dist = SwitchingProcess.dist(test_dists, test_states)
    for i in range(len(test_dists)):
        test_logp = test_dist.logp(
            np.tile(test_dists[i].mode.eval(), test_states.shape)).eval()
        assert test_logp[test_states != i].max() < test_logp[test_states ==
                                                             i].min()

    # Try a continuous mixture
    test_states = np.r_[2, 0, 1, 2, 0, 1]
    test_dists = [
        pm.Normal.dist(0.0, 1.0),
        pm.Normal.dist(100.0, 1.0),
        pm.Normal.dist(1000.0, 1.0),
    ]
    test_dist = SwitchingProcess.dist(test_dists, test_states)
    assert np.array_equal(test_dist.shape, test_states.shape)

    test_sample = test_dist.random()
    assert test_sample.shape == (test_states.shape[0], )
    assert np.all(test_sample[test_states == 0] < 10)
    assert np.all(50 < test_sample[test_states == 1])
    assert np.all(test_sample[test_states == 1] < 150)
    assert np.all(900 < test_sample[test_states == 2])

    # Make sure we can use a large number of distributions in the mixture
    test_states = np.ones(50)
    test_dists = [Constant.dist(i) for i in range(50)]
    test_dist = SwitchingProcess.dist(test_dists, test_states)
    assert np.array_equal(test_dist.shape, test_states.shape)

    with pytest.raises(TypeError):
        SwitchingProcess.dist([1], test_states)

    with aesara.change_flags(compute_test_value="off"):
        # Test for the case when a default can't be computed
        test_dist = pm.Poisson.dist(at.scalar())

        # Confirm that there's no default
        with pytest.raises(AttributeError):
            test_dist.default()

        # Let it try to sample using `Distribution.random` and fail
        with pytest.raises(ValueError):
            SwitchingProcess.dist([test_dist], test_states)

    # Evaluate multiple observed state sequences in an extreme case
    test_states = at.imatrix("states")
    test_states.tag.test_value = np.zeros((10, 4)).astype("int32")
    test_dist = SwitchingProcess.dist(
        [Constant.dist(0), Constant.dist(1)], test_states)
    test_obs = np.tile(np.arange(4), (10, 1)).astype("int32")
    test_logp = test_dist.logp(test_obs)
    exp_logp = np.tile(
        np.array([0.0] + [-np.inf] * 3, dtype=aesara.config.floatX), (10, 1))
    assert np.array_equal(test_logp.tag.test_value, exp_logp)