def test_add_state(self): """ Addition of input and output states to a circuit. """ qc = QubitCircuit(3) qc.add_state("0", targets=[0]) qc.add_state("+", targets=[1], state_type="output") qc.add_state("-", targets=[1]) assert qc.input_states[0] == "0" assert qc.input_states[2] is None assert qc.output_states[1] == "+" qc1 = QubitCircuit(10) qc1.add_state("0", targets=[2, 3, 5, 6]) qc1.add_state("+", targets=[1, 4, 9]) qc1.add_state("A", targets=[1, 4, 9], state_type="output") qc1.add_state("A", targets=[1, 4, 9], state_type="output") qc1.add_state("beta", targets=[0], state_type="output") assert qc1.input_states[0] is None assert qc1.input_states[2] == "0" assert qc1.input_states[3] == "0" assert qc1.input_states[6] == "0" assert qc1.input_states[1] == "+" assert qc1.input_states[4] == "+" assert qc1.output_states[2] is None assert qc1.output_states[1] == "A" assert qc1.output_states[4] == "A" assert qc1.output_states[9] == "A" assert qc1.output_states[0] == "beta"
def test_add_circuit(self): """ Addition of a circuit to a `QubitCircuit` """ qc = QubitCircuit(6) qc.add_gate("CNOT", targets=[1], controls=[0]) test_gate = Gate("SWAP", targets=[1, 4]) qc.add_gate(test_gate) qc.add_gate("TOFFOLI", controls=[0, 1], targets=[2]) qc.add_gate("SNOT", targets=[3]) qc.add_gate(test_gate, index=[3]) qc.add_measurement("M0", targets=[0], classical_store=[1]) qc.add_1q_gate("RY", start=4, end=5, arg_value=1.570796) qc1 = QubitCircuit(6) qc1.add_circuit(qc) # Test if all gates and measurements are added assert len(qc1.gates) == len(qc.gates) for i in range(len(qc1.gates)): assert (qc1.gates[i].name == qc.gates[i].name) assert (qc1.gates[i].targets == qc.gates[i].targets) if (isinstance(qc1.gates[i], Gate) and isinstance(qc.gates[i], Gate)): assert (qc1.gates[i].controls == qc.gates[i].controls) assert (qc1.gates[i].classical_controls == qc.gates[i].classical_controls) elif (isinstance(qc1.gates[i], Measurement) and isinstance(qc.gates[i], Measurement)): assert (qc1.gates[i].classical_store == qc.gates[i].classical_store) # Test exception when qubit out of range pytest.raises(NotImplementedError, qc1.add_circuit, qc, start=4) qc2 = QubitCircuit(8) qc2.add_circuit(qc, start=2) # Test if all gates are added assert len(qc2.gates) == len(qc.gates) # Test if the positions are correct for i in range(len(qc2.gates)): if qc.gates[i].targets is not None: assert (qc2.gates[i].targets[0] == qc.gates[i].targets[0]+2) if (isinstance(qc.gates[i], Gate) and qc.gates[i].controls is not None): assert (qc2.gates[i].controls[0] == qc.gates[i].controls[0]+2)
def teleport(state, mres): q0, q1 = map(int, twoQ_basis[mres]) s0_name = twoQ_basis[mres] + '0' s1_name = twoQ_basis[mres] + '1' s0 = qt.bra(s0_name) s1 = qt.bra(s1_name) a = (s0 * state).tr() b = (s1 * state).tr() red_state = (a * qt.ket([0], 2) + b * qt.ket([1], 2)).unit() H = Gate('SNOT', targets=0) sqrtX = Gate('SQRTNOT', targets=0) qc = QubitCircuit(N=1) if q1 == 1: qc.add_gate(sqrtX) qc.add_gate(sqrtX) if q0 == 1: qc.add_gate(H) qc.add_gate(sqrtX) qc.add_gate(sqrtX) qc.add_gate(H) gates_sequence = qc.propagators() scheme = oper.gate_sequence_product(gates_sequence) return scheme * red_state
def test_export_import(): qc = QubitCircuit(3) qc.add_gate("CRY", targets=1, controls=0, arg_value=np.pi) qc.add_gate("CRX", targets=1, controls=0, arg_value=np.pi) qc.add_gate("CRZ", targets=1, controls=0, arg_value=np.pi) qc.add_gate("CNOT", targets=1, controls=0) qc.add_gate("TOFFOLI", targets=2, controls=[0, 1]) # qc.add_gate("SQRTNOT", targets=0) qc.add_gate("CS", targets=1, controls=0) qc.add_gate("CT", targets=1, controls=0) qc.add_gate("SWAP", targets=[0, 1]) qc.add_gate("QASMU", targets=[0], arg_value=[np.pi, np.pi, np.pi]) qc.add_gate("RX", targets=[0], arg_value=np.pi) qc.add_gate("RY", targets=[0], arg_value=np.pi) qc.add_gate("RZ", targets=[0], arg_value=np.pi) qc.add_gate("SNOT", targets=[0]) qc.add_gate("X", targets=[0]) qc.add_gate("Y", targets=[0]) qc.add_gate("Z", targets=[0]) qc.add_gate("S", targets=[0]) qc.add_gate("T", targets=[0]) # qc.add_gate("CSIGN", targets=[0], controls=[1]) read_qc = read_qasm(circuit_to_qasm_str(qc), strmode=True) props = qc.propagators() read_props = read_qc.propagators() for u0, u1 in zip(props, read_props): assert (u0 - u1).norm() < 1e-12
def test_dispersivecqed_combination(self): """ Dispersive cQED Setup: compare unitary matrix for ISWAP, SQRTISWAP, RX and RY gates and the propogator matrix of the implemented physical model. """ N = 3 qc1 = QubitCircuit(N) qc1.add_gate("ISWAP", targets=[0, 1]) qc1.add_gate("RZ", arg_value=np.pi / 2, arg_label=r"\pi/2", targets=[1]) qc1.add_gate("RX", arg_value=np.pi / 2, arg_label=r"\pi/2", targets=[0]) U_ideal = gate_sequence_product(qc1.propagators()) p = DispersivecQED(N, correct_global_phase=True) U_list = p.run(qc1) U_physical = gate_sequence_product(U_list) print((U_ideal - U_physical).norm()) assert_((U_ideal - U_physical).norm() < 1e-2)
def test_numerical_evo(self): """ Test of run_state with qutip solver """ N = 3 qc = QubitCircuit(N) qc.add_gate("RX", targets=[0], arg_value=np.pi / 2) qc.add_gate("CNOT", targets=[0], controls=[1]) qc.add_gate("ISWAP", targets=[2, 1]) qc.add_gate("CNOT", targets=[0], controls=[2]) # qc.add_gate("SQRTISWAP", targets=[0, 2]) with warnings.catch_warnings(record=True): test = DispersivecQED(N, g=0.1) tlist, coeff = test.load_circuit(qc) # test numerical run_state qu0 = rand_ket(2**N) qu0.dims = [[2] * N, [1] * N] rho0 = tensor(basis(10, 0), qu0) qu1 = gate_sequence_product([qu0] + qc.propagators()) result = test.run_state(rho0=rho0, analytical=False, options=Options(store_final_state=True, nsteps=50000)).final_state assert_allclose(fidelity(result, tensor(basis(10, 0), qu1)), 1., rtol=1e-2, err_msg="Numerical run_state fails in DispersivecQED")
def test_add_gate(self): """ Addition of a gate object directly to a `QubitCircuit` """ qc = QubitCircuit(3) qc.add_gate("CNOT", targets=[1], controls=[0]) test_gate = Gate("RZ", targets=[1], arg_value=1.570796, arg_label="P") qc.add_gate(test_gate) qc.add_gate("TOFFOLI", controls=[0, 1], targets=[2]) qc.add_gate("SNOT", targets=[3]) qc.add_gate(test_gate, index=[3]) # Test explicit gate addition assert_(qc.gates[0].name == "CNOT") assert_(qc.gates[0].targets == [1]) assert_(qc.gates[0].controls == [0]) # Test direct gate addition assert_(qc.gates[1].name == test_gate.name) assert_(qc.gates[1].targets == test_gate.targets) assert_(qc.gates[1].controls == test_gate.controls) # Test specified position gate addition assert_(qc.gates[3].name == test_gate.name) assert_(qc.gates[3].targets == test_gate.targets) assert_(qc.gates[3].controls == test_gate.controls)
def measurement_circuit(indices): """ Return a measurement circuit for the given Pauli decomposition term. :param str indices: The Pauli terms to return a measurement circuit for. The returned circuit rotates the +1 and -1 eigenspaces of the Pauli term into the computational basis. :return QubitCircuit: A circuit that will rotate the Pauli measurement into the computational basis. Note:: If the indices are "I" or "II" or "III..." this function will return `None`. These terms have only a (repeated) +1 eigenvalue and so cannot be measured in the same way as the other terms. Passing the identity terms is supported here for convenience, but measurement on these terms always returned the eigenvalue +1. """ n = len(indices) assert n in PAULI_MEASUREMENT_CIRCUITS if indices == "I" * n: return None qc = QubitCircuit(N=n) for gate, kwargs in PAULI_MEASUREMENT_CIRCUITS[n][indices]: qc.add_gate(gate, **kwargs) return qc
def test_reverse(self): """ Reverse a quantum circuit """ qc = QubitCircuit(3) qc.add_gate("RX", targets=[0], arg_value=3.141, arg_label=r"\pi/2") qc.add_gate("CNOT", targets=[1], controls=[0]) qc.add_gate("SNOT", targets=[2]) # Keep input output same qc.add_state("0", targets=[0]) qc.add_state("+", targets=[1], state_type="output") qc.add_state("-", targets=[1]) qc.reverse_circuit() assert_(qc.gates[2].name == "SNOT") assert_(qc.gates[1].name == "CNOT") assert_(qc.gates[0].name == "RX") assert_(qc.input_states[0] == "0") assert_(qc.input_states[2] == None) assert_(qc.output_states[1] == "+")
def __permute_circuit(self, qc2add, pos=None): """ **Override the add_circuit function in QuTiP** Adds a block of a qubit circuit to the main circuit. Globalphase gates are not added. Parameters ---------- qc : QubitCircuit The circuit block to be added to the main circuit. pos : list The arrangement of qubits. """ if pos is not None: temp_qc = QubitCircuit(self.N) if max(pos) >= self.N or min(pos) < 0: raise NotImplementedError("Qubit allocated outside the circuit") for gate in qc2add.gates: if gate.targets is not None: temp_tar = [pos[target] for target in gate.targets] else: temp_tar = None if gate.controls is not None: temp_ctrl = [pos[control] for control in gate.controls] else: temp_ctrl = None temp_qc.add_gate(gate.name, temp_tar, temp_ctrl, gate.arg_value,gate.arg_label), return temp_qc else: return qc2add
def _measurement_circuit(): qc = QubitCircuit(2, num_cbits=2) qc.add_measurement("M0", targets=[0], classical_store=0) qc.add_measurement("M1", targets=[1], classical_store=1) return qc
def test_user_gate(self): """ User defined gate for QubitCircuit """ def customer_gate1(arg_values): mat = np.zeros((4, 4), dtype=np.complex) mat[0, 0] = mat[1, 1] = 1. mat[2:4, 2:4] = gates.rx(arg_values) return Qobj(mat, dims=[[2, 2], [2, 2]]) def customer_gate2(): mat = np.array([[1., 0], [0., 1.j]]) return Qobj(mat, dims=[[2], [2]]) qc = QubitCircuit(3) qc.user_gates = {"CTRLRX": customer_gate1, "T1": customer_gate2} qc.add_gate("CTRLRX", targets=[1, 2], arg_value=np.pi/2) qc.add_gate("T1", targets=[1]) props = qc.propagators() result1 = tensor(identity(2), customer_gate1(np.pi/2)) np.testing.assert_allclose(props[0], result1) result2 = tensor(identity(2), customer_gate2(), identity(2)) np.testing.assert_allclose(props[1], result2)
def test_scheduling_pulse( instructions, method, expected_length, random_shuffle, gates_schedule): circuit = QubitCircuit(4) for instruction in instructions: circuit.add_gate( Gate(instruction.name, instruction.targets, instruction.controls)) if random_shuffle: repeat_num = 5 else: repeat_num = 0 result0 = gate_sequence_product(circuit.propagators()) # run the scheduler scheduler = Scheduler(method) gate_cycle_indices = scheduler.schedule( instructions, gates_schedule=gates_schedule, repeat_num=repeat_num) # check if the scheduled length is expected assert(max(gate_cycle_indices) == expected_length) scheduled_gate = [[] for i in range(max(gate_cycle_indices)+1)] # check if the scheduled circuit is correct for i, cycles in enumerate(gate_cycle_indices): scheduled_gate[cycles].append(circuit.gates[i]) circuit.gates = sum(scheduled_gate, []) result1 = gate_sequence_product(circuit.propagators()) assert(tracedist(result0*result1.dag(), qeye(result0.dims[0])) < 1.0e-7)
def test_reverse(self): """ Reverse a quantum circuit """ qc = QubitCircuit(3) qc.add_gate("RX", targets=[0], arg_value=3.141, arg_label=r"\pi/2") qc.add_gate("CNOT", targets=[1], controls=[0]) qc.add_measurement("M1", targets=[1]) qc.add_gate("SNOT", targets=[2]) # Keep input output same qc.add_state("0", targets=[0]) qc.add_state("+", targets=[1], state_type="output") qc.add_state("-", targets=[1]) qc_rev = qc.reverse_circuit() assert qc_rev.gates[0].name == "SNOT" assert qc_rev.gates[1].name == "M1" assert qc_rev.gates[2].name == "CNOT" assert qc_rev.gates[3].name == "RX" assert qc_rev.input_states[0] == "0" assert qc_rev.input_states[2] is None assert qc_rev.output_states[1] == "+"
def test_simple_hadamard(self): N = 1 H_d = sigmaz() H_c = [sigmax()] qc = QubitCircuit(N) qc.add_gate("SNOT", 0) # test load_circuit, with verbose info num_tslots = 10 evo_time = 10 test = OptPulseProcessor(N, H_d, H_c) tlist, coeffs = test.load_circuit( qc, num_tslots=num_tslots, evo_time=evo_time, verbose=True) # test run_state rho0 = qubit_states(1, [0]) plus = (qubit_states(1, [0]) + qubit_states(1, [1])).unit() result = test.run_state(rho0) assert_allclose(fidelity(result.states[-1], plus), 1, rtol=1.0e-6) # test add/remove ctrl test.add_ctrl(sigmay()) test.remove_ctrl(0) assert_( len(test.ctrls) == 1, msg="Method of remove_ctrl could be wrong.") assert_allclose(test.drift, H_d) assert_( sigmay() in test.ctrls, msg="Method of remove_ctrl could be wrong.")
def test_simple_hadamard(self): """ Test for optimizing a simple hadamard gate """ N = 1 H_d = sigmaz() H_c = sigmax() qc = QubitCircuit(N) qc.add_gate("SNOT", 0) # test load_circuit, with verbose info num_tslots = 10 evo_time = 10 test = OptPulseProcessor(N, drift=H_d) test.add_control(H_c, targets=0) tlist, coeffs = test.load_circuit(qc, num_tslots=num_tslots, evo_time=evo_time, verbose=True) # test run_state rho0 = qubit_states(1, [0]) plus = (qubit_states(1, [0]) + qubit_states(1, [1])).unit() result = test.run_state(rho0) assert_allclose(fidelity(result.states[-1], plus), 1, rtol=1.0e-6) # test add/remove ctrl test.add_control(sigmay()) test.remove_pulse(0) assert_(len(test.pulses) == 1, msg="Method of remove_pulse could be wrong.") assert_allclose(test.drift.drift_hamiltonians[0].qobj, H_d) assert_(sigmay() in test.ctrls, msg="Method of remove_pulse could be wrong.")
def test_multi_gates(self): N = 2 H_d = tensor([sigmaz()]*2) H_c = [] test = OptPulseProcessor(N, H_d, H_c) test.add_ctrl(sigmax(), cyclic_permutation=True) test.add_ctrl(sigmay(), cyclic_permutation=True) test.add_ctrl(tensor([sigmay(), sigmay()])) # qubits circuit with 3 gates setting_args = {"SNOT": {"num_tslots": 10, "evo_time": 1}, "SWAP": {"num_tslots": 30, "evo_time": 3}, "CNOT": {"num_tslots": 30, "evo_time": 3}} qc = QubitCircuit(N) qc.add_gate("SNOT", 0) qc.add_gate("SWAP", targets=[0, 1]) qc.add_gate('CNOT', controls=1, targets=[0]) test.load_circuit(qc, setting_args=setting_args, merge_gates=False) rho0 = rand_ket(4) # use random generated ket state rho0.dims = [[2, 2], [1, 1]] U = gate_sequence_product(qc.propagators()) rho1 = U * rho0 result = test.run_state(rho0) assert_(fidelity(result.states[-1], rho1) > 1-1.0e-6)
def dispersive_gate_correction(self, qc1, rwa=True): """ Method to resolve ISWAP and SQRTISWAP gates in a cQED system by adding single qubit gates to get the correct output matrix. Parameters ---------- qc: Qobj The circular spin chain circuit to be resolved rwa: Boolean Specify if RWA is used or not. Returns ---------- qc: QubitCircuit Returns QubitCircuit of resolved gates for the qubit circuit in the desired basis. """ qc = QubitCircuit(qc1.N, qc1.reverse_states) for gate in qc1.gates: qc.gates.append(gate) if rwa: if gate.name == "SQRTISWAP": qc.gates.append( Gate("RZ", [gate.targets[0]], None, arg_value=-np.pi / 4, arg_label=r"-\pi/4")) qc.gates.append( Gate("RZ", [gate.targets[1]], None, arg_value=-np.pi / 4, arg_label=r"-\pi/4")) qc.gates.append( Gate("GLOBALPHASE", None, None, arg_value=-np.pi / 4, arg_label=r"-\pi/4")) elif gate.name == "ISWAP": qc.gates.append( Gate("RZ", [gate.targets[0]], None, arg_value=-np.pi / 2, arg_label=r"-\pi/2")) qc.gates.append( Gate("RZ", [gate.targets[1]], None, arg_value=-np.pi / 2, arg_label=r"-\pi/2")) qc.gates.append( Gate("GLOBALPHASE", None, None, arg_value=-np.pi / 2, arg_label=r"-\pi/2")) return qc
def testresolve(self, gate_from, gate_to, targets, controls): qc1 = QubitCircuit(2) qc1.add_gate(gate_from, targets=targets, controls=controls) U1 = gates.gate_sequence_product(qc1.propagators()) qc2 = qc1.resolve_gates(basis=gate_to) U2 = gates.gate_sequence_product(qc2.propagators()) assert _op_dist(U1, U2) < 1e-12
def test_N_level_system(self): """ Test for circuit with N-level system. """ mat3 = rand_unitary_haar(3) def controlled_mat3(arg_value): """ A qubit control an operator acting on a 3 level system """ control_value = arg_value dim = mat3.dims[0][0] return (tensor(fock_dm(2, control_value), mat3) + tensor(fock_dm(2, 1 - control_value), identity(dim))) qc = QubitCircuit(2, dims=[3, 2]) qc.user_gates = {"CTRLMAT3": controlled_mat3} qc.add_gate("CTRLMAT3", targets=[1, 0], arg_value=1) props = qc.propagators() final_fid = average_gate_fidelity(mat3, ptrace(props[0], 0) - 1) assert pytest.approx(final_fid, 1.0e-6) == 1 init_state = basis([3, 2], [0, 1]) result = qc.run(init_state) final_fid = fidelity(result, props[0] * init_state) assert pytest.approx(final_fid, 1.0e-6) == 1.
def test_qasm_str(): expected_qasm_str = ('// QASM 2.0 file generated by QuTiP\n\nOPENQASM 2.0;' '\ninclude "qelib1.inc";\n\nqreg q[2];\ncreg c[1];\n\n' 'x q[0];\nmeasure q[1] -> c[0]\n') simple_qc = QubitCircuit(2, num_cbits=1) simple_qc.add_gate("X", targets=[0]) simple_qc.add_measurement("M", targets=[1], classical_store=0) assert circuit_to_qasm_str(simple_qc) == expected_qasm_str
def read_qasm(qasm_input, mode="qiskit", version="2.0", strmode=False): ''' Read OpenQASM intermediate representation (https://github.com/Qiskit/openqasm) and return a :class:`.QubitCircuit` and state inputs as specified in the QASM file. Parameters ---------- qasm_input : str File location or String Input for QASM file to be imported. In case of string input, the parameter strmode must be True. mode : str QASM mode to be read in. When mode is "qiskit", the "qelib1.inc" include is automatically included, without checking externally. Otherwise, each include is processed. version : str QASM version of the QASM file. Only version 2.0 is currently supported. strmode : bool if specified as True, indicates that qasm_input is in string format rather than from file. Returns ------- qc : :class:`.QubitCircuit` Returns a :class:`.QubitCircuit` object specified in the QASM file. ''' if strmode: qasm_lines = qasm_input.splitlines() else: f = open(qasm_input, "r") qasm_lines = f.read().splitlines() f.close() # split input into lines and ignore comments qasm_lines = [line.strip() for line in qasm_lines] qasm_lines = list(filter(lambda x: x[:2] != "//" and x != "", qasm_lines)) if version != "2.0": raise NotImplementedError("QASM: Only OpenQASM 2.0 \ is currently supported.") if qasm_lines.pop(0) != "OPENQASM 2.0;": raise SyntaxError("QASM: File does not contain QASM 2.0 header") qasm_obj = QasmProcessor(qasm_lines, mode=mode, version=version) qasm_obj.commands = _tokenize(qasm_obj.commands) qasm_obj._process_includes() qasm_obj._initialize_pass() qc = QubitCircuit(qasm_obj.num_qubits, num_cbits=qasm_obj.num_cbits) qasm_obj._final_pass(qc) return qc
def _swap_qubits(self, all_keys, keys): swap_circuit = QubitCircuit(N=len(all_keys)) for i, key in enumerate(keys): j = all_keys.index(key) if j != i: gate = Gate("SWAP", targets=[i, j]) swap_circuit.add_gate(gate) all_keys[i], all_keys[j] = all_keys[j], all_keys[i] swap_mat = gate_sequence_product(swap_circuit.propagators()).full() return all_keys, swap_mat
def bell_prep(N, post_proc=False): qc = QubitCircuit(N * 2) if post_proc == False: iterator = range(N) else: iterator = reversed(range(N)) for i in iterator: qc.add_gate("CNOT", i + N, i) qc.add_gate("SNOT", i) return qc
def _circuit1(): circuit1 = QubitCircuit(6) circuit1.add_gate("SNOT", 2) circuit1.add_gate("CNOT", 4, 2) circuit1.add_gate("CNOT", 3, 2) circuit1.add_gate("CNOT", 1, 2) circuit1.add_gate("CNOT", 5, 4) circuit1.add_gate("CNOT", 1, 5) circuit1.add_gate("SWAP", [0, 1]) return circuit1
def testGateParams(a1, a2, a3, a4): QC = QubitCircuit(2) QC.add_gate("RX", targets=0, arg_value=a1) QC.add_gate("RY", targets=1, arg_value=a2) QC.add_gate("CNOT", targets=1, controls=0) QC.add_gate("RY", targets=0, arg_value=a3) QC.add_gate("RX", targets=1, arg_value=a4) U_list = QC.propagators() finalGate = gate_sequence_product(U_list) return calcGateFidelityN(finalGate, targetGate, 2)
def testCNOTtoCSIGN(self): """ CNOT to CSIGN: compare unitary matrix for CNOT and product of resolved matrices in terms of CSIGN. """ qc1 = QubitCircuit(2) qc1.add_gate("CNOT", targets=[0], controls=[1]) U1 = gate_sequence_product(qc1.propagators()) qc2 = qc1.resolve_gates(basis="CSIGN") U2 = gate_sequence_product(qc2.propagators()) assert_((U1 - U2).norm() < 1e-12)
def testFREDKINdecompose(self): """ FREDKIN to rotation and CNOT: compare unitary matrix for FREDKIN and product of resolved matrices in terms of rotation gates and CNOT. """ qc1 = QubitCircuit(3) qc1.add_gate("FREDKIN", targets=[0, 1], controls=[2]) U1 = gates.gate_sequence_product(qc1.propagators()) qc2 = qc1.resolve_gates() U2 = gates.gate_sequence_product(qc2.propagators()) assert _op_dist(U1, U2) < 1e-12
def testSNOTdecompose(self): """ SNOT to rotation: compare unitary matrix for SNOT and product of resolved matrices in terms of rotation gates. """ qc1 = QubitCircuit(1) qc1.add_gate("SNOT", targets=0) U1 = gates.gate_sequence_product(qc1.propagators()) qc2 = qc1.resolve_gates() U2 = gates.gate_sequence_product(qc2.propagators()) assert _op_dist(U1, U2) < 1e-12
def testISWAPtoCNOT(self): """ ISWAP to CNOT: compare unitary matrix for ISWAP and product of resolved matrices in terms of CNOT. """ qc1 = QubitCircuit(2) qc1.add_gate("ISWAP", targets=[0, 1]) U1 = gate_sequence_product(qc1.propagators()) qc2 = qc1.resolve_gates(basis="CNOT") U2 = gate_sequence_product(qc2.propagators()) assert_((U1 - U2).norm() < 1e-12)