def predict(self, time, true_value=None): if time < self._time: raise ValueError( 'Predicting the past (current time=%s, prediction time=%s)' % (self._time, time)) if true_value is not None and filtering.FilterPypeOptions.TRUE_VALUE in self._pype_options: self._pype.send(filtering.TrueValue(self, self._time, true_value)) if time == self._time: return state_distrs = [] row = 0 for p in self._processes: process_dim = p.process_dim m = self._state_distr.mean[row:row + process_dim, 0:1] c = self._state_distr.cov[row:row + process_dim, row:row + process_dim] state_distrs.append( p.propagate_distr(time, self._time, N(mean=m, cov=c))) row += process_dim state_mean = np.vstack([d.mean for d in state_distrs]) state_cov = block_diag(*[d.cov for d in state_distrs]) self._state_distr = N(mean=state_mean, cov=state_cov, copy=False) self._is_posterior = False self._time = time if filtering.FilterPypeOptions.PRIOR_STATE in self._pype_options: self._pype.send(self.state)
def process_run_df(self, df): auto_refresh = self._auto_refresh self._auto_refresh = False try: for i in range(len(df)): time = df.iloc[i]['time'] observable_name = df.iloc[i]['observable_name'] accepted = df.iloc[i]['accepted'] obs_mean = df.iloc[i]['obs_mean'] obs_cov = df.iloc[i]['obs_cov'] predicted_obs_mean = df.iloc[i]['predicted_obs_mean'] predicted_obs_cov = df.iloc[i]['predicted_obs_cov'] cross_cov = df.iloc[i]['cross_cov'] innov_mean = df.iloc[i]['innov_mean'] innov_cov = df.iloc[i]['innov_cov'] prior_state_mean = df.iloc[i]['prior_state_mean'] prior_state_cov = df.iloc[i]['prior_state_cov'] posterior_state_mean = df.iloc[i]['posterior_state_mean'] posterior_state_cov = df.iloc[i]['posterior_state_cov'] true_value = df.iloc[i]['true_value'] log_likelihood = df.iloc[i]['log_likelihood'] gain = df.iloc[i]['gain'] # TODO Use an appropriate FilterState, it doesn't have to be KalmanFilterState prior_filter_state_object = kalman.KalmanFilterState( None, time, False, N(prior_state_mean, prior_state_cov), self._filter_name) # TODO Use an appropriate FilterState, it doesn't have to be KalmanFilterState posterior_filter_state_object = kalman.KalmanFilterState( None, time, True, N(posterior_state_mean, posterior_state_cov), self._filter_name) self.process_filter_object(prior_filter_state_object) self.process_filter_object(posterior_filter_state_object) # Need the following check to skip the initial state row, which # may be present in the DataFrame: if not (i == 0 and observable_name is None): true_value_object = filtering.TrueValue( None, time, true_value, self._filter_name) obs = filtering.Obs(None, time, N(obs_mean, obs_cov), observable_name) predicted_obs = filtering.PredictedObs( None, time, N(predicted_obs_mean, predicted_obs_cov), cross_cov, observable_name) innov_distr = N(innov_mean, innov_cov) # TODO Use an appropriate ObsResult, it doesn't have to be KalmanObsResult obs_result_object = kalman.KalmanObsResult( accepted, obs, predicted_obs, innov_distr, log_likelihood, gain) if true_value is not None: self.process_filter_object(true_value_object) if obs_mean is not None: self.process_filter_object(obs_result_object) finally: self.refresh() self._auto_refresh = auto_refresh
def observe(self, obs_distr, predicted_obs, true_value): if true_value is not None and filtering.FilterPypeOptions.TRUE_VALUE in self._pype_options: self._pype.send(filtering.TrueValue(self, self._time, true_value)) innov = obs_distr.mean - predicted_obs.distr.mean innov_cov = predicted_obs.distr.cov + obs_distr.cov innov_cov_inv = np.linalg.inv(innov_cov) gain = np.dot(predicted_obs.cross_cov.T, innov_cov_inv) m = self._state_distr.mean + np.dot(gain, innov) c = self._state_distr.cov - np.dot(gain, predicted_obs.cross_cov) self._state_distr = N(mean=m, cov=c, copy=False) self._is_posterior = True if filtering.FilterPypeOptions.POSTERIOR_STATE in self._pype_options: self._pype.send(self.state) log_likelihood = -.5 * (obs_distr.dim * KalmanFilter.LN_2PI + np.log(np.linalg.det(innov_cov)) + \ np.dot(np.dot(innov.T, innov_cov_inv), innov)) obs = filtering.Obs(predicted_obs.observable, self._time, obs_distr) obs_result = KalmanObsResult(True, obs, predicted_obs, N(mean=innov, cov=innov_cov, copy=False), log_likelihood, gain) if filtering.FilterPypeOptions.OBS_RESULT in self._pype_options: self._pype.send(obs_result) return obs_result
def predict(self, time, true_value=None): if time < self._time: raise ValueError( 'Predicting the past (current time=%s, prediction time=%s)' % (self._time, time)) if true_value is not None and filtering.FilterPypeOptions.TRUE_VALUE in self._pype_options: self._pype.send(filtering.TrueValue(self, self._time, true_value)) if time == self._time: return state_distrs = [] row = 0 for p in self._processes: process_dim = p.process_dim m = self._state_distr.mean[row:row + process_dim, 0:1] c = self._state_distr.cov[row:row + process_dim, row:row + process_dim] state_distr = p.propagate_distr( self._time, N(mean=m, cov=c), time, assume_distr=self._approximate_distr) if not isinstance(state_distr, N): if self._approximate_distr: state_distr = N.approximate(state_distr, copy=False) else: raise ValueError( 'The propagated state distribution is not Normal; to approximate with a Normal distribution, set the approximate_distr parameter to True (currently False)' ) state_distrs.append(state_distr) row += process_dim state_mean = np.vstack([d.mean for d in state_distrs]) state_cov = block_diag(*[d.cov for d in state_distrs]) self._state_distr = N(mean=state_mean, cov=state_cov, copy=False) self._is_posterior = False self._time = time if filtering.FilterPypeOptions.PRIOR_STATE in self._pype_options: self._pype.send(self.state)