Пример #1
0
def test_eigsh_caching():
    def matvec(mps, A, B, C):
        return ncon([A, mps, B, C],
                    [[3, 1, -1], [1, 2, 4], [3, 5, -2, 2], [5, 4, -3]],
                    backend='symmetric')

    backend = symmetric_backend.SymmetricBackend()
    D = 100
    M = 5
    mpsinds = [
        Index(U1Charge(np.random.randint(5, 15, D, dtype=np.int16)), False),
        Index(U1Charge(np.array([0, 1, 2, 3], dtype=np.int16)), False),
        Index(U1Charge(np.random.randint(5, 18, D, dtype=np.int16)), True)
    ]
    mpoinds = [
        Index(U1Charge(np.random.randint(0, 5, M)), False),
        Index(U1Charge(np.random.randint(0, 10, M)), True), mpsinds[1],
        mpsinds[1].flip_flow()
    ]
    Linds = [mpoinds[0].flip_flow(), mpsinds[0].flip_flow(), mpsinds[0]]
    Rinds = [mpoinds[1].flip_flow(), mpsinds[2].flip_flow(), mpsinds[2]]
    mps = BlockSparseTensor.random(mpsinds)
    mpo = BlockSparseTensor.random(mpoinds)
    L = BlockSparseTensor.random(Linds)
    R = BlockSparseTensor.random(Rinds)
    ncv = 20
    backend.eigsh_lanczos(matvec, [L, mpo, R],
                          initial_state=mps,
                          num_krylov_vecs=ncv)
    assert get_cacher().cache == {}
Пример #2
0
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_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 get_contractable_tensors(R1, R2, cont, dtype, num_charges):
  DsA = np.random.randint(5, 10, R1)
  DsB = np.random.randint(5, 10, R2)
  assert R1 >= cont
  assert R2 >= cont
  chargesA = [
      BaseCharge(
          np.random.randint(-5, 6, (num_charges, DsA[n])),
          charge_types=[U1Charge] * num_charges) for n in range(R1 - cont)
  ]
  commoncharges = [
      BaseCharge(
          np.random.randint(-5, 6, (num_charges, DsA[n + R1 - cont])),
          charge_types=[U1Charge] * num_charges) for n in range(cont)
  ]
  chargesB = [
      BaseCharge(
          np.random.randint(-5, 6, (num_charges, DsB[n])),
          charge_types=[U1Charge] * num_charges) for n in range(R2 - cont)
  ]
  #contracted indices
  indsA = np.random.choice(np.arange(R1), cont, replace=False)
  indsB = np.random.choice(np.arange(R2), cont, replace=False)

  flowsA = np.full(R1, False, dtype=np.bool)
  flowsB = np.full(R2, False, dtype=np.bool)
  flowsB[indsB] = True

  indicesA = [None for _ in range(R1)]
  indicesB = [None for _ in range(R2)]
  for n, iA in enumerate(indsA):
    indicesA[iA] = Index(commoncharges[n], flowsA[iA])
    indicesB[indsB[n]] = Index(commoncharges[n], flowsB[indsB[n]])
  compA = list(set(np.arange(R1)) - set(indsA))
  compB = list(set(np.arange(R2)) - set(indsB))

  for n, cA in enumerate(compA):
    indicesA[cA] = Index(chargesA[n], flowsA[cA])
  for n, cB in enumerate(compB):
    indicesB[cB] = Index(chargesB[n], flowsB[cB])

  indices_final = []
  for n in sorted(compA):
    indices_final.append(indicesA[n])
  for n in sorted(compB):
    indices_final.append(indicesB[n])
  A = BlockSparseTensor.random(indices=indicesA, dtype=dtype)
  B = BlockSparseTensor.random(indices=indicesB, dtype=dtype)
  return A, B, indsA, indsB
Пример #5
0
def test_diagonal(Ds, dtype, num_charges, flow):
    np.random.seed(10)
    backend = symmetric_backend.SymmetricBackend()
    np_flow = -np.int((np.int(flow) - 0.5) * 2)
    indices = [
        Index(
            BaseCharge(np.random.randint(-2, 3, (Ds[n], num_charges)),
                       charge_types=[U1Charge] * num_charges), flow)
        for n in range(2)
    ]
    arr = BlockSparseTensor.random(indices, dtype=dtype)
    fused = fuse_charges(arr.flat_charges, arr.flat_flows)
    inds = np.nonzero(fused == np.zeros((1, num_charges), dtype=np.int16))[0]
    # pylint: disable=no-member
    left, _ = np.divmod(inds, Ds[1])
    unique = np.unique(np_flow * (indices[0]._charges[0].charges[left, :]),
                       axis=0)
    diagonal = backend.diagonal(arr)

    sparse_blocks, _, block_shapes = _find_diagonal_sparse_blocks(
        arr.flat_charges, arr.flat_flows, 1)
    data = np.concatenate([
        np.diag(np.reshape(arr.data[sparse_blocks[n]], block_shapes[:, n]))
        for n in range(len(sparse_blocks))
    ])
    np.testing.assert_allclose(data, diagonal.data)
    np.testing.assert_allclose(unique, diagonal.flat_charges[0].unique_charges)
    with pytest.raises(NotImplementedError):
        diagonal = backend.diagonal(arr, axis1=0)
    with pytest.raises(NotImplementedError):
        diagonal = backend.diagonal(arr, axis2=1)
    with pytest.raises(NotImplementedError):
        diagonal = backend.diagonal(arr, offset=1)
def get_square_matrix(shape, num_charges, dtype=np.float64):
  charge = BaseCharge(
      np.random.randint(-5, 5, (shape, num_charges)),
      charge_types=[U1Charge] * num_charges)
  flows = [True, False]
  indices = [Index(charge, flows[n]) for n in range(2)]
  return BlockSparseTensor.random(indices=indices, dtype=dtype)
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_addition(R, dtype, num_charges):
    np.random.seed(10)
    backend = symmetric_backend.SymmetricBackend()
    a = get_tensor(R, num_charges, dtype)
    b = BlockSparseTensor.random(a.sparse_shape)
    res = backend.addition(a, b)
    np.testing.assert_allclose(res.data, a.data + b.data)
def get_square_matrix(num_charges, dtype=np.float64):
    D = np.random.randint(40, 60)
    charges = BaseCharge(np.random.randint(-5, 6, (num_charges, D)),
                         charge_types=[U1Charge] * num_charges)

    flows = [False, True]
    indices = [Index(charges, flows[n]) for n in range(2)]
    return BlockSparseTensor.random(indices=indices, dtype=dtype)
Пример #11
0
def get_random_symmetric(shape, flows, num_charges, seed=10, dtype=np.float64):
    assert np.all(np.asarray(shape) == shape[0])
    np.random.seed(seed)
    R = len(shape)
    charge = BaseCharge(np.random.randint(-5, 5, (shape[0], num_charges)),
                        charge_types=[U1Charge] * num_charges)

    indices = [Index(charge, flows[n]) for n in range(R)]
    return BlockSparseTensor.random(indices=indices, dtype=dtype)
def test_eigsh_small_number_krylov_vectors_sanity_check():
    np.random.seed(10)
    dtype = np.float64
    backend = symmetric_backend.SymmetricBackend()
    index = Index(U1Charge.random(2, 0, 0), True)
    indices = [index, index.copy().flip_flow()]

    H = BlockSparseTensor.random(indices, dtype=dtype)
    H.data = np.array([1, 2, 3, 4], dtype=np.float64)

    init = BlockSparseTensor.random([index], dtype=dtype)
    init.data = np.array([1, 1], dtype=np.float64)

    def mv(x, mat):
        return mat @ x

    eta, _ = backend.eigsh_lanczos(mv, [H], init, num_krylov_vecs=1)
    np.testing.assert_allclose(eta[0], 5)
def get_tensor(R, num_charges, dtype=np.float64):
    Ds = np.random.randint(8, 12, R)
    charges = [
        BaseCharge(np.random.randint(-5, 6, (num_charges, Ds[n])),
                   charge_types=[U1Charge] * num_charges) for n in range(R)
    ]
    flows = list(np.full(R, fill_value=False, dtype=np.bool))
    indices = [Index(charges[n], flows[n]) for n in range(R)]
    return BlockSparseTensor.random(indices=indices, dtype=dtype)
Пример #14
0
def get_hermitian_matrix(num_charges, dtype=np.float64):
    D = np.random.randint(40, 60)
    charges = BaseCharge(np.random.randint(-5, 6, (D, num_charges)),
                         charge_types=[U1Charge] * num_charges)

    flows = [False, True]
    indices = [Index(charges, flows[n]) for n in range(2)]
    A = BlockSparseTensor.random(indices=indices, dtype=dtype)
    return A + A.conj().T
Пример #15
0
def get_random(shape, num_charges, dtype=np.float64):
    R = len(shape)
    charges = [
        BaseCharge(np.random.randint(-5, 5, (num_charges, shape[n])),
                   charge_types=[U1Charge] * num_charges) for n in range(R)
    ]
    flows = list(np.full(R, fill_value=False, dtype=np.bool))
    indices = [Index(charges[n], flows[n]) for n in range(R)]
    return BlockSparseTensor.random(indices=indices, dtype=dtype)
def test_subbtraction_raises(R, dtype, num_charges):
  np.random.seed(10)
  backend = symmetric_backend.SymmetricBackend()
  a = get_tensor(R, num_charges, dtype)
  b = get_tensor(R + 1, num_charges, dtype)
  with pytest.raises(ValueError):
    backend.subtraction(a, b)
  shape = b.sparse_shape
  c = BlockSparseTensor.random([shape[n] for n in reversed(range(len(shape)))])
  with pytest.raises(ValueError):
    backend.subtraction(a, c)
Пример #17
0
def test_eigs_valid_init_operator_with_shape_sanity_check(dtype):
    np.random.seed(10)
    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)

    def mv(vec, mat):
        return mat @ vec

    init = BlockSparseTensor.random([index], dtype=dtype)
    eta1, U1 = backend.eigs(mv, [H], init)

    eta2, U2 = np.linalg.eig(H.todense())

    compare_eigvals_and_eigvecs(np.stack([u.todense() for u in U1], axis=1),
                                eta1,
                                U2,
                                eta2,
                                thresh=1E-8)
def test_sparse_shape(dtype, num_charges):
    np.random.seed(10)
    Ds = [11, 12, 13]
    R = len(Ds)
    charges = [
        BaseCharge(np.random.randint(-5, 6, (num_charges, Ds[n])),
                   charge_types=[U1Charge] * num_charges) for n in range(R)
    ]
    flows = list(np.full(R, fill_value=False, dtype=np.bool))
    indices = [Index(charges[n], flows[n]) for n in range(R)]
    a = BlockSparseTensor.random(indices=indices, dtype=dtype)
    backend = symmetric_backend.SymmetricBackend()
    for s1, s2 in zip(a.sparse_shape, backend.sparse_shape(a)):
        assert s1 == s2
def test_eigsh_valid_init_operator_with_shape_sanity_check(dtype):
    np.random.seed(10)
    backend = symmetric_backend.SymmetricBackend()
    D = 16
    index = Index(U1Charge.random(D, 0, 0), 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)
    eta1, U1 = backend.eigsh_lanczos(mv, [H], init)
    v1 = np.reshape(U1[0].todense(), (D))
    v1 = v1 / sum(v1)

    eta2, U2 = np.linalg.eigh(H.todense())
    v2 = U2[:, 0]
    v2 = v2 / sum(v2)

    np.testing.assert_allclose(eta1[0], min(eta2))
    np.testing.assert_allclose(v1, v2)
Пример #20
0
def test_sparse_shape(num_charges):
    np.random.seed(10)
    dtype = np.float64
    shape = [10, 11, 12, 13]
    R = len(shape)
    charges = [
        BaseCharge(np.random.randint(-5, 5, (shape[n], num_charges)),
                   charge_types=[U1Charge] * num_charges) for n in range(R)
    ]
    flows = list(np.full(R, fill_value=False, dtype=np.bool))
    indices = [Index(charges[n], flows[n]) for n in range(R)]
    a = BlockSparseTensor.random(indices=indices, dtype=dtype)
    node = tn.Node(a, backend='symmetric')
    for s1, s2 in zip(node.sparse_shape, indices):
        assert s1 == s2
Пример #21
0
def test_decomps_raise():
    np.random.seed(10)
    dtype = np.float64
    backend = symmetric_backend.SymmetricBackend()
    D = 16
    R = 3
    indices = [Index(U1Charge.random(D, -5, 5), True) for _ in range(R)]
    H = BlockSparseTensor.random(indices, dtype=dtype)
    with pytest.raises(
            NotImplementedError,
            match="Can't specify non_negative_diagonal with BlockSparse."):
        backend.qr(H, non_negative_diagonal=True)
    with pytest.raises(
            NotImplementedError,
            match="Can't specify non_negative_diagonal with BlockSparse."):
        backend.rq(H, non_negative_diagonal=True)
Пример #22
0
def test_eigs_cache_exception():
    dtype = np.float64
    np.random.seed(10)
    backend = symmetric_backend.SymmetricBackend()
    D = 16
    index = Index(U1Charge.random(D, 0, 0), True)

    def mv(vec):
        raise ValueError()

    init = BlockSparseTensor.random([index], dtype=dtype)
    with pytest.raises(ValueError):
        backend.eigs(mv, [], init)
    cacher = get_cacher()
    assert not cacher.do_caching
    assert not get_caching_status()
    assert cacher.cache == {}