def compose(self, other: OperatorBase, permutation: Optional[List[int]] = None, front: bool = False) -> OperatorBase: new_self, other = self._expand_shorter_operator_and_permute(other, permutation) if front: return other.compose(new_self) if isinstance(other, ComposedOp): return ComposedOp([new_self] + other.oplist) return ComposedOp([new_self, other])
def compose(self, other: OperatorBase, permutation: Optional[List[int]] = None, front: bool = False) -> OperatorBase: if not self.is_measurement and not front: raise ValueError( 'Composition with a Statefunctions in the first operand is not defined.' ) new_self, other = self._expand_shorter_operator_and_permute( other, permutation) if front: return other.compose(new_self) if isinstance(other, (PauliOp, CircuitOp, MatrixOp)): op_circuit_self = CircuitOp(self.primitive) # Avoid reimplementing compose logic composed_op_circs = cast( CircuitOp, op_circuit_self.compose(other.to_circuit_op())) # Returning CircuitStateFn return CircuitStateFn(composed_op_circs.primitive, is_measurement=self.is_measurement, coeff=self.coeff * other.coeff) if isinstance(other, CircuitStateFn) and self.is_measurement: # pylint: disable=cyclic-import from ..operator_globals import Zero return self.compose(CircuitOp( other.primitive, other.coeff)).compose(Zero ^ self.num_qubits) return ComposedOp([new_self, other])
def convert(self, operator: OperatorBase) -> OperatorBase: if not isinstance(operator, (SummedOp, PauliSumOp)): raise TypeError("Trotterization converters can only convert SummedOp or PauliSumOp.") if not isinstance(operator.coeff, (float, int)): raise TypeError( "Trotterization converters can only convert operators with real coefficients." ) operator_iter: Union[PauliSumOp, List[PrimitiveOp]] if isinstance(operator, PauliSumOp): operator_iter = operator coeffs = operator.primitive.coeffs coeff = operator.coeff else: operator_iter = cast(List[PrimitiveOp], operator.oplist) coeffs = [op.coeff for op in operator_iter] coeff = operator.coeff # We artificially make the weights positive, TODO check approximation performance weights = np.abs(coeffs) lambd = np.sum(weights) N = 2 * (lambd**2) * (coeff**2) factor = lambd * coeff / (N * self.reps) # The protocol calls for the removal of the individual coefficients, # and multiplication by a constant factor. scaled_ops = [(op * (factor / op.coeff)).exp_i() for op in operator_iter] sampled_ops = algorithm_globals.random.choice( scaled_ops, size=(int(N * self.reps),), p=weights / lambd ) return ComposedOp(sampled_ops).reduce()
def convert(self, operator: OperatorBase) -> OperatorBase: if not isinstance(operator, (SummedOp, PauliSumOp)): raise TypeError( 'Trotterization converters can only convert SummedOp or PauliSumOp.' ) if isinstance(operator.coeff, (float, ParameterExpression)): coeff = operator.coeff else: if isreal(operator.coeff): coeff = operator.coeff.real else: raise TypeError( "Coefficient of the operator must be float or ParameterExpression, " f"but {operator.coeff}:{type(operator.coeff)} is given.") if isinstance(operator, PauliSumOp): comp_list = self._recursive_expansion(operator, coeff, self.order, self.reps) if isinstance(operator, SummedOp): comp_list = Suzuki._recursive_expansion(operator.oplist, coeff, self.order, self.reps) single_rep = ComposedOp(cast(List[OperatorBase], comp_list)) full_evo = single_rep.power(self.reps) return full_evo.reduce()
def statefn_replacement_fn( cob_instr_op: PrimitiveOp, dest_pauli_op: Union[PauliOp, PauliSumOp, ListOp]) -> OperatorBase: r""" A built-in convenience replacement function which produces state functions isomorphic to an ``OperatorStateFn`` state function holding the origin ``PauliOp``. Args: cob_instr_op: The basis-change ``CircuitOp``. dest_pauli_op: The destination Pauli type operator. Returns: The ``~CircuitOp @ StateFn`` composition equivalent to a state function defined by the original ``PauliOp``. """ return ComposedOp([cob_instr_op.adjoint(), StateFn(dest_pauli_op)])
def operator_replacement_fn( cob_instr_op: PrimitiveOp, dest_pauli_op: Union[PauliOp, PauliSumOp, ListOp] ) -> OperatorBase: r""" A built-in convenience replacement function which produces Operators isomorphic to the origin ``PauliOp``. Args: cob_instr_op: The basis-change ``CircuitOp``. dest_pauli_op: The destination ``PauliOp``. Returns: The ``~CircuitOp @ PauliOp @ CircuitOp`` composition isomorphic to the original ``PauliOp``. """ return ComposedOp([cob_instr_op.adjoint(), dest_pauli_op, cob_instr_op])
def measurement_replacement_fn( cob_instr_op: PrimitiveOp, dest_pauli_op: Union[PauliOp, PauliSumOp, ListOp] ) -> OperatorBase: r""" A built-in convenience replacement function which produces measurements isomorphic to an ``OperatorStateFn`` measurement holding the origin ``PauliOp``. Args: cob_instr_op: The basis-change ``CircuitOp``. dest_pauli_op: The destination Pauli type operator. Returns: The ``~StateFn @ CircuitOp`` composition equivalent to a measurement by the original ``PauliOp``. """ return ComposedOp([StateFn(dest_pauli_op, is_measurement=True), cob_instr_op])