Esempio n. 1
0
 def test_cnot_rxx_decompose(self):
     """Verify CNOT decomposition into RXX gate is correct"""
     cnot = Operator(CXGate())
     decomps = [cnot_rxx_decompose(),
                cnot_rxx_decompose(plus_ry=True, plus_rxx=True),
                cnot_rxx_decompose(plus_ry=True, plus_rxx=False),
                cnot_rxx_decompose(plus_ry=False, plus_rxx=True),
                cnot_rxx_decompose(plus_ry=False, plus_rxx=False)]
     for decomp in decomps:
         self.assertTrue(cnot.equiv(decomp))
Esempio n. 2
0
    def run(self, dag):
        """Run the MSBasisDecomposer pass on `dag`.

        Replace U3,CX nodes in input dag with equivalent Rx,Ry,Rxx gates.

        Args:
            dag(DAGCircuit): input dag

        Raises:
            QiskitError: if input dag includes gates outside U3,CX.

        Returns:
            DAGCircuit: output dag
        """
        one_q_decomposer = OneQubitEulerDecomposer(basis="XYX")
        cnot_decomposition = cnot_rxx_decompose()

        for node in dag.op_nodes():
            basic_insts = ["measure", "reset", "barrier", "snapshot", "delay"]
            if node.name in basic_insts:
                # TODO: this is legacy behavior. basic_insts should be removed and these
                #  instructions should be part of the device-reported basis. Currently, no
                #  backend reports "measure", for example.
                continue
            if node.name in self.basis_gates:  # If already a base, ignore.
                continue

            if not isinstance(node.op, self.supported_input_gates):
                raise QiskitError(
                    "Cannot convert the circuit to the given basis, %s. "
                    "No rule to expand instruction %s." % (str(self.basis_gates), node.op.name)
                )

            if isinstance(node.op, U3Gate):
                replacement_circuit = one_q_decomposer(node.op)
            elif isinstance(node.op, CXGate):
                # N.B. We can't circuit_to_dag once outside the loop because
                # substitute_node_with_dag will modify the input DAG if the
                # node to be replaced is conditional.

                replacement_circuit = cnot_decomposition
            else:
                raise QiskitError(
                    f"Unable to handle instruction ({node.op.name}, {type(node.op)})."
                )

            replacement_dag = circuit_to_dag(replacement_circuit)

            # N.B. wires kwarg can be omitted for both 1Q and 2Q substitutions.
            # For 1Q, one-to-one mapping is always correct. For 2Q,
            # cnot_rxx_decompose follows convention of control as q[0], target
            # as q[1], which matches qarg order in CX node.

            dag.substitute_node_with_dag(node, replacement_dag)

        return dag
def_x = QuantumCircuit(q)
for inst, qargs, cargs in [
    (HGate(), [q[0]], []),
    (SGate(), [q[0]], []),
    (SGate(), [q[0]], []),
    (HGate(), [q[0]], []),
]:
    def_x.append(inst, qargs, cargs)
_sel.add_equivalence(XGate(), def_x)


# CXGate

for plus_ry in [False, True]:
    for plus_rxx in [False, True]:
        cx_to_rxx = cnot_rxx_decompose(plus_ry, plus_rxx)
        _sel.add_equivalence(CXGate(), cx_to_rxx)

q = QuantumRegister(2, "q")
cx_to_cz = QuantumCircuit(q)
for inst, qargs, cargs in [
    (HGate(), [q[1]], []),
    (CZGate(), [q[0], q[1]], []),
    (HGate(), [q[1]], []),
]:
    cx_to_cz.append(inst, qargs, cargs)
_sel.add_equivalence(CXGate(), cx_to_cz)

q = QuantumRegister(2, "q")
cx_to_iswap = QuantumCircuit(q, global_phase=3 * pi / 4)
for inst, qargs, cargs in [