Exemple #1
0
def test_eig_sum(nr_sites, local_dim, rank, rgen):
    # Need at least three sites for var_sites = 2
    if nr_sites < 3:
        pt.skip("Nothing to test")
        return
    rank = max(1, rank // 2)
    mpo = factory.random_mpo(nr_sites, local_dim, rank, randstate=rgen,
                             hermitian=True, normalized=True)
    mpo.canonicalize()
    mps = factory.random_mpa(nr_sites, local_dim, rank, randstate=rgen,
                             dtype=np.complex_, normalized=True)
    mpas = [mpo, mps]

    vec = mps.to_array().ravel()
    op = mpo.to_array_global().reshape((local_dim**nr_sites,) * 2)
    op += np.outer(vec, vec.conj())
    eigvals, eigvec = np.linalg.eigh(op)

    # Eigenvals should be real for a hermitian matrix
    assert (np.abs(eigvals.imag) < 1e-10).all(), str(eigvals.imag)
    mineig_pos = eigvals.argmin()
    mineig, mineig_eigvec = eigvals[mineig_pos], eigvec[:, mineig_pos]
    mineig_mp, mineig_eigvec_mp = mp.eig_sum(
        mpas, num_sweeps=5, startvec_rank=5 * rank, randstate=rgen,
        eigs=ft.partial(eigsh, k=1, which='SA', tol=1e-6),
        var_sites=2)
    mineig_eigvec_mp = mineig_eigvec_mp.to_array().flatten()

    overlap = np.inner(mineig_eigvec.conj(), mineig_eigvec_mp)
    assert_almost_equal(mineig_mp, mineig)
    assert_almost_equal(abs(overlap), 1)
Exemple #2
0
def test_inner_prod_mps(nr_sites, local_dim, rank, dtype, rgen):
    mpa1 = factory.random_mpa(nr_sites,
                              local_dim,
                              1,
                              dtype=dtype,
                              randstate=rgen,
                              normalized=True)
    mpa2 = factory.random_mpa(nr_sites,
                              local_dim,
                              rank,
                              dtype=dtype,
                              randstate=rgen,
                              normalized=True)

    res_slow = mp.inner(mpa1, mpa2)
    res_fast = mpsp.inner_prod_mps(mpa1, mpa2)
    assert_almost_equal(res_slow, res_fast)

    try:
        mpsp.inner_prod_mps(mpa2, mpa1)
    except AssertionError:
        pass
    else:
        if rank > 1:
            raise AssertionError(
                "inner_prod_mps should only accept r=1 in first argument")

    mpa1 = factory.random_mpo(nr_sites, local_dim, 1)
    try:
        mpsp.inner_prod_mps(mpa1, mpa1)
    except AssertionError:
        pass
    else:
        raise AssertionError("inner_prod_mps should only accept ndims=1")
Exemple #3
0
def test_eig(nr_sites, local_dim, rank, which, var_sites, rgen, request):
    if nr_sites <= var_sites:
        pt.skip("Nothing to test")
        return  # No local optimization can be defined
    if not (_pytest_want_long(request) or
            (nr_sites, local_dim, rank, var_sites, which) in {
                (3, 2, 4, 1, 'SA'), (4, 3, 5, 1, 'LM'), (5, 2, 1, 2, 'LA'),
                (6, 2, 4, 2, 'SA'),
            }):
        pt.skip("Should only be run in long tests")
    # With startvec_rank = 2 * rank and this seed, eig() gets
    # stuck in a local minimum. With startvec_rank = 3 * rank,
    # it does not.
    mpo = factory.random_mpo(nr_sites, local_dim, rank, randstate=rgen,
                             hermitian=True, normalized=True)
    mpo.canonicalize()
    op = mpo.to_array_global().reshape((local_dim**nr_sites,) * 2)
    v0 = factory._zrandn([local_dim**nr_sites], rgen)
    eigval, eigvec = eigsh(op, k=1, which=which, v0=v0)
    eigval, eigvec = eigval[0], eigvec[:, 0]

    eig_rank = (4 - var_sites) * rank
    eigval_mp, eigvec_mp = mp.eig(
        mpo, num_sweeps=5, var_sites=1, startvec_rank=eig_rank, randstate=rgen,
        eigs=ft.partial(eigsh, k=1, which=which, tol=1e-6, maxiter=250))
    eigvec_mp = eigvec_mp.to_array().flatten()

    overlap = np.inner(eigvec.conj(), eigvec_mp)
    assert_almost_equal(eigval, eigval_mp, decimal=14)
    assert_almost_equal(1, abs(overlap), decimal=14)
Exemple #4
0
def test_mppovm_expectation(nr_sites, width, local_dim, rank, nopovm, rgen):
    # Verify that :func:`povm.MPPovm.expectations()` produces
    # correct results.
    pmap = nopovm.probability_map
    mpnopovm = povm.MPPovm.from_local_povm(nopovm, width)
    # Use a random MPO rho for testing (instead of a positive MPO).
    rho = factory.random_mpo(nr_sites, local_dim, rank, rgen)
    reductions = mpsmpo.reductions_mpo(rho, width)
    # Compute expectation values with mpnopovm.expectations(), which
    # uses mpnopovm.probability_map.
    expectations = list(mpnopovm.expectations(rho))
    assert len(expectations) == nr_sites - width + 1

    for evals_mp, rho_red in zip_longest(expectations, reductions):
        # Compute expectation values by constructing each tensor
        # product POVM element.
        rho_red_matrix = rho_red.to_array_global().reshape(
            (local_dim**width,) * 2)
        evals = []
        for factors in it.product(nopovm, repeat=width):
            elem = utils.mkron(*factors)
            evals.append(np.trace(np.dot(elem, rho_red_matrix)))
        evals = np.array(evals).reshape((len(nopovm),) * width)

        # Compute expectation with a different construction. In the
        # end, this is (should be, we verify it here) equivalent to
        # what `mpnopovm.expectations()` does.
        evals_ten = rho_red.ravel().to_array()
        for _ in range(width):
            evals_ten = np.tensordot(evals_ten, pmap, axes=(0, 1))

        assert_array_almost_equal(evals_ten, evals)
        assert_array_almost_equal(evals_mp.to_array(), evals)
Exemple #5
0
def test_inner_prod_mps(nr_sites, local_dim, rank, dtype, rgen):
    mpa1 = factory.random_mpa(nr_sites, local_dim, 1, dtype=dtype,
                              randstate=rgen, normalized=True)
    mpa2 = factory.random_mpa(nr_sites, local_dim, rank, dtype=dtype,
                              randstate=rgen, normalized=True)

    res_slow = mp.inner(mpa1, mpa2)
    res_fast = mpsp.inner_prod_mps(mpa1, mpa2)
    assert_almost_equal(res_slow, res_fast)

    try:
        mpsp.inner_prod_mps(mpa2, mpa1)
    except AssertionError:
        pass
    else:
        if rank > 1:
            raise AssertionError(
                "inner_prod_mps should only accept r=1 in first argument")

    mpa1 = factory.random_mpo(nr_sites, local_dim, 1)
    try:
        mpsp.inner_prod_mps(mpa1, mpa1)
    except AssertionError:
        pass
    else:
        raise AssertionError("inner_prod_mps should only accept ndims=1")
Exemple #6
0
def test_eig_sum_benchmark(
        nr_sites, local_dim, rank, ev_rank, rgen, benchmark):
    mpo = factory.random_mpo(nr_sites, local_dim, rank, randstate=rgen,
                             hermitian=True, normalized=True)
    mpo.canonicalize()
    mps = factory.random_mpa(nr_sites, local_dim, rank, randstate=rgen,
                             dtype=np.complex_, normalized=True)

    benchmark(
        mp.eig_sum,
        [mpo, mps], startvec_rank=ev_rank, randstate=rgen,
        var_sites=1, num_sweeps=1,
    )
Exemple #7
0
def test_eig_sum(nr_sites, local_dim, rank, rgen):
    # Need at least three sites for var_sites = 2
    if nr_sites < 3:
        pt.skip("Nothing to test")
        return
    rank = max(1, rank // 2)
    mpo = factory.random_mpo(nr_sites,
                             local_dim,
                             rank,
                             randstate=rgen,
                             hermitian=True,
                             normalized=True)
    mpo.canonicalize()
    mps = factory.random_mpa(nr_sites,
                             local_dim,
                             rank,
                             randstate=rgen,
                             dtype=np.complex_,
                             normalized=True)
    mpas = [mpo, mps]

    vec = mps.to_array().ravel()
    op = mpo.to_array_global().reshape((local_dim**nr_sites, ) * 2)
    op += np.outer(vec, vec.conj())
    eigvals, eigvec = np.linalg.eigh(op)

    # Eigenvals should be real for a hermitian matrix
    assert (np.abs(eigvals.imag) < 1e-10).all(), str(eigvals.imag)
    mineig_pos = eigvals.argmin()
    mineig, mineig_eigvec = eigvals[mineig_pos], eigvec[:, mineig_pos]
    mineig_mp, mineig_eigvec_mp = mp.eig_sum(mpas,
                                             num_sweeps=5,
                                             startvec_rank=5 * rank,
                                             randstate=rgen,
                                             eigs=ft.partial(eigsh,
                                                             k=1,
                                                             which='SA',
                                                             tol=1e-6),
                                             var_sites=2)
    mineig_eigvec_mp = mineig_eigvec_mp.to_array().flatten()

    overlap = np.inner(mineig_eigvec.conj(), mineig_eigvec_mp)
    assert_almost_equal(mineig_mp, mineig)
    assert_almost_equal(abs(overlap), 1)
Exemple #8
0
def test_eig(nr_sites, local_dim, rank, which, var_sites, rgen, request):
    if nr_sites <= var_sites:
        pt.skip("Nothing to test")
        return  # No local optimization can be defined
    if not (_pytest_want_long(request) or
            (nr_sites, local_dim, rank, var_sites, which) in {
                (3, 2, 4, 1, 'SA'),
                (4, 3, 5, 1, 'LM'),
                (5, 2, 1, 2, 'LA'),
                (6, 2, 4, 2, 'SA'),
            }):
        pt.skip("Should only be run in long tests")
    # With startvec_rank = 2 * rank and this seed, eig() gets
    # stuck in a local minimum. With startvec_rank = 3 * rank,
    # it does not.
    mpo = factory.random_mpo(nr_sites,
                             local_dim,
                             rank,
                             randstate=rgen,
                             hermitian=True,
                             normalized=True)
    mpo.canonicalize()
    op = mpo.to_array_global().reshape((local_dim**nr_sites, ) * 2)
    v0 = factory._zrandn([local_dim**nr_sites], rgen)
    eigval, eigvec = eigsh(op, k=1, which=which, v0=v0)
    eigval, eigvec = eigval[0], eigvec[:, 0]

    eig_rank = (4 - var_sites) * rank
    eigval_mp, eigvec_mp = mp.eig(mpo,
                                  num_sweeps=5,
                                  var_sites=1,
                                  startvec_rank=eig_rank,
                                  randstate=rgen,
                                  eigs=ft.partial(eigsh,
                                                  k=1,
                                                  which=which,
                                                  tol=1e-6,
                                                  maxiter=250))
    eigvec_mp = eigvec_mp.to_array().flatten()

    overlap = np.inner(eigvec.conj(), eigvec_mp)
    assert_almost_equal(eigval, eigval_mp, decimal=14)
    assert_almost_equal(1, abs(overlap), decimal=14)
Exemple #9
0
def test_reductions_mpo(nr_sites, local_dim, rank, max_red_width, rgen):
    mpo = factory.random_mpo(nr_sites, local_dim, rank,
                             randstate=rgen)
    op = mpo.to_array_global()

    start, stop, red = _get_reductions(mm.reductions_mpo, mpo, max_red_width)
    for start, stop, reduced_mpo in zip(start, stop, red):
        # Check that startsites/stopsites and width produce the same result:
        reduced_mpo2 = tuple(mm.reductions_mpo(mpo, stop - start))[start]
        assert_array_almost_equal(reduced_mpo.to_array(),
                                  reduced_mpo2.to_array())
        traceout = tuple(range(start)) + tuple(range(stop, nr_sites))
        red_from_op = utils.partial_trace(op, traceout)
        assert_array_almost_equal(
            reduced_mpo.to_array_global(), red_from_op,
            err_msg="not equal at {}:{}".format(start, stop))

    # check default argument for startsite
    assert len(list(mm.reductions_mpo(mpo, max_red_width))) \
        == nr_sites - max_red_width + 1
Exemple #10
0
def test_reductions_mpo(nr_sites, local_dim, rank, max_red_width, rgen):
    mpo = factory.random_mpo(nr_sites, local_dim, rank,
                             randstate=rgen)
    op = mpo.to_array_global()

    start, stop, red = _get_reductions(mm.reductions_mpo, mpo, max_red_width)
    for start, stop, reduced_mpo in zip(start, stop, red):
        # Check that startsites/stopsites and width produce the same result:
        reduced_mpo2 = tuple(mm.reductions_mpo(mpo, stop - start))[start]
        assert_array_almost_equal(reduced_mpo.to_array(),
                                  reduced_mpo2.to_array())
        traceout = tuple(range(start)) + tuple(range(stop, nr_sites))
        red_from_op = utils.partial_trace(op, traceout)
        assert_array_almost_equal(
            reduced_mpo.to_array_global(), red_from_op,
            err_msg="not equal at {}:{}".format(start, stop))

    # check default argument for startsite
    assert len(list(mm.reductions_mpo(mpo, max_red_width))) \
        == nr_sites - max_red_width + 1
Exemple #11
0
def test_eig_sum_benchmark(nr_sites, local_dim, rank, ev_rank, rgen,
                           benchmark):
    mpo = factory.random_mpo(nr_sites,
                             local_dim,
                             rank,
                             randstate=rgen,
                             hermitian=True,
                             normalized=True)
    mpo.canonicalize()
    mps = factory.random_mpa(nr_sites,
                             local_dim,
                             rank,
                             randstate=rgen,
                             dtype=np.complex_,
                             normalized=True)

    benchmark(
        mp.eig_sum,
        [mpo, mps],
        startvec_rank=ev_rank,
        randstate=rgen,
        var_sites=1,
        num_sweeps=1,
    )