Exemple #1
0
    def test_eval_hamiltonian_pauli_list(self):
        """
        Test of trial_circuit_ry and eval_hamiltonian with a pauli list
        """
        ham_name = self._get_resource_path(
            "../performance/H2/H2Equilibrium.txt")
        pauli_list = Hamiltonian_from_file(ham_name)
        n = 2
        m = 6
        device = 'local_statevector_simulator'

        theta = np.array([
            -0.607547697211, -0.126136414606, -0.684606358705, 0.928714748593,
            -1.84440103405, -0.467002424077, 2.29249034315, 0.488810054396,
            0.710266990661, 1.05553444322, 0.0540731003458, 0.257953416342,
            0.588281649703, 0.885244238613, -1.01700702421, -0.133693031283,
            -0.438185501332, 0.493443494428, -0.199009119848, -1.27498360732,
            0.293494154438, 0.108950311827, 0.031726785859, 1.27263986303
        ])
        entangler_map = {0: [1]}

        energy = eval_hamiltonian(
            QuantumProgram(), pauli_list,
            trial_circuit_ry(n, m, theta, entangler_map, None, False), 1,
            device)
        np.testing.assert_almost_equal(
            -0.45295043823057191 + 3.3552033732997923e-18j, energy)
Exemple #2
0
    def test_group_paulis(self):
        """ qiskit.tools.apps.optimization.group_paulis function"""
        ham_name = self._get_resource_path("../performance/H2/H2Equilibrium.txt")
        zz = np.array([0, 0])
        oo = np.array([1, 1])

        pauli_list = Hamiltonian_from_file(ham_name)
        pauli_list_grouped = group_paulis(pauli_list)

        self.assertEqual(len(pauli_list_grouped), 2)
        r0 = [i[0] for i in pauli_list_grouped]
        r1 = [i[1] for i in pauli_list_grouped]

        self.assertEqual(len(r0), 2)
        r00 = [i[0] for i in r0]
        r01 = [i[1] for i in r0]
        e01 = [Pauli(oo, zz), Pauli(zz, oo)]
        self.assertEqual([0, 0], r00)
        self.assertEqual(e01, r01)

        self.assertEqual(len(r1), 2)
        r10 = [i[0] for i in r1]
        r11 = [i[1] for i in r1]
        e11 = [Pauli(oo, zz), Pauli(zz, oo)]
        self.assertEqual([0.011279956224107712, 0.18093133934472627], r10)
        self.assertEqual(e11, r11)

        expected_stout = ("Post Rotations of TPB set 0:\nZZ\n0\n\nZZ\n0.0112800\n"
                          "II\n-1.0523761\nZI\n0.3979357\nIZ\n"
                          "0.3979357\n\n\nPost Rotations of TPB set 1:\nXX\n0\n\n"
                          "XX\n0.1809313")
        with patch('sys.stdout', new=StringIO()) as fakeOutput:
            print_pauli_list_grouped(pauli_list_grouped)

        self.assertMultiLineEqual(fakeOutput.getvalue().strip(), expected_stout)
Exemple #3
0
    def test_hamiltonian(self):
        # printing an example from a H2 file
        hfile = self._get_resource_path("H2Equilibrium.txt")
        hamiltonian = make_Hamiltonian(Hamiltonian_from_file(hfile))
        self.log.info(hamiltonian)
        # [[-0.24522469381221926 0 0 0.18093133934472627 ]
        # [0 -1.0636560168497590 0.18093133934472627 0]
        # [0 0.18093133934472627 -1.0636560168497592 0]
        # [0.18093133934472627 0 0 -1.8369675149908681]]
        self.assertSequenceEqual([str(i) for i in hamiltonian[0]],
                                 ['(-0.245224693812+0j)', '0j', '0j', '(0.180931339345+0j)'])
        self.assertSequenceEqual([str(i) for i in hamiltonian[1]],
                                 ['0j', '(-1.06365601685+0j)', '(0.180931339345+0j)', '0j'])
        self.assertSequenceEqual([str(i) for i in hamiltonian[2]],
                                 ['0j', '(0.180931339345+0j)', '(-1.06365601685+0j)', '0j'])
        self.assertSequenceEqual([str(i) for i in hamiltonian[3]],
                                 ['(0.180931339345+0j)', '0j', '0j', '(-1.83696751499+0j)'])

        # printing an example from a graph input
        n = 3
        v0 = np.zeros(n)
        v0[2] = 1
        v1 = np.zeros(n)
        v1[0] = 1
        v1[1] = 1
        v2 = np.zeros(n)
        v2[0] = 1
        v2[2] = 1
        v3 = np.zeros(n)
        v3[1] = 1
        v3[2] = 1

        pauli_list = [(1, Pauli(v0, np.zeros(n))), (1, Pauli(v1, np.zeros(n))),
                      (1, Pauli(v2, np.zeros(n))), (1, Pauli(v3, np.zeros(n)))]
        a = make_Hamiltonian(pauli_list)
        self.log.info(a)

        w, v = la.eigh(a, eigvals=(0, 0))
        self.log.info(w)
        self.log.info(v)

        data = {'000': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'001': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'010': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'011': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'100': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'101': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'110': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'111': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
Exemple #4
0
def vqe(molecule='H2', depth=6, max_trials=200, shots=1):
    if molecule == 'H2':
        n_qubits = 2
        Z1 = 1
        Z2 = 1
        min_distance = 0.2
        max_distance = 4

    elif molecule == 'LiH':
        n_qubits = 4
        Z1 = 1
        Z2 = 3
        min_distance = 0.5
        max_distance = 5

    else:
        raise QISKitError("Unknown molecule for VQE.")

    # Read Hamiltonian
    ham_name = os.path.join(os.path.dirname(__file__),
                            molecule + '/' + molecule + 'Equilibrium.txt')
    pauli_list = Hamiltonian_from_file(ham_name)
    H = make_Hamiltonian(pauli_list)

    # Exact Energy
    exact = np.amin(la.eig(H)[0]).real
    print('The exact ground state energy is: {}'.format(exact))

    # Optimization
    device = 'qasm_simulator'
    if shots == 1:
        device = 'statevector_simulator'

    if 'statevector' not in device:
        H = group_paulis(pauli_list)

    entangler_map = get_backend(device).configuration()['coupling_map']

    if entangler_map == 'all-to-all':
        entangler_map = {i: [j for j in range(n_qubits) if j != i] for i in range(n_qubits)}
    else:
        entangler_map = mapper.coupling_list2dict(entangler_map)

    initial_theta = np.random.randn(2 * n_qubits * depth)   # initial angles
    initial_c = 0.01                                        # first theta perturbations
    target_update = 2 * np.pi * 0.1                         # aimed update on first trial
    save_step = 20                                          # print optimization trajectory

    cost = partial(cost_function, H, n_qubits, depth, entangler_map, shots, device)

    SPSA_params, circuits_cal = SPSA_calibration(cost, initial_theta, initial_c,
                                                 target_update, stat=25)
    output, circuits_opt = SPSA_optimization(cost, initial_theta, SPSA_params, max_trials,
                                             save_step, last_avg=1)

    return circuits_cal + circuits_opt
Exemple #5
0
    def test_hamiltonian(self):
        # printing an example from a H2 file
        hfile = self._get_resource_path("H2Equilibrium.txt")
        self.log.info(make_Hamiltonian(Hamiltonian_from_file(hfile)))

        # printing an example from a graph input
        n = 3
        v0 = np.zeros(n)
        v0[2] = 1
        v1 = np.zeros(n)
        v1[0] = 1
        v1[1] = 1
        v2 = np.zeros(n)
        v2[0] = 1
        v2[2] = 1
        v3 = np.zeros(n)
        v3[1] = 1
        v3[2] = 1

        pauli_list = [(1, Pauli(v0, np.zeros(n))), (1, Pauli(v1, np.zeros(n))),
                      (1, Pauli(v2, np.zeros(n))), (1, Pauli(v3, np.zeros(n)))]
        a = make_Hamiltonian(pauli_list)
        self.log.info(a)

        w, v = la.eigh(a, eigvals=(0, 0))
        self.log.info(w)
        self.log.info(v)

        data = {'000': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'001': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'010': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'011': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'100': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'101': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'110': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'111': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
Exemple #6
0
    def test_hamiltonian(self):
        # pylint: disable=unexpected-keyword-arg
        # printing an example from a H2 file
        hfile = self._get_resource_path("H2Equilibrium.txt")
        hamiltonian = make_Hamiltonian(Hamiltonian_from_file(hfile))
        self.log.info(hamiltonian)
        # [[-0.24522469381221926 0 0 0.18093133934472627 ]
        # [0 -1.0636560168497590 0.18093133934472627 0]
        # [0 0.18093133934472627 -1.0636560168497592 0]
        # [0.18093133934472627 0 0 -1.8369675149908681]]

        expected_result = [
            [(-0.245224693812+0j), 0j, 0j, (0.180931339345+0j)],
            [0j, (-1.06365601685+0j), (0.180931339345+0j), 0j],
            [0j, (0.180931339345+0j), (-1.06365601685+0j), 0j],
            [(0.180931339345+0j), 0j, 0j, (-1.83696751499+0j)]
        ]

        for i in range(4):
            with self.subTest(i=i):
                for result, expected in zip(hamiltonian[i], expected_result[i]):
                    self.assertAlmostEqual(result, expected)

        # printing an example from a graph input
        n = 3
        v0 = np.zeros(n)
        v0[2] = 1
        v1 = np.zeros(n)
        v1[0] = 1
        v1[1] = 1
        v2 = np.zeros(n)
        v2[0] = 1
        v2[2] = 1
        v3 = np.zeros(n)
        v3[1] = 1
        v3[2] = 1

        pauli_list = [(1, Pauli(v0, np.zeros(n))), (1, Pauli(v1, np.zeros(n))),
                      (1, Pauli(v2, np.zeros(n))), (1, Pauli(v3, np.zeros(n)))]
        a = make_Hamiltonian(pauli_list)
        self.log.info(a)

        w, v = la.eigh(a, eigvals=(0, 0))
        self.log.info(w)
        self.log.info(v)

        data = {'000': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'001': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'010': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'011': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'100': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'101': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'110': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
        data = {'111': 10}
        self.log.info(Energy_Estimate(data, pauli_list))
Exemple #7
0
def two_qubit_reduction(ham_in, m, out_file=None, threshold=0.000000000001):
    """
    Eliminates the central and last qubit in a list of Pauli that has
    diagonal operators (Z,I) at those positions.abs

    It can be used to taper two qubits in parity and binary-tree mapped
    fermionic Hamiltonians when the spin orbitals are ordered in two spin
    sectors, according to the number of particles in the system.

    Args:
        ham_in (list): a list of Paulis representing the mapped fermionic
            Hamiltonian
        m (int): number of fermionic particles
        out_file (string or None): name of the optional file to write the Pauli
            list on
        threshold (float): threshold for Pauli simplification
    Returns:
        list: A tapered Hamiltonian in the form of list of Paulis with
            coefficients
    """
    ham_out = []
    if m % 4 == 0:
        par_1 = 1
        par_2 = 1
    elif m % 4 == 1:
        par_1 = -1
        par_2 = -1    # could be also +1, +1/-1 are  spin-parity sectors
    elif m % 4 == 2:
        par_1 = 1
        par_2 = -1
    else:
        par_1 = -1
        par_2 = -1    # could be also +1, +1/-1 are  spin-parity sectors
    if isinstance(ham_in, str):
        # conversion from Hamiltonian text file to pauli_list
        ham_in = Hamiltonian_from_file(ham_in)
    # number of qubits
    n = len(ham_in[0][1].v)
    for pauli_term in ham_in:  # loop over Pauli terms
        coeff_out = pauli_term[0]
        # Z operator encountered at qubit n/2-1
        if pauli_term[1].v[n // 2 -
                           1] == 1 and pauli_term[1].w[n // 2 - 1] == 0:
            coeff_out = par_2 * coeff_out
        # Z operator encountered at qubit n-1
        if pauli_term[1].v[n - 1] == 1 and pauli_term[1].w[n - 1] == 0:
            coeff_out = par_1 * coeff_out
        v_temp = []
        w_temp = []
        for j in range(n):
            if j != n // 2 - 1 and j != n - 1:
                v_temp.append(pauli_term[1].v[j])
                w_temp.append(pauli_term[1].w[j])
        pauli_term_out = [coeff_out, Pauli(v_temp, w_temp)]
        ham_out = pauli_term_append(pauli_term_out, ham_out, threshold)

    ####################################################################
    # ################          WRITE TO FILE         ##################
    ####################################################################

    if out_file is not None:
        out_stream = open(out_file, 'w')
        for pauli_term in ham_out:
            out_stream.write(pauli_term[1].to_label() + '\n')
            out_stream.write('%.15f' % pauli_term[0].real + '\n')
        out_stream.close()
    return ham_out
Exemple #8
0
    def test_optimization_of_H2_at_bond_length(self):
        """From chemistry tutorial, but shorter.

        https://github.com/QISKit/qiskit-tutorial/blob/master/\
        4_applications/quantum_chemistry.ipynb#Optimization-of-H2-at-bond-length but shorter."""
        n = 2
        m = 6
        device = 'local_statevector_simulator'

        np.random.seed(42)
        initial_theta = np.random.randn(2 * n * m)
        entangler_map = {
            0: [1]
        }  # the map of two-qubit gates with control at key and target at values
        shots = 1
        max_trials = 1
        ham_name = self._get_resource_path(
            "../performance/H2/H2Equilibrium.txt")

        # Exact Energy
        pauli_list = Hamiltonian_from_file(ham_name)
        H = make_Hamiltonian(pauli_list)
        exact = np.amin(la.eig(H)[0]).real
        self.log.info('The exact ground state energy is: %s', exact)
        self.assertEqual(exact, -1.8572746704950902)

        # Optimization
        Q_program = QuantumProgram()

        def cost_function(Q_program, H, n, m, entangler_map, shots, device,
                          theta):
            # pylint: disable=missing-docstring
            return eval_hamiltonian(
                Q_program, H,
                trial_circuit_ryrz(n, m, theta, entangler_map, None, False),
                shots, device).real

        initial_c = 0.01
        target_update = 2 * np.pi * 0.1

        expected_stout = ("calibration step # 0 of 1\n"
                          "calibrated SPSA_parameters[0] is 2.5459894")
        with patch('sys.stdout', new=StringIO()) as fakeOutput:
            SPSA_params = SPSA_calibration(
                partial(cost_function, Q_program, H, n, m, entangler_map,
                        shots, device), initial_theta, initial_c,
                target_update, 1)
        self.assertMultiLineEqual(fakeOutput.getvalue().strip(),
                                  expected_stout)

        expected_stout = ("objective function at theta+ for step # 0\n"
                          "-1.0909948\n"
                          "objective function at theta- for step # 0\n"
                          "-1.0675805\n"
                          "Final objective function is: -1.2619548")
        with patch('sys.stdout', new=StringIO()) as fakeOutput:
            output = SPSA_optimization(
                partial(cost_function, Q_program, H, n, m, entangler_map,
                        shots, device), initial_theta, SPSA_params, max_trials)

        self.assertMultiLineEqual(fakeOutput.getvalue().strip(),
                                  expected_stout)

        output1 = np.array([
            -2.48391736629, 2.84236721813, -2.3329429812, 4.50366137571,
            -3.21478489403, -3.21476847625, 4.55984433481, -2.21319679015,
            2.51115713337, 3.52319156289, 2.51721382649, 2.51490176573,
            3.22259379087, 1.06735127465, 1.25571368679, 2.41834399006,
            1.96780039897, 3.2948788519, 2.07260744378, -4.39293522064,
            -1.51498275038, 2.75485521882, 3.04815972399, 1.55588333309
        ])
        output4 = np.array([
            0.486714153011, -0.128264301171, 0.637688538101, 1.53302985641,
            -0.244153374723, -0.244136956949, 1.58921281551, 0.757434729153,
            -0.459474385935, 0.552560043586, -0.453417692812, -0.45572975357,
            0.251962271566, -1.90328024466, -1.71491783251, -0.552287529241,
            -1.00283112033, 0.324247332595, -0.898024075521, -1.42230370134,
            1.45564876892, -0.215776300487, 0.0775282046879, -1.41474818621
        ])
        output5 = np.array([
            0.506714153011, -0.148264301171, 0.657688538101, 1.51302985641,
            -0.224153374723, -0.224136956949, 1.56921281551, 0.777434729153,
            -0.479474385935, 0.532560043586, -0.473417692812, -0.47572975357,
            0.231962271566, -1.92328024466, -1.73491783251, -0.572287529241,
            -1.02283112033, 0.304247332595, -0.918024075521, -1.40230370134,
            1.47564876892, -0.235776300487, 0.0575282046879, -1.43474818621
        ])

        self.assertEqual(6, len(output))
        np.testing.assert_almost_equal(-1.2619547992193472, output[0])
        self.assertEqual(output1.all(), output[1].all())
        np.testing.assert_almost_equal([-1.0909948471209499], output[2])
        np.testing.assert_almost_equal([-1.0675805189515357], output[3])
        self.assertEqual(1, len(output[4]))
        self.assertEqual(output4.all(), output[4][0].all())
        self.assertEqual(output5.all(), output[5][0].all())
def two_qubit_reduction(ham_in, m, out_file=None, threshold=0.000000000001):
    """
    This function takes in a mapped fermionic Hamiltonian with an even number of modes n, obtained with the parity (for every even n) or binary-tree mapping (in case the number of modes is a power of 2, n=2^k, k integer) and removes two qubits at positions n/2,n according to the total number of particles m.


    ham_in can be both a pauli_list type or a string with a input Hamiltonian text filename.
    The function returns a pauli_list and optionally creates a Hamiltonian text file with name out_file
    m is the number of particles (e.g. electrons) in the system

    """

    ham_out = []

    if m % 4 == 0:
        par_1 = 1
        par_2 = 1
    elif m % 4 == 1:
        par_1 = -1
        par_2 = -1  # could be also +1, +1/-1 are degenerate spin-parity sectors
    elif m % 4 == 2:
        par_1 = 1
        par_2 = -1
    else:
        par_1 = -1
        par_2 = -1  # could be also +1, +1/-1 are degenerate spin-parity sectors

    if type(ham_in) is str:

        file_name = ham_in
        ham_in = Hamiltonian_from_file(
            ham_in)  # conversion from Hamiltonian text file to pauli_list

    # number of qubits
    n = len(ham_in[0][1].v)

    for pauli_term in ham_in:  #loop over Pauli terms

        coeff_out = pauli_term[0]

        if pauli_term[1].v[n // 2 - 1] == 1 and pauli_term[1].w[
                n // 2 - 1] == 0:  # Z operator encountered at qubit n/2-1

            coeff_out = par_2 * coeff_out

        if pauli_term[1].v[n - 1] == 1 and pauli_term[1].w[
                n - 1] == 0:  # Z operator encountered at qubit n-1

            coeff_out = par_1 * coeff_out

        v_temp = []
        w_temp = []
        for j in range(n):
            if j != n // 2 - 1 and j != n - 1:

                v_temp.append(pauli_term[1].v[j])
                w_temp.append(pauli_term[1].w[j])

        pauli_term_out = [coeff_out, Pauli(v_temp, w_temp)]
        ham_out = pauli_term_append(pauli_term_out, ham_out, threshold)
    """
    ####################################################################
    #################          WRITE TO FILE         ###################
    ####################################################################
    """

    if out_file != None:

        out_stream = open(out_file, 'w')

        for pauli_term in ham_out:
            out_stream.write(pauli_term[1].to_label() + '\n')
            out_stream.write('%.15f' % pauli_term[0].real + '\n')

        out_stream.close()

    return ham_out