Beispiel #1
0
    def backward_rv(
        self,
        rv_obtained,
        rv,
        rv_forwarded=None,
        gain=None,
        t=None,
        dt=None,
        _diffusion=1.0,
        **kwargs,
    ):
        if dt is None:
            raise ValueError(
                "Continuous-time transitions require a time-increment ``dt``."
            )

        # Fetch things into preconditioned space
        rv_obtained = _preconditioner.apply_precon(self.precon.inverse(dt), rv_obtained)
        rv = _preconditioner.apply_precon(self.precon.inverse(dt), rv)
        rv_forwarded = (
            _preconditioner.apply_precon(self.precon.inverse(dt), rv_forwarded)
            if rv_forwarded is not None
            else None
        )
        gain = (
            self.precon.inverse(dt) @ gain @ self.precon.inverse(dt).T
            if gain is not None
            else None
        )

        # Apply preconditioning to system matrices
        new_drift_matrix = self.precon.inverse(dt) @ self.drift_matrix @ self.precon(dt)
        new_force_vector = self.precon.inverse(dt) @ self.force_vector
        new_dispersion_matrix = self.precon.inverse(dt) @ self.dispersion_matrix
        new_lti_sde = continuous.LTISDE(
            drift_matrix=new_drift_matrix,
            force_vector=new_force_vector,
            dispersion_matrix=new_dispersion_matrix,
            forward_implementation=self.forward_implementation,
            backward_implementation=self.backward_implementation,
        )

        # Discretise and propagate
        discretised_model = new_lti_sde.discretise(dt=dt)
        rv, info = discretised_model.backward_rv(
            rv_obtained=rv_obtained,
            rv=rv,
            rv_forwarded=rv_forwarded,
            gain=gain,
            t=t,
            _diffusion=_diffusion,
        )

        # Undo preconditioning and return
        rv = _preconditioner.apply_precon(self.precon(dt), rv)
        return rv, info
Beispiel #2
0
    def forward_rv(
        self,
        rv,
        t,
        dt=None,
        compute_gain=False,
        _diffusion=1.0,
        **kwargs,
    ):
        if dt is None:
            raise ValueError(
                "Continuous-time transitions require a time-increment ``dt``.")

        # Fetch things into preconditioned space
        rv = _preconditioner.apply_precon(self.precon.inverse(dt), rv)

        # Apply preconditioning to system matrices
        new_drift_matrix = self.precon.inverse(
            dt) @ self.drift_matrix @ self.precon(dt)
        new_force_vector = self.precon.inverse(dt) @ self.force_vector
        new_dispersion_matrix = self.precon.inverse(
            dt) @ self.dispersion_matrix
        new_lti_sde = continuous.LTISDE(
            drift_matrix=new_drift_matrix,
            force_vector=new_force_vector,
            dispersion_matrix=new_dispersion_matrix,
            forward_implementation=self.forward_implementation,
            backward_implementation=self.backward_implementation,
        )

        # Discretise and propagate
        discretised_model = new_lti_sde.discretise(dt=dt)
        rv, info = discretised_model.forward_rv(rv,
                                                t,
                                                compute_gain=compute_gain,
                                                _diffusion=_diffusion)

        # Undo preconditioning and return
        rv = _preconditioner.apply_precon(self.precon(dt), rv)
        info["crosscov"] = self.precon(dt) @ info["crosscov"] @ self.precon(
            dt).T
        if "gain" in info:
            info["gain"] = self.precon(
                dt) @ info["gain"] @ self.precon.inverse(dt).T

        return rv, info