Example #1
0
    def test_bksf_mapping(self):
        """Test bksf mapping.

        The spectrum of bksf mapping should be half of jordan wigner mapping.
        """
        driver = PySCFDriver(atom='H .0 .0 0.7414; H .0 .0 .0',
                             unit=UnitsType.ANGSTROM,
                             charge=0,
                             spin=0,
                             basis='sto3g')
        molecule = driver.run()
        fer_op = FermionicOperator(h1=molecule.one_body_integrals,
                                   h2=molecule.two_body_integrals)
        jw_op = fer_op.mapping('jordan_wigner')
        bksf_op = fer_op.mapping('bksf')
        jw_op.to_matrix()
        bksf_op.to_matrix()
        jw_eigs = np.linalg.eigvals(jw_op.matrix.toarray())
        bksf_eigs = np.linalg.eigvals(bksf_op.matrix.toarray())

        jw_eigs = np.sort(np.around(jw_eigs.real, 6))
        bksf_eigs = np.sort(np.around(bksf_eigs.real, 6))
        overlapped_spectrum = np.sum(np.isin(jw_eigs, bksf_eigs))

        self.assertEqual(overlapped_spectrum, jw_eigs.size // 2)
Example #2
0
def lih(dist=1.5):
    mol = PySCFDriver(atom=
                      'H 0.0 0.0 0.0;'\
                      'Li 0.0 0.0 {}'.format(dist), unit=UnitsType.ANGSTROM, charge=0,
                      spin=0, basis='sto-3g')
    mol = mol.run()
    freeze_list = [0]
    remove_list = [-3, -2]
    repulsion_energy = mol.nuclear_repulsion_energy
    num_particles = mol.num_alpha + mol.num_beta
    num_spin_orbitals = mol.num_orbitals * 2
    remove_list = [x % mol.num_orbitals for x in remove_list]
    freeze_list = [x % mol.num_orbitals for x in freeze_list]
    remove_list = [x - len(freeze_list) for x in remove_list]
    remove_list += [
        x + mol.num_orbitals - len(freeze_list) for x in remove_list
    ]
    freeze_list += [x + mol.num_orbitals for x in freeze_list]
    ferOp = FermionicOperator(h1=mol.one_body_integrals,
                              h2=mol.two_body_integrals)
    ferOp, energy_shift = ferOp.fermion_mode_freezing(freeze_list)
    num_spin_orbitals -= len(freeze_list)
    num_particles -= len(freeze_list)
    ferOp = ferOp.fermion_mode_elimination(remove_list)
    num_spin_orbitals -= len(remove_list)

    qubitOp = ferOp.mapping(map_type='parity', threshold=0.00000001)
    qubitOp = Z2Symmetries.two_qubit_reduction(qubitOp, num_particles)

    shift = energy_shift + repulsion_energy
    cHam = op_converter.to_matrix_operator(qubitOp)
    cHam = cHam.dense_matrix + shift * numpy.identity(16)

    return cHam
Example #3
0
def get_qubit_op(dist):
    #atom="Li .0 .0 .0; H .0 .0 " + str(dist)
    #atom="Be .0 .0 .0; H .0 .0 -" + str(dist) + "; H .0 .0 " + str(dist)
    driver = PySCFDriver("Li .0 .0 .0; H .0 .0 " + str(dist),
                         unit=UnitsType.ANGSTROM,
                         charge=0,
                         spin=0,
                         basis='sto3g')
    molecule = driver.run()
    freeze_list = [0]
    remove_list = [-3, -2]
    repulsion_energy = molecule.nuclear_repulsion_energy
    num_particles = molecule.num_alpha + molecule.num_beta
    num_spin_orbitals = molecule.num_orbitals * 2
    remove_list = [x % molecule.num_orbitals for x in remove_list]
    freeze_list = [x % molecule.num_orbitals for x in freeze_list]
    remove_list = [x - len(freeze_list) for x in remove_list]
    remove_list += [
        x + molecule.num_orbitals - len(freeze_list) for x in remove_list
    ]
    freeze_list += [x + molecule.num_orbitals for x in freeze_list]
    ferOp = FermionicOperator(h1=molecule.one_body_integrals,
                              h2=molecule.two_body_integrals)
    ferOp, energy_shift = ferOp.fermion_mode_freezing(freeze_list)
    num_spin_orbitals -= len(freeze_list)
    num_particles -= len(freeze_list)
    ferOp = ferOp.fermion_mode_elimination(remove_list)
    num_spin_orbitals -= len(remove_list)
    qubitOp = ferOp.mapping(map_type='parity', threshold=0.00000001)
    qubitOp = Z2Symmetries.two_qubit_reduction(qubitOp, num_particles)
    shift = energy_shift + repulsion_energy
    return qubitOp, num_particles, num_spin_orbitals, shift
Example #4
0
    def _build_single_hopping_operator(index, num_particles, num_orbitals, qubit_mapping,
                                       two_qubit_reduction, z2_symmetries):

        h_1 = np.zeros((num_orbitals, num_orbitals), dtype=complex)
        h_2 = np.zeros((num_orbitals, num_orbitals, num_orbitals, num_orbitals), dtype=complex)
        if len(index) == 2:
            i, j = index
            h_1[i, j] = 4.0
        elif len(index) == 4:
            i, j, k, m = index
            h_2[i, j, k, m] = 16.0
        fer_op = FermionicOperator(h_1, h_2)
        qubit_op = fer_op.mapping(qubit_mapping)
        if two_qubit_reduction:
            qubit_op = Z2Symmetries.two_qubit_reduction(qubit_op, num_particles)

        commutativities = []
        if not z2_symmetries.is_empty():
            for symmetry in z2_symmetries.symmetries:
                symmetry_op = WeightedPauliOperator(paulis=[[1.0, symmetry]])
                commuting = qubit_op.commute_with(symmetry_op)
                anticommuting = qubit_op.anticommute_with(symmetry_op)

                if commuting != anticommuting:  # only one of them is True
                    if commuting:
                        commutativities.append(True)
                    elif anticommuting:
                        commutativities.append(False)
                else:
                    raise AquaError("Symmetry {} is nor commute neither anti-commute "
                                    "to exciting operator.".format(symmetry.to_label()))

        return qubit_op, commutativities
    def test_qpe(self, distance):
        self.algorithm = 'QPE'
        self.log.debug('Testing End-to-End with QPE on H2 with inter-atomic distance {}.'.format(distance))
        try:
            driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 {}'.format(distance),
                                 unit=UnitsType.ANGSTROM,
                                 charge=0,
                                 spin=0,
                                 basis='sto3g')
        except QiskitChemistryError:
            self.skipTest('PYSCF driver does not appear to be installed')

        self.molecule = driver.run()
        qubit_mapping = 'parity'
        fer_op = FermionicOperator(
            h1=self.molecule.one_body_integrals, h2=self.molecule.two_body_integrals)
        self.qubit_op = fer_op.mapping(map_type=qubit_mapping,
                                       threshold=1e-10).two_qubit_reduced_operator(2)

        exact_eigensolver = ExactEigensolver(self.qubit_op, k=1)
        results = exact_eigensolver.run()
        self.reference_energy = results['energy']
        self.log.debug(
            'The exact ground state energy is: {}'.format(results['energy']))

        num_particles = self.molecule.num_alpha + self.molecule.num_beta
        two_qubit_reduction = True
        num_orbitals = self.qubit_op.num_qubits + \
            (2 if two_qubit_reduction else 0)

        num_time_slices = 50
        n_ancillae = 9

        state_in = HartreeFock(self.qubit_op.num_qubits, num_orbitals,
                               num_particles, qubit_mapping, two_qubit_reduction)
        iqft = Standard(n_ancillae)

        qpe = QPE(self.qubit_op, state_in, iqft, num_time_slices, n_ancillae,
                  expansion_mode='suzuki',
                  expansion_order=2, shallow_circuit_concat=True)
        backend = qiskit.Aer.get_backend('qasm_simulator')
        run_config = RunConfig(shots=100, max_credits=10, memory=False)
        quantum_instance = QuantumInstance(backend, run_config, pass_manager=PassManager())
        result = qpe.run(quantum_instance)
        
        self.log.debug('eigvals:                  {}'.format(result['eigvals']))
        self.log.debug('top result str label:     {}'.format(result['top_measurement_label']))
        self.log.debug('top result in decimal:    {}'.format(result['top_measurement_decimal']))
        self.log.debug('stretch:                  {}'.format(result['stretch']))
        self.log.debug('translation:              {}'.format(result['translation']))
        self.log.debug('final energy from QPE:    {}'.format(result['energy']))
        self.log.debug('reference energy:         {}'.format(self.reference_energy))
        self.log.debug('ref energy (transformed): {}'.format(
            (self.reference_energy + result['translation']) * result['stretch']))
        self.log.debug('ref binary str label:     {}'.format(decimal_to_binary((self.reference_energy + result['translation']) * result['stretch'],
                                                                               max_num_digits=n_ancillae + 3,
                                                                               fractional_part_only=True)))

        np.testing.assert_approx_equal(
            result['energy'], self.reference_energy, significant=2)
Example #6
0
def get_H2_data(dist):
    """ 
    Use the qiskit chemistry package to get the qubit Hamiltonian for LiH

    Parameters
    ----------
    dist : float
        The nuclear separations

    Returns
    -------
    qubitOp : qiskit.aqua.operators.WeightedPauliOperator
        Qiskit representation of the qubit Hamiltonian
    shift : float
        The ground state of the qubit Hamiltonian needs to be corrected by this amount of
        energy to give the real physical energy. This includes the replusive energy between
        the nuclei and the energy shift of the frozen orbitals.
    """
    driver = PySCFDriver(atom="H .0 .0 .0; H .0 .0 " + str(dist), 
                         unit=UnitsType.ANGSTROM, 
                         charge=0, 
                         spin=0, 
                         basis='sto3g',
                        )
    molecule = driver.run()
    repulsion_energy = molecule.nuclear_repulsion_energy
    num_particles = molecule.num_alpha + molecule.num_beta
    num_spin_orbitals = molecule.num_orbitals * 2
    ferOp = FermionicOperator(h1=molecule.one_body_integrals, h2=molecule.two_body_integrals)
    qubitOp = ferOp.mapping(map_type='parity', threshold=1E-8)
    qubitOp = Z2Symmetries.two_qubit_reduction(qubitOp,num_particles)
    shift = repulsion_energy

    return qubitOp, shift
def get_qubit_op(target_molecule):
    geometry, multiplicity, charge = generate_molecule_dict()
    driver = PySCFDriver(atom=geometry_convert(target_molecule),
                         unit=UnitsType.ANGSTROM,
                         charge=charge[target_molecule],
                         spin=0,
                         basis='sto3g')
    molecule = driver.run()
    repulsion_energy = molecule.nuclear_repulsion_energy
    num_particles = molecule.num_alpha + molecule.num_beta
    num_spin_orbitals = molecule.num_orbitals * 2
    one_RDM = make_one_rdm(target_molecule)
    w = calculate_noons(one_RDM)
    freeze_list, remove_list = generate_freeze_remove_list(w)
    remove_list = [x % molecule.num_orbitals for x in remove_list]
    freeze_list = [x % molecule.num_orbitals for x in freeze_list]
    remove_list = [x - len(freeze_list) for x in remove_list]
    remove_list += [
        x + molecule.num_orbitals - len(freeze_list) for x in remove_list
    ]
    freeze_list += [x + molecule.num_orbitals for x in freeze_list]
    ferOp = FermionicOperator(h1=molecule.one_body_integrals,
                              h2=molecule.two_body_integrals)
    ferOp, energy_shift = ferOp.fermion_mode_freezing(freeze_list)
    num_spin_orbitals -= len(freeze_list)
    num_particles -= len(freeze_list)
    ferOp = ferOp.fermion_mode_elimination(remove_list)
    num_spin_orbitals -= len(remove_list)
    qubitOp = ferOp.mapping(map_type='bravyi_kitaev', threshold=0.00000001)
    qubitOp = Z2Symmetries.two_qubit_reduction(qubitOp, num_particles)
    shift = energy_shift + repulsion_energy
    return qubitOp, num_particles, num_spin_orbitals, shift
    def test_particle_hole(self, atom, charge=0, spin=0, basis='sto3g', hf_method=HFMethodType.RHF):
        """ particle hole test """
        try:
            driver = PySCFDriver(atom=atom,
                                 unit=UnitsType.ANGSTROM,
                                 charge=charge,
                                 spin=spin,
                                 basis=basis,
                                 hf_method=hf_method)
        except QiskitChemistryError:
            self.skipTest('PYSCF driver does not appear to be installed')

        config = '{}, charge={}, spin={}, basis={}, {}'.format(atom, charge,
                                                               spin, basis,
                                                               hf_method.value)

        molecule = driver.run()
        fer_op = FermionicOperator(h1=molecule.one_body_integrals, h2=molecule.two_body_integrals)

        ph_fer_op, ph_shift = fer_op.particle_hole_transformation([molecule.num_alpha,
                                                                   molecule.num_beta])

        # ph_shift should be the electronic part of the hartree fock energy
        self.assertAlmostEqual(-ph_shift,
                               molecule.hf_energy-molecule.nuclear_repulsion_energy, msg=config)

        # Energy in original fer_op should same as ph transformed one added with ph_shift
        jw_op = fer_op.mapping('jordan_wigner')
        result = ExactEigensolver(jw_op).run()

        ph_jw_op = ph_fer_op.mapping('jordan_wigner')
        ph_result = ExactEigensolver(ph_jw_op).run()

        self.assertAlmostEqual(result['energy'], ph_result['energy']-ph_shift, msg=config)
Example #9
0
    def setUp(self):
        super().setUp()
        # np.random.seed(50)
        self.seed = 50
        aqua_globals.random_seed = self.seed
        try:
            driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735',
                                 unit=UnitsType.ANGSTROM,
                                 basis='sto3g')
        except QiskitChemistryError:
            self.skipTest('PYSCF driver does not appear to be installed')
            return

        molecule = driver.run()
        self.num_particles = molecule.num_alpha + molecule.num_beta
        self.num_spin_orbitals = molecule.num_orbitals * 2
        fer_op = FermionicOperator(h1=molecule.one_body_integrals,
                                   h2=molecule.two_body_integrals)
        map_type = 'PARITY'
        qubit_op = fer_op.mapping(map_type)
        self.qubit_op = Z2Symmetries.two_qubit_reduction(
            to_weighted_pauli_operator(qubit_op), self.num_particles)
        self.num_qubits = self.qubit_op.num_qubits
        self.init_state = HartreeFock(self.num_spin_orbitals,
                                      self.num_particles)
        self.var_form_base = None
Example #10
0
    def test_qpe(self, distance):
        """ qpe test """
        self.log.debug('Testing End-to-End with QPE on '
                       'H2 with inter-atomic distance %s.', distance)
        try:
            driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 {}'.format(distance),
                                 unit=UnitsType.ANGSTROM,
                                 charge=0,
                                 spin=0,
                                 basis='sto3g')
        except QiskitChemistryError:
            self.skipTest('PYSCF driver does not appear to be installed')

        molecule = driver.run()
        qubit_mapping = 'parity'
        fer_op = FermionicOperator(
            h1=molecule.one_body_integrals, h2=molecule.two_body_integrals)
        qubit_op = fer_op.mapping(map_type=qubit_mapping, threshold=1e-10)
        qubit_op = Z2Symmetries.two_qubit_reduction(qubit_op, 2)

        exact_eigensolver = ExactEigensolver(qubit_op, k=1)
        results = exact_eigensolver.run()
        reference_energy = results['energy']
        self.log.debug('The exact ground state energy is: %s', results['energy'])

        num_particles = molecule.num_alpha + molecule.num_beta
        two_qubit_reduction = True
        num_orbitals = qubit_op.num_qubits + \
            (2 if two_qubit_reduction else 0)

        num_time_slices = 1
        n_ancillae = 6

        state_in = HartreeFock(qubit_op.num_qubits, num_orbitals,
                               num_particles, qubit_mapping, two_qubit_reduction)
        iqft = Standard(n_ancillae)

        qpe = QPE(qubit_op, state_in, iqft, num_time_slices, n_ancillae,
                  expansion_mode='suzuki',
                  expansion_order=2, shallow_circuit_concat=True)
        backend = qiskit.BasicAer.get_backend('qasm_simulator')
        quantum_instance = QuantumInstance(backend, shots=100)
        result = qpe.run(quantum_instance)

        self.log.debug('eigvals:                  %s', result['eigvals'])
        self.log.debug('top result str label:     %s', result['top_measurement_label'])
        self.log.debug('top result in decimal:    %s', result['top_measurement_decimal'])
        self.log.debug('stretch:                  %s', result['stretch'])
        self.log.debug('translation:              %s', result['translation'])
        self.log.debug('final energy from QPE:    %s', result['energy'])
        self.log.debug('reference energy:         %s', reference_energy)
        self.log.debug('ref energy (transformed): %s',
                       (reference_energy + result['translation']) * result['stretch'])
        self.log.debug('ref binary str label:     %s',
                       decimal_to_binary(
                           (reference_energy + result['translation']) * result['stretch'],
                           max_num_digits=n_ancillae + 3, fractional_part_only=True))

        np.testing.assert_approx_equal(result['energy'], reference_energy, significant=2)
Example #11
0
def createPlot(exactGroundStateEnergy=-1.14,
               numberOfIterations=1000,
               bondLength=0.735,
               initialParameters=None,
               numberOfParameters=16,
               shotsPerPoint=1000,
               registerSize=12,
               map_type='jordan_wigner'):
    if initialParameters is None:
        initialParameters = np.random.rand(numberOfParameters)
    global qubitOp
    global qr_size
    global shots
    global values
    global plottingTime
    plottingTime = True
    shots = shotsPerPoint
    qr_size = registerSize
    optimizer = COBYLA(maxiter=numberOfIterations)
    iterations = []
    values = []
    for i in range(numberOfIterations):
        iterations.append(i + 1)

    #Build molecule with PySCF
    driver = PySCFDriver(atom="H .0 .0 .0; H .0 .0 " + str(bondLength),
                         unit=UnitsType.ANGSTROM,
                         charge=0,
                         spin=0,
                         basis='sto3g')
    molecule = driver.run()
    repulsion_energy = molecule.nuclear_repulsion_energy
    num_spin_orbitals = molecule.num_orbitals * 2
    num_particles = molecule.num_alpha + molecule.num_beta

    #Map fermionic operator to qubit operator and start optimization
    ferOp = FermionicOperator(h1=molecule.one_body_integrals,
                              h2=molecule.two_body_integrals)
    qubitOp = ferOp.mapping(map_type=map_type, threshold=0.00000001)
    sol_opt = optimizer.optimize(numberOfParameters,
                                 energy_opt,
                                 gradient_function=None,
                                 variable_bounds=None,
                                 initial_point=initialParameters)

    #Adjust values to obtain Energy Error
    for i in range(len(values)):
        values[i] = values[i] + repulsion_energy - exactGroundStateEnergy

    #Saving and Plotting Data
    filename = 'Energy Error - Iterations'
    with open(filename, 'wb') as f:
        pickle.dump([iterations, values], f)
    plt.plot(iterations, values)
    plt.ylabel('Energy Error')
    plt.xlabel('Iterations')
    plt.show()
    def test_readme_sample(self):
        """ readme sample test """
        # pylint: disable=import-outside-toplevel

        # --- Exact copy of sample code ----------------------------------------

        from qiskit.chemistry import FermionicOperator
        from qiskit.chemistry.drivers import PySCFDriver, UnitsType
        from qiskit.aqua.operators import Z2Symmetries

        # Use PySCF, a classical computational chemistry software
        # package, to compute the one-body and two-body integrals in
        # molecular-orbital basis, necessary to form the Fermionic operator
        driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735',
                             unit=UnitsType.ANGSTROM,
                             basis='sto3g')
        molecule = driver.run()
        num_particles = molecule.num_alpha + molecule.num_beta
        num_spin_orbitals = molecule.num_orbitals * 2

        # Build the qubit operator, which is the input to the VQE algorithm in Aqua
        ferm_op = FermionicOperator(h1=molecule.one_body_integrals,
                                    h2=molecule.two_body_integrals)
        map_type = 'PARITY'
        qubit_op = ferm_op.mapping(map_type)
        qubit_op = Z2Symmetries.two_qubit_reduction(qubit_op, num_particles)
        num_qubits = qubit_op.num_qubits

        # setup a classical optimizer for VQE
        from qiskit.aqua.components.optimizers import L_BFGS_B
        optimizer = L_BFGS_B()

        # setup the initial state for the variational form
        from qiskit.chemistry.components.initial_states import HartreeFock
        init_state = HartreeFock(num_qubits, num_spin_orbitals, num_particles)

        # setup the variational form for VQE
        from qiskit.aqua.components.variational_forms import RYRZ
        var_form = RYRZ(num_qubits, initial_state=init_state)

        # setup and run VQE
        from qiskit.aqua.algorithms import VQE
        algorithm = VQE(qubit_op, var_form, optimizer)

        # set the backend for the quantum computation
        from qiskit import Aer
        backend = Aer.get_backend('statevector_simulator')

        result = algorithm.run(backend)
        print(result['energy'])

        # ----------------------------------------------------------------------

        self.assertAlmostEqual(result['energy'], -1.8572750301938803, places=6)
Example #13
0
def get_LiH_qubit_op(dist):
    """ 
    Use the qiskit chemistry package to get the qubit Hamiltonian for LiH

    Parameters
    ----------
    dist : float
        The nuclear separations

    Returns
    -------
    qubitOp : qiskit.aqua.operators.WeightedPauliOperator
        Qiskit representation of the qubit Hamiltonian
    shift : float
        The ground state of the qubit Hamiltonian needs to be corrected by this amount of
        energy to give the real physical energy. This includes the replusive energy between
        the nuclei and the energy shift of the frozen orbitals.
    """
    driver = PySCFDriver(
        atom="Li .0 .0 .0; H .0 .0 " + str(dist),
        unit=UnitsType.ANGSTROM,
        charge=0,
        spin=0,
        basis='sto3g',
    )
    molecule = driver.run()
    freeze_list = [0]
    remove_list = [-3, -2]
    repulsion_energy = molecule.nuclear_repulsion_energy
    num_particles = molecule.num_alpha + molecule.num_beta
    num_spin_orbitals = molecule.num_orbitals * 2
    remove_list = [x % molecule.num_orbitals for x in remove_list]
    freeze_list = [x % molecule.num_orbitals for x in freeze_list]
    remove_list = [x - len(freeze_list) for x in remove_list]
    remove_list += [
        x + molecule.num_orbitals - len(freeze_list) for x in remove_list
    ]
    freeze_list += [x + molecule.num_orbitals for x in freeze_list]
    ferOp = FermionicOperator(h1=molecule.one_body_integrals,
                              h2=molecule.two_body_integrals)
    ferOp, energy_shift = ferOp.fermion_mode_freezing(freeze_list)
    num_spin_orbitals -= len(freeze_list)
    num_particles -= len(freeze_list)
    ferOp = ferOp.fermion_mode_elimination(remove_list)
    num_spin_orbitals -= len(remove_list)
    qubitOp = ferOp.mapping(map_type='parity', threshold=1E-8)
    #qubitOp = qubitOp.two_qubit_reduced_operator(num_particles)
    qubitOp = Z2Symmetries.two_qubit_reduction(qubitOp, num_particles)
    shift = repulsion_energy + energy_shift

    return qubitOp, shift
Example #14
0
def get_qubit_op(dist):
    driver = PySCFDriver(atom="H .0 .0 .0; H .0 .0 " + str(dist),
                         unit=UnitsType.ANGSTROM,
                         charge=0,
                         spin=0,
                         basis='sto3g')
    molecule = driver.run()
    nuc_energy = molecule.nuclear_repulsion_energy
    num_particles = molecule.num_alpha + molecule.num_beta
    num_spin_orbitals = molecule.num_orbitals * 2
    ferOp = FermionicOperator(h1=molecule.one_body_integrals,
                              h2=molecule.two_body_integrals)
    qubitOp = ferOp.mapping(map_type='parity', threshold=0.00000001)
    qubitOp = Z2Symmetries.two_qubit_reduction(qubitOp, num_particles)
    return qubitOp, num_particles, num_spin_orbitals, nuc_energy
def JW_H(systemData={'driver_string': 'Li 0.0 0.0 0.0; H 0.0 0.0 1.548', 'basis': 'sto3g'}):
                            
    driver = PySCFDriver(   atom=systemData["atomstring"],
                            basis=systemData["basis"]       )

    mol = driver.run()
    OB = mol.one_body_integrals
    TB = mol.two_body_integrals

    FerOp = FermionicOperator(OB, TB)
    mapping = FerOp.mapping('jordan_wigner')
    weights = [w[0] for w in mapping.paulis]
    operators = [w[1].to_label() for w in mapping.paulis]

    return nk.operator.PauliStrings(operators, weights)
def createPlot1(bondLengthMin=0.5,
                bondLengthMax=1.5,
                numberOfPoints=10,
                initialParameters=None,
                numberOfParameters=16,
                shotsPerPoint=1000,
                registerSize=12,
                map_type='jordan_wigner'):
    if initialParameters is None:
        initialParameters = np.random.rand(numberOfParameters)
    global qubitOp
    global qr_size
    global shots
    shots = shotsPerPoint
    qr_size = registerSize
    optimizer = COBYLA(maxiter=20)
    bondLengths = []
    values = []
    delta = (bondLengthMax - bondLengthMin) / numberOfPoints
    for i in range(numberOfPoints):
        bondLengths.append(bondLengthMin + i * delta)
    for bondLength in bondLengths:
        driver = PySCFDriver(atom="H .0 .0 .0; H .0 .0 " + str(bondLength),
                             unit=UnitsType.ANGSTROM,
                             charge=0,
                             spin=0,
                             basis='sto3g')
        molecule = driver.run()
        repulsion_energy = molecule.nuclear_repulsion_energy
        num_spin_orbitals = molecule.num_orbitals * 2
        num_particles = molecule.num_alpha + molecule.num_beta
        ferOp = FermionicOperator(h1=molecule.one_body_integrals,
                                  h2=molecule.two_body_integrals)
        qubitOp = ferOp.mapping(map_type=map_type, threshold=0.00000001)
        sol_opt = optimizer.optimize(numberOfParameters,
                                     energy_opt,
                                     gradient_function=None,
                                     variable_bounds=None,
                                     initial_point=initialParameters)
        values.append(sol_opt[1] + repulsion_energy)
    filename = 'Energy - BondLengths'
    with open(filename, 'wb') as f:
        pickle.dump([bondLengths, values], f)
    plt.plot(bondLengths, values)
    plt.ylabel('Ground State Energy')
    plt.xlabel('Bond Length')
    plt.show()
def load_qubitop_for_molecule(molecule_data):
    atom_list = [a[0] + ' ' + " ".join([str(elem) for elem in a[1]]) for a in molecule_data['geometry']]
    atom = "; ".join(atom_list) 
    #atom = 'Li .0 .0 .0; H .0 .0 3.9'
    basis = molecule_data['basis']
    transform = molecule_data['transform']
    electrons = molecule_data['electrons']
    active = molecule_data['active_orbitals']
    driver = PySCFDriver(atom=atom, unit=UnitsType.ANGSTROM, basis=basis, charge=0, spin=0)
    molecule = driver.run()
    num_particles = molecule.num_alpha + molecule.num_beta
    num_spin_orbitals = molecule.num_orbitals * 2
    #print("# of electrons: {}".format(num_particles))
    #print("# of spin orbitals: {}".format(num_spin_orbitals))
    freeze_list = [x for x in range(int(active/2), int(num_particles/2))]
    remove_list = [-x for x in range(active,molecule.num_orbitals-int(num_particles/2)+int(active/2))]
    #print(freeze_list)
    #print(remove_list)

    if transform == 'BK':
        map_type = 'bravyi_kitaev'
    elif transform == 'JW':
        map_type = 'jordan_wigner'
    else:
        map_type = 'parity'
    remove_list = [x % molecule.num_orbitals for x in remove_list]
    freeze_list = [x % molecule.num_orbitals for x in freeze_list]
    remove_list = [x - len(freeze_list) for x in remove_list]
    remove_list += [x + molecule.num_orbitals - len(freeze_list)  for x in remove_list]
    freeze_list += [x + molecule.num_orbitals for x in freeze_list]
    fermiOp = FermionicOperator(h1=molecule.one_body_integrals, h2=molecule.two_body_integrals)
    energy_shift = 0
    if len(freeze_list) > 0:
        fermiOp, energy_shift = fermiOp.fermion_mode_freezing(freeze_list)
    num_spin_orbitals -= len(freeze_list)
    num_particles -= len(freeze_list)
    if len(remove_list) > 0:
        fermiOp = fermiOp.fermion_mode_elimination(remove_list)
    num_spin_orbitals -= len(remove_list)
    qubitOp = fermiOp.mapping(map_type=map_type, threshold=0.00000001)
    if len(freeze_list) > 0 or len(remove_list) >0:
        qubitOp = Z2Symmetries.two_qubit_reduction(qubitOp, num_particles)

    #print(qubitOp.print_operators())
    num_spin_orbitals= qubitOp.num_qubits
    return molecule, qubitOp, map_type, num_particles, num_spin_orbitals
Example #18
0
def h2(dist=0.75):
    mol = PySCFDriver(atom=
                      'H 0.0 0.0 0.0;'\
                      'H 0.0 0.0 {}'.format(dist), unit=UnitsType.ANGSTROM, charge=0,
                      spin=0, basis='sto-3g')
    mol = mol.run()
    h1 = mol.one_body_integrals
    h2 = mol.two_body_integrals

    nuclear_repulsion_energy = mol.nuclear_repulsion_energy
    num_particles = mol.num_alpha + mol.num_beta + 0
    ferOp = FermionicOperator(h1=h1, h2=h2)
    qubitOp = ferOp.mapping(map_type='parity', threshold=0.00000001)
    qubitOp = Z2Symmetries.two_qubit_reduction(qubitOp, num_particles)

    cHam = op_converter.to_matrix_operator(qubitOp)
    cHam = cHam.dense_matrix + nuclear_repulsion_energy * numpy.identity(4)

    return cHam
Example #19
0
import time

nb = 12
h2 = np.random.random((nb, nb, nb, nb))
h1 = np.random.random((nb, nb))
#h2 = np.zeros((nb,nb,nb,nb))
#h1 = np.zeros((nb,nb))

#h2[0,1,2,3]=1

ferop_new = FermionicOperatorNBody([h1, h2])

tin = time.time()
qubitop_new = ferop_new.mapping('jordan_wigner')
tout = time.time()

print('execution time new = {}'.format(tout - tin))

ferop_old = FermionicOperator(h1, h2)

tin = time.time()
qubitop_old = ferop_old.mapping('jordan_wigner')
tout = time.time()

print('execution time old = {}'.format(tout - tin))

if qubitop_old == qubitop_new:
    print('CORRECT')
else:
    print('MISTAKE')
Example #20
0
    def run_real_qiskit(self):

        result = Result()

        # ----- Import libraries and initialize -----

        from qiskit.chemistry.drivers import PySCFDriver, UnitsType
        from qiskit.chemistry import QMolecule, FermionicOperator
        from qiskit.chemistry.core import Hamiltonian, TransformationType, QubitMappingType
        from qiskit.chemistry.transformations import FermionicTransformation

        self.init()

        self.driver = PySCFDriver(atom=self.convert_g_to_str(self.g),
                                  unit=UnitsType.ANGSTROM,
                                  charge=0,
                                  spin=0,
                                  max_cycle=5000,
                                  max_memory=1024 * 128,
                                  basis='sto3g')

        def load_molecule(filename):
            if os.path.exists(filename):
                print(f"Found {filename}. Loading...")
                molecule = QMolecule(filename)
                molecule.load()
            else:
                # Regenerate
                print(f"Couldn't find {filename}. Regenerating...")
                molecule = self.driver.run()
                molecule.save(filename)
            return molecule

        self.molecule = load_molecule(self.filename)

        # ----- Perform test -----

        # Build qubit operator (full)
        fermop = FermionicOperator(h1=self.molecule.one_body_integrals,
                                   h2=self.molecule.two_body_integrals)

        # Freeze
        energy_shift = 0
        if len(self.freeze_list) > 0:
            fermop, energy_shift = fermop.fermion_mode_freezing(
                self.freeze_list)

        # Rebase remove
        remove_list = [
            x - np.where(np.array(self.freeze_list) < x)[0].size
            for x in self.remove_list
        ]

        # Remove
        if len(self.remove_list) > 0:
            fermop = fermop.fermion_mode_elimination(remove_list)

        result.h1 = fermop.h1
        result.h2 = fermop.h2
        result.energy_shift = energy_shift

        # Generate qubit op
        qubitop = fermop.mapping('parity')
        #import pdb; pdb.set_trace()
        #qubitop = Z2Symmetries.two_qubit_reduction(qubitop, num_particles)

        # Generate results
        qubit_op_str = qubitop.print_details()

        # Write results to file
        results_dir = "results/old"
        output_file = "qubitop1.txt"

        pathlib.Path(results_dir).mkdir(parents=True, exist_ok=True)
        with open(os.path.join(results_dir, output_file), "w") as f:
            f.write(qubit_op_str)

        result.qubitop = qubitop

        return result
Example #21
0
        mol = gto.M(atom=atom, basis='sto-3g')

        O = get_ovlp(mol)
        X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O)))

        fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp)
        fer_op.transform(X)
    else:
        fer_op = FermionicOperator(h1=_q_.one_body_integrals,
                                   h2=_q_.two_body_integrals)

    # s = np.shape(fer_op.h1)
    # fer_op.h1 = np.zeros(s)
    # print(fer_op.h1)

    ref_op = fer_op.mapping('jordan_wigner')
    print(ref_op.print_operators())
    ee = ExactEigensolver(ref_op, k=1)
    ee_result = ee.run()
    temp_min_eigvals = ee_result['eigvals']
    print(temp_min_eigvals)
    exit(0)

    print("checking r matrices...")
    for r_matrix in r_matrices:
        temp_fer_op = copy.deepcopy(fer_op)
        temp_fer_op.transform(r_matrix)

        if np.all(np.isclose(np.abs(temp_fer_op.h1 - fer_op.h1), 0.0)) and \
                np.all(np.isclose(np.abs(temp_fer_op.h2 - fer_op.h2), 0.0)):
            print("r matrix is okay.")
Example #22
0
def number_operator(num_qubits):
    h1 = np.identity(num_qubits)
    op = FermionicOperator(h1)
    num_op = op.mapping('jordan_wigner')
    return num_op
# prepare fermionic hamiltonian with orbital freezing and eliminating, and then map to qubit hamiltonian
# and if PARITY mapping is selected, reduction qubits
energy_shift = 0.0
qubit_reduction = True if map_type == 'parity' else False

ferOp = FermionicOperator(h1=h1, h2=h2)
if len(freeze_list) > 0:
    ferOp, energy_shift = ferOp.fermion_mode_freezing(freeze_list)
    num_spin_orbitals -= len(freeze_list)
    num_particles -= len(freeze_list)
if len(remove_list) > 0:
    ferOp = ferOp.fermion_mode_elimination(remove_list)
    num_spin_orbitals -= len(remove_list)

qubitOp = ferOp.mapping(map_type=map_type, threshold=0.00000001)
qubitOp = qubitOp.two_qubit_reduced_operator(
    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,
Example #24
0
H_2 Hamilton integral with  1.43 UnitsType.BOHR = 0.7414 A
'''
driver = PySCFDriver(atom='H 0.0 0.0 0.0; H 0.0 0.0 1.41968',
                     unit=UnitsType.BOHR,
                     charge=0,
                     spin=0,
                     basis='sto3g')
molecule = driver.run()

print(molecule.one_body_integrals)
print(molecule.two_body_integrals)

ferOp = FermionicOperator(h1=molecule.one_body_integrals,
                          h2=molecule.two_body_integrals)

qubitOp = ferOp.mapping(map_type='parity', threshold=0.00000001)

# Obliczenie klasyczne
exact_eigensolver = ExactEigensolver(qubitOp, k=1)
ret = exact_eigensolver.run()
print('The classically computed energy is: {:.12f}'.format(
    ret['eigvals'][0].real))

backend = Aer.get_backend('statevector_simulator')

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

num_spin_orbitals = 4
num_particles = 2
Example #25
0
	# Build qubit operator (full)
	fermop = FermionicOperator(h1 = molecule.one_body_integrals, h2 = molecule.two_body_integrals)

	# Freeze
	fermop, energy_shift = fermop.fermion_mode_freezing(freeze_list)

	# Remove
	fermop = fermop.fermion_mode_elimination(remove_list)

	# Update variables
	num_spin_orbitals -= len(freeze_list)
	num_particles -= len(freeze_list)
	num_spin_orbitals -= len(remove_list)
	
	# Generate qubit op
	qubitop = fermop.mapping('parity')
	qubitop = Z2Symmetries.two_qubit_reduction(qubitop, num_particles)

	qubit_op_str = qubitop.print_details()
	open("results/old/qubitop1.txt", "w").write(qubit_op_str)
else:  # New
	fermop, energy_shift = FermionicOperator.construct_operator(molecule, freeze_list, remove_list)

	# Update variables
	num_spin_orbitals -= len(freeze_list)
	num_particles -= len(freeze_list)
	num_spin_orbitals -= len(remove_list)

	# Generate qubit op
	#import pdb; pdb.set_trace()
	qubitop = fermop.mapping('parity')
def createPlot3(minShots=50,
                stepSize=50,
                maxShots=1000,
                exactGroundStateEnergy=-1.14,
                totalNumberOfShots=10000,
                bondLength=0.735,
                initialParameters=None,
                numberOfParameters=16,
                registerSize=12,
                map_type='jordan_wigner'):
    if initialParameters is None:
        initialParameters = np.random.rand(numberOfParameters)
    global qubitOp
    global qr_size
    global shots
    global values
    qr_size = registerSize

    #Build Molecule and stuff
    driver = PySCFDriver(atom="H .0 .0 .0; H .0 .0 " + str(bondLength),
                         unit=UnitsType.ANGSTROM,
                         charge=0,
                         spin=0,
                         basis='sto3g')
    molecule = driver.run()
    repulsion_energy = molecule.nuclear_repulsion_energy
    num_spin_orbitals = molecule.num_orbitals * 2
    num_particles = molecule.num_alpha + molecule.num_beta
    ferOp = FermionicOperator(h1=molecule.one_body_integrals,
                              h2=molecule.two_body_integrals)
    qubitOp = ferOp.mapping(map_type=map_type, threshold=0.00000001)

    #create Shots Array
    shotValues = []
    numberOfDataPoints = math.floor((maxShots - minShots) / stepSize)
    for i in range(numberOfDataPoints):
        shotValues.append(minShots + i * stepSize)

    values = []
    print(shotValues)
    for shotsPerPoint in shotValues:
        shots = shotsPerPoint
        if shotsPerPoint <= totalNumberOfShots:
            optimizer = COBYLA(maxiter=math.floor(totalNumberOfShots /
                                                  shotsPerPoint))
            sol_opt = optimizer.optimize(numberOfParameters,
                                         energy_opt,
                                         gradient_function=None,
                                         variable_bounds=None,
                                         initial_point=initialParameters)
            values.append(sol_opt[1] + repulsion_energy)
        else:
            raise Exception('Error: Total number of shots too small.')

    #Calculate Energy Error
    for i in range(len(values)):
        values[i] = values[i] + repulsion_energy - exactGroundStateEnergy

    #Saving and Plotting Data
    filename = 'Energy Error - Number of Shots'
    with open(filename, 'wb') as f:
        pickle.dump([shotValues, values], f)
    plt.plot(shotValues, values)
    plt.ylabel('Energy Error')
    plt.xlabel('Number of Shots')
    plt.show()
Example #27
0
    def get_rdm(self):
        """
            Obtain the 1- and 2-RDM matrices for given variational parameters.
            This makes sense for problem decomposition methods if these amplitudes are the ones
            that minimizes energy.

        Returns:
            (numpy.array, numpy.array): One & two-particle RDMs (rdm1_np & rdm2_np, float64).
        Raises:
            RuntimeError: If no simulation has been run before calling this method.
        """

        if len(self.optimized_amplitudes) == 0:
            raise RuntimeError(
                'Cannot retrieve RDM because method "Simulate" needs to run first.'
            )

        # Initialize RDM matrices and other work arrays
        n_orbital = self.num_orbitals
        one_rdm = np.zeros(tuple([n_orbital] * 2))
        two_rdm = np.zeros(tuple([n_orbital] * 4))

        tmp_h1 = np.zeros(self.one_body_integrals.shape)
        tmp_h2 = np.zeros(self.two_body_integrals.shape)

        # h1 and h2 are the one- and two-body integrals for the whole system
        # They are in spin-orbital basis, seemingly with all alpha orbitals first and then all beta second
        # eg lines and columns refer to 1a, 2a, 3a ... , then 1b, 2b, 3b ....

        # Compute values for 1-RDM matrix
        # -------------------------------
        for mol_coords, _ in np.ndenumerate(one_rdm):

            rdm_contribution = 0.
            one_rdm[mol_coords] = 0.0

            # Find all entries of one-RDM that contributes to the computation of that entry of one-rdm
            for spin_coords in product(
                [mol_coords[0], mol_coords[0] + self.num_spin_orbitals // 2],
                [mol_coords[1], mol_coords[1] + self.num_spin_orbitals // 2]):

                # Skip values too close to zero
                if abs(self.one_body_integrals[spin_coords]) < 1e-10:
                    continue

                # Ignore all Fermionic Hamiltonian term except one
                tmp_h1[spin_coords] = 1.
                coeff = -1. if (spin_coords[0] // n_orbital !=
                                spin_coords[1] // n_orbital) else 1.

                # Accumulate contribution of the term to RDM value
                tmp_ferOp = FermionicOperator(h1=tmp_h1, h2=tmp_h2)
                tmp_qubitOp = tmp_ferOp.mapping(map_type=self.map_type,
                                                threshold=1e-8)
                tmp_qubitOp.chop(10**-10)
                if tmp_qubitOp.num_qubits == 0:
                    continue
                self.qubit_hamiltonian = tmp_qubitOp
                ene_temp = self.simulate(
                    self.optimized_amplitudes) - self.nuclear_repulsion_energy
                rdm_contribution += coeff * ene_temp

                # Reset entries of tmp_h1
                tmp_h1[spin_coords] = 0.

            # Write the value to the 1-RDM matrix
            one_rdm[mol_coords] = rdm_contribution

        # Compute values for 2-RDM matrix
        # -------------------------------
        for mol_coords, _ in np.ndenumerate(two_rdm):

            rdm_contribution = 0.
            two_rdm[mol_coords] = 0.0

            # Find all entries of h1 that contributes to the computation of that entry of one-rdm
            for spin_coords in product(
                [mol_coords[0], mol_coords[0] + self.num_spin_orbitals // 2],
                [mol_coords[1], mol_coords[1] + self.num_spin_orbitals // 2],
                [mol_coords[2], mol_coords[2] + self.num_spin_orbitals // 2],
                [mol_coords[3], mol_coords[3] + self.num_spin_orbitals // 2]):

                # Skip values too close to zero
                if abs(self.two_body_integrals[spin_coords]) < 1e-10:
                    continue

                # Set entries to the right coefficient for tmp_h1
                tmp_h2[spin_coords] = 1.

                # Count alphas and betas. If odd, coefficient is -1, else its 1.
                # Or maybe its a quadrant thin? Check with Yukio ?
                n_betas_total = sum(
                    [spin_orb // n_orbital for spin_orb in spin_coords])
                if (n_betas_total == 0) or (n_betas_total == 4):
                    coeff = 2.0
                elif n_betas_total == 2:
                    coeff = -1.0 if (spin_coords[0] // n_orbital !=
                                     spin_coords[1] // n_orbital) else 1.0

                # Accumulate contribution of the term to RDM value
                tmp_ferOp = FermionicOperator(h1=tmp_h1, h2=tmp_h2)
                tmp_qubitOp = tmp_ferOp.mapping(map_type=self.map_type,
                                                threshold=1e-8)
                tmp_qubitOp.chop(10**-10)
                if tmp_qubitOp.num_qubits == 0:
                    continue

                self.qubit_hamiltonian = tmp_qubitOp
                ene_temp = self.simulate(
                    self.optimized_amplitudes) - self.nuclear_repulsion_energy
                rdm_contribution += coeff * ene_temp

                # Reset entries of tmp_h2
                tmp_h2[spin_coords] = 0.

            # Write the value to the 1-RDM matrix
            two_rdm[mol_coords] = rdm_contribution

        return one_rdm, two_rdm
Example #28
0
class QiskitParametricSolver(ParametricQuantumSolver):
    """
        Performs an energy estimation for a molecule with a supprted parametric circuit.
        Can be initialized with PySCF objects (molecule and mean-field)
    """
    class Ansatze(Enum):
        """ Enumeration of the ansatz circuits that are supported."""
        UCCSD = 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 = []

    def simulate(self, var_params):
        """ Evaluate the parameterized circuit for the input amplitudes.

        Args:
            var_params (list): The initial amplitudes (float64).
        Returns:
            float64: The total energy (energy).
        Raise:
            ValueError: If the dimension of the amplitude list is incorrect.
        """
        if len(var_params) != self.amplitude_dimension:
            raise ValueError("Incorrect dimension for amplitude list.")

        # Use the Qiskit VQE class to perform a single energy evaluation
        from qiskit.aqua.components.optimizers import COBYLA
        cobyla = COBYLA(maxiter=0)
        vqe = VQE(self.qubit_hamiltonian,
                  self.var_form,
                  cobyla,
                  initial_point=var_params)
        quantum_instance = QuantumInstance(backend=self.backend, shots=1000000)
        results = vqe.run(quantum_instance)

        energy = results['eigvals'][0] + self.nuclear_repulsion_energy

        # Save the amplitudes so we have the optimal ones for RDM calculation
        self.optimized_amplitudes = var_params

        return energy

    def get_rdm(self):
        """
            Obtain the 1- and 2-RDM matrices for given variational parameters.
            This makes sense for problem decomposition methods if these amplitudes are the ones
            that minimizes energy.

        Returns:
            (numpy.array, numpy.array): One & two-particle RDMs (rdm1_np & rdm2_np, float64).
        Raises:
            RuntimeError: If no simulation has been run before calling this method.
        """

        if len(self.optimized_amplitudes) == 0:
            raise RuntimeError(
                'Cannot retrieve RDM because method "Simulate" needs to run first.'
            )

        # Initialize RDM matrices and other work arrays
        n_orbital = self.num_orbitals
        one_rdm = np.zeros(tuple([n_orbital] * 2))
        two_rdm = np.zeros(tuple([n_orbital] * 4))

        tmp_h1 = np.zeros(self.one_body_integrals.shape)
        tmp_h2 = np.zeros(self.two_body_integrals.shape)

        # h1 and h2 are the one- and two-body integrals for the whole system
        # They are in spin-orbital basis, seemingly with all alpha orbitals first and then all beta second
        # eg lines and columns refer to 1a, 2a, 3a ... , then 1b, 2b, 3b ....

        # Compute values for 1-RDM matrix
        # -------------------------------
        for mol_coords, _ in np.ndenumerate(one_rdm):

            rdm_contribution = 0.
            one_rdm[mol_coords] = 0.0

            # Find all entries of one-RDM that contributes to the computation of that entry of one-rdm
            for spin_coords in product(
                [mol_coords[0], mol_coords[0] + self.num_spin_orbitals // 2],
                [mol_coords[1], mol_coords[1] + self.num_spin_orbitals // 2]):

                # Skip values too close to zero
                if abs(self.one_body_integrals[spin_coords]) < 1e-10:
                    continue

                # Ignore all Fermionic Hamiltonian term except one
                tmp_h1[spin_coords] = 1.
                coeff = -1. if (spin_coords[0] // n_orbital !=
                                spin_coords[1] // n_orbital) else 1.

                # Accumulate contribution of the term to RDM value
                tmp_ferOp = FermionicOperator(h1=tmp_h1, h2=tmp_h2)
                tmp_qubitOp = tmp_ferOp.mapping(map_type=self.map_type,
                                                threshold=1e-8)
                tmp_qubitOp.chop(10**-10)
                if tmp_qubitOp.num_qubits == 0:
                    continue
                self.qubit_hamiltonian = tmp_qubitOp
                ene_temp = self.simulate(
                    self.optimized_amplitudes) - self.nuclear_repulsion_energy
                rdm_contribution += coeff * ene_temp

                # Reset entries of tmp_h1
                tmp_h1[spin_coords] = 0.

            # Write the value to the 1-RDM matrix
            one_rdm[mol_coords] = rdm_contribution

        # Compute values for 2-RDM matrix
        # -------------------------------
        for mol_coords, _ in np.ndenumerate(two_rdm):

            rdm_contribution = 0.
            two_rdm[mol_coords] = 0.0

            # Find all entries of h1 that contributes to the computation of that entry of one-rdm
            for spin_coords in product(
                [mol_coords[0], mol_coords[0] + self.num_spin_orbitals // 2],
                [mol_coords[1], mol_coords[1] + self.num_spin_orbitals // 2],
                [mol_coords[2], mol_coords[2] + self.num_spin_orbitals // 2],
                [mol_coords[3], mol_coords[3] + self.num_spin_orbitals // 2]):

                # Skip values too close to zero
                if abs(self.two_body_integrals[spin_coords]) < 1e-10:
                    continue

                # Set entries to the right coefficient for tmp_h1
                tmp_h2[spin_coords] = 1.

                # Count alphas and betas. If odd, coefficient is -1, else its 1.
                # Or maybe its a quadrant thin? Check with Yukio ?
                n_betas_total = sum(
                    [spin_orb // n_orbital for spin_orb in spin_coords])
                if (n_betas_total == 0) or (n_betas_total == 4):
                    coeff = 2.0
                elif n_betas_total == 2:
                    coeff = -1.0 if (spin_coords[0] // n_orbital !=
                                     spin_coords[1] // n_orbital) else 1.0

                # Accumulate contribution of the term to RDM value
                tmp_ferOp = FermionicOperator(h1=tmp_h1, h2=tmp_h2)
                tmp_qubitOp = tmp_ferOp.mapping(map_type=self.map_type,
                                                threshold=1e-8)
                tmp_qubitOp.chop(10**-10)
                if tmp_qubitOp.num_qubits == 0:
                    continue

                self.qubit_hamiltonian = tmp_qubitOp
                ene_temp = self.simulate(
                    self.optimized_amplitudes) - self.nuclear_repulsion_energy
                rdm_contribution += coeff * ene_temp

                # Reset entries of tmp_h2
                tmp_h2[spin_coords] = 0.

            # Write the value to the 1-RDM matrix
            two_rdm[mol_coords] = rdm_contribution

        return one_rdm, two_rdm

    def default_initial_var_parameters(self):
        """ Returns initial variational parameters for a VQE simulation.

        Returns initial variational parameters for the circuit that is generated
        for a given ansatz.

        Returns:
            list: Initial parameters.
        """
        if self.ansatz == self.__class__.Ansatze.UCCSD:
            return self.var_form.preferred_init_points
        else:
            raise RuntimeError(
                "Unsupported ansatz for automatic parameter generation")
Example #29
0
from qiskit.chemistry.drivers import PySCFDriver, UnitsType

t_initial = time.time()

distance = 0.735
driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 {}'.format(distance),
                     unit=UnitsType.ANGSTROM,
                     charge=0,
                     spin=0,
                     basis='sto3g')
molecule = driver.run()

qubit_mapping = 'jordan_wigner'
fer_op = FermionicOperator(h1=molecule.one_body_integrals,
                           h2=molecule.two_body_integrals)
qubit_op = fer_op.mapping(map_type=qubit_mapping,
                          threshold=1e-10).two_qubit_reduced_operator(2)

exact_eigensolver = ExactEigensolver(qubit_op, k=1)
result_ee = exact_eigensolver.run()
reference_energy = result_ee['energy']
print('The exact ground state energy is: {} eV'.format(result_ee['energy'] *
                                                       27.21138506))

num_particles = molecule.num_alpha + molecule.num_beta
two_qubit_reduction = (qubit_mapping == 'parity')
num_orbitals = qubit_op.num_qubits + (2 if two_qubit_reduction else 0)

print('Number of qubits: ', qubit_op.num_qubits)

num_time_slices = 50
n_ancillae = 8
Example #30
0
    nbeta = num_h // 2
    nalpha = num_h - nbeta
    spin = nalpha - nbeta
    return atom_list, spin


atoms = hydrogen_chain(num_h)[0]
driver = PySCFDriver(atom=atoms, unit=UnitsType.ANGSTROM, basis='sto3g')
molecule = driver.run()
num_particles = molecule.num_alpha + molecule.num_beta
num_spin_orbitals = molecule.num_orbitals * 2
# Build the qubit operator, which is the input to the VQE algorithm in Aqua
ferm_op = FermionicOperator(h1=molecule.one_body_integrals,
                            h2=molecule.two_body_integrals)
map_type = 'PARITY'
qubit_op = ferm_op.mapping(map_type)
qubit_op = Z2Symmetries.two_qubit_reduction(qubit_op, num_particles)
num_qubits = qubit_op.num_qubits
print("Num qubits: %s" % num_qubits)
# setup a classical optimizer for VQE
#from qiskit.aqua.components.optimizers import L_BFGS_B
#optimizer = L_BFGS_B()
# optimizer = SPSA(maxiter=200)
optimizer = COBYLA(maxiter=1, tol=1e3)
# setup the initial state for the variational form
from qiskit.chemistry.components.initial_states import HartreeFock

init_state = HartreeFock(num_spin_orbitals, num_particles)
# setup the variational form for VQE
from qiskit.circuit.library import TwoLocal