def H_hop(self, i, j, f, dir): ''' TODO: pkron vs ikron performance? i, j: (directed) edge qubits indices f: face qubit index dir: {'vertical', 'horizontal'} Returns hopping term acting on qbits ijf, (XiXjOf + YiYjOf)/2 where Of is Xf, Yf or Identity depending on ijf ''' X, Y = (qu.pauli(mu) for mu in ['x', 'y']) Of = {'vertical': X, 'horizontal': Y}[dir] #if no face qbit if f == None: # print('{}--{}-->{} (None)'.format(i,dir[0],j)) # XXO=qu.ikron(ops=[X,X], dims=self._sim_dims, inds=[i,j]) # YYO=qu.ikron(ops=[Y,Y], dims=self._sim_dims, inds=[i,j]) XXO = qu.pkron(op=X & X, dims=self._sim_dims, inds=[i, j]) YYO = qu.pkron(op=Y & Y, dims=self._sim_dims, inds=[i, j]) #if there's a face qubit: Of acts on index f else: # print('{}--{}-->{}, face {}'.format(i,dir[0],j,f)) # XXO=qu.ikron(ops=[X,X,Of], dims=self._sim_dims, inds=[i,j,f]) # YYO=qu.ikron(ops=[Y,Y,Of], dims=self._sim_dims, inds=[i,j,f]) XXO = qu.pkron(op=X & X & Of, dims=self._sim_dims, inds=(i, j, f)) YYO = qu.pkron(op=Y & Y & Of, dims=self._sim_dims, inds=(i, j, f)) return 0.5 * (XXO + YYO)
def test_dop_reverse_sparse(self): a = qu.rand_rho(4, sparse=True, density=0.5) b = qu.pkron(a, np.array([2, 2, 2]), [2, 0]) c = ((a & qu.eye(2)).A.reshape([2, 2, 2, 2, 2, 2]).transpose([1, 2, 0, 4, 5, 3]).reshape([8, 8])) assert_allclose(b.A, c)
def test_dop_reverse(self): a = qu.rand_rho(4) b = qu.pkron(a, np.array([2, 2, 2]), [2, 0]) c = ((a & qu.eye(2)).A.reshape([2, 2, 2, 2, 2, 2]).transpose([1, 2, 0, 4, 5, 3]).reshape([8, 8])) assert_allclose(b, c)
def test_dop_spread(self): a = qu.rand_rho(4) b = qu.pkron(a, [2, 2, 2], [0, 2]) c = ((a & qu.eye(2)).A.reshape([2, 2, 2, 2, 2, 2]).transpose([0, 2, 1, 3, 5, 4]).reshape([8, 8])) assert_allclose(b, c)
def test_compute_local_expectation_vs_dense(self, Lx, Ly, normalized): # (2Lx-1) * (2Ly-1) lattice ePEPSvector epeps = qnets.QubitEncodeVector.rand(Lx, Ly)\ .convert_to_ePEPS_vector() # qubits + dummies n_sites = (2 * Lx - 1) * (2 * Ly - 1) # vertices + occupied faces in 'original' Lx*Ly lattice n_qubits = (Lx * Ly) + int((Lx - 1) * (Ly - 1) / 2) # 'qubit' Fermi-Hubbard with random parameters t, V, mu = np.random.rand(3) H = hams.SpinlessSimHam(Lx, Ly, t, V, mu) # separate indices of qubits from 'aux' tensors qubit_inds = tuple( starmap(epeps.site_ind, (epeps.qubit_to_coo_map[q] for q in range(n_qubits)))) non_qubit_inds = set(epeps.site_inds) - set(qubit_inds) # 'densify' into vector with qubit dimensions first psi_dense = epeps.to_dense((*qubit_inds, *non_qubit_inds)) if normalized: qu.normalize(psi_dense) dense_terms = [ qu.pkron(term, dims=[2] * n_sites, inds=where) for where, term in H.gen_ham_terms() ] exact = sum((qu.expec(h, psi_dense) for h in dense_terms)) # now compute energy with `ePEPSvector.compute_local_expectation` q2coo = lambda q: epeps.qubit_to_coo_map[q] CooHam = H.convert_to_coordinate_ham(q2coo) terms = CooHam._coo_ham_terms envs, plaqmap = epeps.calc_plaquette_envs_and_map(terms) opts = dict(cutoff=2e-3, max_bond=9, contract_optimize='random-greedy') e = epeps.compute_local_expectation(terms, normalized=normalized, autogroup=False, plaquette_envs=envs, plaquette_map=plaqmap, **opts) assert e == pytest.approx(exact, rel=1e-2)