예제 #1
0
 def _decompose_(self):
     if not self._has_unitary_():
         return None
     return [
         *([] if self.coefficient == 1 else
           [global_phase_op.GlobalPhaseOperation(self.coefficient)]),
         *[self[q].on(q) for q in self.qubits],
     ]
예제 #2
0
 def _decompose_(self, qubits):
     if not self._has_unitary_():
         return NotImplemented
     result = [
         PAULI_GATES[p].on(q) for p, q in zip(self.pauli_mask, qubits) if p
     ]
     if self.coefficient != 1:
         result.append(
             global_phase_op.GlobalPhaseOperation(self.coefficient))
     return result
예제 #3
0
    def _decompose_(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE':
        """Decompose the n-qubit diagonal gates into CNOT and Rz gates.

        A 3 qubits decomposition looks like
        0: ───────────────────────────────────X───Rz(6)───X───Rz(7)───X───Rz(5)───X───Rz(4)───
                                              │           │           │           │
        1: ───────────X───Rz(3)───X───Rz(2)───@───────────┼───────────@───────────┼───────────
                      │           │                       │                       │
        2: ───Rz(1)───@───────────@───────────────────────@───────────────────────@───────────

        where the angles in Rz gates are corresponding to the fast-walsh-Hadamard transfrom
        of diagonal_angles in the Gray Code order.

        For n qubits decomposition looks similar but with 2^n-1 Rz gates and 2^n-2 CNOT gates.

        The algorithm is implemented according to the paper:
            Welch, Jonathan, et al. "Efficient quantum circuits for diagonal unitaries without
            ancillas." New Journal of Physics 16.3 (2014): 033040.
            https://iopscience.iop.org/article/10.1088/1367-2630/16/3/033040/meta
        """
        if protocols.is_parameterized(self):
            return NotImplemented

        n = self._num_qubits_()
        hat_angles = _fast_walsh_hadamard_transform(
            self._diag_angles_radians) / (2**n)

        # There is one global phase shift between unitary matrix of the diagonal gate and the
        # decomposed gates. On its own it is not physically observable. However, if using this
        # diagonal gate for sub-system like controlled gate, it is no longer equivalent. Hence,
        # we add global phase.
        decomposed_circ: List[Any] = [
            global_phase_op.GlobalPhaseOperation(np.exp(1j * hat_angles[0]))
        ]
        for i, bit_flip in _gen_gray_code(n):
            decomposed_circ.extend(
                self._decompose_for_basis(i, bit_flip, -hat_angles[i], qubits))
        return decomposed_circ