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
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