def statistics(self, y, x, vectorize=False): if isinstance(y, np.ndarray) and isinstance(x, np.ndarray): idx = np.logical_and(~np.isnan(y).any(axis=1), ~np.isnan(x).any(axis=1)) y, x = y[idx], x[idx] if self.affine: x = np.hstack((x, np.ones((x.shape[0], 1)))) if vectorize: contract = 'nk,nh->nkh' n = np.ones((y.shape[0], )) else: contract = 'nk,nh->kh' n = y.shape[0] yxT = np.einsum(contract, y, x, optimize=True) xxT = np.einsum(contract, x, x, optimize=True) yyT = np.einsum(contract, y, y, optimize=True) return Stats([yxT, xxT, yyT, n]) else: func = partial(self.statistics, vectorize=vectorize) stats = list(map(func, y, x)) return stats if vectorize else reduce(add, stats)
def weighted_statistics(self, y, x, posterior): if isinstance(y, np.ndarray) and isinstance(x, np.ndarray)\ and not isinstance(posterior, list): idx = np.logical_and(~np.isnan(y).any(axis=1), ~np.isnan(x).any(axis=1)) y, x = y[idx], x[idx] if self.affine: x = np.hstack((x, np.ones((x.shape[0], 1)))) yyT = y.T @ y xxT = x.T @ x xyT = x.T @ y matnorm_stats = np.array([ posterior.M @ self.matnorm.K, self.matnorm.K, np.trace(self.matnorm.K @ np.linalg.inv(posterior.K)) * np.linalg.inv(posterior.V) + posterior.M @ self.matnorm.K @ posterior.M.T, x.shape[1] ]) lingauss_stats = np.array([ 0., 0., yyT - 2. * posterior.M @ xyT + posterior.M @ xxT @ posterior.M.T + np.trace(xxT @ np.linalg.inv(posterior.K)) * np.linalg.inv(posterior.V), x.shape[0] ]) stats = matnorm_stats + lingauss_stats return Stats(stats)
def weighted_statistics(self, y, x, weights, vectorize=False): if isinstance(y, np.ndarray) and isinstance(x, np.ndarray): idx = np.logical_and(~np.isnan(y).any(axis=1), ~np.isnan(x).any(axis=1)) y, x, weights = y[idx], x[idx], weights[idx] if self.affine: x = np.hstack((x, np.ones((x.shape[0], 1)))) if vectorize: c0, c1 = 'nk,n,nh->nkh', 'nk,n,nk->nk' n = weights else: c0, c1 = 'nk,n,nh->kh', 'nk,n,nk->k' n = np.sum(weights) yxT = np.einsum(c0, y, weights, x, optimize=True) xxT = np.einsum(c0, x, weights, x, optimize=True) yy = np.einsum(c1, y, weights, y, optimize=True) return Stats([yxT, xxT, yy, n]) else: func = partial(self.weighted_statistics, vectorize=vectorize) stats = list(map(func, y, x, weights)) return stats if vectorize else reduce(add, stats)
def statistics(self, y, x): if isinstance(y, np.ndarray) and isinstance(x, np.ndarray): idx = np.logical_and(~np.isnan(y).any(axis=1), ~np.isnan(x).any(axis=1)) y, x = y[idx], x[idx] if self.affine: x = np.hstack((x, np.ones((x.shape[0], 1)))) yyT = y.T @ y xxT = x.T @ x xyT = x.T @ y matnorm_stats = np.array([ self.lingauss.A @ self.matnorm.K, self.matnorm.K, self.lingauss.A @ self.matnorm.K @ self.lingauss.A.T, x.shape[1] ]) lingauss_stats = np.array([ 0., 0., yyT - 2. * self.lingauss.A @ xyT + self.lingauss.A @ xxT @ self.lingauss.A.T, x.shape[0] ]) stats = matnorm_stats + lingauss_stats return Stats(stats)
def statistics(self, data): if isinstance(data, np.ndarray): idx = ~np.isnan(data).any(axis=1) data = data[idx] logx = np.log(data) x = data n = np.ones((self.data.shape[0], )) return Stats([logx, n, x, n]) else: return list(map(self.statistics, data))
def statistics(self, data): if isinstance(data, np.ndarray): idx = ~np.isnan(data).any(axis=1) data = data[idx] x = data logdet_x = np.linalg.slogdet(data)[1] n = np.ones((data.shape[0], )) return Stats([x, n, logdet_x, n]) else: return list(map(self.statistics, data))
def weighted_statistics(self, data, weights): if isinstance(data, np.ndarray): idx = ~np.isnan(data).any(axis=1) data = data[idx] weights = weights[idx] logx = np.einsum('n,nk->nk', weights, np.log(data)) x = np.einsum('n,nk->nk', weights, data) n = weights return Stats([logx, n, x, n]) else: return list(map(self.weighted_statistics, data, weights))
def weighted_statistics(self, data, weights): if isinstance(data, np.ndarray): idx = ~np.isnan(data).any(axis=1) data = data[idx] weights = weights[idx] x = np.einsum('n,nkh->nkh', weights, data) logdet_x = np.einsum('n,nkh->nkh', weights, np.linalg.slogdet(data)[1]) n = weights return Stats([x, n, logdet_x, n]) else: return list(map(self.weighted_statistics, data, weights))
def std_to_nat(params): # The definition of stats is slightly different # from literatur to make posterior updates easy # Assumed stats # stats = [lmbda @ A, # -0.5 * lmbda @ AAT, # -0.5 * lmbda, # 0.5 * logdet_lmbda] M = params[0].dot(params[1]) K = params[1] psi = invpd(params[2]) + params[0].dot(K).dot(params[0].T) nu = params[3] - params[2].shape[0] - 1 + params[0].shape[-1] return Stats([M, K, psi, nu])
def std_to_nat(params): # The definition of stats is slightly different # from literatur to make posterior updates easy # Assumed stats # stats = [lmbdas * x, # -0.5 * lmbdas * xx, # 0.5 * log_lmbdas # -0.5 * lmbdas] mu = params[1] * params[0] kappas = params[1] alphas = 2. * params[2] - 1. betas = 2. * params[3] + params[1] * params[0]**2 return Stats([mu, kappas, alphas, betas])
def statistics(self, data, labels, vectorize=False): if isinstance(data, np.ndarray): idx = ~np.isnan(data).any(axis=1) data = data[idx] labels = labels[idx] stats = [ c.statistics(data[labels == idx, :], vectorize) for idx, c in enumerate(self.components) ] return Stats(stats) else: func = partial(self.statistics, vectorize=vectorize) stats = list(map(func, data, labels)) return list(stats) if vectorize else reduce(add, stats)
def weighted_statistics(self, data, weights, vectorize=False): if isinstance(data, np.ndarray): idx = ~np.isnan(data).any(axis=1) data = data[idx] weights = weights[idx] stats = [ c.weighted_statistics(data, weights[:, idx], vectorize) for idx, c in enumerate(self.components) ] return Stats(stats) else: func = partial(self.weighted_statistics, vectorize=vectorize) stats = map(func, data, weights) return list(stats) if vectorize else reduce(add, stats)
def std_to_nat(params): # The definition of stats is slightly different # from literatur to make posterior updates easy # Assumed stats # stats = [lmbda @ x, # -0.5 * lmbda @ xxT, # -0.5 * lmbda, # 0.5 * logdet_lmbda] mu = params[1] * params[0] kappa = params[1] psi = invpd(params[2]) \ + params[1] * np.outer(params[0], params[0]) nu = params[3] - params[2].shape[0] return Stats([mu, kappa, psi, nu])
def statistics(self, data, vectorize=False): if isinstance(data, np.ndarray): idx = ~np.isnan(data).any(axis=1) data = data[idx] x = data xx = np.einsum('nk,nk->nk', data, data) n = np.ones((data.shape[0], )) if not vectorize: x = np.sum(x, axis=0) xx = np.sum(xx, axis=0) n = np.sum(n, axis=0) return Stats([x, n, n, xx]) else: func = partial(self.statistics, vectorize=vectorize) stats = list(map(func, data)) return stats if vectorize else reduce(add, stats)
def statistics(self, data, vectorize=False): if isinstance(data, np.ndarray): idx = ~np.isnan(data).any(axis=1) data = data[idx] if vectorize: c0, c1 = 'nk->nk', 'nk,nh->nkh' n = np.ones((data.shape[0], )) else: c0, c1 = 'nk->k', 'nk,nh->kh' n = data.shape[0] x = np.einsum(c0, data, optimize=True) xxT = np.einsum(c1, data, data, optimize=True) return Stats([x, n, xxT, n]) else: func = partial(self.statistics, vectorize=vectorize) stats = list(map(func, data)) return stats if vectorize else reduce(add, stats)
def weighted_statistics(self, data, weights, vectorize=False): if isinstance(data, np.ndarray): idx = ~np.isnan(data).any(axis=1) data = data[idx] weights = weights[idx] x = np.einsum('n,nk->nk', weights, data) xx = np.einsum('nk,n,nk->nk', data, weights, data) n = np.repeat(weights[:, None], self.dim, axis=1) if not vectorize: x = np.sum(x, axis=0) xx = np.sum(xx, axis=0) n = np.sum(n, axis=0) return Stats([x, n, n, xx]) else: func = partial(self.weighted_statistics, vectorize=vectorize) stats = list(map(func, data, weights)) return stats if vectorize else reduce(add, stats)
def weighted_statistics(self, data, weights, vectorize=False): if isinstance(data, np.ndarray): idx = ~np.isnan(data).any(axis=1) data = data[idx] weights = weights[idx] if vectorize: c0, c1 = 'n,nk->nk', 'nk,n,nh->nkh' n = weights else: c0, c1 = 'n,nk->k', 'nk,n,nh->kh' n = np.sum(weights) x = np.einsum(c0, weights, data, optimize=True) xxT = np.einsum(c1, data, weights, data, optimize=True) return Stats([x, n, xxT, n]) else: func = partial(self.weighted_statistics, vectorize=vectorize) stats = list(map(func, data, weights)) return stats if vectorize else reduce(add, stats)
def nat_to_std(natparam): sigma = - 0.5 * np.linalg.inv(natparam[1]) mu = - 0.5 * sigma @ natparam[0] return Stats([mu, sigma])
def std_to_nat(params): sigma = - 0.5 * np.linalg.inv(params[1]) mu = - 2. * sigma @ params[0] return Stats([mu, sigma])
def std_to_nat(params): alphas = params[0] - 1 betas = -params[1] return Stats([alphas, betas])
def std_to_nat(params): nat = [ NormalWishart.std_to_nat(_params) for _params in zip(*extendlists(params)) ] return Stats(nat)
def statistics(self, A, lmbda): # Stats corresponding to a diagonal Gamma prior on K a = 0.5 * self.drow * np.ones((self.dcol, )) b = -0.5 * np.einsum('kh,km,mh->h', A - self.matnorm.M, lmbda, A - self.matnorm.M) return Stats([a, b])
def nat_to_std(natparam): mu = - 0.5 * natparam[1] @ natparam[0] lmbda = - 0.5 * natparam[1] return Stats([mu, lmbda])
def std_to_nat(params): psi = -0.5 * params[0] nu = -0.5 * (params[1] + psi.shape[0] + 1) return Stats([psi, nu])
def nat_to_std(natparam): sigmas = - 0.5 * (1. / natparam[1]) mu = - 0.5 * sigmas * natparam[0] return Stats([mu, sigmas])
def std_to_nat(params): mu = params[1] @ params[0] lmbda = - 0.5 * params[1] return Stats([mu, lmbda])
def std_to_nat(params): M = params[0].dot(params[1]) K = params[1] return Stats([M, K])
def std_to_nat(params): sigmas = - 0.5 * (1. / params[1]) mu = - 2. * sigmas @ params[0] return Stats([mu, sigmas])
def std_to_nat(params): psi = -0.5 * np.linalg.inv(params[0]) nu = 0.5 * (params[1] - psi.shape[0] - 1) return Stats([psi, nu])