def outer(a, b, out=None): """ Return outer product of two sparse arrays. Parameters ---------- a, b : sparse.SparseArray The input arrays. out : sparse.SparseArray The output array. Examples -------- >>> import numpy as np >>> import sparse >>> a = sparse.COO(np.arange(4)) >>> o = sparse.outer(a, a) >>> o.todense() array([[0, 0, 0, 0], [0, 1, 2, 3], [0, 2, 4, 6], [0, 3, 6, 9]]) """ from sparse import SparseArray, COO if isinstance(a, SparseArray): a = COO(a) if isinstance(b, SparseArray): b = COO(b) return np.multiply.outer(a.flatten(), b.flatten(), out=out)
def parallel_concatenate(kraus1, kraus2): r""" Parallel Concatenation of two kraus operators, A, B to produce "A tensored B". Parameters ---------- kraus1 : list, array, SparseArray List or three-dimensional (numpy or sparse) array of kraus operators on left-side. kraus2: list, array, SparseArray List or three-dimensional (numpy or sparse) array of kraus operators on right-side. Returns ------- array Three-dimensional array of kraus operators. Notes ----- See Mark Wilde's book, "Quantum Information Theory" """ assert isinstance(kraus1, (list, np.ndarray, SparseArray)), \ "Kraus1 should be list or numpy array or sparse array." assert isinstance(kraus2, (list, np.ndarray, SparseArray)), \ "Kraus2 should be list or numpy array or sparse array." # If they aren't in sparse format. if isinstance(kraus1, (list, np.ndarray)): kraus1 = COO(np.array(kraus1, dtype=np.complex128), ) if isinstance(kraus2, (list, np.ndarray)): kraus2 = COO(np.array(kraus2, dtype=np.complex128), ) return kron(kraus1, kraus2)
def out_to_in_matrix(phi_sym, angle_vector, theta_intv, phi_intv): if phi_sym == 2 * np.pi: phi_sym = phi_sym - 0.0001 out_to_in = np.zeros((len(angle_vector), len(angle_vector))) binned_theta_out = np.digitize( np.pi - angle_vector[:, 1], theta_intv, right=True) - 1 phi_rebin = fold_phi(angle_vector[:, 2] + np.pi, phi_sym) phi_out = xr.DataArray( phi_rebin, coords={'theta_bin': (['angle_in'], binned_theta_out)}, dims=['angle_in']) bin_out = phi_out.groupby('theta_bin').apply(overall_bin, args=(phi_intv, angle_vector[:, 0])).data out_to_in[bin_out, np.arange(len(angle_vector))] = 1 up_to_down = out_to_in[int(len(angle_vector) / 2):, :int(len(angle_vector) / 2)] down_to_up = out_to_in[:int(len(angle_vector) / 2), int(len(angle_vector) / 2):] return COO(up_to_down), COO(down_to_up)
def initialize_heisenberg(N, h, J, M): """ Initialize the MPS, MPO, lopr and ropr. """ # MPS mpss = sMPX.rand([2] * N, D=M, bc='obc', seed=0) normalize_factor = 1.0 / gMPX.norm(mpss) mpss = gMPX.mul(normalize_factor, mpss) # make MPS right canonical for i in xrange(N - 1, 0, -1): mpss[i], gaug = canonicalize(0, mpss[i], M=M) mpss[i - 1] = einsum("ijk, kl -> ijl", mpss[i - 1], gaug) # MPO mpos = np.asarray(heisenberg_mpo(N, h, J)) # lopr loprs = [COO(np.array([[[1.0]]]))] # ropr roprs = [COO(np.array([[[1.0]]]))] for i in xrange(N - 1, 0, -1): roprs.append( renormalize(0, mpos[i], roprs[-1], mpss[i].conj(), mpss[i])) # NOTE the loprs and roprs should be list currently to support pop()! return mpss, mpos, loprs, roprs
def test_prune_coo(): coords = np.array([[0, 1, 2, 3]]) data = np.array([1, 0, 1, 2]) s1 = COO(coords, data) s2 = COO(coords, data, prune=True) assert s2.nnz == 3 # Densify s1 because it isn't canonical assert_eq(s1.todense(), s2, check_nnz=False)
def test_invalid_attrs_error(s): with pytest.raises(ValueError): sparse.as_coo(s, shape=(2, 3)) with pytest.raises(ValueError): COO(s, shape=(2, 3)) with pytest.raises(ValueError): sparse.as_coo(s, fill_value=0.0) with pytest.raises(ValueError): COO(s, fill_value=0.0)
def normalize_vecs(mat): """Normalizes probability vectors so they sum to one.""" #convert to array for operation order = len(mat.shape) - 1 mat = COO(mat) row_sums = mat.sum(axis=order) mat = DOK(mat) for point in mat.data: divisor = row_sums[point[:-1]] mat[point] = mat[point] / divisor mat = COO(mat) return mat
def test_caching(): x = COO({(10, 10, 10): 1}) assert x[:].reshape((100, 10)).transpose().tocsr() is not x[:].reshape((100, 10)).transpose().tocsr() x = COO({(10, 10, 10): 1}, cache=True) assert x[:].reshape((100, 10)).transpose().tocsr() is x[:].reshape((100, 10)).transpose().tocsr() x = COO({(1, 1, 1, 1, 1, 1, 1, 2): 1}, cache=True) for i in range(x.ndim): x.reshape((1,) * i + (2,) + (1,) * (x.ndim - i - 1)) assert len(x._cache['reshape']) < 5
def make_matrix_wl(wl): # binning into matrix, including phi RT_mat = np.zeros((len(theta_bins_in)*2, len(theta_bins_in))) A_mat = np.zeros((n_layers, len(theta_bins_in))) for i1 in range(len(theta_bins_in)): theta = theta_lookup[i1]#angle_vector[i1, 1] data = allres.loc[dict(angle=theta, wl=wl)] R_prob = np.real(data['R'].data.item(0)) T_prob = np.real(data['T'].data.item(0)) Alayer_prob = np.real(data['Alayer'].data) phi_out = phis_out[i1] #print(R_prob, T_prob) # reflection phi_int = phi_intv[theta_bins_in[i1]] phi_ind = np.digitize(phi_out, phi_int, right=True) - 1 bin_out_r = np.argmin(abs(angle_vector[:, 0] - theta_bins_in[i1])) + phi_ind #print(bin_out_r, i1+offset) RT_mat[bin_out_r, i1] = R_prob #print(R_prob) # transmission theta_t = np.abs(-np.arcsin((inc.n(wl * 1e-9) / trns.n(wl * 1e-9)) * np.sin(theta_lookup[i1])) + quadrant) #print('angle in, transmitted', angle_vector_th[i1], theta_t) # theta switches half-plane (th < 90 -> th >90 if ~np.isnan(theta_t): theta_out_bin = np.digitize(theta_t, theta_intv, right=True) - 1 phi_int = phi_intv[theta_out_bin] phi_ind = np.digitize(phi_out, phi_int, right=True) - 1 bin_out_t = np.argmin(abs(angle_vector[:, 0] - theta_out_bin)) + phi_ind RT_mat[bin_out_t, i1] = T_prob #print(bin_out_t, i1+offset) # absorption A_mat[:, i1] = Alayer_prob fullmat = COO(RT_mat) A_mat = COO(A_mat) return fullmat, A_mat
def test_invalid_attrs_error(): s = sparse.random((3, 4), density=0.5, format="coo") with pytest.raises(ValueError): sparse.as_coo(s, shape=(2, 3)) with pytest.raises(ValueError): COO(s, shape=(2, 3)) with pytest.raises(ValueError): sparse.as_coo(s, fill_value=0.0) with pytest.raises(ValueError): COO(s, fill_value=0.0)
def test_canonical(): coords = np.array([[0, 0, 0], [0, 1, 0], [1, 0, 3], [0, 1, 0], [1, 0, 3]]).T data = np.arange(5) + 1 old = COO(coords, data, shape=(2, 2, 5)) x = COO(coords, data, shape=(2, 2, 5)) x.sum_duplicates() assert_eq(old, x) # assert x.nnz == 5 # assert x.has_duplicates assert x.nnz == 3 assert not x.has_duplicates
def test_initialization(ndim): shape = [10] * ndim shape[1] *= 2 shape = tuple(shape) coords = np.random.randint(10, size=ndim * 20).reshape(ndim, 20) data = np.random.rand(20) COO(coords, data=data, shape=shape) with pytest.raises(ValueError, match="data length"): COO(coords, data=data[:5], shape=shape) with pytest.raises(ValueError, match="shape of `coords`"): coords = np.random.randint(10, size=20).reshape(1, 20) COO(coords, data=data, shape=shape)
def test_caching(): x = COO({(9, 9, 9): 1}) assert (x[:].reshape((100, 10)).transpose().tocsr() is not x[:].reshape( (100, 10)).transpose().tocsr()) x = COO({(9, 9, 9): 1}, cache=True) assert (x[:].reshape((100, 10)).transpose().tocsr() is x[:].reshape( (100, 10)).transpose().tocsr()) x = COO({(1, 1, 1, 1, 1, 1, 1, 2): 1}, cache=True) for i in range(x.ndim): x.reshape(x.size) assert len(x._cache["reshape"]) < 5
def __init__(self, kraus_ops, numb_qubits, dim_in=2, dim_out=2): r""" Construct for the kraus operators represented as sparse matrices. Parameters ---------- kraus_ops : list, array, SparseArray List containing all the kraus operators representing a quantum channel. numb_qubits : list Number of particles/qubits [M, N] of the input and output of the quantum channel. dim_in : int Dimension of a single-particle/qubit hilbert space. For qubit, dimension is two by definition. dim_out : int Dimension of a single-particle/qubit hilbert space of the output. For qubit, dimension is two by definition. """ # If kraus operators aren't in sparse format. if isinstance(kraus_ops, (list, np.ndarray)): self.kraus_ops = COO(np.array(kraus_ops, dtype=np.complex128), ) else: self.kraus_ops = kraus_ops super(SparseKraus, self).__init__(kraus_ops, numb_qubits, dim_in, dim_out)
def __frequency_response_transformation(self) -> COO: """Convert a channel frequency response to a linear transformation tensor. Returns: COO: Sparse linear transformation tensor of dimension N_Rx x N_Tx x F*T x F*T. Note that the slice over the first and last dimension will be a diagonal matrix. """ num_rx = self.num_receive_streams num_tx = self.num_transmit_streams num_s = self.num_samples num_frequencies = self.__state.shape[3] num_symbols = num_s * num_frequencies diagonal_ids = np.arange(num_symbols) rx_ids = np.arange(num_rx) tx_ids = np.arange(num_tx) coordinates = [ rx_ids.repeat(num_tx * num_symbols), np.tile(tx_ids.repeat(num_symbols), num_rx), # ToDo: This is probably not completely correct np.tile(diagonal_ids, num_rx * num_tx), np.tile(diagonal_ids, num_rx * num_tx) ] transformation = COO(coordinates, self.__state.flatten(), shape=(num_rx, num_tx, num_symbols, num_symbols)) return transformation
def __impulse_response_transformation(self) -> COO: """Convert a channel impulse response to a linear transformation tensor. Returns: COO: Sparse linear transformation tensor of dimension N_Rx x N_Tx x T+L x T. Note that the slice over the last two dimensions will form a lower triangular matrix. """ num_rx = self.num_receive_streams num_tx = self.num_transmit_streams num_taps = self.__state.shape[3] num_s = self.num_samples num_out = num_s + num_taps - 1 num_in = num_s in_ids = np.repeat(np.arange(num_in), num_taps) out_ids = np.array([np.arange(num_taps) + t for t in range(num_in)]).flatten() rx_ids = np.arange(num_rx) tx_ids = np.arange(num_tx) coordinates = [ rx_ids.repeat(num_tx * num_taps * num_in), tx_ids.repeat(num_rx * num_taps * num_in).reshape( (num_tx, -1), order='F').flatten(), np.tile(out_ids, num_rx * num_tx), np.tile(in_ids, num_rx * num_tx) ] transformation = COO(coordinates, self.__state.flatten(), shape=(num_rx, num_tx, num_out, num_in)) return transformation
def test_scipy_sparse_interaction(scipy_format, x): x = x.todense() sp = getattr(scipy.sparse, scipy_format + "_matrix")(x) coo = COO(x) assert isinstance(sp + coo, COO) assert isinstance(coo + sp, COO) assert_eq(sp, coo)
def random_sparse(size: Tuple[int, ...]): """ Generates a random sparse matrix of shape 'size' Parameters ---------- size : tuple of int Returns ------- sparse : array_like, shape size) """ nnz = int(np.random.random() * np.product(size)) data = np.random.random(nnz) dimns = [np.arange(0, s) for s in size] coords = np.array(list(product(*dimns))) coords_index = np.arange(0, np.product(size)) coords_index = np.random.choice(coords_index, nnz, replace=False) coords_index = list(sorted(coords_index)) coords = coords[coords_index].T return da.from_array(COO(coords, data=data, shape=size, has_duplicates=False, sorted=True, fill_value=0), chunks=size)
def test_elemwise_binary_empty(y): x = COO({}, shape=(10, 10)) for z in [x * y, y * x]: assert z.nnz == 0 assert z.coords.shape == (2, 0) assert z.data.shape == (0, )
def test_block_svd(shape, density, sort, full_matrices, dim_keep, return_dwt): if dim_keep >= np.min(shape): dim_keep = None #np.random.seed(2) np.set_printoptions(3, linewidth = 1000, suppress = True) x = sparse.random(shape, density, format='coo') y = x.todense() if return_dwt: u, s, vt, dwt = core.block_svd(x, sort = sort, full_matrices = full_matrices, dim_keep = dim_keep, return_dwt = return_dwt) else: u, s, vt = core.block_svd(x, sort = sort, full_matrices = full_matrices, dim_keep = dim_keep) xnew = u.dot(s).dot(vt) u_np, s_np, vt_np = np.linalg.svd(y, full_matrices = False) if (dim_keep is not None) and (sort == True) and (full_matrices == False): x = COO(u_np[:, :dim_keep].dot(np.diag(s_np[:dim_keep])).dot(vt_np[:dim_keep, :])) assert np.allclose(x.todense(), xnew.todense()) if not sort: s_sort = -np.sort(-s.data) else: s_sort = s.data assert np.allclose(s_sort, s_np[:len(s_sort)]) if return_dwt: assert(np.allclose(dwt, s_np[len(s_sort):].sum()))
def heisenberg_mpo(N, h, J): """ Create Heisenberg MPO. """ Sp = np.array([[0.0, 1.0], [0.0, 0.0]]) Sm = np.array([[0.0, 0.0], [1.0, 0.0]]) Sz = np.array([[0.5, 0.0], [0.0, -0.5]]) I = np.array([[1.0, 0.0], [0.0, 1.0]]) z = np.array([[0.0, 0.0], [0.0, 0.0]]) W = [] W.append( np.einsum('abnN -> aNnb', np.array([[-h * Sz, 0.5 * J * Sm, 0.5 * J * Sp, J * Sz, I]]))) for i in xrange(N - 2): W.append( np.einsum( 'abnN -> aNnb', np.array([[I, z, z, z, z], [Sp, z, z, z, z], [Sm, z, z, z, z], [Sz, z, z, z, z], [-h * Sz, 0.5 * J * Sm, 0.5 * J * Sp, J * Sz, I]]))) W.append( np.einsum('abnN -> aNnb', np.array([[I], [Sp], [Sm], [Sz], [-h * Sz]]))) for i in xrange(len(W)): W[i] = COO(W[i]) return W
def get_adj(self, batch, seq_len): """ Returns the adjacency matrix required for applying GCN Parameters ---------- batch: batch returned by getBatch generator seq_len: Maximum length of sentence in the batch Returns ------- Adjacency matrix shape=[Number of dependency labels, Batch size, seq_len, seq_len] """ num_edges = np.sum(batch['elen']) b_ind = np.expand_dims(np.repeat(np.arange(self.p.batch_size), batch['elen']), axis=1) e_ind = np.reshape(batch['edges'], [-1, 3])[:num_edges] adj_ind = np.concatenate([b_ind, e_ind], axis=1) adj_ind = adj_ind[:, [3, 0, 1, 2]] adj_data = np.ones(num_edges, dtype=np.float32) return COO(adj_ind.T, adj_data, shape=(self.num_deLabel, self.p.batch_size, seq_len, seq_len)).todense()
def test_scipy_sparse_interaction(scipy_format): x = sparse.random((10, 20), density=0.2).todense() sp = getattr(scipy.sparse, scipy_format + '_matrix')(x) coo = COO(x) assert isinstance(sp + coo, COO) assert isinstance(coo + sp, COO) assert_eq(sp, coo)
def test_scalar_shape_construction(): x = np.random.rand(5) coords = np.arange(5)[None] s = COO(coords, x, shape=5) assert_eq(x, s)
def serial_concatenate(kraus1, kraus2): r""" Return Serial Concatenation of two kraus operators, A, B to produce "A composed B". Parameters ---------- kraus1 : array or SparseKraus Three-dimensional array of kraus operators on left-side. kraus2: array or SparseKraus Three-dimensional array of kraus operators on right-side. Returns ------- array Three-dimensional array of kraus operators. Notes ----- See Mark Wilde's book, "Quantum Information Theory" """ assert isinstance(kraus1, (list, np.ndarray, SparseArray)), \ "Kraus1 should be list or numpy array or sparse array." assert isinstance(kraus2, (list, np.ndarray, SparseArray)), \ "Kraus2 should be list or numpy array or sparse array." # If they aren't in sparse if isinstance(kraus1, (list, np.ndarray)): kraus1 = COO(np.array(kraus1, dtype=np.complex128), ) if isinstance(kraus2, (list, np.ndarray)): kraus2 = COO(np.array(kraus2, dtype=np.complex128), ) # Test that the dimensions of kraus operators match. for k2 in kraus2: for k1 in kraus1: if not k2.shape[0] == k1.shape[1]: raise TypeError( "Dimension of Kraus Operators should match each other." ) # Multiply all kraus operators with one another kraus_ops = [ matmul(kraus1[j], kraus2[i]) for j in range(0, len(kraus1)) for i in range(0, len(kraus2)) ] # Reshape them to be three-dimensional. return COO(np.array(kraus_ops, dtype=np.complex128), )
def test_elemwise_binary_empty(): x = COO({}, shape=(10, 10)) y = sparse.random((10, 10), density=0.5) for z in [x * y, y * x]: assert z.nnz == 0 assert z.coords.shape == (2, 0) assert z.data.shape == (0,)
def test_cache_csr(): x = sparse.random((10, 5), density=0.5).todense() s = COO(x, cache=True) assert isinstance(s.tocsr(), scipy.sparse.csr_matrix) assert isinstance(s.tocsc(), scipy.sparse.csc_matrix) assert s.tocsr() is s.tocsr() assert s.tocsc() is s.tocsc()
def as_like_arrays(*data): if all(isinstance(d, dask_array_type) for d in data): return data elif any(isinstance(d, sparse_array_type) for d in data): from sparse import COO return tuple(COO(d) for d in data) else: return tuple(np.asarray(d) for d in data)
def test_invalid_shape_error(): s = sparse.random((3, 4), density=0.5, format='coo') with pytest.raises(ValueError): sparse.as_coo(s, shape=(2, 3)) with pytest.raises(ValueError): COO(s, shape=(2, 3))
def test_as_coo(format): x = format(sparse.random((3, 4), density=0.5, format="coo").todense()) s1 = sparse.as_coo(x) s2 = COO(x) assert_eq(x, s1) assert_eq(x, s2)