def from_op_list( cls, operations: Sequence[raw_types.Operation], qubit_order: Sequence[raw_types.Qid] ) -> 'CliffordGate': """Construct a new Clifford gates from several known operations. Args: operations: A list of cirq operations to construct the Clifford gate. The combination order is the first element in the list applies the transformation on the stabilizer state first. qubit_order: Determines how qubits are ordered when decomposite the operations. Returns: A CliffordGate instance, which has the transformation on the stabilizer state equivalent to the composition of operations. Raises: ValueError: When one or more operations do not have stabilizer effect. """ for op in operations: if op.gate and op.gate._has_stabilizer_effect_(): continue raise ValueError( "Clifford Gate can only be constructed from the " "operations that has stabilizer effect." ) base_tableau = qis.CliffordTableau(len(qubit_order)) args = sim.clifford.CliffordTableauSimulationState( tableau=base_tableau, qubits=qubit_order, prng=np.random.RandomState(0) # unused ) for op in operations: protocols.act_on(op, args, allow_decompose=True) return CliffordGate.from_clifford_tableau(args.tableau)
def _to_clifford_tableau( rotation_map: Optional[Dict[Pauli, Tuple[Pauli, bool]]] = None, *, x_to: Optional[Tuple[Pauli, bool]] = None, z_to: Optional[Tuple[Pauli, bool]] = None, ) -> qis.CliffordTableau: """Transfer the rotation map to clifford tableau representation""" if x_to is None and z_to is None and rotation_map is None: raise ValueError( "The function either takes rotation_map or a combination " ' of x_to and z_to but none were given.' ) elif rotation_map is not None: x_to = rotation_map[pauli_gates.X] z_to = rotation_map[pauli_gates.Z] else: assert x_to is not None and z_to is not None, "Both x_to and z_to have to be provided." clifford_tableau = qis.CliffordTableau(num_qubits=1) clifford_tableau.xs[0, 0] = x_to[0] in (pauli_gates.X, pauli_gates.Y) clifford_tableau.zs[0, 0] = x_to[0] in (pauli_gates.Y, pauli_gates.Z) clifford_tableau.xs[1, 0] = z_to[0] in (pauli_gates.X, pauli_gates.Y) clifford_tableau.zs[1, 0] = z_to[0] in (pauli_gates.Y, pauli_gates.Z) clifford_tableau.rs = np.array([x_to[1], z_to[1]]) return clifford_tableau
def SWAP(cls) -> 'cirq.CliffordGate': if not hasattr(cls, '_SWAP'): t = qis.CliffordTableau(num_qubits=2) t.xs = np.array([[0, 1], [1, 0], [0, 0], [0, 0]]) t.zs = np.array([[0, 0], [0, 0], [0, 1], [1, 0]]) cls._SWAP = CliffordGate.from_clifford_tableau(t) return cls._SWAP
def _gate_tableau(num_qubits: int, gate: raw_types.Gate) -> 'cirq.CliffordTableau': qubits = devices.LineQubit.range(num_qubits) t = qis.CliffordTableau(num_qubits=num_qubits) args = sim.CliffordTableauSimulationState( tableau=t, qubits=qubits, prng=np.random.RandomState() ) protocols.act_on(gate, args, qubits, allow_decompose=False) return args.tableau
def _generate_clifford_from_known_gate( cls, num_qubits: int, gate: raw_types.Gate) -> 'CliffordGate': qubits = devices.LineQubit.range(num_qubits) t = qis.CliffordTableau(num_qubits=num_qubits) args = sim.ActOnCliffordTableauArgs(tableau=t, qubits=qubits, prng=np.random.RandomState(), log_of_measurement_results={}) protocols.act_on(gate, args, qubits, allow_decompose=False) return CliffordGate.from_clifford_tableau(args.tableau)
def _generate_clifford_from_known_gate( cls, num_qubits: int, gate: raw_types.Gate ) -> Union['SingleQubitCliffordGate', 'CliffordGate']: qubits = devices.LineQubit.range(num_qubits) t = qis.CliffordTableau(num_qubits=num_qubits) args = sim.CliffordTableauSimulationState(tableau=t, qubits=qubits, prng=np.random.RandomState()) protocols.act_on(gate, args, qubits, allow_decompose=False) if num_qubits == 1: return SingleQubitCliffordGate.from_clifford_tableau(args.tableau) return CliffordGate.from_clifford_tableau(args.tableau)
def _pad_tableau( clifford_tableau: qis.CliffordTableau, num_qubits_after_padding: int, axes: List[int] ) -> qis.CliffordTableau: """Roughly, this function copies self.tableau into the "identity" matrix.""" # Sanity check if len(set(axes)) != clifford_tableau.n: raise ValueError( "Input axes of padding should match with the number of qubits in the input tableau." ) if clifford_tableau.n > num_qubits_after_padding: raise ValueError( "The number of qubits in the input tableau should not be larger than " "num_qubits_after_padding." ) padded_tableau = qis.CliffordTableau(num_qubits_after_padding) v_index = np.concatenate((np.asarray(axes), num_qubits_after_padding + np.asarray(axes))) padded_tableau.xs[np.ix_(v_index, axes)] = clifford_tableau.xs padded_tableau.zs[np.ix_(v_index, axes)] = clifford_tableau.zs padded_tableau.rs[v_index] = clifford_tableau.rs return padded_tableau