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))
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 [