예제 #1
0
    def __rpow__(self, base):
        if isinstance(base, (int, float)) and base > 0:
            if abs(self.coefficient.real) > 0.0001:
                raise NotImplementedError(
                    'Exponentiated to a non-Hermitian PauliString '
                    f'<{base}**{self}>. Coefficient must be imaginary.')

            half_turns = 2 * math.log(base) * (-self.coefficient.imag /
                                               math.pi)

            if len(self) == 1:
                q, p = next(iter(self.items()))
                gates = {
                    pauli_gates.X: common_gates.XPowGate,
                    pauli_gates.Y: common_gates.YPowGate,
                    pauli_gates.Z: common_gates.ZPowGate,
                }
                return gates[p](exponent=half_turns, global_shift=-0.5).on(q)

            # HACK: Avoid circular dependency.
            from cirq.ops import pauli_string_phasor
            return pauli_string_phasor.PauliStringPhasor(
                PauliString(qubit_pauli_map=self._qubit_pauli_map),
                exponent_neg=+half_turns / 4,
                exponent_pos=-half_turns / 4)
        return NotImplemented
예제 #2
0
    def __pow__(self, power):
        if power == 1:
            return self
        if power == -1:
            return PauliString(qubit_pauli_map=self._qubit_pauli_map,
                               coefficient=self.coefficient**-1)
        if isinstance(power, (int, float)):
            r, i = cmath.polar(self.coefficient)
            if abs(r - 1) > 0.0001:
                # Raising non-unitary PauliStrings to a power is not supported.
                return NotImplemented

            if len(self) == 1:
                q, p = next(iter(self.items()))
                gates = {
                    pauli_gates.X: common_gates.XPowGate,
                    pauli_gates.Y: common_gates.YPowGate,
                    pauli_gates.Z: common_gates.ZPowGate,
                }
                return gates[p](exponent=power).on(q)

            global_half_turns = power * (i / math.pi)

            # HACK: Avoid circular dependency.
            from cirq.ops import pauli_string_phasor
            return pauli_string_phasor.PauliStringPhasor(
                PauliString(qubit_pauli_map=self._qubit_pauli_map),
                exponent_neg=global_half_turns + power,
                exponent_pos=global_half_turns)
        return NotImplemented
예제 #3
0
 def __iter__(self) -> Iterator['cirq.PauliStringPhasor']:
     for pauli_string in self._pauli_sum:
         theta = pauli_string.coefficient * self._multiplier
         theta *= self._exponent / np.pi
         if isinstance(theta, complex):
             theta = theta.real
         yield pauli_string_phasor.PauliStringPhasor(
             pauli_string.with_coefficient(1.0), exponent_neg=-theta, exponent_pos=theta
         )
예제 #4
0
 def _decompose_(self):
     # HACK: Avoid circular dependency.
     from cirq.ops import pauli_string_phasor
     return pauli_string_phasor.PauliStringPhasor(self)._decompose_()