예제 #1
0
    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)
예제 #2
0
    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)
예제 #5
0
    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
예제 #7
0
 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)
예제 #8
0
    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)
예제 #9
0
    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)
예제 #10
0
    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)
예제 #11
0
    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)
예제 #12
0
    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)
예제 #13
0
    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)
예제 #14
0
    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)
예제 #15
0
    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)
예제 #16
0
    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)
예제 #17
0
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