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)
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)
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)
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
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
""" 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
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, [