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)
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")
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)
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)
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, )
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)
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)
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
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, )