Esempio n. 1
0
def get_uccsd_circuit(molecule, theta_vector=None, use_basis_gates=False):
    """Produce the full UCCSD circuit.
    Args:
    molecule :: string - must be a key of MOLECULE_TO_INFO
    theta_vector :: array - arguments for the vqe ansatz. If None, will generate random angles.
    use_basis_gates :: bool - Mike and Ike gates if False, Basis gates if True.
       
    Returns:
    circuit :: qiskit.QuantumCircuit - the UCCSD circuit parameterized
                                       by theta_vector, unoptimized
    """
    molecule_info = MOLECULE_TO_INFO[molecule]
    driver = PySCFDriver(atom=molecule_info.atomic_string, basis='sto3g')
    qmolecule = driver.run()
    hamiltonian = Hamiltonian(
        qubit_mapping=QubitMappingType.PARITY,
        two_qubit_reduction=True,
        freeze_core=True,
        orbital_reduction=molecule_info.orbital_reduction)

    energy_input = hamiltonian.run(qmolecule)
    qubit_op = energy_input.qubit_op
    num_spin_orbitals = hamiltonian.molecule_info['num_orbitals']
    num_particles = hamiltonian.molecule_info['num_particles']
    map_type = hamiltonian._qubit_mapping
    qubit_reduction = hamiltonian.molecule_info['two_qubit_reduction']

    HF_state = HartreeFock(qubit_op.num_qubits, num_spin_orbitals,
                           num_particles, map_type, qubit_reduction)
    var_form = UCCSD(qubit_op.num_qubits,
                     depth=1,
                     num_orbitals=num_spin_orbitals,
                     num_particles=num_particles,
                     active_occupied=molecule_info.active_occupied,
                     active_unoccupied=molecule_info.active_unoccupied,
                     initial_state=HF_state,
                     qubit_mapping=map_type,
                     two_qubit_reduction=qubit_reduction,
                     num_time_slices=1)

    if theta_vector is None:
        theta_vector = [
            np.random.rand() * 2 * np.pi
            for _ in range(var_form._num_parameters)
        ]

    circuit = var_form.construct_circuit(theta_vector,
                                         use_basis_gates=use_basis_gates)

    return circuit
Esempio n. 2
0
def _compute_mp2(qmolecule, threshold):
    terms = {}
    mp2_delta = 0

    num_particles = qmolecule.num_alpha + qmolecule.num_beta
    num_orbitals = qmolecule.num_orbitals
    ints = qmolecule.mo_eri_ints
    oe = qmolecule.orbital_energies

    # Orbital indexes given by this method are numbered according to the blocked spin ordering
    singles, doubles = UCCSD.compute_excitation_lists(num_particles, num_orbitals * 2, same_spin_doubles=True)

    # doubles is list of [from, to, from, to] in spin orbital indexing where alpha runs
    # from 0 to num_orbitals-1, and beta from num_orbitals to num_orbitals*2-1
    for n in range(len(doubles)):
        idxs = doubles[n]
        i = idxs[0] % num_orbitals  # Since spins are same drop to MO indexing
        j = idxs[2] % num_orbitals
        a = idxs[1] % num_orbitals
        b = idxs[3] % num_orbitals

        tiajb = ints[i, a, j, b]
        tibja = ints[i, b, j, a]

        num = (2 * tiajb - tibja)
        denom = oe[b] + oe[a] - oe[i] - oe[j]
        coeff = -num / denom
        coeff = coeff if abs(coeff) > threshold else 0
        e_delta = coeff * tiajb
        e_delta = e_delta if abs(e_delta) > threshold else 0

        terms[_list_to_str(idxs)] = (coeff, e_delta)
        mp2_delta += e_delta

    return terms, mp2_delta
Esempio n. 3
0
    def test_tapered_op(self):
        """ tapered op test """
        tapered_ops = self.z2_symmetries.taper(self.qubit_op)
        smallest_idx = 0  # Prior knowledge of which tapered_op has ground state
        the_tapered_op = tapered_ops[smallest_idx]

        optimizer = SLSQP(maxiter=1000)

        init_state = HartreeFock(num_qubits=the_tapered_op.num_qubits,
                                 num_orbitals=self.core._molecule_info['num_orbitals'],
                                 qubit_mapping=self.core._qubit_mapping,
                                 two_qubit_reduction=self.core._two_qubit_reduction,
                                 num_particles=self.core._molecule_info['num_particles'],
                                 sq_list=the_tapered_op.z2_symmetries.sq_list)

        var_form = UCCSD(num_qubits=the_tapered_op.num_qubits, depth=1,
                         num_orbitals=self.core._molecule_info['num_orbitals'],
                         num_particles=self.core._molecule_info['num_particles'],
                         active_occupied=None, active_unoccupied=None,
                         initial_state=init_state,
                         qubit_mapping=self.core._qubit_mapping,
                         two_qubit_reduction=self.core._two_qubit_reduction,
                         num_time_slices=1,
                         z2_symmetries=the_tapered_op.z2_symmetries)

        algo = VQE(the_tapered_op, var_form, optimizer)

        backend = BasicAer.get_backend('statevector_simulator')
        quantum_instance = QuantumInstance(backend=backend)

        algo_result = algo.run(quantum_instance)

        _, result = self.core.process_algorithm_result(algo_result)

        self.assertAlmostEqual(result['energy'], self.reference_energy, places=6)
Esempio n. 4
0
    def __init__(self, operator, num_orbitals, num_particles,
                 qubit_mapping=None, two_qubit_reduction=False,
                 active_occupied=None, active_unoccupied=None,
                 is_eom_matrix_symmetric=True, se_list=None, de_list=None,
                 z2_symmetries=None, untapered_op=None):
        """Constructor.

        Args:
            operator (WeightedPauliOperator): qubit operator
            num_orbitals (int):  total number of spin orbitals
            num_particles (Union(list, int)): number of particles, if it is a list,
                                        the first number
                                        is alpha and the second number if beta.
            qubit_mapping (str): qubit mapping type
            two_qubit_reduction (bool): two qubit reduction is applied or not
            active_occupied (list): list of occupied orbitals to include, indices are
                                    0 to n where n is num particles // 2
            active_unoccupied (list): list of unoccupied orbitals to include, indices are
                                    0 to m where m is (num_orbitals - num particles) // 2
            is_eom_matrix_symmetric (bool): is EoM matrix symmetric
            se_list (list[list]): single excitation list, overwrite the setting in active space
            de_list (list[list]): double excitation list, overwrite the setting in active space
            z2_symmetries (Z2Symmetries): represent the Z2 symmetries
            untapered_op (WeightedPauliOperator): if the operator is tapered, we need
                                                    untapered operator
                                                    to build element of EoM matrix
        """
        self._operator = operator
        self._num_orbitals = num_orbitals
        self._num_particles = num_particles
        self._qubit_mapping = qubit_mapping
        self._two_qubit_reduction = two_qubit_reduction
        self._active_occupied = active_occupied
        self._active_unoccupied = active_unoccupied

        se_list_default, de_list_default = UCCSD.compute_excitation_lists(
            self._num_particles, self._num_orbitals, self._active_occupied, self._active_unoccupied)

        if se_list is None:
            self._se_list = se_list_default
        else:
            self._se_list = se_list
            logger.info("Use user-specified single excitation list: %s", self._se_list)

        if de_list is None:
            self._de_list = de_list_default
        else:
            self._de_list = de_list
            logger.info("Use user-specified double excitation list: %s", self._de_list)

        self._z2_symmetries = z2_symmetries if z2_symmetries is not None \
            else Z2Symmetries([], [], [])
        self._untapered_op = untapered_op if untapered_op is not None else operator

        self._is_eom_matrix_symmetric = is_eom_matrix_symmetric
Esempio n. 5
0
    def test_h2_one_qubit_statevector(self):
        """Test H2 with tapering and statevector backend."""
        two_qubit_reduction = True
        qubit_mapping = 'parity'
        core = Hamiltonian(transformation=TransformationType.FULL,
                           qubit_mapping=QubitMappingType.PARITY,
                           two_qubit_reduction=two_qubit_reduction,
                           freeze_core=False,
                           orbital_reduction=[])
        qubit_op, _ = core.run(self.molecule)

        num_orbitals = core.molecule_info['num_orbitals']
        num_particles = core.molecule_info['num_particles']

        # tapering
        z2_symmetries = Z2Symmetries.find_Z2_symmetries(qubit_op)
        # know the sector
        tapered_op = z2_symmetries.taper(qubit_op)[1]

        initial_state = HartreeFock(tapered_op.num_qubits,
                                    num_orbitals=num_orbitals,
                                    num_particles=num_particles,
                                    qubit_mapping=qubit_mapping,
                                    two_qubit_reduction=two_qubit_reduction,
                                    sq_list=tapered_op.z2_symmetries.sq_list)
        var_form = UCCSD(num_qubits=tapered_op.num_qubits,
                         depth=1,
                         num_orbitals=num_orbitals,
                         num_particles=num_particles,
                         initial_state=initial_state,
                         qubit_mapping=qubit_mapping,
                         two_qubit_reduction=two_qubit_reduction,
                         z2_symmetries=tapered_op.z2_symmetries)
        optimizer = SPSA(max_trials=50)

        eom_vqe = QEomVQE(tapered_op,
                          var_form,
                          optimizer,
                          num_orbitals=num_orbitals,
                          num_particles=num_particles,
                          qubit_mapping=qubit_mapping,
                          two_qubit_reduction=two_qubit_reduction,
                          z2_symmetries=tapered_op.z2_symmetries,
                          untapered_op=qubit_op)

        backend = BasicAer.get_backend('statevector_simulator')
        quantum_instance = QuantumInstance(backend)
        result = eom_vqe.run(quantum_instance)
        np.testing.assert_array_almost_equal(self.reference,
                                             result['energies'],
                                             decimal=5)
    def test_tapered_op(self):
        # set_qiskit_chemistry_logging(logging.DEBUG)
        tapered_ops = []
        for coeff in itertools.product([1, -1], repeat=len(self.sq_list)):
            tapered_op = Operator.qubit_tapering(self.qubit_op, self.cliffords,
                                                 self.sq_list, list(coeff))
            tapered_ops.append((list(coeff), tapered_op))

        smallest_idx = 0  # Prior knowledge of which tapered_op has ground state
        the_tapered_op = tapered_ops[smallest_idx][1]
        the_coeff = tapered_ops[smallest_idx][0]

        optimizer = SLSQP(maxiter=1000)

        init_state = HartreeFock(
            num_qubits=the_tapered_op.num_qubits,
            num_orbitals=self.core._molecule_info['num_orbitals'],
            qubit_mapping=self.core._qubit_mapping,
            two_qubit_reduction=self.core._two_qubit_reduction,
            num_particles=self.core._molecule_info['num_particles'],
            sq_list=self.sq_list)

        var_form = UCCSD(
            num_qubits=the_tapered_op.num_qubits,
            depth=1,
            num_orbitals=self.core._molecule_info['num_orbitals'],
            num_particles=self.core._molecule_info['num_particles'],
            active_occupied=None,
            active_unoccupied=None,
            initial_state=init_state,
            qubit_mapping=self.core._qubit_mapping,
            two_qubit_reduction=self.core._two_qubit_reduction,
            num_time_slices=1,
            cliffords=self.cliffords,
            sq_list=self.sq_list,
            tapering_values=the_coeff,
            symmetries=self.symmetries)

        algo = VQE(the_tapered_op, var_form, optimizer, 'matrix')

        backend = BasicAer.get_backend('statevector_simulator')
        quantum_instance = QuantumInstance(backend=backend)

        algo_result = algo.run(quantum_instance)

        lines, result = self.core.process_algorithm_result(algo_result)

        self.assertAlmostEqual(result['energy'],
                               self.reference_energy,
                               places=6)
Esempio n. 7
0
    def test_h2_two_qubits_statevector(self):
        """Test H2 with parity mapping and statevector backend."""
        two_qubit_reduction = True
        qubit_mapping = 'parity'
        core = Hamiltonian(transformation=TransformationType.FULL,
                           qubit_mapping=QubitMappingType.PARITY,
                           two_qubit_reduction=two_qubit_reduction,
                           freeze_core=False,
                           orbital_reduction=[])
        qubit_op, _ = core.run(self.molecule)

        num_orbitals = core.molecule_info['num_orbitals']
        num_particles = core.molecule_info['num_particles']

        initial_state = HartreeFock(qubit_op.num_qubits,
                                    num_orbitals=num_orbitals,
                                    num_particles=num_particles,
                                    qubit_mapping=qubit_mapping,
                                    two_qubit_reduction=two_qubit_reduction)
        var_form = UCCSD(num_qubits=qubit_op.num_qubits,
                         depth=1,
                         num_orbitals=num_orbitals,
                         num_particles=num_particles,
                         initial_state=initial_state,
                         qubit_mapping=qubit_mapping,
                         two_qubit_reduction=two_qubit_reduction)
        optimizer = COBYLA(maxiter=1000)

        eom_vqe = QEomVQE(qubit_op,
                          var_form,
                          optimizer,
                          num_orbitals=num_orbitals,
                          num_particles=num_particles,
                          qubit_mapping=qubit_mapping,
                          two_qubit_reduction=two_qubit_reduction)

        backend = BasicAer.get_backend('statevector_simulator')
        quantum_instance = QuantumInstance(backend)
        result = eom_vqe.run(quantum_instance)
        np.testing.assert_array_almost_equal(self.reference,
                                             result['energies'],
                                             decimal=5)
Esempio n. 8
0

backend = BasicAer.get_backend("statevector_simulator")
distances = np.arange(0.5)
exact_energies = []
vqe_energies = []
optimizer = SLSQP(maxiter=5)
for dist in distances:
    qubitOp, num_particles, num_spin_orbitals, shift = get_qubit_op(dist)
    result = ExactEigensolver(qubitOp).run()
    exact_energies.append(result['energy'] + shift)
    initial_state = HartreeFock(
        qubitOp.num_qubits,
        num_spin_orbitals,
        num_particles,
        'parity'
    )
    var_form = UCCSD(
        qubitOp.num_qubits,
        depth=1,
        num_orbitals=num_spin_orbitals,
        num_particles=num_particles,
        initial_state=initial_state,
        qubit_mapping='parity'
    )
    vqe = VQE(qubitOp, var_form, optimizer, 'matrix')
    results = vqe.run(backend)['energy'] + shift
    vqe_energies.append(results)
    print("Interatomic Distance:", np.round(dist, 2), "VQE Result:", results, "Exact Energy:", exact_energies[-1])

print("All energies have been calculated")
Esempio n. 9
0
hamiltonian = algo_input[0]

num_orbitals = core.molecule_info['num_orbitals']
num_particles = core.molecule_info['num_particles']

init_state = HartreeFock(hamiltonian.num_qubits,
                         num_orbitals,
                         num_particles,
                         qubit_mapping=qubit_mapping,
                         two_qubit_reduction=two_qubit_reduction)

depth = 1
var_form = UCCSD(hamiltonian.num_qubits,
                 depth,
                 num_orbitals,
                 num_particles,
                 initial_state=init_state,
                 qubit_mapping=qubit_mapping,
                 two_qubit_reduction=two_qubit_reduction)

optimizer = COBYLA(maxiter=5000)

algo = VQE(hamiltonian, var_form, optimizer)

results = algo.run(sv_simulator)
print(results)
energy = results['energy']
opt_params = results['opt_params']
ground_state = results['min_vector']

eom = QEquationOfMotion(hamiltonian,
Esempio n. 10
0
    num_particles) if qubit_reduction else qubitOp
qubitOp.chop(10**-10)

#print(qubitOp.print_operators())
print(qubitOp, flush=True)

# setup HartreeFock state
HF_state = HartreeFock(qubitOp.num_qubits, num_spin_orbitals, num_particles,
                       map_type, qubit_reduction)

# setup UCCSD variational form
var_form = UCCSD(qubitOp.num_qubits,
                 depth=1,
                 num_orbitals=num_spin_orbitals,
                 num_particles=num_particles,
                 active_occupied=[0],
                 active_unoccupied=[0, 1],
                 initial_state=HF_state,
                 qubit_mapping=map_type,
                 two_qubit_reduction=qubit_reduction,
                 num_time_slices=1)

circuit = var_form.construct_circuit(parameters, use_basis_gates=False)

print("Target circuit initialized.", flush=True)
#circuit.draw(output='text', line_length=350)

backend_sim = Aer.get_backend('unitary_simulator')

result = qiskit.execute(circuit, backend_sim).result()

U = result.get_unitary()
    num_particles=molecule.num_alpha+molecule.num_beta
    
    map_type='jordan_wigner'
    ferOp = FermionicOperator(h1=molecule.one_body_integrals, h2=molecule.two_body_integrals)
    qubitOp = ferOp.mapping(map_type=map_type, threshold=0.00000001)

    
    exact_solution = ExactEigensolver(qubitOp).run()['energy']
    exact_solution=exact_solution+repulsion_energy

    #optimizer = SLSQP(maxiter=5)
    optimizer = COBYLA(maxiter=opt_iter)
    HF_state=HartreeFock(qubitOp.num_qubits, num_spin_orbitals, num_particles, map_type)
    #var_form = RYRZ(qubitOp.num_qubits, depth=1, entanglement="linear")
    var_form = UCCSD(qubitOp.num_qubits, depth=1, num_orbitals=num_spin_orbitals, num_particles=num_particles,
                     active_occupied=None, active_unoccupied=None, initial_state=HF_state,
                     qubit_mapping='jordan_wigner', two_qubit_reduction=False, num_time_slices=1,
                     shallow_circuit_concat=True, z2_symmetries=None)
    
    
    #No parallelization
    energies_exp_n=[]
    for n in range(experiments):
        t=time.time()
        #Without parallelisation
        n_shots=50
        n_instances=1
        instances=[]
        for i in range(n_instances):
            instances.append(QuantumInstance(backend=BasicAer.get_backend("qasm_simulator"), shots=n_shots))
        
        if 'parameters_n_P' in locals():
Esempio n. 12
0
                               orbital_reduction=[-3, -2])
        qubit_op, aux_ops = operator.run(qmolecule)
        if algorithms[j] == 'ExactEigensolver':
            result = ExactEigensolver(qubit_op, aux_operators=aux_ops).run()
        optimizer = COBYLA(maxiter=1000)
        initial_state = HartreeFock(
            qubit_op.num_qubits,
            operator.molecule_info['num_orbitals'],
            operator.molecule_info['num_particles'],
            qubit_mapping=operator._qubit_mapping,
            two_qubit_reduction=operator._two_qubit_reduction)

        var_form = UCCSD(qubit_op.num_qubits,
                         depth=1,
                         num_orbitals=operator.molecule_info['num_orbitals'],
                         num_particles=operator.molecule_info['num_particles'],
                         initial_state=initial_state,
                         qubit_mapping=operator._qubit_mapping,
                         two_qubit_reduction=operator._two_qubit_reduction)

        algo = VQE(qubit_op, var_form, optimizer)
        result = algo.run(
            QuantumInstance(BasicAer.get_backend('statevector_simulator')))

        lines, result = operator.process_algorithm_result(result)
        energies[j][i] = result['energy']
        hf_energies[i] = result['hf_energy']

    distances[i] = d

pylab.plot(distances, hf_energies, label='Hartree-Fock')
Esempio n. 13
0
    def __init__(self,
                 ansatz,
                 molecule,
                 mean_field=None,
                 backend_options=None):
        """Initialize the settings for simulation.
        If the mean field is not provided it is automatically calculated.

        Args:
            ansatz (QiskitParametricSolver.Ansatze): Ansatz for the quantum solver.
            molecule (pyscf.gto.Mole): The molecule to simulate.
            mean_field (pyscf.scf.RHF): The mean field of the molecule.
            backend_options (dict): Extra parameters that control the behaviour
                of the solver.
        """

        # Check the ansatz
        assert (isinstance(ansatz, QiskitParametricSolver.Ansatze))
        self.ansatz = ansatz

        # Calculate the mean field if the user has not already done it.
        if not mean_field:
            mean_field = scf.RHF(molecule)
            mean_field.verbose = 0
            mean_field.scf()

            if (mean_field.converged == False):
                orb_temp = mean_field.mo_coeff
                occ_temp = mean_field.mo_occ
                nr = scf.newton(mean_field)
                energy = nr.kernel(orb_temp, occ_temp)
                mean_field = nr

        # Check the convergence of the mean field
        if not mean_field.converged:
            warnings.warn(
                "QiskitParametricSolver simulating with mean field not converged.",
                RuntimeWarning)

        # Initialize molecule quantities
        # ------------------------------
        self.num_orbitals = mean_field.mo_coeff.shape[0]
        self.num_spin_orbitals = self.num_orbitals * 2
        self.num_particles = molecule.nelec[0] + molecule.nelec[1]
        self.nuclear_repulsion_energy = gto.mole.energy_nuc(molecule)

        # Build one body integrals in Qiskit format
        one_body_integrals_pyscf = mean_field.mo_coeff.T @ mean_field.get_hcore(
        ) @ mean_field.mo_coeff
        self.one_body_integrals = QMolecule.onee_to_spin(
            one_body_integrals_pyscf)

        # Build two body integrals in Qiskit format
        eri = ao2mo.incore.full(mean_field._eri,
                                mean_field.mo_coeff,
                                compact=False)
        eri2 = eri.reshape(tuple([self.num_orbitals] * 4))
        self.two_body_integrals = QMolecule.twoe_to_spin(eri2)

        # Build Hamiltonians
        # ------------------
        # Set the fermionic Hamiltonian
        self.f_hamiltonian = FermionicOperator(h1=self.one_body_integrals,
                                               h2=self.two_body_integrals)

        # Transform the fermionic Hamiltonian into qubit Hamiltonian
        self.map_type = 'jordan_wigner'
        self.qubit_hamiltonian = self.f_hamiltonian.mapping(
            map_type=self.map_type, threshold=1e-8)
        self.qubit_hamiltonian.chop(10**-10)
        self.n_qubits = self.qubit_hamiltonian.num_qubits

        # Qubits, mapping, backend
        backend_opt = ('statevector_simulator', 'matrix')
        # backend_opt = ('qasm_simulator', 'paulis')
        self.backend = Aer.get_backend(backend_opt[0])
        self.backend_opt = backend_opt

        # Set ansatz and initial parameters
        # ---------------------------------

        # Define initial state
        self.init_state = HartreeFock(self.qubit_hamiltonian.num_qubits,
                                      self.num_spin_orbitals,
                                      self.num_particles, self.map_type,
                                      False)  # No qubit reduction

        # Select ansatz, set the dimension of the amplitudes
        self.var_form = UCCSD(self.qubit_hamiltonian.num_qubits,
                              depth=1,
                              num_orbitals=self.num_spin_orbitals,
                              num_particles=self.num_particles,
                              initial_state=self.init_state,
                              qubit_mapping=self.map_type,
                              two_qubit_reduction=False,
                              num_time_slices=1)

        self.amplitude_dimension = self.var_form._num_parameters
        self.optimized_amplitudes = []
Esempio n. 14
0
print("The total ground state energy is: {:.12f}".format(ret['eigvals'][0].real + energy_shift + nuclear_repulsion_energy))

#from qiskit import IBMQ
#from qiskit.providers.ibmq import least_busy
#IBMQ.load_accounts()
#large_enough_devices = IBMQ.backends(filters=lambda x: x.configuration().n_qubits > 4 and not x.configuration().simulator)
#backend = least_busy(large_enough_devices)

backend = Aer.get_backend('statevector_simulator')

# setup COBYLA optimizer
max_eval = 200
cobyla = COBYLA(maxiter=max_eval)

# setup HartreeFock state
HF_state = HartreeFock(qubitOp.num_qubits, num_spin_orbitals, num_particles, map_type, qubit_reduction)

# setup UCCSD variational form
var_form = UCCSD(qubitOp.num_qubits, depth=1, num_orbitals=num_spin_orbitals, num_particles=num_particles,active_occupied=[0], active_unoccupied=[0,1], initial_state=HF_state, qubit_mapping=map_type, two_qubit_reduction=qubit_reduction, num_time_slices=1)

# setup VQE
vqe = VQE(qubitOp, var_form, cobyla, 'matrix')
quantum_instance = QuantumInstance(backend=backend)

# Run algorithms and retrieve the results

results = vqe.run(quantum_instance)
print("The computed ground state energy is: {:.12f}".format(results['eigvals'][0]))
print("Final energy: {:.12f}".format(results['eigvals'][0] + energy_shift + nuclear_repulsion_energy))
print("Parameters: {}".format(results['opt_params']))