def _convert_one(self, op: 'cirq.Operation') -> 'cirq.OP_TREE':
        # Known matrix?
        mat = protocols.unitary(op, None) if len(op.qubits) <= 2 else None
        if mat is not None and len(op.qubits) == 1:
            gates = optimizers.single_qubit_matrix_to_phased_x_z(mat)
            return [g.on(op.qubits[0]) for g in gates]
        if mat is not None and len(op.qubits) == 2:
            return optimizers.two_qubit_matrix_to_operations(
                op.qubits[0], op.qubits[1], mat, allow_partial_czs=True, clean_operations=False
            )

        return NotImplemented
Exemple #2
0
    def _convert_one(self, op: ops.Operation) -> ops.OP_TREE:
        """
        Decomposer intercept:  Upon cirq.protocols.decompose catch and
        return new OP_Tree

        This should decompose based on number of qubits.
        """
        if len(op.qubits) == 1:
            mat = protocols.unitary(op, None)
            gates = optimizers.single_qubit_matrix_to_phased_x_z(mat)
            return [g.on(op.qubits[0]) for g in gates]
        elif len(op.qubits) == 2 and isinstance(op, ops.GateOperation):
            return known_two_q_operations_to_sycamore_operations(
                op.qubits[0], op.qubits[1], op, self.tabulation)
        return NotImplemented
Exemple #3
0
    def convert_one(self, op: ops.Operation) -> ops.OP_TREE:
        """Convert a single (one- or two-qubit) operation

        into ion trap native gates
        Args:
            op: gate operation to be converted

        Returns:
            the desired operation implemented with ion trap gates
        """

        # Known gate name
        if not isinstance(op, ops.GateOperation):
            raise TypeError(f"{op!r} is not a gate operation.")

        if is_native_ion_gate(op.gate):
            return [op]
        # one choice of known Hadamard gate decomposition
        if isinstance(op.gate, ops.HPowGate) and op.gate.exponent == 1:
            return [
                ops.rx(np.pi).on(op.qubits[0]),
                ops.ry(-1 * np.pi / 2).on(op.qubits[0])
            ]
        # one choice of known CNOT gate decomposition
        if isinstance(op.gate, ops.CNotPowGate) and op.gate.exponent == 1:
            return [
                ops.ry(np.pi / 2).on(op.qubits[0]),
                ms(np.pi / 4).on(op.qubits[0], op.qubits[1]),
                ops.rx(-1 * np.pi / 2).on(op.qubits[0]),
                ops.rx(-1 * np.pi / 2).on(op.qubits[1]),
                ops.ry(-1 * np.pi / 2).on(op.qubits[0]),
            ]
        # Known matrix
        mat = protocols.unitary(op, None) if len(op.qubits) <= 2 else None
        if mat is not None and len(op.qubits) == 1:
            gates = optimizers.single_qubit_matrix_to_phased_x_z(mat)
            return [g.on(op.qubits[0]) for g in gates]
        if mat is not None and len(op.qubits) == 2:
            return two_qubit_matrix_to_ion_operations(op.qubits[0],
                                                      op.qubits[1], mat)

        if self.ignore_failures:
            return [op]

        raise TypeError("Don't know how to work with {!r}. "
                        "It isn't a native Ion Trap operation, "
                        "a 1 or 2 qubit gate with a known unitary, "
                        "or composite.".format(op.gate))