Beispiel #1
0
    def _construct_qpe_evolution(self):
        """Implement the Quantum Phase Estimation algorithm"""

        a = QuantumRegister(self._num_ancillae, name='a')
        c = ClassicalRegister(self._num_ancillae, name='c')
        q = QuantumRegister(self._operator.num_qubits, name='q')
        qc = QuantumCircuit(a, q, c)

        # initialize state_in
        qc.data += self._state_in.construct_circuit('circuit', q).data

        # Put all ancillae in uniform superposition
        qc.u2(0, np.pi, a) if self._use_basis_gates else qc.h(a)

        # phase kickbacks via dynamics
        pauli_list = self._operator.reorder_paulis(
            grouping=self._paulis_grouping)
        if len(pauli_list) == 1:
            slice_pauli_list = pauli_list
        else:
            if self._expansion_mode == 'trotter':
                slice_pauli_list = pauli_list
            elif self._expansion_mode == 'suzuki':
                slice_pauli_list = Operator._suzuki_expansion_slice_pauli_list(
                    pauli_list, 1, self._expansion_order)
            else:
                raise ValueError('Unrecognized expansion mode {}.'.format(
                    self._expansion_mode))
        for i in range(self._num_ancillae):
            qc.data += self._operator.construct_evolution_circuit(
                slice_pauli_list,
                -2 * np.pi,
                self._num_time_slices,
                q,
                a,
                ctl_idx=i,
                use_basis_gates=self._use_basis_gates).data
            # global phase shift for the ancilla due to the identity pauli term
            qc.u1(2 * np.pi * self._ancilla_phase_coef * (2**i), a[i])

        # inverse qft on ancillae
        self._iqft.construct_circuit('circuit', a, qc)

        # measuring ancillae
        qc.measure(a, c)

        self._circuit = qc
Beispiel #2
0
    def _estimate_phase_iteratively(self):
        """Iteratively construct the different order of controlled evolution circuit to carry out phase estimation"""
        pauli_list = self._operator.reorder_paulis(
            grouping=self._paulis_grouping)
        if len(pauli_list) == 1:
            slice_pauli_list = pauli_list
        else:
            if self._expansion_mode == 'trotter':
                slice_pauli_list = pauli_list
            else:
                slice_pauli_list = Operator._suzuki_expansion_slice_pauli_list(
                    pauli_list, 1, self._expansion_order)

        self._ret['top_measurement_label'] = ''

        omega_coef = 0
        # k runs from the number of iterations back to 1
        for k in range(self._num_iterations, 0, -1):
            omega_coef /= 2
            qc = self._construct_kth_evolution(slice_pauli_list, k,
                                               -2 * np.pi * omega_coef)
            measurements = self.execute(qc).get_counts(qc)

            if '0' not in measurements:
                if '1' in measurements:
                    x = 1
                else:
                    raise RuntimeError(
                        'Unexpected measurement {}.'.format(measurements))
            else:
                if '1' not in measurements:
                    x = 0
                else:
                    x = 1 if measurements['1'] > measurements['0'] else 0
            self._ret['top_measurement_label'] = '{}{}'.format(
                x, self._ret['top_measurement_label'])
            omega_coef = omega_coef + x / 2
            logger.info(
                'Reverse iteration {} of {} with measured bit {}'.format(
                    k, self._num_iterations, x))
        return omega_coef