Exemplo n.º 1
0
    def _replace_pauli_sums(cls, operator):
        from qiskit.providers.aer.extensions import SnapshotExpectationValue
        # The 'expval_measurement' label on the snapshot instruction is special - the
        # CircuitSampler will look for it to know that the circuit is a Expectation
        # measurement, and not simply a
        # circuit to replace with a DictStateFn

        # Change to Pauli representation if necessary
        if not {'Pauli'} == operator.primitive_strings():
            logger.warning(
                'Measured Observable is not composed of only Paulis, converting to '
                'Pauli representation, which can be expensive.')
            # Setting massive=False because this conversion is implicit. User can perform this
            # action on the Observable with massive=True explicitly if they so choose.
            operator = operator.to_pauli_op(massive=False)

        if isinstance(operator, SummedOp):
            paulis = [[meas.coeff, meas.primitive] for meas in operator.oplist]
            snapshot_instruction = SnapshotExpectationValue(
                'expval_measurement', paulis, variance=True)
            snapshot_op = CircuitStateFn(snapshot_instruction,
                                         is_measurement=True)
            return snapshot_op
        if isinstance(operator, PauliOp):
            paulis = [[operator.coeff, operator.primitive]]
            snapshot_instruction = SnapshotExpectationValue(
                'expval_measurement', paulis, variance=True)
            snapshot_op = CircuitStateFn(snapshot_instruction,
                                         is_measurement=True)
            return snapshot_op
        if isinstance(operator, ListOp):
            return operator.traverse(cls._replace_pauli_sums)
Exemplo n.º 2
0
    def _replace_pauli_sums(cls, operator):
        try:
            from qiskit.providers.aer.extensions import SnapshotExpectationValue
        except ImportError as ex:
            raise MissingOptionalLibraryError(
                libname="qiskit-aer",
                name="AerPauliExpectation",
                pip_install="pip install qiskit-aer",
            ) from ex
        # The 'expval_measurement' label on the snapshot instruction is special - the
        # CircuitSampler will look for it to know that the circuit is a Expectation
        # measurement, and not simply a
        # circuit to replace with a DictStateFn
        if operator.__class__ == ListOp:
            return operator.traverse(cls._replace_pauli_sums)

        if isinstance(operator, PauliSumOp):
            paulis = [(meas[1], meas[0])
                      for meas in operator.primitive.to_list()]
            snapshot_instruction = SnapshotExpectationValue(
                "expval_measurement", paulis)
            return CircuitStateFn(snapshot_instruction,
                                  coeff=operator.coeff,
                                  is_measurement=True)

        # Change to Pauli representation if necessary
        if {"Pauli"} != operator.primitive_strings():
            logger.warning(
                "Measured Observable is not composed of only Paulis, converting to "
                "Pauli representation, which can be expensive.")
            # Setting massive=False because this conversion is implicit. User can perform this
            # action on the Observable with massive=True explicitly if they so choose.
            operator = operator.to_pauli_op(massive=False)

        if isinstance(operator, SummedOp):
            paulis = [[meas.coeff, meas.primitive] for meas in operator.oplist]
            snapshot_instruction = SnapshotExpectationValue(
                "expval_measurement", paulis)
            snapshot_op = CircuitStateFn(snapshot_instruction,
                                         is_measurement=True)
            return snapshot_op
        if isinstance(operator, PauliOp):
            paulis = [[operator.coeff, operator.primitive]]
            snapshot_instruction = SnapshotExpectationValue(
                "expval_measurement", paulis)
            snapshot_op = CircuitStateFn(snapshot_instruction,
                                         is_measurement=True)
            return snapshot_op

        raise TypeError(
            f"Conversion of OperatorStateFn of {operator.__class__.__name__} is not defined."
        )
    def evaluation_instruction(self, statevector_mode, use_simulator_snapshot_mode=False):
        """

        Args:
            statevector_mode (bool): will it be run on statevector simulator or not
            use_simulator_snapshot_mode (bool): will it use qiskit aer simulator operator mode

        Returns:
            dict: Pauli-instruction pair.

        Raises:
            AquaError: if Operator is empty
        """
        if self.is_empty():
            raise AquaError("Operator is empty, check the operator.")
        instructions = {}
        qr = QuantumRegister(self.num_qubits)
        qc = QuantumCircuit(qr)
        if use_simulator_snapshot_mode and self.paulis:
            # pylint: disable=import-outside-toplevel
            from qiskit.providers.aer.extensions import SnapshotExpectationValue
            snapshot = SnapshotExpectationValue('expval', self.paulis, variance=True)
            instructions = {'expval_snapshot': snapshot}
        elif statevector_mode:
            for _, pauli in self._paulis:
                tmp_qc = qc.copy(name="Pauli " + pauli.to_label())
                if np.all(np.logical_not(pauli.z)) and np.all(np.logical_not(pauli.x)):  # all I
                    continue
                # This explicit barrier is needed for statevector simulator since Qiskit-terra
                # will remove global phase at default compilation level but the results here
                # rely on global phase.
                tmp_qc.barrier(list(range(self.num_qubits)))
                tmp_qc.append(pauli, list(range(self.num_qubits)))
                instructions[pauli.to_label()] = tmp_qc.to_instruction()
        else:
            cr = ClassicalRegister(self.num_qubits)
            qc.add_register(cr)
            for basis, _ in self._basis:
                tmp_qc = qc.copy(name="Pauli " + basis.to_label())
                tmp_qc = pauli_measurement(tmp_qc, basis, qr, cr, barrier=True)
                instructions[basis.to_label()] = tmp_qc.to_instruction()
        return instructions