Exemple #1
0
    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))
Exemple #2
0
    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)))
Exemple #3
0
 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)))
Exemple #4
0
    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))
Exemple #5
0
    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))
Exemple #6
0
 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))))
Exemple #7
0
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