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