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_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))
예제 #4
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=[])
예제 #5
0
def test_index_copy():
    D = 10
    B = 4
    dtype = np.int16
    np.random.seed(10)
    q1 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype))
    q2 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype))
    i = Index(charges=[q1, q2], flow=[False, True])
    icopy = i.copy()
    assert not np.any([a is b for a, b in zip(i._charges, icopy._charges)])
    assert i.flow is not icopy.flow
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)
예제 #7
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)
예제 #8
0
def eye(column_index: Index,
        row_index: Optional[Index] = None,
        dtype: Optional[Type[np.number]] = None) -> BlockSparseTensor:
  """
  Return an identity matrix.
  Args:
    column_index: The column index of the matrix.
    row_index: The row index of the matrix.
    dtype: The dtype of the matrix.
  Returns:
    BlockSparseTensor
  """
  if row_index is None:
    row_index = column_index.copy().flip_flow()
  if dtype is None:
    dtype = np.float64

  blocks, _, shapes = _find_diagonal_sparse_blocks(
      column_index.flat_charges + row_index.flat_charges,
      column_index.flat_flows + row_index.flat_flows,
      len(column_index.flat_charges))
  data = np.empty(np.int64(np.sum(np.prod(shapes, axis=0))), dtype=dtype)
  for n, block in enumerate(blocks):
    data[block] = np.ravel(np.eye(shapes[0, n], shapes[1, n], dtype=dtype))
  order = [list(np.arange(0, len(column_index.flat_charges)))] + [
      list(
          np.arange(
              len(column_index.flat_charges),
              len(column_index.flat_charges) + len(row_index.flat_charges)))
  ]
  return BlockSparseTensor(
      data=data,
      charges=column_index.flat_charges + row_index.flat_charges,
      flows=column_index.flat_flows + row_index.flat_flows,
      order=order,
      check_consistency=False)
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)