def backward_sample(self, steps=1): """ Generate state sequence using distributions: .. math:: p(\theta_{t} | \theta_{t + k} D_t) """ from statlib.distributions import rmvnorm if steps != 1: raise Exception('only do one step backward sampling for now...') T = self.nobs # Backward sample mu_draws = np.zeros((T + 1, self.ndim)) m = self.mu_mode C = self.mu_scale a = self.mu_forc_mode R = self.mu_forc_scale mu_draws[T] = rmvnorm(m[T], C[T]) # initial values for smoothed dist'n for t in xrange(T - 1, -1, -1): # B_{t} = C_t G_t+1' R_t+1^-1 B = chain_dot(C[t], self.G.T, LA.inv(R[t + 1])) # smoothed mean ht = m[t] + np.dot(B, mu_draws[t + 1] - a[t + 1]) Ht = C[t] - chain_dot(B, R[t + 1], B.T) mu_draws[t] = rmvnorm(ht, np.atleast_2d(Ht)) return mu_draws.squeeze()
def backward_sample(self, steps=1): """ Generate state sequence using distributions: .. math:: p(\theta_{t} | \theta_{t + k} D_t) """ from statlib.distributions import rmvnorm if steps != 1: raise Exception('only do one step backward sampling for now...') T = self.nobs # Backward sample mu_draws = np.zeros((T + 1, self.ndim)) m = self.mu_mode C = self.mu_scale a = self.mu_forc_mode R = self.mu_forc_scale mu_draws[T] = rmvnorm(m[T], C[T]) # initial values for smoothed dist'n for t in xrange(T-1, -1, -1): # B_{t} = C_t G_t+1' R_t+1^-1 B = chain_dot(C[t], self.G.T, LA.inv(R[t+1])) # smoothed mean ht = m[t] + np.dot(B, mu_draws[t+1] - a[t+1]) Ht = C[t] - chain_dot(B, R[t+1], B.T) mu_draws[t] = rmvnorm(ht, np.atleast_2d(Ht)) return mu_draws.squeeze()
def _update_mu(v, w, phi, lam): # FFBS # allocate result arrays mode = np.zeros((T + 1, p)) a = np.zeros((T + 1, p)) C = np.zeros((T + 1, p)) R = np.zeros((T + 1, p)) # simple priors... mode[0] = 0 C[0] = np.eye(p) # Forward filter Ft = m_([[1]]) for i, obs in enumerate(y): t = i + 1 at = phi * mode[t - 1] if t > 1 else mode[0] Rt = phi**2 * C[t - 1] + w if t > 1 else C[0] Vt = lam[t - 1] * v Qt = chain_dot(Ft.T, Rt, Ft) + Vt At = np.dot(Rt, Ft) / Qt # forecast theta as time t ft = np.dot(Ft.T, at) err = obs - ft # update mean parameters mode[t] = at + np.dot(At, err) C[t] = Rt - np.dot(At, np.dot(Qt, At.T)) a[t] = at R[t] = Rt # Backward sample mu = np.zeros((T + 1, p)) # initial values for smoothed dist'n fR = C[-1] fm = mode[-1] for t in xrange(T + 1): if t < T: # B_{t} = C_t G_t+1' R_t+1^-1 B = np.dot(C[t] * phi, la.inv(np.atleast_2d(R[t + 1]))) # smoothed mean fm = mode[t] + np.dot(B, mode[t + 1] - a[t + 1]) fR = C[t] + chain_dot(B, C[t + 1] - R[t + 1], B.T) mu[t] = dist.rmvnorm(fm, np.atleast_2d(fR)) return mu.squeeze()
def _update_mu(v, w, phi, lam): # FFBS # allocate result arrays mode = np.zeros((T + 1, p)) a = np.zeros((T + 1, p)) C = np.zeros((T + 1, p)) R = np.zeros((T + 1, p)) # simple priors... mode[0] = 0 C[0] = np.eye(p) # Forward filter Ft = m_([[1]]) for i, obs in enumerate(y): t = i + 1 at = phi * mode[t - 1] if t > 1 else mode[0] Rt = phi ** 2 * C[t - 1] + w if t > 1 else C[0] Vt = lam[t - 1] * v Qt = chain_dot(Ft.T, Rt, Ft) + Vt At = np.dot(Rt, Ft) / Qt # forecast theta as time t ft = np.dot(Ft.T, at) err = obs - ft # update mean parameters mode[t] = at + np.dot(At, err) C[t] = Rt - np.dot(At, np.dot(Qt, At.T)) a[t] = at R[t] = Rt # Backward sample mu = np.zeros((T + 1, p)) # initial values for smoothed dist'n fR = C[-1] fm = mode[-1] for t in xrange(T + 1): if t < T: # B_{t} = C_t G_t+1' R_t+1^-1 B = np.dot(C[t] * phi, la.inv(np.atleast_2d(R[t+1]))) # smoothed mean fm = mode[t] + np.dot(B, mode[t+1] - a[t+1]) fR = C[t] + chain_dot(B, C[t+1] - R[t+1], B.T) mu[t] = dist.rmvnorm(fm, np.atleast_2d(fR)) return mu.squeeze()