예제 #1
0
    def test_flipping_shuffling(self):
        np.random.seed(0)
        shapes = [(2, 3), (2, 2), (5, 2)]  # sizes of submatricies
        d = len(shapes)

        # first do the exact computation
        K = KronMatrix([np.random.rand(*shape) for shape in shapes])
        x = np.random.rand(K.shape[1], 1)
        y = K * x

        # now shuffle K and the vector x and try to recover y
        for i in range(1, d):  # i is the index which should go first
            # do the forward shuffle
            shuffle = np.concatenate(([
                i,
            ], np.delete(np.arange(d), i)))
            K_s = KronMatrix([K.K[axis] for axis in shuffle])
            X = x.reshape(np.asarray(shapes).T[1])
            x_s = np.transpose(X, shuffle).reshape((-1, 1))
            y_s = K_s * x_s

            # now reverse the shuffle in y
            new_shapes = [shapes[j] for j in shuffle]
            reverse = np.squeeze([np.where(shuffle == j)[0] for j in range(d)])
            Y_s = y_s.reshape(np.asarray(new_shapes).T[0])
            yy = np.transpose(Y_s, reverse).reshape((-1, 1))
            assert_array_almost_equal(yy, y)
예제 #2
0
 def test_log_det(self):
     for sym in [True, False]:
         np.random.seed(0)
         A = [np.random.rand(5, 5) + np.eye(5) for i in range(2)]
         A = [Ai.dot(Ai.T) + 1e-6 * np.eye(5) for Ai in A]  # make it SPD
         A = KronMatrix(A, sym=sym)
         eig = A.eig_vals()
         assert_array_almost_equal(eig.log_det(),\
               np.linalg.slogdet(A.expand())[1])
    def test_row_col_khatri_rao_matrix(self):
        np.random.seed(0)
        N, p, d = 5, 6, 3
        grid_shape = np.random.randint(low=2, high=15, size=d)
        R = np.empty(d, dtype=object)
        R[:] = [np.random.rand(p, m) - 0.5 for m in grid_shape]
        K = np.empty(d, dtype=object)
        K[:] = [np.random.rand(m, m) - 0.5 for m in grid_shape]
        C = np.empty(d, dtype=object)
        C[:] = [np.random.rand(m, N) - 0.5 for m in grid_shape]
        for i in range(d):
            R[i][
                0, :] = 0.  # set this to zero so there's a zero in the final matrix
        vec = np.random.rand(N, 1) - 0.5
        vecT = np.random.rand(p, 1) - 0.5

        # initialize RowKronColKhatriRaoMatrix
        A = RowColKhatriRaoMatrix(R=R, K=K, C=C)
        # initialize RowColKhatriRaoMatrixTransposed
        AT = RowColKhatriRaoMatrixTransposed(R=R, K=K, C=C)
        # initialize KhatriRaoMatrix's and KronMatrix to test
        R = KhatriRaoMatrix(R, partition=0)
        C = KhatriRaoMatrix(C, partition=1)
        K = KronMatrix(K)

        # test matvec
        assert_array_almost_equal(A * vec, R * (K * (C * vec)))

        # test matvec with transpose
        assert_array_almost_equal(A.T * vecT, C.T * (K.T * (R.T * vecT)))

        # now try with RowColKhatriRaoMatrixTransposed
        assert_array_almost_equal(AT * vecT, C.T * (K.T * (R.T * vecT)))

        # test the expand method to compute the whole matrix
        RKC = R.expand().dot(K.expand().dot(C.expand()))
        assert_array_almost_equal(A.expand(), RKC)

        # test the log expand
        log_A, sign = A.expand(logged=True)
        assert_array_almost_equal(sign * np.exp(log_A), RKC)
예제 #4
0
	def __init__(self, A, partition=None):
		"""
		Khatri-Rao Block Matrix.

		Inputs:
			A : list of sub matricies or 2d array of KronMatricies. 
				If the latter then partition is ignored.
			partition : int specifying the direction that the 
				Khatri-Rao Matrix is partitioned:
				0 : row partitioned
				1 : column partitioned
				If A is an array of KronMatricies then this has now effect.
		"""
		# determine whether KronMatricies have been formed from the partitions
		if np.ndim(A)==2 and isinstance(A[0,0], KronMatrix): 
			# all the work is done
			super(KhatriRaoMatrix, self).__init__(A)
			return

		# else I need to create KronMatrices from each partition
		# get the number of blocks that will be needed
		assert partition in range(2)
		if partition == 0:
			block_shape = (A[0].shape[0], 1)
		elif partition == 1:
			block_shape = (1,A[0].shape[1])
		else:
			raise ValueError('unknown partition')

		# form the KronMatricies
		Akron = np.empty(max(block_shape), dtype=object) # make 1d, reshape later
		for i in range(max(block_shape)):
			if partition == 0:
				Akron[i] = KronMatrix([Aj[(i,),:] for Aj in A], sym=False)
			elif partition == 1:
				Akron[i] = KronMatrix([Aj[:,(i,)] for Aj in A], sym=False)
		Akron = Akron.reshape(block_shape)

		# Create a BlockMatrix from this
		super(KhatriRaoMatrix, self).__init__(Akron)
예제 #5
0
from gp_grief.tensors import KronMatrix
"""
SET UP
"""
np.random.seed(0)
d, n = 3, 5
N = n**d
A = [np.array(np.random.rand(n, n), order='F') for i in range(d)]
A = [np.array(Ai.dot(Ai.T) + 1e-6 * np.identity(n), order='F') for Ai in A]

Ab = 1
for i in range(d):
    Ab = np.kron(Ab, A[i])
Abnorm = np.linalg.norm(Ab)

K = KronMatrix(A, sym=True)
x = np.matrix(np.random.rand(n**d, 1))
xnorm = np.linalg.norm(x)
lam = 1e-3
"""
TESTS
"""


class TestKronMatrixSym:
    def test_expansion(self):
        error = np.linalg.norm(K.expand() - Ab) / Abnorm
        assert error <= 1e-10

    def test_transpose(self):
        error = np.linalg.norm(K.T.expand() - Ab.T) / Abnorm
예제 #6
0
    def cov_grid(self, x, z=None, dim_noise_var=None, use_toeplitz=False):
        """
        generate matrix, creates covariance matrix mapping between x1 and x2.

        Inputs:
          x : numpy.ndarray of shape (self.grid_dim,)
          z : (optional) numpy.ndarray of shape (self.grid_dim,) if None x2=x1
              for both x1 and x2:
              the ith element in the array must be a matrix of size 
              [n_mesh_i,n_dims_i] where n_dims_i is the number of dimensions 
              in the ith kronecker pdt matrix and n_mesh_i is the number of 
              points along the ith dimension of the grid.
              Note that for spatial temporal datasets, n_dims_i is probably 1
              but for other problems this might be of much higher dimensions.
          dim_noise_var : float (optional)
              diagonal term to use to shift the diagonal of each dimension to 
              improve conditioning

        Outputs:
          K : gp_grief.tensors.KronMatrix of size determined by x and z 
                (prod(n_mesh1(:)), prod(n_mesh2(:))
              covariance matrix
        """
        assert dim_noise_var is not None, "dim_noise_var must be specified"
        # toeplitz stuff
        if isinstance(use_toeplitz, bool):
            use_toeplitz = [
                use_toeplitz,
            ] * self.grid_dim
        else:
            assert np.size(use_toeplitz) == self.grid_dim
        if np.any(use_toeplitz):
            assert z is None, "toeplitz can only be used where the (square)"\
                                + "covariance matrix is being computed"

        # check inputs
        assert len(x) == self.grid_dim  # ensure 1st dim is same as grid dim
        if z is None:
            cross_cov = False
            z = [
                None,
            ] * self.grid_dim  # array of None
        else:
            cross_cov = True
            assert len(
                z) == self.grid_dim  # ensure 1st dim is same as grid dim

        # get the 1d covariance matricies
        K = []
        # loop through and generate the covariance matricies
        for i, (kern, toeplitz) in enumerate(zip(self.kern_list,
                                                 use_toeplitz)):
            if toeplitz and z[i] is None:
                K.append(kern.cov_toeplitz(x=x[i]))
            else:
                K.append(kern.cov(x=x[i], z=z[i]))

        # now create a KronMatrix instance
        # reverse order and set as symmetric only if the two lists are identical
        K = KronMatrix(K[::-1], sym=(z[0] is None))

        # shift the diagonal of the sub-matricies if required
        if dim_noise_var != 0.:
            assert not cross_cov, "not implemented for cross covariances yet"
            K = K.sub_shift(shift=dim_noise_var)
        return K
예제 #7
0
"""
SET UP
"""
np.random.seed(0)
d, n = 3, 5
N    = n**d
A    = [np.array(np.random.rand(n,n),order='F') for i in range(d)]


Ab   = 1
for i in range(d):
	Ab = np.kron(Ab,A[i])
Abnorm = np.linalg.norm(Ab)

K     = KronMatrix(A, sym=False)
x     = np.matrix(np.random.rand(n**d,1))
xnorm = np.linalg.norm(x)
lam   = 1e-3

"""
class TestKronMatrixNotSym:

	def test_expansion (self):
		error = np.linalg.norm(K.expand()-Ab)/Abnorm
		assert error <= 1e-10

	def test_transpose (self):
		error = np.linalg.norm(K.T.expand()-Ab.T)/Abnorm
		assert error <= 1e-10
예제 #8
0
import pytest
import numpy as np
from numpy.testing import assert_array_almost_equal
from gp_grief.tensors import KronMatrix
"""
SET UP
"""
np.random.seed(1)
d = 10
n = 3
eigs = KronMatrix([np.random.rand(n) for i in range(d)])
all_eigs = eigs.expand()  # compute all the eigenvalues for comparison
n_eigs = 5  # this is the number of largest/smallest that I want to find
"""
TESTS
"""


class TestKronEigenvalues:
    def test_False_largest(self):
        log_expand = False
        mode = 'largest'
        # get the n_eigs largest/smallest
        eig_order, extreme_eigs, global_loc = eigs.find_extremum_eigs(
            n_eigs,
            mode=mode,
            log_expand=log_expand,
            sort=True,
            compute_global_loc=True)
        # check if extreme_eigs is being computed correctly
        assert_array_almost_equal(extreme_eigs, [