def _stats_ensure_array(stats): ysq, yxT, xxT, n = stats if yxT.ndim != 2: raise Exception("yxT.shape must be (D_out, D_in)") D_out, D_in = yxT.shape # If ysq is D_out x D_out, just take the diagonal if ysq.ndim == 1: assert ysq.shape == (D_out, ) elif ysq.ndim == 2: assert ysq.shape == (D_out, D_out) ysq = np.diag(ysq) else: raise Exception("ysq.shape must be (D_out,) or (D_out, D_out)") # Make sure xxT is D_out x D_in x D_in if xxT.ndim == 2: assert xxT.shape == (D_in, D_in) xxT = np.tile(xxT[None, :, :], (D_out, 1, 1)) elif xxT.ndim == 3: assert xxT.shape == (D_out, D_in, D_in) else: raise Exception( "xxT.shape must be (D_in, D_in) or (D_out, D_in, D_in)") # Make sure n is of shape (D_out,) if np.isscalar(n): n = n * np.ones(D_out) elif n.ndim == 1: assert n.shape == (D_out, ) else: raise Exception("n must be a scalar or an array of shape (D_out,)") return objarray([ysq, yxT, xxT, n])
def _stats_ensure_array(stats): ysq, yxT, xxT, n = stats if yxT.ndim != 2: raise Exception("yxT.shape must be (D_out, D_in)") D_out, D_in = yxT.shape # If ysq is D_out x D_out, just take the diagonal if ysq.ndim == 1: assert ysq.shape == (D_out,) elif ysq.ndim == 2: assert ysq.shape == (D_out, D_out) ysq = np.diag(ysq) else: raise Exception("ysq.shape must be (D_out,) or (D_out, D_out)") # Make sure xxT is D_out x D_in x D_in if xxT.ndim == 2: assert xxT.shape == (D_in, D_in) xxT = np.tile(xxT[None,:,:], (D_out, 1, 1)) elif xxT.ndim == 3: assert xxT.shape == (D_out, D_in, D_in) else: raise Exception("xxT.shape must be (D_in, D_in) or (D_out, D_in, D_in)") # Make sure n is of shape (D_out,) if np.isscalar(n): n = n * np.ones(D_out) elif n.ndim == 1: assert n.shape == (D_out,) else: raise Exception("n must be a scalar or an array of shape (D_out,)") return objarray([ysq, yxT, xxT, n])
def _null_stats(self): return objarray([ np.zeros(self.D_obs), np.zeros((self.D_obs, self.D_latent)), np.zeros((self.D_obs, self.D_latent, self.D_latent)), np.zeros(self.D_obs) ])
def _set_expected_stats(self): D_lat = self.D_latent E_Xsq = np.sum(self.X**2 * self.mask, axis=0) E_XZT = (self.X * self.mask).T.dot(self.E_Z) E_ZZT_vec = self.E_ZZT.reshape((self.E_ZZT.shape[0], D_lat ** 2)) E_ZZT = np.array([np.dot(self.mask[:, d], E_ZZT_vec).reshape((D_lat, D_lat)) for d in range(self.D_obs)]) n = np.sum(self.mask, axis=0) self.E_emission_stats = objarray([E_Xsq, E_XZT, E_ZZT, n])
def _set_expected_stats(self, smoothed_mus, smoothed_sigmas, E_xtp1_xtT): if self.mask is None: return super(LDSStatesMissingData, self).\ _set_expected_stats(smoothed_mus, smoothed_sigmas, E_xtp1_xtT) # Get the emission stats p, n, d, T, mask, inputs, data = \ self.D_emission, self.D_latent, self.D_input, self.T, \ self.mask, self.inputs, self.data E_x_xT = smoothed_sigmas + self.smoothed_mus[:, :, None] * self.smoothed_mus[:, None, :] E_x_uT = smoothed_mus[:, :, None] * self.inputs[:, None, :] E_u_uT = self.inputs[:, :, None] * self.inputs[:, None, :] E_xu_xuT = np.concatenate( (np.concatenate((E_x_xT, E_x_uT), axis=2), np.concatenate((np.transpose(E_x_uT, (0, 2, 1)), E_u_uT), axis=2)), axis=1) E_xut_xutT = E_xu_xuT[:-1].sum(0) E_xtp1_xtp1T = E_x_xT[1:].sum(0) E_xt_xtT = E_x_xT[:-1].sum(0) E_xtp1_xtT = E_xtp1_xtT.sum(0) E_xtp1_utT = (smoothed_mus[1:, :, None] * inputs[:-1, None, :]).sum(0) E_xtp1_xutT = np.hstack((E_xtp1_xtT, E_xtp1_utT)) def is_symmetric(A): return np.allclose(A, A.T) assert is_symmetric(E_xt_xtT) assert is_symmetric(E_xtp1_xtp1T) self.E_dynamics_stats = np.array( [E_xtp1_xtp1T, E_xtp1_xutT, E_xut_xutT, self.T - 1]) # Emission statistics E_ysq = np.sum(data**2 * mask, axis=0) E_yxT = (data * mask).T.dot(smoothed_mus) E_yuT = (data * mask).T.dot(inputs) E_yxuT = np.hstack((E_yxT, E_yuT)) E_xuxuT_vec = E_xu_xuT.reshape((T, -1)) E_xuxuT = np.array([ np.dot(self.mask[:, i], E_xuxuT_vec).reshape((n + d, n + d)) for i in range(p) ]) Tp = np.sum(self.mask, axis=0) self.E_emission_stats = objarray([E_ysq, E_yxuT, E_xuxuT, Tp])
def _set_expected_stats(self, smoothed_mus, smoothed_sigmas, E_xtp1_xtT): # Get the emission stats p, n, d, T, inputs, data = \ self.D_emission, self.D_latent, self.D_input, self.T, \ self.inputs, self.data E_x_xT = smoothed_sigmas + self.smoothed_mus[:, :, None] * self.smoothed_mus[:, None, :] E_x_uT = smoothed_mus[:, :, None] * self.inputs[:, None, :] E_u_uT = self.inputs[:, :, None] * self.inputs[:, None, :] E_xu_xuT = np.concatenate( (np.concatenate((E_x_xT, E_x_uT), axis=2), np.concatenate((np.transpose(E_x_uT, (0, 2, 1)), E_u_uT), axis=2)), axis=1) E_xut_xutT = E_xu_xuT[:-1].sum(0) E_xtp1_xtp1T = E_x_xT[1:].sum(0) E_xtp1_xtT = E_xtp1_xtT.sum(0) E_xtp1_utT = (smoothed_mus[1:, :, None] * inputs[:-1, None, :]).sum(0) E_xtp1_xutT = np.hstack((E_xtp1_xtT, E_xtp1_utT)) # def is_symmetric(A): # return np.allclose(A, A.T) # assert is_symmetric(E_xt_xtT) # assert is_symmetric(E_xtp1_xtp1T) self.E_dynamics_stats = np.array( [E_xtp1_xtp1T, E_xtp1_xutT, E_xut_xutT, self.T - 1]) # Emission statistics E_yyT = np.sum(data**2, axis=0) if self.diagonal_noise else data.T.dot(data) E_yxT = data.T.dot(smoothed_mus) E_yuT = data.T.dot(inputs) E_yxuT = np.hstack((E_yxT, E_yuT)) self.E_emission_stats = objarray([E_yyT, E_yxuT, E_xu_xuT.sum(0), T])
def _null_stats(self): return objarray( [np.zeros(self.D_obs), np.zeros((self.D_obs, self.D_latent)), np.zeros((self.D_obs, self.D_latent, self.D_latent)), np.zeros(self.D_obs)])