def _decompose_(self, qubits): a, b = qubits yield common_gates.CNOT(a, b) yield common_gates.H(a) yield common_gates.CNOT(b, a) yield common_gates.S(a)**self._exponent yield common_gates.CNOT(b, a) yield common_gates.S(a)**-self._exponent yield common_gates.H(a) yield common_gates.CNOT(a, b)
def _decompose_(self, qubits): a, b = qubits yield common_gates.CNOT(a, b) yield common_gates.H(a) yield common_gates.CNOT(b, a) yield common_gates.ZPowGate(exponent=self._exponent / 2, global_shift=self.global_shift).on(a) yield common_gates.CNOT(b, a) yield common_gates.ZPowGate(exponent=-self._exponent / 2, global_shift=-self.global_shift).on(a) yield common_gates.H(a) yield common_gates.CNOT(a, b)
def _decompose_(self, qubits: Sequence[raw_types.QubitId]) -> op_tree.OP_TREE: qubit, = qubits if self == SingleQubitCliffordGate.H: return common_gates.H(qubit), rotations = self.decompose_rotation() return tuple(r(qubit)**(qt / 2) for r, qt in rotations)
def test_invalid_powers(self): gcirq = cirq.Circuit() qreg = [cirq.LineQubit(i) for i in range(5)] cirq_to_qlm(gcirq) try: gcirq.append(g_ops.H(qreg[0])**pi) except ValueError: pass try: gcirq.append(g_ops.SWAP(qreg[0], qreg[1])**pi) except ValueError: pass
def default_decompose( self, qubits: Sequence[raw_types.QubitId]) -> op_tree.OP_TREE: qubit, = qubits if self == SingleQubitCliffordGate.H: return common_gates.H(qubit), rotations = self.decompose_rotation() pauli_gate_map = { Pauli.X: common_gates.X, Pauli.Y: common_gates.Y, Pauli.Z: common_gates.Z } return tuple( (pauli_gate_map[r](qubit)**(qt / 2) for r, qt in rotations))
def _decompose_inside_control(self, target1: raw_types.QubitId, control: raw_types.QubitId, target2: raw_types.QubitId ) -> op_tree.OP_TREE: """A decomposition assuming the control separates the targets. target1: ─@─X───────T──────@────────@─────────X───@─────X^-0.5─ │ │ │ │ │ │ control: ─X─@─X─────@─T^-1─X─@─T────X─@─X^0.5─@─@─X─@────────── │ │ │ │ │ │ target2: ─────@─H─T─X─T──────X─T^-1───X─T^-1────X───X─H─S^-1─── """ a, b, c = target1, control, target2 yield common_gates.CNOT(a, b) yield common_gates.CNOT(b, a) yield common_gates.CNOT(c, b) yield common_gates.H(c) yield common_gates.T(c) yield common_gates.CNOT(b, c) yield common_gates.T(a) yield common_gates.T(b)**-1 yield common_gates.T(c) yield common_gates.CNOT(a, b) yield common_gates.CNOT(b, c) yield common_gates.T(b) yield common_gates.T(c)**-1 yield common_gates.CNOT(a, b) yield common_gates.CNOT(b, c) yield common_gates.X(b)**0.5 yield common_gates.T(c)**-1 yield common_gates.CNOT(b, a) yield common_gates.CNOT(b, c) yield common_gates.CNOT(a, b) yield common_gates.CNOT(b, c) yield common_gates.H(c) yield common_gates.S(c)**-1 yield common_gates.X(a)**-0.5
def _decompose_inside_control( self, target1: 'cirq.Qid', control: 'cirq.Qid', target2: 'cirq.Qid' ) -> 'cirq.OP_TREE': """A decomposition assuming the control separates the targets. target1: ─@─X───────T──────@────────@─────────X───@─────X^-0.5─ │ │ │ │ │ │ control: ─X─@─X─────@─T^-1─X─@─T────X─@─X^0.5─@─@─X─@────────── │ │ │ │ │ │ target2: ─────@─H─T─X─T──────X─T^-1───X─T^-1────X───X─H─S^-1─── """ a, b, c = target1, control, target2 yield common_gates.CNOT(a, b) yield common_gates.CNOT(b, a) yield common_gates.CNOT(c, b) yield common_gates.H(c) yield common_gates.T(c) yield common_gates.CNOT(b, c) yield common_gates.T(a) yield common_gates.T(b) ** -1 yield common_gates.T(c) yield common_gates.CNOT(a, b) yield common_gates.CNOT(b, c) yield common_gates.T(b) yield common_gates.T(c) ** -1 yield common_gates.CNOT(a, b) yield common_gates.CNOT(b, c) yield pauli_gates.X(b) ** 0.5 yield common_gates.T(c) ** -1 yield common_gates.CNOT(b, a) yield common_gates.CNOT(b, c) yield common_gates.CNOT(a, b) yield common_gates.CNOT(b, c) yield common_gates.H(c) yield common_gates.S(c) ** -1 yield pauli_gates.X(a) ** -0.5
def assert_act_on_clifford_tableau_effect_matches_unitary(val: Any) -> None: """Checks that act_on with CliffordTableau generates stabilizers that stabilize the final state vector. Does not work with Operations or Gates expecting non-qubit Qids.""" # pylint: disable=unused-variable __tracebackhide__ = True # pylint: enable=unused-variable num_qubits_val = protocols.num_qubits(val) if not protocols.has_unitary(val) or \ protocols.qid_shape(val) != (2,) * num_qubits_val: return None qubits = LineQubit.range(protocols.num_qubits(val) * 2) qubit_map = {qubit: i for i, qubit in enumerate(qubits)} circuit = Circuit() for i in range(num_qubits_val): circuit.append([ common_gates.H(qubits[i]), common_gates.CNOT(qubits[i], qubits[-i - 1]) ]) if hasattr(val, "on"): circuit.append(val.on(*qubits[:num_qubits_val])) else: circuit.append(val.with_qubits(*qubits[:num_qubits_val])) tableau = _final_clifford_tableau(circuit, qubit_map) if tableau is None: return None state_vector = np.reshape(final_state_vector(circuit, qubit_order=qubits), protocols.qid_shape(qubits)) assert all( state_vector_has_stabilizer(state_vector, stab) for stab in tableau.stabilizers()), ( "act_on clifford tableau is not consistent with " "final_state_vector simulation.\n\nval: {!r}".format(val))
def _decompose_(self, qubits): c1, c2, t = qubits yield common_gates.H(t) yield CCZ(c1, c2, t) ** self._exponent yield common_gates.H(t)
def assert_all_implemented_act_on_effects_match_unitary( val: Any, assert_tableau_implemented: bool = False, assert_ch_form_implemented: bool = False) -> None: """Uses val's effect on final_state_vector to check act_on(val)'s behavior. Checks that act_on with CliffordTableau or StabilizerStateCHForm behaves consistently with act_on through final state vector. Does not work with Operations or Gates expecting non-qubit Qids. If either of the assert_*_implmented args is true, fails if the corresponding method is not implemented for the test circuit. Args: val: A gate or operation that may be an input to protocols.act_on. assert_tableau_implemented: asserts that protocols.act_on() works with val and ActOnCliffordTableauArgs inputs. assert_ch_form_implemented: asserts that protocols.act_on() works with val and ActOnStabilizerStateChFormArgs inputs. """ # pylint: disable=unused-variable __tracebackhide__ = True # pylint: enable=unused-variable num_qubits_val = protocols.num_qubits(val) if (protocols.is_parameterized(val) or not protocols.has_unitary(val) or protocols.qid_shape(val) != (2, ) * num_qubits_val): if assert_tableau_implemented or assert_ch_form_implemented: assert False, ("Could not assert if any act_on methods were " "implemented. Operating on qudits or with a " "non-unitary or parameterized operation is " "unsupported.\n\nval: {!r}".format(val)) return None qubits = LineQubit.range(protocols.num_qubits(val) * 2) qubit_map = {qubit: i for i, qubit in enumerate(qubits)} circuit = Circuit() for i in range(num_qubits_val): circuit.append([ common_gates.H(qubits[i]), common_gates.CNOT(qubits[i], qubits[-i - 1]) ]) if hasattr(val, "on"): circuit.append(val.on(*qubits[:num_qubits_val])) else: circuit.append(val.with_qubits(*qubits[:num_qubits_val])) state_vector = np.reshape(final_state_vector(circuit, qubit_order=qubits), protocols.qid_shape(qubits)) tableau = _final_clifford_tableau(circuit, qubit_map) if tableau is None: assert ( not assert_tableau_implemented ), "Failed to generate final tableau for the test circuit.\n\nval: {!r}".format( val) else: assert all( state_vector_has_stabilizer(state_vector, stab) for stab in tableau.stabilizers()), ( "act_on clifford tableau is not consistent with " "final_state_vector simulation.\n\nval: {!r}".format(val)) stabilizer_ch_form = _final_stabilizer_state_ch_form(circuit, qubit_map) if stabilizer_ch_form is None: assert not assert_ch_form_implemented, ("Failed to generate final " "stabilizer state CH form " "for the test circuit." "\n\nval: {!r}".format(val)) else: np.testing.assert_allclose( np.reshape(stabilizer_ch_form.state_vector(), protocols.qid_shape(qubits)), state_vector, atol=1e-07, err_msg= f"stabilizer_ch_form.state_vector disagrees with state_vector for {val!r}", verbose=True, )
def _decompose_(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE': (qubit, ) = qubits if self == SingleQubitCliffordGate.H: return (common_gates.H(qubit), ) rotations = self.decompose_rotation() return tuple(r.on(qubit)**(qt / 2) for r, qt in rotations)
def _decompose_(self, qubits): c1, c2, t = qubits yield common_gates.H(t) yield CCZPowGate(exponent=self._exponent, global_shift=self.global_shift).on(c1, c2, t) yield common_gates.H(t)
def default_decompose(self, qubits): c1, c2, t = qubits yield common_gates.H(t) yield CCZ(c1, c2, t) yield common_gates.H(t)