def test_jordan_wigner_interaction_op_with_zero_term(self): test_op = FermionOperator('1^ 2^ 3 4') test_op += hermitian_conjugated(test_op) interaction_op = get_interaction_operator(test_op) interaction_op.constant = 0.0 retransformed_test_op = reverse_jordan_wigner( jordan_wigner(interaction_op))
def test_jordan_wigner_twobody_interaction_op_allunique(self): test_op = FermionOperator('1^ 2^ 3 4') test_op += hermitian_conjugated(test_op) retransformed_test_op = reverse_jordan_wigner( jordan_wigner(get_interaction_operator(test_op))) self.assertTrue( normal_ordered(retransformed_test_op).isclose( normal_ordered(test_op)))
def test_ccr_onsite(self): c1 = FermionOperator(((1, 1), )) a1 = hermitian_conjugated(c1) self.assertTrue( normal_ordered( c1 * a1).isclose(FermionOperator(()) - normal_ordered(a1 * c1))) self.assertTrue( jordan_wigner( c1 * a1).isclose(QubitOperator(()) - jordan_wigner(a1 * c1)))
def test_jordan_wigner_one_body(self): # Make sure it agrees with jordan_wigner(FermionTerm). for p in range(self.n_qubits): for q in range(self.n_qubits): # Get test qubit operator. test_operator = jordan_wigner_one_body(p, q) # Get correct qubit operator. fermion_term = FermionOperator(((p, 1), (q, 0))) correct_op = jordan_wigner(fermion_term) hermitian_conjugate = hermitian_conjugated(fermion_term) if not fermion_term.isclose(hermitian_conjugate): correct_op += jordan_wigner(hermitian_conjugate) self.assertTrue(test_operator.isclose(correct_op))
def test_jordan_wigner_two_body(self): # Make sure it agrees with jordan_wigner(FermionTerm). for p in range(self.n_qubits): for q in range(self.n_qubits): for r in range(self.n_qubits): for s in range(self.n_qubits): # Get test qubit operator. test_operator = jordan_wigner_two_body(p, q, r, s) # Get correct qubit operator. fermion_term = FermionOperator( ((p, 1), (q, 1), (r, 0), (s, 0))) correct_op = jordan_wigner(fermion_term) hermitian_conjugate = hermitian_conjugated( fermion_term) if not fermion_term.isclose(hermitian_conjugate): if p == r and q == s: pass else: correct_op += jordan_wigner( hermitian_conjugate) self.assertTrue(test_operator.isclose(correct_op), str(test_operator - correct_op))
def test_jordan_wigner_twobody_interaction_op_reversal_symmetric(self): test_op = FermionOperator('1^ 2^ 2 1') test_op += hermitian_conjugated(test_op) self.assertTrue( jordan_wigner(test_op).isclose( jordan_wigner(get_interaction_operator(test_op))))
def fermi_hubbard(x_dimension, y_dimension, tunneling, coulomb, chemical_potential=None, magnetic_field=None, periodic=True, spinless=False): """Return symbolic representation of a Fermi-Hubbard Hamiltonian. Args: x_dimension: An integer giving the number of sites in width. y_dimension: An integer giving the number of sites in height. tunneling: A float giving the tunneling amplitude. coulomb: A float giving the attractive local interaction strength. chemical_potential: An optional float giving the potential of each site. Default value is None. magnetic_field: An optional float giving a magnetic field at each site. Default value is None. periodic: If True, add periodic boundary conditions. spinless: An optional Boolean. If False, each site has spin up orbitals and spin down orbitals. If True, return a spinless Fermi-Hubbard model. verbose: An optional Boolean. If True, print all second quantized terms. Returns: hubbard_model: An instance of the FermionOperator class. """ # Initialize fermion operator class. n_sites = x_dimension * y_dimension if spinless: n_spin_orbitals = n_sites else: n_spin_orbitals = 2 * n_sites hubbard_model = FermionOperator((), 0.0) # Loop through sites and add terms. for site in range(n_sites): # Add chemical potential and magnetic field terms. if chemical_potential and spinless: x_index = site % x_dimension y_index = (site - 1) // x_dimension sign = (-1.) ** (x_index + y_index) coefficient = sign * chemical_potential hubbard_model += number_operator( n_spin_orbitals, site, coefficient) if chemical_potential and not spinless: coefficient = -1. * chemical_potential hubbard_model += number_operator( n_spin_orbitals, up(site), coefficient) hubbard_model += number_operator( n_spin_orbitals, down(site), coefficient) if magnetic_field and not spinless: coefficient = magnetic_field hubbard_model += number_operator( n_spin_orbitals, up(site), -coefficient) hubbard_model += number_operator( n_spin_orbitals, down(site), coefficient) # Add local pair interaction terms. if not spinless: operators = ((up(site), 1), (up(site), 0), (down(site), 1), (down(site), 0)) hubbard_model += FermionOperator(operators, coulomb) # Index coupled orbitals. right_neighbor = site + 1 bottom_neighbor = site + x_dimension # Account periodic boundaries. if periodic: if (x_dimension > 2) and ((site + 1) % x_dimension == 0): right_neighbor -= (x_dimension - 1) if (y_dimension > 2) and (site + x_dimension + 1 > n_sites): bottom_neighbor -= (x_dimension - 1) * y_dimension # Add transition to neighbor on right. if (site + 1) % x_dimension or (periodic and x_dimension > 2): if spinless: # Add Coulomb term. operators = ((site, 1), (site, 0), (right_neighbor, 1), (right_neighbor, 0)) hubbard_model += FermionOperator(operators, coulomb) # Add hopping term. operators = ((site, 1), (right_neighbor, 0)) hopping_term = FermionOperator(operators, -tunneling) hubbard_model += hopping_term hubbard_model += hermitian_conjugated(hopping_term) else: # Add hopping term. operators = ((up(site), 1), (up(right_neighbor), 0)) hopping_term = FermionOperator(operators, -tunneling) hubbard_model += hopping_term hubbard_model += hermitian_conjugated(hopping_term) operators = ((down(site), 1), (down(right_neighbor), 0)) hopping_term = FermionOperator(operators, -tunneling) hubbard_model += hopping_term hubbard_model += hermitian_conjugated(hopping_term) # Add transition to neighbor below. if site + x_dimension + 1 <= n_sites or (periodic and y_dimension > 2): if spinless: # Add Coulomb term. operators = ((site, 1), (site, 0), (bottom_neighbor, 1), (bottom_neighbor, 0)) hubbard_model += FermionOperator(operators, coulomb) # Add hopping term. operators = ((site, 1), (bottom_neighbor, 0)) hopping_term = FermionOperator(operators, -tunneling) hubbard_model += hopping_term hubbard_model += hermitian_conjugated(hopping_term) else: # Add hopping term. operators = ((up(site), 1), (up(bottom_neighbor), 0)) hopping_term = FermionOperator(operators, -tunneling) hubbard_model += hopping_term hubbard_model += hermitian_conjugated(hopping_term) operators = ((down(site), 1), (down(bottom_neighbor), 0)) hopping_term = FermionOperator(operators, -tunneling) hubbard_model += hopping_term hubbard_model += hermitian_conjugated(hopping_term) # Return. return hubbard_model