예제 #1
0
파일: filters.py 프로젝트: turiya/pyfilter
    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())
예제 #2
0
    def test_LoadModule(self):
        def f(x_, alpha, sigma):
            return alpha * x_

        def g(x_, alpha, sigma):
            return sigma

        norm = DistributionWrapper(Normal, loc=0.0, scale=1.0)
        linear = AffineProcess((f, g), (1.0, 1.0), norm, norm)
        model = LinearGaussianObservations(linear, 1.0, 1.0)

        x, y = model.sample_path(100)

        filt = SISR(model, 200)
        res = filt.longfilter(y)

        filt2 = SISR(model, 300)

        filt2.load_state_dict(filt.state_dict())
        self.assertTrue(filt2.particles[0] == 200)

        res2 = FilterResult(filt2.initialize())
        res2.load_state_dict(res.state_dict())

        self.assertTrue((res2.filter_means == res.filter_means).all())
예제 #3
0
파일: filters.py 프로젝트: turiya/pyfilter
    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
예제 #4
0
    def test_ParallellFiltersAndStability(self):
        x, y = self.model.sample_path(50)

        shape = 3000

        linear = AffineProcess((f, g), (1.0, 1.0), self.norm, self.norm)
        self.model.hidden = linear

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

        filtermeans = result.filter_means

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

        assert mape.median(0)[0].max() < 0.05
예제 #5
0
    def test_SDE(self):
        def f(x, a, s):
            return -a * x

        def g(x, a, s):
            return s

        em = AffineEulerMaruyama((f, g), (0.02, 0.15), Normal(0., 1.), Normal(0., 1.), dt=1e-2, num_steps=10)
        model = LinearGaussianObservations(em, scale=1e-3)

        x, y = model.sample_path(500)

        with self.assertRaises(NotImplementedError):
            SISR(model, 200)

        for filt in [SISR(model, 500, proposal=Bootstrap()), UKF(model)]:
            filt = filt.initialize().longfilter(y)

            means = filt.filtermeans
            if isinstance(filt, UKF):
                means = means[:, 0]

            self.assertLess(torch.std(x - means), 5e-2)
예제 #6
0
    def test_StateDict(self):
        # ===== Define model ===== #
        norm = Normal(0., 1.)
        linear = AffineProcess((f, g), (1., 1.), norm, norm)
        linearobs = AffineObservations((fo, go), (1., 1.), norm)
        model = StateSpaceModel(linear, linearobs)

        # ===== Define filter ===== #
        filt = SISR(model, 100).initialize()

        # ===== Get statedict ===== #
        sd = filt.state_dict()

        # ===== Verify that we don't save multiple instances ===== #
        assert '_model' in sd and '_model' not in sd['_proposal']

        newfilt = SISR(model, 1000).load_state_dict(sd)
        assert newfilt._w_old is not None and newfilt.ssm is newfilt._proposal._model

        # ===== Test same with UKF and verify that we save UT ===== #
        ukf = UKF(model).initialize()
        sd = ukf.state_dict()

        assert '_model' in sd and '_model' not in sd['_ut']
예제 #7
0
    def test_ParallelUnscented(self):
        x, y = self.model.sample_path(50)

        shape = 30

        linear = AffineProcess((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 = filt.filtermeans

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

        assert mape.median(0)[0].max() < 0.05
예제 #8
0
파일: filters.py 프로젝트: merz9b/pyfilter
    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
예제 #9
0
    def test_SDE(self):
        def f(x, a, s):
            return -a * x

        def g(x, a, s):
            return s

        dt = 1e-2
        norm = DistributionWrapper(Normal, loc=0.0, scale=sqrt(dt))

        em = AffineEulerMaruyama((f, g), (0.02, 0.15), norm, norm, dt=1e-2, num_steps=10)
        model = LinearGaussianObservations(em, scale=1e-3)

        x, y = model.sample_path(500)

        for filt in [SISR(model, 500, proposal=prop.Bootstrap()), UKF(model)]:
            result = filt.longfilter(y)

            means = result.filter_means
            if isinstance(filt, UKF):
                means = means[:, 0]

            self.assertLess(torch.std(x - means), 5e-2)
예제 #10
0
    def test_InitializeFilter(self):
        filt = SISR(self.model, 1000).initialize()

        assert filt._x_cur.shape == torch.Size([1000])
예제 #11
0
    def test_Inference(self):
        # ===== Distributions ===== #
        dist = Normal(0., 1.)
        mvn = Independent(Normal(torch.zeros(2), torch.ones(2)), 1)

        # ===== Define model ===== #
        linear = AffineProcess((f, g), (1., 0.25), dist, dist)
        model = LinearGaussianObservations(linear, scale=0.1)

        mv_linear = AffineProcess((fmvn, gmvn), (0.5, 0.25), mvn, mvn)
        mvnmodel = LinearGaussianObservations(mv_linear,
                                              torch.tensor([1., 2.]),
                                              scale=0.1)

        # ===== Test for multiple models ===== #
        priors = Exponential(1.), make_invgamma(2., 1.)

        hidden1d = AffineProcess((f, g), priors, dist, dist)
        oned = LinearGaussianObservations(hidden1d, 1., make_invgamma(2., 1.))

        hidden2d = AffineProcess((fmvn, gmvn), priors, mvn, mvn)
        twod = LinearGaussianObservations(hidden2d, torch.tensor([1., 2.]),
                                          make_invgamma(2., 1.))

        particles = 1000
        # ====== Run inference ===== #
        for trumod, model in [(model, oned), (mvnmodel, twod)]:
            x, y = trumod.sample_path(1000)

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

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

                alg = alg.fit(y)

                w = normalize(alg._w_rec if hasattr(alg, '_w_rec') else torch.
                              ones(particles))

                tru_params = trumod.hidden.theta + trumod.observable.theta
                inf_params = alg.filter.ssm.hidden.theta + alg.filter.ssm.observable.theta

                for trup, p in zip(tru_params, inf_params):
                    if not p.trainable:
                        continue

                    kde = p.get_kde(weights=w)

                    transed = p.bijection.inv(trup)
                    densval = kde.logpdf(transed.numpy().reshape(-1, 1))
                    priorval = p.distr.log_prob(trup)

                    assert (densval > priorval.numpy()).all()
예제 #12
0
    def test_InitializeFilter(self):
        state = SISR(self.model, 1000).initialize()

        assert state.x.shape == torch.Size([1000])