コード例 #1
0
ファイル: clifford_simulator.py プロジェクト: km4391/Cirq
 def is_supported_operation(op: 'cirq.Operation') -> bool:
     """Checks whether given operation can be simulated by this simulator."""
     if protocols.is_measurement(op): return True
     if isinstance(op, GlobalPhaseOperation): return True
     if not protocols.has_unitary(op): return False
     u = cirq.unitary(op)
     if u.shape == (2, 2):
         return not SingleQubitCliffordGate.from_unitary(u) is None
     else:
         return op.gate in [cirq.CNOT, cirq.CZ]
コード例 #2
0
def _strat_has_stabilizer_effect_from_unitary(val: Any) -> Optional[bool]:
    """Attempts to infer whether val has stabilizer effect from its unitary.
    Returns whether unitary of `val` normalizes the Pauli group. Works only for
    2x2 unitaries.
    """
    if not protocols.has_unitary(val):
        return None
    unitary = protocols.unitary(val)
    if unitary.shape == (2, 2):
        return SingleQubitCliffordGate.from_unitary(unitary) is not None
    return None
コード例 #3
0
def _strat_has_stabilizer_effect_from_unitary(val: Any) -> Optional[bool]:
    """Attempts to infer whether val has stabilizer effect from its unitary.
    Returns whether unitary of `val` normalizes the Pauli group. Works only for
    2x2 unitaries.
    """
    # Do not try this strategy if there is no unitary or if the number of
    # qubits is not 1 since that would be expensive.
    if not protocols.has_unitary(val) or protocols.num_qubits(val) != 1:
        return None
    unitary = protocols.unitary(val)
    return SingleQubitCliffordGate.from_unitary(unitary) is not None
コード例 #4
0
 def is_supported_operation(op: 'cirq.Operation') -> bool:
     """Checks whether given operation can be simulated by this simulator."""
     # TODO: support more general Pauli measurements
     if isinstance(op.gate, cirq.MeasurementGate): return True
     if isinstance(op, GlobalPhaseOperation): return True
     if not protocols.has_unitary(op): return False
     if len(op.qubits) == 1:
         u = unitary(op)
         return SingleQubitCliffordGate.from_unitary(u) is not None
     else:
         return op.gate in [cirq.CNOT, cirq.CZ]
コード例 #5
0
ファイル: clifford_simulator.py プロジェクト: louishp/Cirq
    def apply_single_qubit_unitary(self, op: 'cirq.Operation'):
        qubit = self.qubit_map[op.qubits[0]]
        if op.gate == cirq.I:
            return

        if op.gate == cirq.X:
            self._apply_X(qubit)
            return

        if op.gate == cirq.Y:
            self._apply_Y(qubit)
            return

        if op.gate == cirq.Z:
            self._apply_Z(qubit)
            return

        if op.gate == cirq.H:
            self._apply_H(qubit)
            return

        u = unitary(op)
        clifford_gate = SingleQubitCliffordGate.from_unitary(u)
        if clifford_gate is None:
            raise ValueError('%s cannot be run with Clifford simulator.' %
                             str(op.gate))

        h = unitary(ops.H)
        s = unitary(ops.S)
        applied_unitary = np.eye(2)
        for axis, quarter_turns in clifford_gate.decompose_rotation():
            for _ in range(quarter_turns % 4):
                if axis == pauli_gates.X:
                    self._apply_H(qubit)
                    self._apply_S(qubit)
                    self._apply_H(qubit)
                    applied_unitary = h @ s @ h @ applied_unitary
                elif axis == pauli_gates.Y:
                    self._apply_S(qubit)
                    self._apply_S(qubit)
                    self._apply_H(qubit)
                    applied_unitary = h @ s @ s @ applied_unitary
                else:
                    assert axis == pauli_gates.Z
                    self._apply_S(qubit)
                    applied_unitary = s @ applied_unitary

        max_idx = max(np.ndindex(*u.shape), key=lambda t: abs(u[t]))
        phase_shift = u[max_idx] / applied_unitary[max_idx]
        self.ch_form.omega *= phase_shift
コード例 #6
0
def _strat_act_on_clifford_tableau_from_single_qubit_decompose(
    val: Any, args: 'cirq.ActOnCliffordTableauArgs', qubits: Sequence['cirq.Qid']
) -> bool:
    if num_qubits(val) == 1:
        if not has_unitary(val):
            return NotImplemented
        u = unitary(val)
        clifford_gate = SingleQubitCliffordGate.from_unitary(u)
        if clifford_gate is not None:
            for axis, quarter_turns in clifford_gate.decompose_rotation():
                if axis == pauli_gates.X:
                    common_gates.XPowGate(exponent=quarter_turns / 2)._act_on_(args, qubits)
                elif axis == pauli_gates.Y:
                    common_gates.YPowGate(exponent=quarter_turns / 2)._act_on_(args, qubits)
                else:
                    assert axis == pauli_gates.Z
                    common_gates.ZPowGate(exponent=quarter_turns / 2)._act_on_(args, qubits)
            return True

    return NotImplemented
コード例 #7
0
    def _strat_act_from_single_qubit_decompose(
            self, val: Any, qubits: Sequence['cirq.Qid']) -> bool:
        if num_qubits(val) == 1:
            if not has_unitary(val):
                return NotImplemented
            u = unitary(val)
            clifford_gate = SingleQubitCliffordGate.from_unitary(u)
            if clifford_gate is not None:
                # Gather the effective unitary applied so as to correct for the
                # global phase later.
                final_unitary = np.eye(2)
                for axis, quarter_turns in clifford_gate.decompose_rotation():
                    gate = axis**(quarter_turns / 2)
                    self._strat_apply_gate(gate, qubits)
                    final_unitary = np.matmul(unitary(gate), final_unitary)

                # Find the entry with the largest magnitude in the input unitary.
                k = max(np.ndindex(*u.shape), key=lambda t: abs(u[t]))
                # Correct the global phase that wasn't conserved in the above
                # decomposition.
                self._state.apply_global_phase(u[k] / final_unitary[k])
                return True

        return NotImplemented