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)
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