def test_child_class():
    class Impl(ops.ReversibleCompositeGate):
        def default_decompose(self, qubits):
            yield _FlipGate(1)(*qubits)
            yield _FlipGate(2)(*qubits), _FlipGate(3)(*qubits)

    gate = Impl()
    reversed_gate = gate.inverse()
    assert gate is reversed_gate.inverse()

    q = ops.QubitId()
    assert (ops.freeze_op_tree(gate.default_decompose(
        [q])) == (_FlipGate(1)(q), (_FlipGate(2)(q), _FlipGate(3)(q))))
    assert (ops.freeze_op_tree(reversed_gate.default_decompose(
        [q])) == ((_FlipGate(~3)(q), _FlipGate(~2)(q)), _FlipGate(~1)(q)))
Esempio n. 2
0
 def _decompose_(self) -> ops.OP_TREE:
     if len(self.pauli_string) <= 0:
         return
     if self.pauli_string.coefficient not in [-1, +1]:
         raise NotImplementedError("TODO: arbitrary coefficients.")
     qubits = self.qubits
     any_qubit = qubits[0]
     to_z_ops = ops.freeze_op_tree(self.pauli_string.to_z_basis_ops())
     xor_decomp = tuple(xor_nonlocal_decompose(qubits, any_qubit))
     yield to_z_ops
     yield xor_decomp
     sign = self.pauli_string.coefficient.real
     yield ops.Z(any_qubit)**protocols.mul(self.half_turns, sign)
     yield protocols.inverse(xor_decomp)
     yield protocols.inverse(to_z_ops)
Esempio n. 3
0
 def _decompose_(self) -> ops.OP_TREE:
     if len(self.pauli_string) <= 0:
         return
     qubits = self.qubits
     any_qubit = qubits[0]
     to_z_ops = ops.freeze_op_tree(self.pauli_string.to_z_basis_ops())
     xor_decomp = tuple(xor_nonlocal_decompose(qubits, any_qubit))
     yield to_z_ops
     yield xor_decomp
     if isinstance(self.half_turns, sympy.Symbol):
         if self.pauli_string.negated:
             yield ops.X(any_qubit)
         yield ops.Z(any_qubit)**self.half_turns
         if self.pauli_string.negated:
             yield ops.X(any_qubit)
     else:
         half_turns = self.half_turns * (-1 if self.pauli_string.negated
                                         else 1)
         yield ops.Z(any_qubit)**half_turns
     yield protocols.inverse(xor_decomp)
     yield protocols.inverse(to_z_ops)
Esempio n. 4
0
 def default_decompose(self) -> ops.OP_TREE:
     if len(self.pauli_string) <= 0:
         return
     qubits = self.qubits
     any_qubit = qubits[0]
     to_z_ops = ops.freeze_op_tree(self.pauli_string.to_z_basis_ops())
     xor_decomp = tuple(xor_nonlocal_decompose(qubits, any_qubit))
     yield to_z_ops
     yield xor_decomp
     if isinstance(self.half_turns, value.Symbol):
         if self.pauli_string.negated:
             yield ops.X(any_qubit)
         yield ops.RotZGate(half_turns=self.half_turns)(any_qubit)
         if self.pauli_string.negated:
             yield ops.X(any_qubit)
     else:
         half_turns = self.half_turns * (-1 if self.pauli_string.negated
                                            else 1)
         yield ops.Z(any_qubit) ** half_turns
     yield ops.inverse(xor_decomp)
     yield ops.inverse(to_z_ops)
 def rev_freeze(root):
     return ops.freeze_op_tree(ops.inverse_of_invertible_op_tree(root))