Beispiel #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
Beispiel #2
0
def test_spin_symmetric_bogoliubov_transform(
        n_spatial_orbitals,
        conserves_particle_number,
        atol=5e-5):
    n_qubits = 2*n_spatial_orbitals
    qubits = LineQubit.range(n_qubits)

    # Initialize a random quadratic Hamiltonian
    quad_ham = random_quadratic_hamiltonian(
            n_spatial_orbitals,
            conserves_particle_number,
            real=True,
            expand_spin=True,
            seed=28166)

    # Reorder the Hamiltonian and get sparse matrix
    quad_ham = openfermion.get_quadratic_hamiltonian(
            openfermion.reorder(
                openfermion.get_fermion_operator(quad_ham),
                openfermion.up_then_down)
    )
    quad_ham_sparse = get_sparse_operator(quad_ham)

    # Compute the orbital energies and transformation_matrix
    up_orbital_energies, _, _ = (
            quad_ham.diagonalizing_bogoliubov_transform(spin_sector=0))
    down_orbital_energies, _, _ = (
            quad_ham.diagonalizing_bogoliubov_transform(spin_sector=1))
    _, transformation_matrix, _ = (
            quad_ham.diagonalizing_bogoliubov_transform())

    # Pick some orbitals to occupy
    up_orbitals = list(range(2))
    down_orbitals = [0, 2, 3]
    energy = sum(up_orbital_energies[up_orbitals]) + sum(
            down_orbital_energies[down_orbitals]) + quad_ham.constant

    # Construct initial state
    initial_state = (
            sum(2**(n_qubits - 1 - int(i)) for i in up_orbitals)
            + sum(2**(n_qubits - 1 - int(i+n_spatial_orbitals))
                  for i in down_orbitals)
    )

    # Apply the circuit
    circuit = cirq.Circuit.from_ops(
            bogoliubov_transform(
                qubits, transformation_matrix, initial_state=initial_state))
    state = circuit.apply_unitary_effect_to_state(initial_state)

    # Check that the result is an eigenstate with the correct eigenvalue
    numpy.testing.assert_allclose(
            quad_ham_sparse.dot(state), energy * state, atol=atol)
Beispiel #3
0
def test_prepare_gaussian_state_with_spin_symmetry(n_spatial_orbitals,
                                                   conserves_particle_number,
                                                   occupied_orbitals,
                                                   initial_state,
                                                   atol=1e-5):

    n_qubits = 2 * n_spatial_orbitals
    qubits = LineQubit.range(n_qubits)

    # Initialize a random quadratic Hamiltonian
    quad_ham = random_quadratic_hamiltonian(
            n_spatial_orbitals,
            conserves_particle_number,
            real=True,
            expand_spin=True,
            seed=639)

    # Reorder the Hamiltonian and get sparse matrix
    quad_ham = openfermion.get_quadratic_hamiltonian(
            openfermion.reorder(
                openfermion.get_fermion_operator(quad_ham),
                openfermion.up_then_down)
    )
    quad_ham_sparse = get_sparse_operator(quad_ham)

    # Compute the energy of the desired state
    energy = 0.0
    for spin_sector in range(2):
        orbital_energies, _, _ = (
            quad_ham.diagonalizing_bogoliubov_transform(
                spin_sector=spin_sector)
        )
        energy += sum(orbital_energies[i]
                      for i in occupied_orbitals[spin_sector])
    energy += quad_ham.constant

    # Get the state using a circuit simulation
    circuit = cirq.Circuit.from_ops(
            prepare_gaussian_state(
                qubits, quad_ham, occupied_orbitals,
                initial_state=initial_state))

    if isinstance(initial_state, list):
        initial_state = sum(1 << (n_qubits - 1 - i) for i in initial_state)
    state = circuit.apply_unitary_effect_to_state(initial_state)

    # Check that the result is an eigenstate with the correct eigenvalue
    numpy.testing.assert_allclose(
            quad_ham_sparse.dot(state), energy * state, atol=atol)
Beispiel #4
0
    def __call__(self, fermion_operator: openfermion.FermionOperator, *args,
                 **kwargs) -> QubitHamiltonian:
        """
        :param fermion_operator:
            an openfermion FermionOperator
        :return:
            The openfermion QubitOperator of this class ecoding
        """
        if self.up_then_down:
            op = openfermion.reorder(operator=fermion_operator,
                                     order_function=openfermion.up_then_down,
                                     num_modes=2 * self.n_orbitals)
        else:
            op = fermion_operator

        fop = self.do_transform(fermion_operator=op, *args, **kwargs)
        fop.compress()
        return self.post_processing(QubitHamiltonian.from_openfermion(fop))
Beispiel #5
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
longer_time = 1.0
long_time = 0.1
short_time = 0.05

# 5-qubit random DiagonalCoulombHamiltonian
diag_coul_hamiltonian = openfermion.random_diagonal_coulomb_hamiltonian(
    5, real=False, seed=65233)
diag_coul_initial_state, diag_coul_exact_state = (
    produce_simulation_test_parameters(diag_coul_hamiltonian,
                                       long_time,
                                       seed=49075))

# Hubbard model, reordered
hubbard_model = openfermion.fermi_hubbard(2, 2, 1.0, 4.0)
hubbard_model = openfermion.reorder(hubbard_model, openfermion.up_then_down)
hubbard_hamiltonian = openfermion.get_diagonal_coulomb_hamiltonian(
    hubbard_model)
hubbard_initial_state, hubbard_exact_state = (
    produce_simulation_test_parameters(hubbard_hamiltonian,
                                       long_time,
                                       seed=8200))

# 4-qubit H2 2-2 with bond length 0.7414
bond_length = 0.7414
geometry = [('H', (0., 0., 0.)), ('H', (0., 0., bond_length))]
h2_hamiltonian = openfermion.load_molecular_hamiltonian(
    geometry, 'sto-3g', 1, format(bond_length), 2, 2)
h2_initial_state, h2_exact_state = produce_simulation_test_parameters(
    h2_hamiltonian, longer_time, seed=44303)