def logdet(self): d, s = self._d, self._s_perp fsh = full_shape([d.shape, s.shape]) logdet = np.zeros(fsh) for idx in itertools.product(*map(range, fsh)): d_idx, s_idx = broadcast(idx, d.shape), broadcast(idx, s.shape) logdet[idx] = np.log(d[d_idx]).sum() + \ (self.dim - d[d_idx].size) * np.log(s[s_idx]) return logdet
def full(self): S = np.zeros(full_shape([self._d.shape, self._Q.shape]) + (self.dim, self.dim)) for idx in itertools.product(*map(range, S.shape[:-2])): d_idx, Q_idx = broadcast(idx, self._d.shape), broadcast(idx, self._Q.shape) d, Q = self._d[d_idx], self._Q[Q_idx] S[idx + (Ellipsis,)] = np.dot(Q*d, Q.T) sp_idx = broadcast(idx, self._s_perp.shape) sp = self._s_perp[sp_idx] S[idx + (Ellipsis,)] += (np.eye(self.dim) - np.dot(Q, Q.T)) * sp return FullMatrix(S)
def _QDQ_x(Q, d, x): fsh = full_shape([x.shape[:-1], Q.shape, d.shape]) prod = np.zeros(fsh + (x.shape[-1],)) for full_idx in itertools.product(*map(range, fsh)): Q_idx = broadcast(full_idx, Q.shape) d_idx = broadcast(full_idx, d.shape) x_idx = broadcast(full_idx, x.shape[:-1]) curr_d, curr_Q = d[d_idx], Q[Q_idx] curr_x = x[x_idx + (slice(None),)] curr_QTx = np.dot(curr_Q.T, curr_x) prod[full_idx + (slice(None),)] = np.dot(curr_Q, curr_d * curr_QTx) return prod
def _QDQ_x(Q, d, x): fsh = full_shape([x.shape[:-1], Q.shape, d.shape]) prod = np.zeros(fsh + (x.shape[-1], )) for full_idx in itertools.product(*map(range, fsh)): Q_idx = broadcast(full_idx, Q.shape) d_idx = broadcast(full_idx, d.shape) x_idx = broadcast(full_idx, x.shape[:-1]) curr_d, curr_Q = d[d_idx], Q[Q_idx] curr_x = x[x_idx + (slice(None), )] curr_QTx = np.dot(curr_Q.T, curr_x) prod[full_idx + (slice(None), )] = np.dot(curr_Q, curr_d * curr_QTx) return prod
def full(self): S = np.zeros( full_shape([self._d.shape, self._Q.shape]) + (self.dim, self.dim)) for idx in itertools.product(*map(range, S.shape[:-2])): d_idx, Q_idx = broadcast(idx, self._d.shape), broadcast( idx, self._Q.shape) d, Q = self._d[d_idx], self._Q[Q_idx] S[idx + (Ellipsis, )] = np.dot(Q * d, Q.T) sp_idx = broadcast(idx, self._s_perp.shape) sp = self._s_perp[sp_idx] S[idx + (Ellipsis, )] += (np.eye(self.dim) - np.dot(Q, Q.T)) * sp return FullMatrix(S)
def assign_one(self, idx, j, x_new): if type(idx) == int: idx = (idx,) diff = x_new - self._X[idx + (j,)] self._X[idx + (j,)] = x_new Lambda_idx = broadcast(idx, self._Lambda.shape) self._Z_diff[idx] += self._J_diff[idx + (j,)] * diff + -0.5 * self._Lambda[Lambda_idx].elt(j, j) * diff ** 2 self._J_diff[idx + (slice(None),)] -= diff * self._Lambda[Lambda_idx].col(j)
def assign_one(self, idx, j, x_new): if type(idx) == int: idx = (idx,) diff = x_new - self._X[idx + (j,)] self._X[idx + (j,)] = x_new Lambda_idx = broadcast(idx, self._Lambda.shape) self._Z_diff[idx] += self._J_diff[idx + (j,)] * diff + \ -0.5 * self._Lambda[Lambda_idx].elt(j, j) * diff ** 2 self._J_diff[idx + (slice(None),)] -= diff * self._Lambda[Lambda_idx].col(j)
def random(d_shape, Q_shape, sp_shape, dim, low_rank=False): s_perp = np.random.gamma(1., 1., size=sp_shape) smsh = tuple(np.array([d_shape, Q_shape]).min(0)) if low_rank: rank = np.random.randint(1, dim+1, size=smsh) else: rank = dim * np.ones(smsh, dtype=int) d = np.zeros(d_shape, dtype=object) for idx in itertools.product(*map(range, d_shape)): sm_idx = broadcast(idx, smsh) d[idx] = np.random.gamma(1., 1., size=rank[sm_idx]) Q = np.zeros(Q_shape, dtype=object) for idx in itertools.product(*map(range, Q_shape)): sm_idx = broadcast(idx, smsh) Q[idx], _ = np.linalg.qr(np.random.normal(size=(dim, rank[sm_idx]))) return EigMatrix(d, Q, s_perp, dim)
def random(d_shape, Q_shape, sp_shape, dim, low_rank=False): s_perp = np.random.gamma(1., 1., size=sp_shape) smsh = tuple(np.array([d_shape, Q_shape]).min(0)) if low_rank: rank = np.random.randint(1, dim + 1, size=smsh) else: rank = dim * np.ones(smsh, dtype=int) d = np.zeros(d_shape, dtype=object) for idx in itertools.product(*map(range, d_shape)): sm_idx = broadcast(idx, smsh) d[idx] = np.random.gamma(1., 1., size=rank[sm_idx]) Q = np.zeros(Q_shape, dtype=object) for idx in itertools.product(*map(range, Q_shape)): sm_idx = broadcast(idx, smsh) Q[idx], _ = np.linalg.qr(np.random.normal(size=(dim, rank[sm_idx]))) return EigMatrix(d, Q, s_perp, dim)