def test_frozen_matrix_normal(self): for i in range(1, 5): for j in range(1, 5): M = 0.3 * np.ones((i, j)) U = 0.5 * np.identity(i) + 0.5 * np.ones((i, i)) V = 0.7 * np.identity(j) + 0.3 * np.ones((j, j)) frozen = matrix_normal(mean=M, rowcov=U, colcov=V) rvs1 = frozen.rvs(random_state=1234) rvs2 = matrix_normal.rvs(mean=M, rowcov=U, colcov=V, random_state=1234) assert_equal(rvs1, rvs2) X = frozen.rvs(random_state=1234) pdf1 = frozen.pdf(X) pdf2 = matrix_normal.pdf(X, mean=M, rowcov=U, colcov=V) assert_equal(pdf1, pdf2) logpdf1 = frozen.logpdf(X) logpdf2 = matrix_normal.logpdf(X, mean=M, rowcov=U, colcov=V) assert_equal(logpdf1, logpdf2)
def test_array_input(self): # Check array of inputs has the same output as the separate entries. num_rows = 4 num_cols = 3 M = 0.3 * np.ones((num_rows, num_cols)) U = 0.5 * np.identity(num_rows) + 0.5 * np.ones((num_rows, num_rows)) V = 0.7 * np.identity(num_cols) + 0.3 * np.ones((num_cols, num_cols)) N = 10 frozen = matrix_normal(mean=M, rowcov=U, colcov=V) X1 = frozen.rvs(size=N, random_state=1234) X2 = frozen.rvs(size=N, random_state=4321) X = np.concatenate((X1[np.newaxis, :, :, :], X2[np.newaxis, :, :, :]), axis=0) assert_equal(X.shape, (2, N, num_rows, num_cols)) array_logpdf = frozen.logpdf(X) assert_equal(array_logpdf.shape, (2, N)) for i in range(2): for j in range(N): separate_logpdf = matrix_normal.logpdf(X[i, j], mean=M, rowcov=U, colcov=V) assert_allclose(separate_logpdf, array_logpdf[i, j], 1E-10)
def testLogPDFScalarBatch(self): seed_stream = test_util.test_seed_stream() loc, scale_row, scale_col = self._random_loc_and_scale([], [2, 3], seed_stream) matrix_normal = tfd.MatrixNormalLinearOperator(loc, scale_row, scale_col, validate_args=True) x = tf.random.normal(shape=[2, 3], seed=seed_stream(), dtype=self.dtype) log_pdf = matrix_normal.log_prob(x) pdf = matrix_normal.prob(x) loc_, row_cov_, col_cov_, log_pdf_, pdf_, x_ = self.evaluate([ loc, tf.linalg.matmul(scale_row.to_dense(), scale_row.to_dense(), adjoint_b=True), tf.linalg.matmul(scale_col.to_dense(), scale_col.to_dense(), adjoint_b=True), log_pdf, pdf, x ]) scipy_matrix_normal = stats.matrix_normal(mean=loc_, rowcov=row_cov_, colcov=col_cov_) self.assertEqual((), log_pdf_.shape) self.assertEqual((), pdf_.shape) self.assertAllClose(scipy_matrix_normal.logpdf(x_), log_pdf_) self.assertAllClose(scipy_matrix_normal.pdf(x_), pdf_)
def testLogPDFBatch(self): seed_stream = test_util.test_seed_stream() loc, scale_row, scale_col = self._random_loc_and_scale( batch_shape=[3], matrix_shape=[3, 5], seed_stream=seed_stream) matrix_normal = tfd.MatrixNormalLinearOperator(loc, scale_row, scale_col, validate_args=True) x = tf.random.normal(shape=[3, 3, 5], seed=seed_stream(), dtype=self.dtype) log_pdf = matrix_normal.log_prob(x) pdf = matrix_normal.prob(x) loc_, row_cov_, col_cov_, log_pdf_, pdf_, x_ = self.evaluate([ loc, tf.linalg.matmul(scale_row.to_dense(), scale_row.to_dense(), adjoint_b=True), tf.linalg.matmul(scale_col.to_dense(), scale_col.to_dense(), adjoint_b=True), log_pdf, pdf, x ]) self.assertEqual((3, ), log_pdf_.shape) self.assertEqual((3, ), pdf_.shape) for i in range(3): scipy_matrix_normal = stats.matrix_normal(mean=loc_[i], rowcov=row_cov_[i], colcov=col_cov_[i]) expected_log_pdf = scipy_matrix_normal.logpdf(x_[i]) expected_pdf = scipy_matrix_normal.pdf(x_[i]) self.assertAllClose(expected_log_pdf, log_pdf_[i], rtol=3e-5) self.assertAllClose(expected_pdf, pdf_[i], rtol=3e-5)
def sample_theta(self, data_statistics): """ :param data_statistics: output of self.compute_statistics() :return: """ S_xx, S_yy, S_yx = data_statistics for k in range(self.L): s_xx = S_xx[:, :, k] + self.sampling_parameters['K'] s_yx = S_yx[:, :, k] + self.sampling_parameters[ 'M'] @ self.sampling_parameters['K'] s_yy = S_yy[:, :, k] + self.sampling_parameters['M'] @ ( self.sampling_parameters['K'] @ self.sampling_parameters['M'].T) M = s_yx @ inv(s_xx) s_ygx = s_yy - M @ s_yx.T # enforce symmetry s_ygx = (s_ygx + s_ygx.T) / 2 sigma = invwishart(df=self.sampling_parameters['n_0'] + self.state_counts['Ns'][k], scale=self.sampling_parameters['S_0'] + s_ygx).rvs() A = matrix_normal(mean=M + self.sampling_parameters['M'], rowcov=sigma, colcov=inv(s_xx)).rvs() self.theta['A'][:, :, k] = A self.theta['inv_sigma'][:, :, k] = inv(sigma)
def generate_expressionTrait(self, MatrixVariate=False): self.generate_parameters() term1 = self.X @ self.beta term2 = self.G @ self.delta if MatrixVariate: try: U = matrix_normal(rowcov=self.K, colcov=self.rho_u).rvs(1) except: K = self.K + 1e-8 * np.eye(self.num_sample) U = matrix_normal(rowcov=K, colcov=self.rho_u).rvs(1) epsilon = matrix_normal(rowcov=np.diag(np.ones(self.num_sample)), colcov=self.rho_e).rvs(1) term3 = U @ np.sqrt(self.xi) term4 = epsilon @ np.sqrt( np.diag(np.ones(self.num_trait)) - self.xi) term5 = (term3 + term4) @ np.sqrt(self.eta) self.Y = term1 + term2 + term5 else: Vu = np.sqrt(self.eta) @ np.sqrt(self.xi) @ self.rho_u @ np.sqrt( self.xi) @ np.sqrt(self.eta) Ve = np.sqrt(self.eta) @ np.sqrt(np.eye(self.num_trait) - self.xi) @ self.rho_u @ np.sqrt( np.eye(self.num_trait) - self.xi) @ np.sqrt(self.eta) mean = np.zeros(self.num_trait) U, Lambda, _ = np.linalg.svd(self.K) Lambda[Lambda < 1e-13] = 1e-13 _vec_e = np.zeros([self.num_trait, self.num_sample]) now = datetime.now().time() print('******************************* Generating Y:', " now the time is ", now) print(self.num_sample) for n in range(self.num_sample): if (n + 1) % 20 == 0: print('sampling : {} of {}'.format(n + 1, self.num_sample), flush=True) cov = Lambda[n] * Vu + Ve _vec_e[:, n] = np.random.multivariate_normal(mean=mean, cov=cov, size=1) vec_e = U @ _vec_e.T self.Y = term1 + term2 + vec_e
def sample_init_theta(self, seed=None): for k in range(self.L): sigma = invwishart(df=self.sampling_parameters['n_0'] + self.state_counts['Ns'][k], scale=self.sampling_parameters['S_0'] + 0, seed=seed).rvs() A = matrix_normal(mean=self.sampling_parameters['M'], rowcov=sigma, colcov=inv(self.sampling_parameters['K'])).rvs() self.theta['A'][:, :, k] = A self.theta['inv_sigma'][:, :, k] = inv(sigma)
def test_covariance_expansion(self): # Check that covariance can be specified with scalar or vector num_rows = 4 num_cols = 3 M = 0.3 * np.ones((num_rows,num_cols)) Uv = 0.2*np.ones(num_rows) Us = 0.2 Vv = 0.1*np.ones(num_cols) Vs = 0.1 Ir = np.identity(num_rows) Ic = np.identity(num_cols) assert_equal(matrix_normal(mean=M, rowcov=Uv, colcov=Vv).rowcov, 0.2*Ir) assert_equal(matrix_normal(mean=M, rowcov=Uv, colcov=Vv).colcov, 0.1*Ic) assert_equal(matrix_normal(mean=M, rowcov=Us, colcov=Vs).rowcov, 0.2*Ir) assert_equal(matrix_normal(mean=M, rowcov=Us, colcov=Vs).colcov, 0.1*Ic)
def test_covariance_expansion(self): # Check that covariance can be specified with scalar or vector num_rows = 4 num_cols = 3 M = 0.3 * np.ones((num_rows, num_cols)) Uv = 0.2 * np.ones(num_rows) Us = 0.2 Vv = 0.1 * np.ones(num_cols) Vs = 0.1 Ir = np.identity(num_rows) Ic = np.identity(num_cols) assert_equal( matrix_normal(mean=M, rowcov=Uv, colcov=Vv).rowcov, 0.2 * Ir) assert_equal( matrix_normal(mean=M, rowcov=Uv, colcov=Vv).colcov, 0.1 * Ic) assert_equal( matrix_normal(mean=M, rowcov=Us, colcov=Vs).rowcov, 0.2 * Ir) assert_equal( matrix_normal(mean=M, rowcov=Us, colcov=Vs).colcov, 0.1 * Ic)
def test_default_inputs(self): # Check that default argument handling works num_rows = 4 num_cols = 3 M = 0.3 * np.ones((num_rows,num_cols)) U = 0.5 * np.identity(num_rows) + 0.5 * np.ones((num_rows, num_rows)) V = 0.7 * np.identity(num_cols) + 0.3 * np.ones((num_cols, num_cols)) Z = np.zeros((num_rows, num_cols)) Zr = np.zeros((num_rows, 1)) Zc = np.zeros((1, num_cols)) Ir = np.identity(num_rows) Ic = np.identity(num_cols) I1 = np.identity(1) assert_equal(matrix_normal.rvs(mean=M, rowcov=U, colcov=V).shape, (num_rows, num_cols)) assert_equal(matrix_normal.rvs(mean=M).shape, (num_rows, num_cols)) assert_equal(matrix_normal.rvs(rowcov=U).shape, (num_rows, 1)) assert_equal(matrix_normal.rvs(colcov=V).shape, (1, num_cols)) assert_equal(matrix_normal.rvs(mean=M, colcov=V).shape, (num_rows, num_cols)) assert_equal(matrix_normal.rvs(mean=M, rowcov=U).shape, (num_rows, num_cols)) assert_equal(matrix_normal.rvs(rowcov=U, colcov=V).shape, (num_rows, num_cols)) assert_equal(matrix_normal(mean=M).rowcov, Ir) assert_equal(matrix_normal(mean=M).colcov, Ic) assert_equal(matrix_normal(rowcov=U).mean, Zr) assert_equal(matrix_normal(rowcov=U).colcov, I1) assert_equal(matrix_normal(colcov=V).mean, Zc) assert_equal(matrix_normal(colcov=V).rowcov, I1) assert_equal(matrix_normal(mean=M, rowcov=U).colcov, Ic) assert_equal(matrix_normal(mean=M, colcov=V).rowcov, Ir) assert_equal(matrix_normal(rowcov=U, colcov=V).mean, Z)
def test_moments(self): # Check that the sample moments match the parameters num_rows = 4 num_cols = 3 M = 0.3 * np.ones((num_rows,num_cols)) U = 0.5 * np.identity(num_rows) + 0.5 * np.ones((num_rows, num_rows)) V = 0.7 * np.identity(num_cols) + 0.3 * np.ones((num_cols, num_cols)) N = 1000 frozen = matrix_normal(mean=M, rowcov=U, colcov=V) X = frozen.rvs(size=N, random_state=1234) sample_mean = np.mean(X,axis=0) assert_allclose(sample_mean, M, atol=0.1) sample_colcov = np.cov(X.reshape(N*num_rows,num_cols).T) assert_allclose(sample_colcov, V, atol=0.1) sample_rowcov = np.cov(np.swapaxes(X,1,2).reshape( N*num_cols,num_rows).T) assert_allclose(sample_rowcov, U, atol=0.1)
def test_moments(self): # Check that the sample moments match the parameters num_rows = 4 num_cols = 3 M = 0.3 * np.ones((num_rows, num_cols)) U = 0.5 * np.identity(num_rows) + 0.5 * np.ones((num_rows, num_rows)) V = 0.7 * np.identity(num_cols) + 0.3 * np.ones((num_cols, num_cols)) N = 1000 frozen = matrix_normal(mean=M, rowcov=U, colcov=V) X = frozen.rvs(size=N, random_state=1234) sample_mean = np.mean(X, axis=0) assert_allclose(sample_mean, M, atol=0.1) sample_colcov = np.cov(X.reshape(N * num_rows, num_cols).T) assert_allclose(sample_colcov, V, atol=0.1) sample_rowcov = np.cov( np.swapaxes(X, 1, 2).reshape(N * num_cols, num_rows).T) assert_allclose(sample_rowcov, U, atol=0.1)
def test_matches_multivariate(self): # Check that the pdfs match those obtained by vectorising and # treating as a multivariate normal. for i in range(1, 5): for j in range(1, 5): M = 0.3 * np.ones((i, j)) U = 0.5 * np.identity(i) + 0.5 * np.ones((i, i)) V = 0.7 * np.identity(j) + 0.3 * np.ones((j, j)) frozen = matrix_normal(mean=M, rowcov=U, colcov=V) X = frozen.rvs(random_state=1234) pdf1 = frozen.pdf(X) logpdf1 = frozen.logpdf(X) vecX = X.T.flatten() vecM = M.T.flatten() cov = np.kron(V, U) pdf2 = multivariate_normal.pdf(vecX, mean=vecM, cov=cov) logpdf2 = multivariate_normal.logpdf(vecX, mean=vecM, cov=cov) assert_allclose(pdf1, pdf2, rtol=1E-10) assert_allclose(logpdf1, logpdf2, rtol=1E-10)
def test_array_input(self): # Check array of inputs has the same output as the separate entries. num_rows = 4 num_cols = 3 M = 0.3 * np.ones((num_rows,num_cols)) U = 0.5 * np.identity(num_rows) + 0.5 * np.ones((num_rows, num_rows)) V = 0.7 * np.identity(num_cols) + 0.3 * np.ones((num_cols, num_cols)) N = 10 frozen = matrix_normal(mean=M, rowcov=U, colcov=V) X1 = frozen.rvs(size=N, random_state=1234) X2 = frozen.rvs(size=N, random_state=4321) X = np.concatenate((X1[np.newaxis,:,:,:],X2[np.newaxis,:,:,:]), axis=0) assert_equal(X.shape, (2, N, num_rows, num_cols)) array_logpdf = frozen.logpdf(X) assert_equal(array_logpdf.shape, (2, N)) for i in range(2): for j in range(N): separate_logpdf = matrix_normal.logpdf(X[i,j], mean=M, rowcov=U, colcov=V) assert_allclose(separate_logpdf, array_logpdf[i,j], 1E-10)
def test_matches_multivariate(self): # Check that the pdfs match those obtained by vectorising and # treating as a multivariate normal. for i in range(1,5): for j in range(1,5): M = 0.3 * np.ones((i,j)) U = 0.5 * np.identity(i) + 0.5 * np.ones((i,i)) V = 0.7 * np.identity(j) + 0.3 * np.ones((j,j)) frozen = matrix_normal(mean=M, rowcov=U, colcov=V) X = frozen.rvs(random_state=1234) pdf1 = frozen.pdf(X) logpdf1 = frozen.logpdf(X) vecX = X.T.flatten() vecM = M.T.flatten() cov = np.kron(V,U) pdf2 = multivariate_normal.pdf(vecX, mean=vecM, cov=cov) logpdf2 = multivariate_normal.logpdf(vecX, mean=vecM, cov=cov) assert_allclose(pdf1, pdf2, rtol=1E-10) assert_allclose(logpdf1, logpdf2, rtol=1E-10)
def test_frozen_matrix_normal(self): for i in range(1,5): for j in range(1,5): M = 0.3 * np.ones((i,j)) U = 0.5 * np.identity(i) + 0.5 * np.ones((i,i)) V = 0.7 * np.identity(j) + 0.3 * np.ones((j,j)) frozen = matrix_normal(mean=M, rowcov=U, colcov=V) rvs1 = frozen.rvs(random_state=1234) rvs2 = matrix_normal.rvs(mean=M, rowcov=U, colcov=V, random_state=1234) assert_equal(rvs1, rvs2) X = frozen.rvs(random_state=1234) pdf1 = frozen.pdf(X) pdf2 = matrix_normal.pdf(X, mean=M, rowcov=U, colcov=V) assert_equal(pdf1, pdf2) logpdf1 = frozen.logpdf(X) logpdf2 = matrix_normal.logpdf(X, mean=M, rowcov=U, colcov=V) assert_equal(logpdf1, logpdf2)
def update_slds_theta(Y, fwd_vals, params, priors, ar=1, **kwargs): S_0, n_0 = priors L, D, theta = params['L'], params['D'], params['theta'] n = fwd_vals['n'] # set pseudo_obs = pseudo_obs if ar == 2: if D > 1: mx, mn = np.max(Y.shape), np.min(Y.shape) Y_bar = np.concatenate( [np.zeros_like(Y), np.zeros_like(Y)], axis=-1).astype(np.float32) Y_bar[0, :] += np.concatenate([Y[0, :], Y[0, :]]) Y_bar[1:, :mn] += Y[:-1] Y_bar[1, mn:] += Y[0, :] Y_bar[2:, mn:] += Y[:-2] else: Y_bar = np.zeros(shape=(Y.shape[0], D * 2), dtype=np.float32) Y_bar[0] += Y[0] Y_bar[1:, 0] += Y[:-1] Y_bar[1, 1] += Y[0] Y_bar[2:, 1] += Y[:-2] else: # lagged observations Y_bar = np.zeros_like(Y, dtype=np.float32) Y_bar[0] += Y[0] Y_bar[1:] += Y[:-1] # step 5 caluculate the sufficient statistics for the pseudo_obs S_ybarybar, S_yybar, S_yy = slds_sufficient_statistics( Y, Y_bar, fwd_vals, ar, params) for k in range(0, L): S_ybarybar_k, S_yybar_k, S_yy_k = S_ybarybar[k], S_yybar[k], S_yy[k] S_ybarybar_k_inv = invert(S_ybarybar_k) # sigma_k Sy_vert_ybar = S_yy_k - np.dot(np.dot(S_yybar_k, S_ybarybar_k_inv), S_yybar_k.T) # sig = stats.invwishart(scale=Sy_vert_ybar+S_0, df=np.sum(n[:,k])+n_0).rvs().astype(np.float32) sig = stats.invwishart(scale=Sy_vert_ybar + S_0, df=np.sum(n[k]) + n_0).rvs().astype(np.float32) if type(sig) != np.ndarray: sig = np.reshape(sig, newshape=(1, 1)) sigma_ = theta[k]['sigma'] # sigma_ = sig sigma_inv_ = invert(sigma_) # TODO: I there is ambiguity in paper, not sure about this M = np.dot(S_yybar_k, S_ybarybar_k_inv) # PhD suggests this one # K_inv = S_ybarybar_k_inv if ar == 2: A = stats.matrix_normal(mean=M, rowcov=sigma_inv_, colcov=S_ybarybar_k_inv).rvs() A = np.array([A[:D, D:], A[:D, :D]], dtype=np.float32) else: A = stats.matrix_normal(mean=M, rowcov=sigma_inv_, colcov=S_ybarybar_k_inv).rvs().reshape( D, -D).astype(np.float32) theta[k]['A'] = A theta[k]['sigma'] = sig return theta