def test_ChargeArray_reshape_raises(): Ds = [8, 9, 10, 11] indices = [ Index(U1Charge.random(dimension=Ds[n], minval=-5, maxval=5), False) for n in range(4) ] arr = ChargeArray.random(indices) with pytest.raises(ValueError, match=r"The shape \(2, 4, 9, 2, 5, 11\)"): arr.reshape([2, 4, 9, 2, 5, 11]) with pytest.raises(ValueError, match="A tensor with"): arr.reshape([64, 65]) arr2 = arr.reshape([72, 110]) with pytest.raises( ValueError, match=r"The shape \(9, 8, 10, 11\) is incompatible with the" r" elementary shape \(8, 9, 10, 11\) of the tensor."): arr2.reshape([9, 8, 10, 11]) Ds = [8, 9, 0, 11] indices = [ Index(U1Charge.random(dimension=Ds[n], minval=-5, maxval=5), False) for n in range(4) ] arr3 = ChargeArray.random(indices) with pytest.raises(ValueError): arr3.reshape([72, 0])
def test_tensordot_raises(): R1 = 3 R2 = 3 R3 = 3 dtype = np.float64 np.random.seed(10) Ds1 = np.arange(2, 2 + R1) Ds2 = np.arange(2 + R1, 2 + R1 + R2) Ds3 = np.arange(2 + R1, 2 + R1 + R3) is1 = [ Index(U1Charge.random(dimension=Ds1[n], minval=-5, maxval=5), False) for n in range(R1) ] is2 = [ Index(U1Charge.random(dimension=Ds2[n], minval=-5, maxval=5), False) for n in range(R2) ] is3 = [ Index(U1Charge.random(dimension=Ds3[n], minval=-5, maxval=5), False) for n in range(R3) ] A = BlockSparseTensor.random(is1, dtype=dtype) B = BlockSparseTensor.random(is2, dtype=dtype) C = BlockSparseTensor.random(is3, dtype=dtype) with pytest.raises(ValueError, match="same length"): tensordot(A, B, ([0, 1, 2, 3], [1, 2])) with pytest.raises(ValueError, match="same length"): tensordot(A, B, ([0, 1], [0, 1, 2, 3])) with pytest.raises(ValueError, match="same length"): tensordot(A, B, ([0], [1, 2])) with pytest.raises(ValueError, match='invalid input'): tensordot(A, B, [0, [1, 2]]) with pytest.raises(ValueError, match="incompatible elementary flows"): tensordot(A, B, ([0, 0], [1, 2])) with pytest.raises(ValueError): tensordot(A, B, ([0, 1], [1, 1])) with pytest.raises(ValueError, match="rank of `tensor1` is smaller than "): tensordot(A, B, ([0, 4], [1, 2])) with pytest.raises(ValueError, match="rank of `tensor2` is smaller than "): tensordot(A, B, ([0, 1], [0, 4])) with pytest.raises(ValueError): tensordot(A, B, ([0, 4], [1, 4])) with pytest.raises(ValueError): tensordot(A, B, ([0, 1], [0, 1])) with pytest.raises(ValueError): tensordot(A, A, ([0, 1], [0, 1])) with pytest.raises(ValueError): tensordot(A, A.conj(), ([0, 1], [1, 0])) with pytest.raises(ValueError, match="is incompatible with `tensor1.shape"): tensordot(A, A.conj(), ([0, 1, 2, 3], [0, 1, 2, 3])) with pytest.raises(ValueError, match="is incompatible with `tensor1.shape"): tensordot(A, C, ([0, 1, 2, 3], [0, 1, 2, 3]))
def test_eigs_raises(): np.random.seed(10) dtype = np.float64 backend = symmetric_backend.SymmetricBackend() D = 16 index = Index(U1Charge.random(D, 0, 0), True) indices = [index, index.copy().flip_flow()] H = BlockSparseTensor.random(indices, dtype=dtype) init = BlockSparseTensor.random([index], dtype=dtype) with pytest.raises(ValueError, match='which = SI is currently not supported.'): backend.eigs(lambda x: x, [H], initial_state=init, which='SI') with pytest.raises(ValueError, match='which = LI is currently not supported.'): backend.eigs(lambda x: x, [H], initial_state=init, which='LI') with pytest.raises( ValueError, match="if no `initial_state` is passed, then `shape` and" "`dtype` have to be provided"): backend.eigs(lambda x: x, [H]) with pytest.raises(ValueError, match="`num_krylov_vecs`"): backend.eigs(lambda x: x, [H], numeig=3, num_krylov_vecs=3) with pytest.raises(TypeError, match="Expected a"): backend.eigs(lambda x: x, [H], initial_state=[])
def test_flat_meta_data(): i1 = Index([U1Charge.random(-2, 2, 20), U1Charge.random(-2, 2, 20)], flow=[True, False]) i2 = Index([U1Charge.random(-2, 2, 20), U1Charge.random(-2, 2, 20)], flow=[False, True]) expected_charges = [ i1._charges[0], i1._charges[1], i2._charges[0], i2._charges[1] ] expected_flows = [True, False, False, True] charges, flows = get_flat_meta_data([i1, i2]) np.testing.assert_allclose(flows, expected_flows) for n, c in enumerate(charges): assert charge_equal(c, expected_charges[n])
def test_tn_reshape(dtype): np.random.seed(10) Ds = [8, 9, 10, 11] indices = [ Index(U1Charge.random(dimension=Ds[n], minval=-5, maxval=5), False) for n in range(4) ] arr = BlockSparseTensor.random(indices, dtype=dtype) arr2 = reshape(arr, [72, 110]) for n in range(2): for m in range(2): assert charge_equal(arr2.charges[n][m], indices[n * 2 + m].charges) np.testing.assert_allclose(arr2.shape, [72, 110]) np.testing.assert_allclose(arr2._order, [[0, 1], [2, 3]]) np.testing.assert_allclose(arr2.flows, [[False, False], [False, False]]) assert arr2.ndim == 2 arr3 = reshape(arr, Ds) for n in range(4): assert charge_equal(arr3.charges[n][0], indices[n].charges) np.testing.assert_allclose(arr3.shape, Ds) np.testing.assert_allclose(arr3._order, [[0], [1], [2], [3]]) np.testing.assert_allclose(arr3.flows, [[False], [False], [False], [False]]) assert arr3.ndim == 4
def test_BlockSparseTensor_init(): np.random.seed(10) D = 10 rank = 4 flows = np.random.choice([True, False], size=rank, replace=True) charges = [ U1Charge.random(dimension=D, minval=-5, maxval=5) for _ in range(rank) ] fused = fuse_charges(charges, flows) data = np.random.uniform(0, 1, size=len( np.nonzero(fused == np.zeros((1, 1)))[0])) order = [[n] for n in range(rank)] arr = BlockSparseTensor(data, charges, flows, order=order) np.testing.assert_allclose(data, arr.data) for c1, c2 in zip(charges, arr.charges): assert charge_equal(c1, c2[0]) for c1, c2 in zip(charges, arr._charges): assert charge_equal(c1, c2) data = np.random.uniform( 0, 1, size=len(np.nonzero(fused == np.zeros((1, 1)))[0]) + 1) with pytest.raises(ValueError): arr = BlockSparseTensor(data, charges, flows, order=order, check_consistency=True)
def test_eigsh_lanczos_sanity_check_2(dtype): np.random.seed(10) D = 16 backend = symmetric_backend.SymmetricBackend() index = Index(U1Charge.random(D, 0, 0), True) indices = [index, index.copy().flip_flow()] H = BlockSparseTensor.random(indices, dtype=dtype) H = H + H.conj().T def mv(x, mat): return mat @ x eta1, U1 = backend.eigsh_lanczos(mv, [H], shape=(H.sparse_shape[1].flip_flow(), ), dtype=dtype) eta2, U2 = np.linalg.eigh(H.todense()) v1 = np.reshape(U1[0].todense(), (D)) v1 = v1 / sum(v1) v2 = U2[:, 0] v2 = v2 / sum(v2) np.testing.assert_allclose(eta1[0], min(eta2)) np.testing.assert_allclose(v1, v2)
def test_eigsh_lanczos_reorthogonalize_sanity_check(dtype, numeig): np.random.seed(10) D = 24 backend = symmetric_backend.SymmetricBackend() index = Index(U1Charge.random(D, 0, 0), True) indices = [index, index.copy().flip_flow()] H = BlockSparseTensor.random(indices, dtype=dtype) H = H + H.conj().T def mv(x, mat): return mat @ x eta1, U1 = backend.eigsh_lanczos(mv, [H], shape=(H.sparse_shape[1].flip_flow(), ), dtype=dtype, numeig=numeig, num_krylov_vecs=D, reorthogonalize=True, ndiag=1, tol=10**(-12), delta=10**(-12)) eta2, U2 = np.linalg.eigh(H.todense()) np.testing.assert_allclose(eta1[0:numeig], eta2[0:numeig]) for n in range(numeig): v2 = U2[:, n] v2 /= np.sum(v2) #fix phases v1 = np.reshape(U1[n].todense(), (D)) v1 /= np.sum(v1) np.testing.assert_allclose(v1, v2, rtol=10**(-5), atol=10**(-5))
def test_eigsh_valid_init_operator_with_shape(dtype): np.random.seed(100) backend = symmetric_backend.SymmetricBackend() np_backend = numpy_backend.NumPyBackend() D = 16 index = Index(U1Charge.random(D, -1, 1), True) indices = [index, index.copy().flip_flow()] a = BlockSparseTensor.random(indices, dtype=dtype) H = a + a.T.conj() def mv(vec, mat): return mat @ vec init = BlockSparseTensor.random([index], dtype=dtype) # note: this will only find eigenvalues in the charge (0,0) # block of H because `init` only has non-zero values there. # To find eigen values in other sectors we need to support non-zero # divergence for block-sparse tensors eta1, U1 = backend.eigsh_lanczos(mv, [H], init) eta2, U2 = np_backend.eigsh_lanczos(mv, [H.todense()], init.todense()) v1 = np.reshape(U1[0].todense(), (D)) v1 = v1 / sum(v1) v1 /= np.linalg.norm(v1) v2 = np.reshape(U2[0], (D)) v2 = v2 / sum(v2) v2[np.abs(v2) < 1E-12] = 0.0 v2 /= np.linalg.norm(v2) np.testing.assert_allclose(eta1[0], min(eta2)) np.testing.assert_allclose(v1, v2)
def test_ChargeArray_reshape_raises(): Ds = [8, 9, 10, 11] indices = [Index(U1Charge.random(-5, 5, Ds[n]), False) for n in range(4)] arr = ChargeArray.random(indices) with pytest.raises(ValueError): arr.reshape([64, 65]) arr2 = arr.reshape([72, 110]) with pytest.raises(ValueError): arr2.reshape([9, 8, 10, 11]) Ds = [8, 9, 0, 11] indices = [Index(U1Charge.random(-5, 5, Ds[n]), False) for n in range(4)] arr3 = ChargeArray.random(indices) with pytest.raises(ValueError): arr3.reshape([72, 0])
def test_tn_conj(dtype): np.random.seed(10) indices = [ Index(U1Charge.random(dimension=10, minval=-5, maxval=5), False) for _ in range(4) ] a = BlockSparseTensor.randn(indices, dtype=dtype) b = conj(a) np.testing.assert_allclose(b.data, np.conj(a.data))
def test_flat_flows(): Ds = [10, 11, 12, 13] charges = [U1Charge.random(Ds[n], -5, 5) for n in range(4)] flows = [True, False, True, False] inds = [Index(c, flows[n]) for n, c in enumerate(charges)] a = BlockSparseTensor.random(inds, dtype=np.float64) order = [0, 3, 1, 2] a = a.transpose(order) np.testing.assert_allclose(a.flat_flows, [a._flows[o] for o in a.flat_order])
def test_norm(dtype): np.random.seed(10) Ds = np.asarray([8, 9, 10, 11]) rank = Ds.shape[0] flows = np.random.choice([True, False], size=rank, replace=True) indices = [Index(U1Charge.random(-5, 5, Ds[n]), flows[n]) for n in range(4)] arr = BlockSparseTensor.random(indices, dtype=dtype) dense_norm = np.linalg.norm(arr.todense()) np.testing.assert_allclose(norm(arr), dense_norm)
def test_truediv_raises(): np.random.seed(10) indices = [ Index(U1Charge.random(dimension=10, minval=-5, maxval=5), False) for _ in range(4) ] a = BlockSparseTensor.randn(indices) with pytest.raises(TypeError): _ = a / np.array([1, 2])
def test_sign(): np.random.seed(10) Ds = np.array([8, 9, 10, 11]) flows = [True, False, True, False] indices = [ Index(U1Charge.random(dimension=Ds[n], minval=-5, maxval=5), flows[n]) for n in range(4) ] arr = BlockSparseTensor.random(indices) np.testing.assert_allclose(sign(arr).data, np.sign(arr.data))
def test_ChargeArray_transpose_raises(): Ds = np.array([8, 9, 10, 11]) flows = [True, False, True, False] indices = [ Index(U1Charge.random(-5, 5, Ds[n]), flows[n]) for n in range(4) ] arr = ChargeArray.random(indices) order = [2, 1, 0] with pytest.raises(ValueError): arr.transpose(order)
def test_ChargeArray_conj(dtype): Ds = np.array([8, 9, 10, 11]) flows = [True, False, True, False] indices = [ Index(U1Charge.random(dimension=Ds[n], minval=-5, maxval=5), flows[n]) for n in range(4) ] arr = ChargeArray.random(indices, dtype=dtype) conj = arr.conj() np.testing.assert_allclose(conj.data, np.conj(arr.data))
def test_ChargeArray_init_raises(): np.random.seed(10) D = 10 rank = 4 charges = [U1Charge.random(-5, 5, D) for _ in range(rank)] data = np.random.uniform(0, 1, size=D**rank) flows = np.random.choice([True, False], size=rank, replace=True) order = [[n + 10] for n in range(rank)] with pytest.raises(ValueError): ChargeArray(data, charges, flows, order=order)
def test_flat_charges(): Ds = [10, 11, 12, 13] charges = [U1Charge.random(Ds[n], -5, 5) for n in range(4)] flows = [True, False, True, False] inds = [Index(c, flows[n]) for n, c in enumerate(charges)] a = BlockSparseTensor.random(inds, dtype=np.float64) order = [0, 3, 1, 2] a = a.transpose(order) for n, o in enumerate(a.flat_order): charge_equal(a.flat_charges[n], a._charges[o])
def test_fromdense_raises(): np.random.seed(10) Ds = [8, 9, 10, 11] rank = len(Ds) flows = np.random.choice([True, False], size=rank, replace=True) charges = [U1Charge.random(Ds[n], -5, 5) for n in range(rank)] indices = [Index(charges[n], flows[n]) for n in range(rank)] dense = np.random.random_sample([8, 9, 9, 11]) with pytest.raises(ValueError): _ = BlockSparseTensor.fromdense(indices, dense)
def test_ChargeArray_generic(dtype): Ds = [8, 9, 10, 11] indices = [Index(U1Charge.random(-5, 5, Ds[n]), False) for n in range(4)] arr = ChargeArray.random(indices, dtype=dtype) assert arr.ndim == 4 assert arr.dtype == dtype np.testing.assert_allclose(arr.shape, Ds) np.testing.assert_allclose(arr.flat_flows, [False, False, False, False]) for n in range(4): assert charge_equal(indices[n]._charges[0], arr.flat_charges[n]) assert arr.sparse_shape[n] == indices[n]
def test_tn_transpose(): np.random.seed(10) Ds = np.array([8, 9, 10, 11]) flows = [True, False, True, False] indices = [Index(U1Charge.random(-5, 5, Ds[n]), flows[n]) for n in range(4)] arr = BlockSparseTensor.random(indices) order = [2, 1, 0, 3] arr2 = transpose(arr, order) np.testing.assert_allclose(Ds[order], arr2.shape) np.testing.assert_allclose(arr2._order, [[2], [1], [0], [3]]) np.testing.assert_allclose(arr2.flows, [[True], [False], [True], [False]])
def test_ChargeArray_transpose(): Ds = np.array([8, 9, 10, 11]) flows = [True, False, True, False] indices = [ Index(U1Charge.random(-5, 5, Ds[n]), flows[n]) for n in range(4) ] arr = ChargeArray.random(indices) order = [2, 1, 0, 3] arr2 = arr.transpose(order) np.testing.assert_allclose(Ds[order], arr2.shape) np.testing.assert_allclose(arr2._order, [[2], [1], [0], [3]]) np.testing.assert_allclose(arr2.flows, [[True], [False], [True], [False]])
def test_BlockSparseTensor_contiguous_1(): Ds = [10, 11, 12, 13] charges = [U1Charge.random(Ds[n], -5, 5) for n in range(4)] flows = [True, False, True, False] inds = [Index(c, flows[n]) for n, c in enumerate(charges)] b = BlockSparseTensor.random(inds, dtype=np.float64) order = [0, 3, 2, 1] b = b.transpose(order) b_ = b.contiguous(inplace=False) np.testing.assert_allclose(b.flows, b_.flows) for n in range(4): assert charge_equal(b._charges[order[n]], b_._charges[n])
def test_add_sub_raises(op): np.random.seed(10) Ds1 = [3, 4, 5, 6] Ds2 = [4, 5, 6, 7] indices1 = [Index(U1Charge.random(-5, 5, Ds1[n]), False) for n in range(4)] indices2 = [Index(U1Charge.random(-5, 5, Ds2[n]), False) for n in range(4)] a = BlockSparseTensor.randn(indices1) b = BlockSparseTensor.randn(indices2) with pytest.raises(TypeError): op(a, np.array([1, 2, 3])) with pytest.raises(ValueError): op(a, b) Ds3 = [3, 3, 3, 3] Ds4 = [9, 9] indices3 = [Index(U1Charge.random(-5, 5, Ds3[n]), False) for n in range(4)] indices4 = [Index(U1Charge.random(-5, 5, Ds4[n]), False) for n in range(2)] c = BlockSparseTensor.randn(indices3).reshape([9, 9]) d = BlockSparseTensor.randn(indices4) with pytest.raises(ValueError): op(c, d) Ds5 = [200, 200] Ds6 = [200, 200] indices5 = [Index(U1Charge.random(-5, 5, Ds5[n]), False) for n in range(2)] indices6 = [Index(U1Charge.random(-5, 5, Ds6[n]), False) for n in range(2)] e = BlockSparseTensor.randn(indices5) f = BlockSparseTensor.randn(indices6) with pytest.raises(ValueError): op(e, f)
def test_tensordot_raises(): R1 = 3 R2 = 3 dtype = np.float64 np.random.seed(10) Ds1 = np.arange(2, 2 + R1) Ds2 = np.arange(2 + R1, 2 + R1 + R2) is1 = [ Index(U1Charge.random(dimension=Ds1[n], minval=-5, maxval=5), False) for n in range(R1) ] is2 = [ Index(U1Charge.random(dimension=Ds2[n], minval=-5, maxval=5), False) for n in range(R2) ] A = BlockSparseTensor.random(is1, dtype=dtype) B = BlockSparseTensor.random(is2, dtype=dtype) with pytest.raises(ValueError): tensordot(A, B, ([0, 1, 2, 3], [1, 2])) with pytest.raises(ValueError): tensordot(A, B, ([0, 1], [0, 1, 2, 3])) with pytest.raises(ValueError): tensordot(A, B, ([0], [1, 2])) with pytest.raises(ValueError): tensordot(A, B, [0, [1, 2]]) with pytest.raises(ValueError): tensordot(A, B, ([0, 0], [1, 2])) with pytest.raises(ValueError): tensordot(A, B, ([0, 1], [1, 1])) with pytest.raises(ValueError): tensordot(A, B, ([0, 4], [1, 2])) with pytest.raises(ValueError): tensordot(A, B, ([0, 4], [1, 4])) with pytest.raises(ValueError): tensordot(A, B, ([0, 1], [0, 1])) with pytest.raises(ValueError): tensordot(A, A, ([0, 1], [0, 1])) with pytest.raises(ValueError): tensordot(A, A.conj(), ([0, 1], [1, 0]))
def test_tensordot_single_arg(): R = 3 dtype = np.float64 np.random.seed(10) Ds = [10, 10, 10] inds = [ Index(U1Charge.random(dimension=Ds[n], minval=-5, maxval=5), False) for n in range(R) ] A = BlockSparseTensor.random(inds, dtype=dtype) res = tensordot(A, A.conj(), ([0])) dense_res = np.tensordot(A.todense(), A.conj().todense(), ([0], [0])) np.testing.assert_allclose(dense_res, res.todense())
def test_rmul(dtype, num_charges, chargetype): np.random.seed(10) indices = [ Index(get_charge(chargetype, num_charges, 20), False) for _ in range(4) ] indices = [ Index(U1Charge.random(dimension=10, minval=-5, maxval=5), False) for _ in range(4) ] a = BlockSparseTensor.randn(indices, dtype=dtype) b = a * 5 np.testing.assert_allclose(b.data, a.data * 5)
def test_BlockSparseTensor_transpose_data(): np.random.seed(10) Ds = np.array([8, 9, 10, 11]) order = [2, 0, 1, 3] flows = [True, False, True, False] indices = [ Index(U1Charge.random(-5, 5, Ds[n]), flows[n]) for n in range(4) ] arr = BlockSparseTensor.random(indices) data1 = np.ascontiguousarray(np.transpose(arr.todense(), order)) data2 = arr.transpose(order).transpose_data().todense() np.testing.assert_allclose(data1.strides, data2.strides) np.testing.assert_allclose(data1, data2)
def test_qr_decomposition(dtype, R, R1): np.random.seed(10) D = 30 charges = [U1Charge.random(-5, 5, D) for n in range(R)] flows = [True] * R A = BlockSparseTensor.random( [Index(charges[n], flows[n]) for n in range(R)], dtype=dtype) q, r = decompositions.qr_decomposition(bs, A, R1) res = bs.tensordot(q, r, 1) q_dense, r_dense = np_decompositions.qr_decomposition(np, A.todense(), R1) res2 = np.tensordot(q_dense, r_dense, 1) np.testing.assert_almost_equal(res.todense(), res2)