示例#1
0
    def kevin_hubbard_cirq(self):
        # Create Hubbard model Hamiltonian
        # --------------------------------
        x_dim = 3
        y_dim = 2
        n_sites = x_dim * y_dim
        n_modes = 2 * n_sites

        tunneling = 1.0
        coulomb = 4.0

        hubbard_model = of.fermi_hubbard(x_dim, y_dim, tunneling, coulomb)

        # Reorder indices
        hubbard_model = of.reorder(hubbard_model, of.up_then_down)

        # Convert to DiagonalCoulombHamiltonian
        hubbard_hamiltonian = of.get_diagonal_coulomb_hamiltonian(
            hubbard_model)

        # Create qubits
        qubits = cirq.LineQubit.range(n_modes)

        # State preparation circuit for eigenstate of one-body term
        # ---------------------------------------------------------
        # Set the pseudo-particle orbitals to fill
        up_orbitals = range(n_sites // 2)
        down_orbitals = range(n_sites // 2)

        # Create the circuit
        hubbard_state_preparation_circuit = cirq.Circuit.from_ops(
            ofc.prepare_gaussian_state(
                qubits,
                of.QuadraticHamiltonian(hubbard_hamiltonian.one_body),
                occupied_orbitals=(up_orbitals, down_orbitals)),
            strategy=cirq.InsertStrategy.EARLIEST)

        # Trotter simulation circuit
        # --------------------------
        n_steps = 10
        order = 0

        hubbard_simulation_circuit = cirq.Circuit.from_ops(
            ofc.simulate_trotter(qubits,
                                 hubbard_hamiltonian,
                                 time=1.0,
                                 n_steps=n_steps,
                                 order=order,
                                 algorithm=ofc.trotter.LINEAR_SWAP_NETWORK),
            strategy=cirq.InsertStrategy.EARLIEST)

        t0 = time.time()
        self.kevin_optimize_circuit(hubbard_state_preparation_circuit)
        self.kevin_optimize_circuit(hubbard_simulation_circuit)
        t1 = time.time()

        # print('Optimizing circuits took {} seconds'.format(t1 - t0))
        # print(hubbard_state_preparation_circuit.to_text_diagram(transpose=True))

        return hubbard_state_preparation_circuit, hubbard_simulation_circuit
    def test_fermionops_tomatrix_hubbard_model(self):
        hubbard = fermi_hubbard(1,
                                4,
                                tunneling=1.0,
                                coulomb=2.0,
                                periodic=False)

        init_wfn = Wavefunction([[2, 0, 4]])
        init_wfn.set_wfn(strategy="random")

        # This calls fermionops_tomatrix.
        evolved_wfn = init_wfn.time_evolve(1.0, hubbard)

        # Check.
        wfn_cirq = to_cirq(init_wfn)
        unitary = scipy.linalg.expm(-1j * get_sparse_operator(hubbard))
        evolved_wfn_cirq = unitary @ wfn_cirq

        fidelity = abs(
            vdot(evolved_wfn, from_cirq(evolved_wfn_cirq, thresh=1e-12)))**2
        assert numpy.isclose(fidelity, 1.0)
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

import numpy

import cirq
import openfermion

from openfermioncirq.variational.ansatzes import SwapNetworkTrotterAnsatz

# Construct a Hubbard model Hamiltonian
hubbard_model = openfermion.fermi_hubbard(2, 2, 1., 4.)
hubbard_hamiltonian = openfermion.get_diagonal_coulomb_hamiltonian(
    hubbard_model)

# Construct an empty Hamiltonian
zero_hamiltonian = openfermion.DiagonalCoulombHamiltonian(one_body=numpy.zeros(
    (4, 4)),
                                                          two_body=numpy.zeros(
                                                              (4, 4)))


def test_swap_network_trotter_ansatz_params():

    ansatz = SwapNetworkTrotterAnsatz(hubbard_hamiltonian)
    assert (set(ansatz.params()) == {
        cirq.Symbol(name)
示例#4
0
@pytest.mark.parametrize(
        'ansatz, trotter_algorithm, order, hamiltonian, atol', [
    (SwapNetworkTrotterAnsatz(diag_coul_hamiltonian, iterations=1),
        LINEAR_SWAP_NETWORK, 1, diag_coul_hamiltonian, 5e-5),
    (SplitOperatorTrotterAnsatz(diag_coul_hamiltonian, iterations=1),
        SPLIT_OPERATOR, 1, diag_coul_hamiltonian, 5e-5),
    (LowRankTrotterAnsatz(h2_hamiltonian, iterations=1),
        LOW_RANK, 0, h2_hamiltonian, 5e-5),
    (LowRankTrotterAnsatz(lih_hamiltonian, iterations=1, final_rank=3),
        LowRankTrotterAlgorithm(final_rank=3), 0, lih_hamiltonian, 5e-5),
    (SwapNetworkTrotterHubbardAnsatz(2, 2, 1.0, 4.0, iterations=1),
        LINEAR_SWAP_NETWORK, 1,
        openfermion.get_diagonal_coulomb_hamiltonian(
            openfermion.reorder(
                openfermion.fermi_hubbard(2, 2, 1.0, 4.0),
                openfermion.up_then_down)
        ),
        5e-5)
])
def test_trotter_ansatzes_default_initial_params_iterations_1(
        ansatz, trotter_algorithm, order, hamiltonian, atol):
    """Check that a Trotter ansatz with one iteration and default parameters
    is consistent with time evolution with one Trotter step."""

    objective = HamiltonianObjective(hamiltonian)

    qubits = ansatz.qubits

    if isinstance(hamiltonian, openfermion.DiagonalCoulombHamiltonian):
        one_body = hamiltonian.one_body
示例#5
0
def test_convert_to_spin_blocks():
    # skip test if openfermion not installed
    pytest.importorskip("openfermion")
    import openfermion

    hi = nkx.hilbert.SpinOrbitalFermions(3, s=1 / 2)
    term1 = (((0, 1), (1, 0)), )
    term1_conv = _convert_terms_to_spin_blocks(term1, 3, 2)
    assert term1_conv == (((0, 1), (3, 0)), )

    term2 = (((2, 1), (3, 0)), ((4, 1), (5, 0)))
    term2_conv = _convert_terms_to_spin_blocks(term2, 3, 2)
    assert term2_conv == (((1, 1), (4, 0)), ((2, 1), (5, 0)))

    term3 = (((0, 1), (0, 0), (1, 1), (1, 0)), )
    term3_conv = _convert_terms_to_spin_blocks(term3, 3, 2)
    assert term3_conv == (((0, 1), (0, 0), (3, 1), (3, 0)), )

    # check fermi-hubbard - netket
    L = 2
    D = 2
    t = 1  # tunneling/hopping
    U = 0.01  # coulomb
    # create the graph where fermions can hop on
    g = nk.graph.Hypercube(length=L, n_dim=D, pbc=True)
    Nsites = g.n_nodes
    hi = nkx.hilbert.SpinOrbitalFermions(Nsites, s=1 / 2)
    # create an operator representing fermi hubbard interactions
    up = +1 / 2
    down = -1 / 2
    terms = []
    weights = []
    for sz in (up, down):
        for u, v in g.edges():
            c_u = hi._get_index(u, sz)
            c_v = hi._get_index(v, sz)

            terms.append([(c_u, 1), (c_v, 0)])
            terms.append([(c_v, 1), (c_u, 0)])

            weights.append(-t)
            weights.append(-t)

    for u in g.nodes():
        nc_up = hi._get_index(u, up)
        nc_down = hi._get_index(u, down)

        terms.append([(nc_up, 1), (nc_up, 0), (nc_down, 1), (nc_down, 0)])
        weights.append(U)
    op = nkx.operator.FermionOperator2nd(hi, terms, weights)

    # eigenspectrum
    eig = np.linalg.eigvalsh(op.to_dense())

    # check fermi-hubbard - openfermion
    op_of = openfermion.fermi_hubbard(L,
                                      D,
                                      tunneling=t,
                                      coulomb=U,
                                      periodic=True,
                                      spinless=False)
    terms_conv = _convert_terms_to_spin_blocks(op_of.terms, Nsites, 2)
    op_conv = nkx.operator.FermionOperator2nd(hi, terms_conv,
                                              list(op_of.terms.values()))

    # eigenspectrum
    eig_conv = np.linalg.eigvalsh(op_conv.to_dense())

    assert np.allclose(eig_conv, eig)
    assert np.allclose(op.to_dense(), op_conv.to_dense())
示例#6
0
def test_hubbard_model(abscissa: int, ordinate: int, tunneling: float, coulomb: float, magnetic_field: float, chemical_potential: float, periodic: bool, spinless: bool, symmetry: bool):
    hubbard_operator = fermi_hubbard(
        x_dimension=abscissa,
        y_dimension=ordinate,
        tunneling=tunneling,
        coulomb=coulomb,
        chemical_potential=chemical_potential,
        magnetic_field=magnetic_field,
        periodic=periodic,
        spinless=spinless,
        particle_hole_symmetry=symmetry
    )
    # print(hubbard_operator)
    jw_hamiltonian = jordan_wigner(hubbard_operator)
    print('Jordan-Wigner hamiltonian without compression: ')
    print(jw_hamiltonian)
    print()
    jw_hamiltonian.compress()
    print('Jordan-Wigner hamiltonian with compression: ')
    print(jw_hamiltonian)
    print()
    sparse_operator = get_sparse_operator(hubbard_operator)
    print('Sparse operator')
    print(sparse_operator)
    print()
    print(f'Energy of the model is {get_ground_state(sparse_operator)[0]} in units of T and J')

    # xs = range(1, 9)
    # energy_levels = [
    #     get_ground_state(
    #         get_sparse_operator(
    #             fermi_hubbard(
    #                 x_dimension=x,
    #                 y_dimension=ordinate,
    #                 tunneling=tunneling,
    #                 coulomb=coulomb,
    #                 chemical_potential=chemical_potential,
    #                 magnetic_field=magnetic_field,
    #                 periodic=periodic,
    #                 spinless=spinless,
    #                 particle_hole_symmetry=symmetry
    #             )
    #         )
    #     )[0]
    #     for x in xs
    # ]
    #
    # os.makedirs('assets/hubbard', exist_ok=True)
    #
    # draw_plot(
    #     xs, energy_levels,
    #     x_label='X coordinate',
    #     y_label='Ground state energy in units of T and J',
    #     title='Ground state energy of the Hubbard model',
    #     path='assets/hubbard/x.jpeg'
    # )
    #
    # energy_levels = [
    #     get_ground_state(
    #         get_sparse_operator(
    #             fermi_hubbard(
    #                 x_dimension=abscissa,
    #                 y_dimension=x,
    #                 tunneling=tunneling,
    #                 coulomb=coulomb,
    #                 chemical_potential=chemical_potential,
    #                 magnetic_field=magnetic_field,
    #                 periodic=periodic,
    #                 spinless=spinless,
    #                 particle_hole_symmetry=symmetry
    #             )
    #         )
    #     )[0]
    #     for x in xs
    # ]
    # draw_plot(
    #     xs, energy_levels,
    #     x_label='Y coordinate',
    #     y_label='Ground state energy in units of T and J',
    #     title='Ground state energy of the Hubbard model',
    #     path='assets/hubbard/y.jpeg'
    # )

    ts = np.arange(0, 4, 0.2)
    energy_levels = [
        get_ground_state(
            get_sparse_operator(
                fermi_hubbard(
                    x_dimension=abscissa,
                    y_dimension=ordinate,
                    tunneling=t,
                    coulomb=coulomb,
                    chemical_potential=chemical_potential,
                    magnetic_field=magnetic_field,
                    periodic=periodic,
                    spinless=spinless,
                    particle_hole_symmetry=symmetry
                )
            )
        )[0]
        for t in ts
    ]
    draw_plot(
        ts, energy_levels,
        x_label='Tunneling coefficient',
        y_label='Ground state energy in units of T and J',
        title='Ground state energy of the Hubbard model',
        path='assets/hubbard/t.jpeg'
    )
示例#7
0

@pytest.mark.parametrize(
    'ansatz, trotter_algorithm, order, hamiltonian, atol',
    [(SwapNetworkTrotterAnsatz(diag_coul_hamiltonian, iterations=1),
      LINEAR_SWAP_NETWORK, 1, diag_coul_hamiltonian, 5e-5),
     (SplitOperatorTrotterAnsatz(diag_coul_hamiltonian, iterations=1),
      SPLIT_OPERATOR, 1, diag_coul_hamiltonian, 5e-5),
     (LowRankTrotterAnsatz(h2_hamiltonian,
                           iterations=1), LOW_RANK, 0, h2_hamiltonian, 5e-5),
     (LowRankTrotterAnsatz(lih_hamiltonian, iterations=1, final_rank=3),
      LowRankTrotterAlgorithm(final_rank=3), 0, lih_hamiltonian, 5e-5),
     (SwapNetworkTrotterHubbardAnsatz(2, 2, 1.0, 4.0,
                                      iterations=1), LINEAR_SWAP_NETWORK, 1,
      openfermion.get_diagonal_coulomb_hamiltonian(
          openfermion.reorder(openfermion.fermi_hubbard(2, 2, 1.0, 4.0),
                              openfermion.up_then_down)), 5e-5)])
def test_trotter_ansatzes_default_initial_params_iterations_1(
        ansatz, trotter_algorithm, order, hamiltonian, atol):
    """Check that a Trotter ansatz with one iteration and default parameters
    is consistent with time evolution with one Trotter step."""

    objective = HamiltonianObjective(hamiltonian)

    qubits = ansatz.qubits

    if isinstance(hamiltonian, openfermion.DiagonalCoulombHamiltonian):
        one_body = hamiltonian.one_body
    elif isinstance(hamiltonian, openfermion.InteractionOperator):
        one_body = hamiltonian.one_body_tensor