Пример #1
0
    def _setup(self):
        self._operator.to_paulis()
        self._ret['translation'] = sum(
            [abs(p[0]) for p in self._operator.paulis])
        self._ret['stretch'] = 0.5 / self._ret['translation']

        # translate the operator
        self._operator._simplify_paulis()
        translation_op = Operator([[
            self._ret['translation'],
            Pauli(np.zeros(self._operator.num_qubits),
                  np.zeros(self._operator.num_qubits))
        ]])
        translation_op._simplify_paulis()
        self._operator += translation_op

        # stretch the operator
        for p in self._operator._paulis:
            p[0] = p[0] * self._ret['stretch']

        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._slice_pauli_list = slice_pauli_list
Пример #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
Пример #3
0
Файл: qpe.py Проект: simhan/aqua
    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')

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

        # Put all ancillae in uniform superposition
        qc.add(a)
        qc.u2(0, np.pi, a)

        # phase kickbacks via eoh
        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_evolutions = Operator.construct_evolution_circuit(
                slice_pauli_list,
                -2 * np.pi,
                self._num_time_slices,
                q,
                a,
                ctl_idx=i,
                shallow_slicing=self._shallow_circuit_concat)
            if self._shallow_circuit_concat:
                qc.data += qc_evolutions.data
            else:
                qc += qc_evolutions
            # 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.add(c)
        qc.barrier(a)
        qc.measure(a, c)

        self._circuit = qc
Пример #4
0
    def construct_circuit(self,
                          state_register=None,
                          ancilla_register=None,
                          aux_register=None,
                          measure=False):
        """
        Construct the Phase Estimation circuit

        Args:
            state_register (QuantumRegister): the optional register to use for the quantum state
            ancilla_register (QuantumRegister): the optional register to use for the ancillary measurement qubits
            aux_register (QuantumRegister): an optional auxiliary quantum register
            measure (bool): boolean flag to indicate if the built circuit should include ancilla measurement

        Returns:
            the QuantumCircuit object for the constructed circuit
        """

        if self._circuit[measure] is None:
            if self._operator is not None:
                # check for identify paulis to get its coef for applying global phase shift on ancillae later
                num_identities = 0
                for p in self._operator.paulis:
                    if np.all(np.logical_not(p[1].z)) and np.all(
                            np.logical_not(p[1].x)):
                        num_identities += 1
                        if num_identities > 1:
                            raise RuntimeError(
                                'Multiple identity pauli terms are present.')
                        self._ancilla_phase_coef = p[0].real if isinstance(
                            p[0], complex) else p[0]

            if ancilla_register is None:
                a = QuantumRegister(self._num_ancillae, name='a')
            else:
                a = ancilla_register

            if state_register is None:
                if self._operator is not None:
                    q = QuantumRegister(self._operator.num_qubits, name='q')
                elif self._unitary_circuit_factory is not None:
                    q = QuantumRegister(
                        self._unitary_circuit_factory.num_target_qubits,
                        name='q')
                else:
                    raise RuntimeError('Missing operator specification.')
            else:
                q = state_register
            qc = QuantumCircuit(a, q)

            if aux_register is None:
                num_aux_qubits, aux = 0, None
                if self._state_in_circuit_factory is not None:
                    num_aux_qubits = self._state_in_circuit_factory.required_ancillas(
                    )
                if self._unitary_circuit_factory is not None:
                    num_aux_qubits = max(
                        num_aux_qubits,
                        self._unitary_circuit_factory.
                        required_ancillas_controlled())

                if num_aux_qubits > 0:
                    aux = QuantumRegister(num_aux_qubits, name='aux')
                    qc.add_register(aux)
            else:
                aux = aux_register
                qc.add_register(aux)

            # initialize state_in
            if self._state_in is not None:
                qc.data += self._state_in.construct_circuit('circuit', q).data
            elif self._state_in_circuit_factory is not None:
                self._state_in_circuit_factory.build(qc, q, aux)
            else:
                raise RuntimeError('Missing initial state specification.')

            # Put all ancillae in uniform superposition
            qc.u2(0, np.pi, a)

            # phase kickbacks via dynamics
            if self._operator is not None:
                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_evolutions = Operator.construct_evolution_circuit(
                        slice_pauli_list,
                        -2 * np.pi,
                        self._num_time_slices,
                        q,
                        a,
                        ctl_idx=i,
                        shallow_slicing=self._shallow_circuit_concat)
                    if self._shallow_circuit_concat:
                        qc.data += qc_evolutions.data
                    else:
                        qc += qc_evolutions
                    # 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])
            elif self._unitary_circuit_factory is not None:
                for i in range(self._num_ancillae):
                    self._unitary_circuit_factory.build_controlled_power(
                        qc, q, a[i], 2**i, aux)

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

            # measuring ancillae
            if measure:
                c = ClassicalRegister(self._num_ancillae, name='c')
                qc.add_register(c)
                qc.barrier(a)
                qc.measure(a, c)

            self._circuit[measure] = qc

        return self._circuit[measure]