Example #1
0
    def test_Timeseries3DState2DParam(self):
        alpha = 0.5 * torch.ones((500, 1))
        x = torch.randn(size=(500, 200))
        linear = AffineModel((f0, g0), (f, g), (alpha, 1.),
                             (Normal(0., 1.), Normal(0., 1.)))

        assert np.allclose(linear.mean(x), f(x, alpha, 1.))
Example #2
0
    def test_Algorithms(self):
        priors = Exponential(2.), Exponential(2.)
        # ===== Test for multiple models ===== #
        hidden1d = AffineModel((f0, g0), (f, g), priors, (self.linear.noise0, self.linear.noise))
        oned = LinearGaussianObservations(hidden1d, 1., Exponential(1.))

        hidden2d = AffineModel((f0mvn, g0mvn), (fmvn, gmvn), priors, (self.mvn.noise0, self.mvn.noise))
        twod = LinearGaussianObservations(hidden2d, self.a, Exponential(1.))

        # ====== Run inference ===== #
        for trumod, model in [(self.model, oned), (self.mvnmodel, twod)]:
            x, y = trumod.sample(550)

            algs = [
                (NESS, {'particles': 1000, 'filter_': SISR(model.copy(), 200)}),
                (SMC2, {'particles': 1000, 'filter_': SISR(model.copy(), 200)}),
                (NESSMC2, {'particles': 1000, 'filter_': SISR(model.copy(), 200)}),
                (IteratedFilteringV2, {'particles': 1000, 'filter_': SISR(model.copy(), 1000)})
            ]

            for alg, props in algs:
                alg = alg(**props).initialize()

                alg = alg.fit(y)

                parameter = alg.filter.ssm.hidden.theta[-1]

                kde = parameter.get_kde(transformed=False)

                tru_val = trumod.hidden.theta[-1]
                densval = kde.logpdf(tru_val.numpy().reshape(-1, 1))
                priorval = parameter.dist.log_prob(tru_val)

                assert bool(densval > priorval.numpy())
Example #3
0
    def test_UnscentedTransform1D(self):
        # ===== 1D model ===== #
        norm = Normal(0., 1.)
        linear = AffineModel((f0, g0), (f, g), (1., 1.), (norm, norm))
        linearobs = Observable((fo, go), (1., 1.), norm)
        model = StateSpaceModel(linear, linearobs)

        # ===== Perform unscented transform ===== #
        x = model.hidden.i_sample(shape=3000)

        ut = UnscentedTransform(model).initialize(x).construct(0.)

        assert isinstance(ut.x_dist, Normal)
Example #4
0
    def test_ParallelUnscented(self):
        x, y = self.model.sample(50)

        shape = 30

        linear = AffineModel((f0, g0), (f, g), (1., 1.), (self.norm, self.norm))
        self.model.hidden = linear

        filt = SISR(self.model, 1000, proposal=Unscented()).set_nparallel(shape).initialize().longfilter(y)

        filtermeans = torch.cat(filt.filtermeans()).reshape(x.shape[0], -1)

        x = filtermeans[:, 0:1]
        mape = ((x - filtermeans[:, 1:]) / x).abs()

        assert mape.median(0)[0].max() < 0.05
Example #5
0
    def test_ParallellFiltersAndStability(self):
        x, y = self.model.sample(50)

        shape = 30

        linear = AffineModel((f0, g0), (f, g), (1., 1.),
                             (self.norm, self.norm))
        self.model.hidden = linear

        filt = SISR(self.model,
                    1000).set_nparallel(shape).initialize().longfilter(y)

        filtermeans = filt.filtermeans

        x = filtermeans[:, :1]
        mape = ((x - filtermeans[:, 1:]) / x).abs()

        assert mape.median(0)[0].max() < 0.05
Example #6
0
    def test_UnscentedTransform2D(self):
        # ===== 2D model ===== #
        mat = torch.eye(2)
        scale = torch.diag(mat)

        norm = Normal(0., 1.)
        mvn = MultivariateNormal(torch.zeros(2), torch.eye(2))
        mvnlinear = AffineModel((f0mvn, g0), (fmvn, g), (mat, scale),
                                (mvn, mvn))
        mvnoblinear = Observable((fomvn, gomvn), (1., ), norm)

        mvnmodel = StateSpaceModel(mvnlinear, mvnoblinear)

        # ===== Perform unscented transform ===== #
        x = mvnmodel.hidden.i_sample(shape=3000)

        ut = UnscentedTransform(mvnmodel).initialize(x).construct(0.)

        assert isinstance(ut.x_dist, MultivariateNormal) and isinstance(
            ut.y_dist, Normal)
        assert isinstance(ut.x_dist_indep, Independent)
Example #7
0
class Tests(unittest.TestCase):
    norm = Normal(0., 1.)

    linear = AffineModel((f0, g0), (f, g), (1., 1.), (norm, norm))

    def test_TimeseriesCreate_1D(self):

        assert self.linear.mean(torch.tensor(1.)) == 1. and self.linear.scale(
            torch.tensor(1.)) == 1.

    def test_Timeseries2DState(self):
        x = np.random.normal(size=500)

        assert np.allclose(self.linear.mean(torch.tensor(x)), f(x, 1, 1))

    def test_Timeseries3DState2DParam(self):
        alpha = 0.5 * torch.ones((500, 1))
        x = torch.randn(size=(500, 200))
        linear = AffineModel((f0, g0), (f, g), (alpha, 1.),
                             (Normal(0., 1.), Normal(0., 1.)))

        assert np.allclose(linear.mean(x), f(x, alpha, 1.))

    def test_SampleInitial(self):
        x = self.linear.i_sample()

        assert isinstance(x, torch.Tensor)

    def test_Propagate(self):
        out = torch.zeros(500)

        out[0] = self.linear.i_sample()

        for i in range(1, out.shape[0]):
            out[i] = self.linear.propagate(out[i - 1])

        assert not all(out == 0.)

    def test_SampleTrajectory1D(self):
        sample = self.linear.sample(500)

        assert sample.shape[0] == 500

    def test_SampleTrajectory2D(self):
        sample = self.linear.sample(500, 250)

        assert sample.shape == (500, 250, 1)

    def test_Weight1D(self):
        sample = self.linear.i_sample()

        obs = 0.

        assert np.allclose(
            self.linear.weight(obs, sample).numpy(),
            stats.norm.logpdf(obs, loc=sample, scale=1))

    def test_Weight2D(self):
        sample = self.linear.i_sample(shape=(500, 200))

        obs = 1

        assert np.allclose(self.linear.weight(obs, sample),
                           stats.norm.logpdf(obs, loc=sample, scale=1))

    def test_EulerMaruyama(self):
        mod = EulerMaruyma((lambda: 0., lambda: 1.),
                           (lambda u: 0, lambda u: 1), (),
                           ndim=1)

        samples = mod.sample(30)

        assert samples.shape == (30, 1)

    def test_OrnsteinUhlenbeck(self):
        mod = OrnsteinUhlenbeck(0.05, 1, 0.15)

        x = mod.sample(300)

        assert x.shape == (300, 1)
Example #8
0
class Tests(unittest.TestCase):
    # ===== Simple 1D model ===== #
    norm = Normal(0., 1.)
    linear = AffineModel((f0, g0), (f, g), (1., 1.), (norm, norm))
    model = LinearGaussianObservations(linear, 1., 1.)

    # ===== Simple 2D model ===== #
    mvn = Independent(Normal(torch.zeros(2), torch.ones(2)), 1)
    mvn = AffineModel((f0mvn, g0mvn), (fmvn, gmvn), (0.5, 1.), (mvn, mvn))
    a = torch.Tensor([1., 2.])

    mvnmodel = LinearGaussianObservations(mvn, a, 1.)

    def test_InitializeFilter(self):
        filt = SISR(self.model, 1000).initialize()

        assert filt._x_cur.shape == (1000,)

    def test_Filters(self):
        for model in [self.model, self.mvnmodel]:
            x, y = model.sample(500)

            for filter_, props in [(SISR, {'particles': 500}), (APF, {'particles': 500}), (UKF, {})]:
                filt = filter_(model, **props).initialize()

                filt = filt.longfilter(y)

                assert len(filt.s_mx) > 0

                filtmeans = filt.filtermeans.numpy()

                # ===== Run Kalman ===== #
                if model is self.model:
                    kf = pykalman.KalmanFilter(transition_matrices=1., observation_matrices=1.)
                else:
                    kf = pykalman.KalmanFilter(transition_matrices=[[0.5, 1 / 3], [0, 1.]], observation_matrices=[1, 2])

                filterestimates = kf.filter(y.numpy())

                if filtmeans.ndim < 2:
                    filtmeans = filtmeans[:, None]

                rel_error = np.median(np.abs((filtmeans - filterestimates[0]) / filterestimates[0]))

                ll = kf.loglikelihood(y.numpy())

                rel_ll_error = np.abs((ll - np.array(filt.s_ll).sum()) / ll)

                assert rel_error < 0.05 and rel_ll_error < 0.05

    def test_ParallellFiltersAndStability(self):
        x, y = self.model.sample(50)

        shape = 30

        linear = AffineModel((f0, g0), (f, g), (1., 1.), (self.norm, self.norm))
        self.model.hidden = linear

        filt = SISR(self.model, 1000).set_nparallel(shape).initialize().longfilter(y)

        filtermeans = torch.cat(filt.filtermeans()).reshape(x.shape[0], -1)

        x = filtermeans[:, 0:1]
        mape = ((x - filtermeans[:, 1:]) / x).abs()

        assert mape.median(0)[0].max() < 0.05

    def test_ParallelUnscented(self):
        x, y = self.model.sample(50)

        shape = 30

        linear = AffineModel((f0, g0), (f, g), (1., 1.), (self.norm, self.norm))
        self.model.hidden = linear

        filt = SISR(self.model, 1000, proposal=Unscented()).set_nparallel(shape).initialize().longfilter(y)

        filtermeans = torch.cat(filt.filtermeans()).reshape(x.shape[0], -1)

        x = filtermeans[:, 0:1]
        mape = ((x - filtermeans[:, 1:]) / x).abs()

        assert mape.median(0)[0].max() < 0.05

    def test_Algorithms(self):
        priors = Exponential(2.), Exponential(2.)
        # ===== Test for multiple models ===== #
        hidden1d = AffineModel((f0, g0), (f, g), priors, (self.linear.noise0, self.linear.noise))
        oned = LinearGaussianObservations(hidden1d, 1., Exponential(1.))

        hidden2d = AffineModel((f0mvn, g0mvn), (fmvn, gmvn), priors, (self.mvn.noise0, self.mvn.noise))
        twod = LinearGaussianObservations(hidden2d, self.a, Exponential(1.))

        # ====== Run inference ===== #
        for trumod, model in [(self.model, oned), (self.mvnmodel, twod)]:
            x, y = trumod.sample(550)

            algs = [
                (NESS, {'particles': 1000, 'filter_': SISR(model.copy(), 200)}),
                (SMC2, {'particles': 1000, 'filter_': SISR(model.copy(), 200)}),
                (NESSMC2, {'particles': 1000, 'filter_': SISR(model.copy(), 200)}),
                (IteratedFilteringV2, {'particles': 1000, 'filter_': SISR(model.copy(), 1000)})
            ]

            for alg, props in algs:
                alg = alg(**props).initialize()

                alg = alg.fit(y)

                parameter = alg.filter.ssm.hidden.theta[-1]

                kde = parameter.get_kde(transformed=False)

                tru_val = trumod.hidden.theta[-1]
                densval = kde.logpdf(tru_val.numpy().reshape(-1, 1))
                priorval = parameter.dist.log_prob(tru_val)

                assert bool(densval > priorval.numpy())
Example #9
0
class Tests(unittest.TestCase):
    # ===== 1D model ===== #
    norm = Normal(0., 1.)
    linear = AffineModel((f0, g0), (f, g), (1., 1.), (norm, norm))
    linearobs = Observable((fo, go), (1., 1.), norm)
    model = StateSpaceModel(linear, linearobs)

    # ===== 2D model ===== #
    mat = torch.eye(2)
    scale = torch.diag(mat)

    mvn = MultivariateNormal(torch.zeros(2), torch.eye(2))
    mvnlinear = AffineModel((f0mvn, g0mvn), (fmvn, gmvn), (mat, scale),
                            (mvn, mvn))
    mvnoblinear = Observable((fomvn, gomvn), (1., ), norm)

    mvnmodel = StateSpaceModel(mvnlinear, mvnoblinear)

    def test_InitializeModel1D(self):
        sample = self.model.initialize()

        assert isinstance(sample, torch.Tensor)

    def test_InitializeModel(self):
        sample = self.model.initialize(1000)

        assert sample.shape == (1000, )

    def test_Propagate(self):
        x = self.model.initialize(1000)

        sample = self.model.propagate(x)

        assert sample.shape == (1000, )

    def test_Sample(self):
        x, y = self.model.sample(50)

        assert len(x) == 50 and len(y) == 50 and np.array(x).shape == (50, 1)

    def test_SampleMultivariate(self):
        x, y = self.mvnmodel.sample(30)

        assert len(x) == 30 and x[0].shape == (2, )

    def test_SampleMultivariateSamples(self):
        shape = (100, 100)
        x, y = self.mvnmodel.sample(30, samples=shape)

        assert x.shape == (30, 2, *shape) and isinstance(
            x, torch.Tensor) and isinstance(y, torch.Tensor)
        assert self.mvnmodel.h_weight(x[1], x[0]).shape == shape
        if len(shape) > 1:
            assert self.mvnmodel.h_weight(x[1, :, 0, 0], x[0]).shape == shape
        assert self.mvnmodel.weight(y[0, 0], x[0]).shape == shape

    def test_Parameter(self):
        param = Parameter(Beta(1, 3)).sample_()

        assert param.values.shape == torch.Size([])

        newshape = (3000, 1000)
        with self.assertRaises(ValueError):
            param.values = Normal(0., 1.).sample(newshape)

        newvals = Beta(1, 3).sample(newshape)
        param.values = newvals

        assert param.values.shape == newshape

        param.t_values = Normal(0., 1.).sample(newshape)

        assert (param.values != newvals).all()

    def test_LinearGaussianObservations(self):
        linearmodel = LinearGaussianObservations(self.linear)

        steps = 30

        x, y = linearmodel.sample(steps)

        assert len(x) == steps and len(y) == steps

        mat = torch.eye(2)

        mvn_linearmodel = LinearGaussianObservations(self.mvnlinear, a=mat)

        x, y = mvn_linearmodel.sample(30)

        assert len(x) == steps and len(y) == steps
Example #10
0
class Tests(unittest.TestCase):
    norm = Normal(0., 1.)

    linear = AffineModel((f0, g0), (f, g), (1., 1.), (norm, norm))

    def test_TimeseriesCreate_1D(self):

        assert self.linear.mean(torch.tensor(1.)) == 1. and self.linear.scale(
            torch.tensor(1.)) == 1.

    def test_Timeseries2DState(self):
        x = np.random.normal(size=500)

        assert np.allclose(self.linear.mean(torch.tensor(x)), f(x, 1, 1))

    def test_Timeseries3DState2DParam(self):
        alpha = 0.5 * torch.ones((500, 1))
        x = torch.randn(size=(500, 200))
        linear = AffineModel((f0, g0), (f, g), (alpha, 1.),
                             (Normal(0., 1.), Normal(0., 1.)))

        assert np.allclose(linear.mean(x), f(x, alpha, 1.))

    def test_SampleInitial(self):
        x = self.linear.i_sample()

        assert isinstance(x, torch.Tensor)

    def test_Propagate(self):
        out = torch.zeros(500)

        out[0] = self.linear.i_sample()

        for i in range(1, out.shape[0]):
            out[i] = self.linear.propagate(out[i - 1])

        assert not all(out == 0.)

    def test_SampleTrajectory1D(self):
        sample = self.linear.sample(500)

        assert sample.shape[0] == 500

    def test_SampleTrajectory2D(self):
        sample = self.linear.sample(500, 250)

        assert sample.shape == (500, 250)

    def test_Weight1D(self):
        sample = self.linear.i_sample()

        obs = 0.

        assert np.allclose(
            self.linear.weight(obs, sample).numpy(),
            stats.norm.logpdf(obs, loc=sample, scale=1))

    def test_Weight2D(self):
        sample = self.linear.i_sample(shape=(500, 200))

        obs = 1

        assert np.allclose(self.linear.weight(obs, sample),
                           stats.norm.logpdf(obs, loc=sample, scale=1))

    def test_EulerMaruyama(self):
        zero = torch.tensor(0.)
        one = torch.tensor(1.)

        mod = EulerMaruyma((lambda: zero, lambda: one),
                           (lambda u: zero, lambda u: one), (),
                           ndim=1)

        samples = mod.sample(30)

        assert samples.shape == (30, )

    def test_OrnsteinUhlenbeck(self):
        mod = OrnsteinUhlenbeck(0.05, 1, 0.15)

        x = mod.sample(300)

        assert x.shape == (300, )

    def test_StateVariable(self):
        # ===== Emulate last value ===== #
        rands = torch.empty((300, 3)).normal_()
        rands.requires_grad_(True)

        # ===== Pass through function ===== #
        sv = StateVariable(rands)
        agg = sv.sum(-1)

        # ===== Get gradient ===== #
        agg.backward(torch.ones_like(agg))

        assert rands.grad is not None

    def test_Parameter(self):
        # ===== Start stuff ===== #
        param = Parameter(Normal(0., 1.))
        param.sample_(1000)

        assert param.shape == torch.Size([1000])

        # ===== Construct view ===== #
        view = param.view(1000, 1)

        # ===== Change values ===== #
        param.values = torch.empty_like(param).normal_()

        assert (view[:, 0] == param).all()

        # ===== Have in tuple ===== #
        vals = (param.view(1000, 1, 1), )

        param.values = torch.empty_like(param).normal_()

        assert (vals[0][:, 0, 0] == param).all()

        # ===== Set t_values ===== #
        view = param.view(1000, 1)

        param.t_values = torch.empty_like(param).normal_()

        assert (view[:, 0] == param.t_values).all()

        # ===== Check we cannot set different shape ===== #
        with self.assertRaises(ValueError):
            param.values = torch.empty(1).normal_()

        # ===== Check that we cannot set out of bounds values for parameter ===== #
        positive = Parameter(Exponential(1.))
        positive.sample_(1)

        with self.assertRaises(ValueError):
            positive.values = -torch.empty_like(positive).normal_().abs()

        # ===== Check that we can set transformed values ===== #
        values = torch.empty_like(positive).normal_()
        positive.t_values = values

        assert (positive == positive.bijection(values)).all()