Пример #1
0
    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()
Пример #2
0
    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])
Пример #3
0
    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])
Пример #4
0
    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()
Пример #5
0
    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)])
Пример #6
0
    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])
Пример #7
0
    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])