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 sqrtiswap_dec(self, gate): """ Compiler for the SQRTISWAP gate Notes ----- This version of sqrtiswap_dec has very low fidelity, please use iswap """ # FIXME This decomposition has poor behaviour pulse = np.zeros(self.num_ops) q1, q2 = gate.targets pulse[self._sz_ind[q1]] = self.wq[q1] - self.params["w0"] pulse[self._sz_ind[q2]] = self.wq[q2] - self.params["w0"] pulse[self._g_ind[q1]] = self.params["g"][q1] pulse[self._g_ind[q2]] = self.params["g"][q2] J = self.params["g"][q1] * self.params["g"][q2] * ( 1 / self.Delta[q1] + 1 / self.Delta[q2]) / 2 t = (4 * np.pi / abs(J)) / 8 self.dt_list.append(t) self.coeff_list.append(pulse) # corrections gate1 = Gate("RZ", [q1], None, arg_value=-np.pi / 4) self.rz_dec(gate1) gate2 = Gate("RZ", [q2], None, arg_value=-np.pi / 4) self.rz_dec(gate2) gate3 = Gate("GLOBALPHASE", None, None, arg_value=-np.pi / 4) self.globalphase_dec(gate3)
def iswap_compiler(self, gate, args): """ Compiler for the ISWAP gate """ q1, q2 = gate.targets pulse_info = [] pulse_name = "sz" + str(q1) coeff = self.wq[q1] - self.params["w0"] pulse_info += [(pulse_name, coeff)] pulse_name = "sz" + str(q2) coeff = self.wq[q2] - self.params["w0"] pulse_info += [(pulse_name, coeff)] pulse_name = "g" + str(q1) coeff = self.params["g"][q1] pulse_info += [(pulse_name, coeff)] pulse_name = "g" + str(q2) coeff = self.params["g"][q2] pulse_info += [(pulse_name, coeff)] J = self.params["g"][q1] * self.params["g"][q2] * ( 1 / self.Delta[q1] + 1 / self.Delta[q2]) / 2 tlist = (4 * np.pi / abs(J)) / 4 instruction_list = [Instruction(gate, tlist, pulse_info)] # corrections gate1 = Gate("RZ", [q1], None, arg_value=-np.pi/2.) compiled_gate1 = self.rz_compiler(gate1, args) instruction_list += compiled_gate1 gate2 = Gate("RZ", [q2], None, arg_value=-np.pi/2) compiled_gate2 = self.rz_compiler(gate2, args) instruction_list += compiled_gate2 gate3 = Gate("GLOBALPHASE", None, None, arg_value=-np.pi/2) self.globalphase_compiler(gate3, args) return instruction_list
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_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 main(): h_gate = Gate("SNOT", targets=[0]) qc.add_gate(h_gate) x_gate = Gate("X", targets=[1]) qc.add_gate(x_gate) mat = qc.propagators()[0] print(mat) zero = basis(2, 0) one = basis(2, 1) input = tensor(zero, zero) print("====== Input ========") print(input) print("====== Result =======") res = mat * input print(res) qc.png
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 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 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 sqrtiswap_compiler(self, gate, args): """ Compiler for the SQRTISWAP gate Notes ----- This version of sqrtiswap_compiler has very low fidelity, please use iswap """ # FIXME This decomposition has poor behaviour q1, q2 = gate.targets pulse_info = [] pulse_name = "sz" + str(q1) coeff = self.wq[q1] - self.params["w0"] pulse_info += [(pulse_name, coeff)] pulse_name = "sz" + str(q1) coeff = self.wq[q2] - self.params["w0"] pulse_info += [(pulse_name, coeff)] pulse_name = "g" + str(q1) coeff = self.params["g"][q1] pulse_info += [(pulse_name, coeff)] pulse_name = "g" + str(q2) coeff = self.params["g"][q2] pulse_info += [(pulse_name, coeff)] J = self.params["g"][q1] * self.params["g"][q2] * ( 1 / self.Delta[q1] + 1 / self.Delta[q2]) / 2 tlist = (4 * np.pi / abs(J)) / 8 instruction_list = [Instruction(gate, tlist, pulse_info)] # corrections gate1 = Gate("RZ", [q1], None, arg_value=-np.pi/4) compiled_gate1 = self.rz_compiler(gate1, args) instruction_list += compiled_gate1 gate2 = Gate("RZ", [q2], None, arg_value=-np.pi/4) compiled_gate2 = self.rz_compiler(gate2, args) instruction_list += compiled_gate2 gate3 = Gate("GLOBALPHASE", None, None, arg_value=-np.pi/4) self.globalphase_compiler(gate3, args) return instruction_list
def iswap_dec(self, gate): """ Compiler for the ISWAP gate """ pulse = np.zeros(self.num_ops) q1, q2 = gate.targets pulse[self._sz_ind[q1]] = self.wq[q1] - self.params["w0"] pulse[self._sz_ind[q2]] = self.wq[q2] - self.params["w0"] pulse[self._g_ind[q1]] = self.params["g"][q1] pulse[self._g_ind[q2]] = self.params["g"][q2] J = self.params["g"][q1] * self.params["g"][q2] * ( 1 / self.Delta[q1] + 1 / self.Delta[q2]) / 2 t = (4 * np.pi / abs(J)) / 4 self.dt_list.append(t) self.coeff_list.append(pulse) # corrections gate1 = Gate("RZ", [q1], None, arg_value=-np.pi / 2.) self.rz_dec(gate1) gate2 = Gate("RZ", [q2], None, arg_value=-np.pi / 2) self.rz_dec(gate2) gate3 = Gate("GLOBALPHASE", None, None, arg_value=-np.pi / 2) self.globalphase_dec(gate3)
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_1q_gate("RY", start=4, end=5, arg_value=1.570796) qc1 = QubitCircuit(6) qc1.add_circuit(qc) # Test if all gates are added assert_(len(qc1.gates) == len(qc.gates)) # Test each gate 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) assert_(qc1.gates[i].controls == qc.gates[i].controls) # Test exception when qubit out of range assert_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 qc.gates[i].controls is not None: assert_(qc2.gates[i].controls[0] == qc.gates[i].controls[0]+2)
def evolute(state): CNOT01 = Gate('CNOT', targets=1, controls=0) CNOT12 = Gate('CNOT', targets=2, controls=1) CNOT02 = Gate('CNOT', targets=2, controls=0) H0 = Gate('SNOT', targets=0) sqrtX0 = Gate('SQRTNOT', targets=0) H2 = Gate('SNOT', targets=2) qc = QubitCircuit(N=3) # qc.add_gate(sqrtX0) # qc.add_gate(sqrtX0) qc.add_gate(CNOT01) qc.add_gate(H0) # qc.add_gate(CNOT12) # qc.add_gate(H2) # qc.add_gate(CNOT02) # qc.add_gate(H2) gates_sequence = qc.propagators() scheme = oper.gate_sequence_product(gates_sequence) return scheme * state
def test_add_gate(self): """ Addition of a gate object directly 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_1q_gate("RY", start=4, end=5, arg_value=1.570796) # 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 # Test specified position gate addition assert qc.gates[3].name == test_gate.name assert qc.gates[3].targets == test_gate.targets # Test adding 1 qubit gate on [start, end] qubits assert qc.gates[5].name == "RY" assert qc.gates[5].targets == [4] assert qc.gates[5].arg_value == 1.570796 assert qc.gates[6].name == "RY" assert qc.gates[6].targets == [5] assert qc.gates[5].arg_value == 1.570796 # Test Exceptions # Global phase is not included for gate in _single_qubit_gates: if gate not in _para_gates: # No target pytest.raises(ValueError, qc.add_gate, gate, None, None) # Multiple targets pytest.raises(ValueError, qc.add_gate, gate, [0, 1, 2], None) # With control pytest.raises(ValueError, qc.add_gate, gate, [0], [1]) else: # No target pytest.raises(ValueError, qc.add_gate, gate, None, None, 1) # Multiple targets pytest.raises(ValueError, qc.add_gate, gate, [0, 1, 2], None, 1) # With control pytest.raises(ValueError, qc.add_gate, gate, [0], [1], 1) for gate in _ctrl_gates: if gate not in _para_gates: # No target pytest.raises(ValueError, qc.add_gate, gate, None, [1]) # No control pytest.raises(ValueError, qc.add_gate, gate, [0], None) else: # No target pytest.raises(ValueError, qc.add_gate, gate, None, [1], 1) # No control pytest.raises(ValueError, qc.add_gate, gate, [0], None, 1) for gate in _swap_like: if gate not in _para_gates: # Single target pytest.raises(ValueError, qc.add_gate, gate, [0], None) # With control pytest.raises(ValueError, qc.add_gate, gate, [0, 1], [3]) else: # Single target pytest.raises(ValueError, qc.add_gate, gate, [0], None, 1) # With control pytest.raises(ValueError, qc.add_gate, gate, [0, 1], [3], 1) for gate in _fredkin_like: # Single target pytest.raises(ValueError, qc.add_gate, gate, [0], [2]) # No control pytest.raises(ValueError, qc.add_gate, gate, [0, 1], None) for gate in _toffoli_like: # No target pytest.raises(ValueError, qc.add_gate, gate, None, [1, 2]) # Single control pytest.raises(ValueError, qc.add_gate, gate, [0], [1])
def test_add_gate(self): """ Addition of a gate object directly 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_1q_gate("RY", start=4, end=5, arg_value=1.570796) # 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 # Test specified position gate addition assert qc.gates[3].name == test_gate.name assert qc.gates[3].targets == test_gate.targets # Test adding 1 qubit gate on [start, end] qubits assert qc.gates[5].name == "RY" assert qc.gates[5].targets == [4] assert qc.gates[5].arg_value == 1.570796 assert qc.gates[6].name == "RY" assert qc.gates[6].targets == [5] assert qc.gates[5].arg_value == 1.570796 # Test Exceptions # Global phase is not included for gate in _single_qubit_gates: if gate not in _para_gates: # No target pytest.raises(ValueError, qc.add_gate, gate, None, None) # Multiple targets pytest.raises(ValueError, qc.add_gate, gate, [0, 1, 2], None) # With control pytest.raises(ValueError, qc.add_gate, gate, [0], [1]) else: # No target pytest.raises(ValueError, qc.add_gate, gate, None, None, 1) # Multiple targets pytest.raises(ValueError, qc.add_gate, gate, [0, 1, 2], None, 1) # With control pytest.raises(ValueError, qc.add_gate, gate, [0], [1], 1) for gate in _ctrl_gates: if gate not in _para_gates: # No target pytest.raises(ValueError, qc.add_gate, gate, None, [1]) # No control pytest.raises(ValueError, qc.add_gate, gate, [0], None) else: # No target pytest.raises(ValueError, qc.add_gate, gate, None, [1], 1) # No control pytest.raises(ValueError, qc.add_gate, gate, [0], None, 1) for gate in _swap_like: if gate not in _para_gates: # Single target pytest.raises(ValueError, qc.add_gate, gate, [0], None) # With control pytest.raises(ValueError, qc.add_gate, gate, [0, 1], [3]) else: # Single target pytest.raises(ValueError, qc.add_gate, gate, [0], None, 1) # With control pytest.raises(ValueError, qc.add_gate, gate, [0, 1], [3], 1) for gate in _fredkin_like: # Single target pytest.raises(ValueError, qc.add_gate, gate, [0], [2]) # No control pytest.raises(ValueError, qc.add_gate, gate, [0, 1], None) for gate in _toffoli_like: # No target pytest.raises(ValueError, qc.add_gate, gate, None, [1, 2]) # Single control pytest.raises(ValueError, qc.add_gate, gate, [0], [1]) dummy_gate1 = Gate("DUMMY1") inds = [1, 3, 4, 6] qc.add_gate(dummy_gate1, index=inds) # Test adding gates at multiple (sorted) indices at once. # NOTE: Every insertion shifts the indices in the original list of # gates by an additional position to the right. expected_gate_names = [ 'CNOT', # 0 'DUMMY1', # 1 'SWAP', # 2 'TOFFOLI', # 3 'DUMMY1', # 4 'SWAP', # 5 'DUMMY1', # 6 'SNOT', # 7 'RY', # 8 'DUMMY1', # 9 'RY', # 10 ] actual_gate_names = [gate.name for gate in qc.gates] assert actual_gate_names == expected_gate_names dummy_gate2 = Gate("DUMMY2") inds = [11, 0] qc.add_gate(dummy_gate2, index=inds) # Test adding gates at multiple (unsorted) indices at once. expected_gate_names = [ 'DUMMY2', # 0 'CNOT', # 1 'DUMMY1', # 2 'SWAP', # 3 'TOFFOLI', # 4 'DUMMY1', # 5 'SWAP', # 6 'DUMMY1', # 7 'SNOT', # 8 'RY', # 9 'DUMMY1', # 10 'RY', # 11 'DUMMY2', # 12 ] actual_gate_names = [gate.name for gate in qc.gates] assert actual_gate_names == expected_gate_names
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ############################################################################### import warnings import numpy as np import pytest import qutip from qutip.qip.circuit import Gate from qutip.qip.operations.gates import gate_sequence_product from qutip.qip.device.cavityqed import DispersiveCavityQED _tol = 1e-2 _iswap = Gate("ISWAP", targets=[0, 1]) _sqrt_iswap = Gate("SQRTISWAP", targets=[0, 1]) _rz = Gate("RZ", targets=[1], arg_value=np.pi / 2, arg_label=r"\pi/2") _rx = Gate("RX", targets=[0], arg_value=np.pi / 2, arg_label=r"\pi/2") @pytest.mark.parametrize("gates", [ pytest.param([_iswap], id="ISWAP"), pytest.param([_sqrt_iswap], id="SQRTISWAP", marks=pytest.mark.skip), pytest.param([_iswap, _rz, _rx], id="ISWAP RZ RX"), ]) def test_device_against_gate_sequence(gates): n_qubits = 3 circuit = qutip.qip.circuit.QubitCircuit(n_qubits) for gate in gates: circuit.add_gate(gate)
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ############################################################################### import warnings import numpy as np import pytest import qutip from qutip.qip.circuit import Gate from qutip.qip.operations.gates import gate_sequence_product from qutip.qip.device.cavityqed import DispersiveCavityQED from qutip.qip.device.spinchain import LinearSpinChain, CircularSpinChain _tol = 1e-2 _x = Gate("X", targets=[0]) _z = Gate("Z", targets=[0]) _y = Gate("Y", targets=[0]) _snot = Gate("SNOT", targets=[0]) _rz = Gate("RZ", targets=[0], arg_value=np.pi / 2, arg_label=r"\pi/2") _rx = Gate("RX", targets=[0], arg_value=np.pi / 2, arg_label=r"\pi/2") _ry = Gate("RY", targets=[0], arg_value=np.pi / 2, arg_label=r"\pi/2") _iswap = Gate("ISWAP", targets=[0, 1]) _cnot = Gate("CNOT", targets=[0], controls=[1]) _sqrt_iswap = Gate("SQRTISWAP", targets=[0, 1]) single_gate_tests = [ pytest.param(2, [_z], id="Z"), pytest.param(2, [_x], id="X"), pytest.param(2, [_y], id="Y"), pytest.param(2, [_snot], id="SNOT"),
def test_add_circuit(self): """ Addition of a circuit to a `QubitCircuit` """ def customer_gate1(arg_values): mat = np.zeros((4, 4), dtype=np.complex128) mat[0, 0] = mat[1, 1] = 1. mat[2:4, 2:4] = gates.rx(arg_values) return Qobj(mat, dims=[[2, 2], [2, 2]]) qc = QubitCircuit(6) qc.user_gates = {"CTRLRX": customer_gate1} 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) qc.add_gate("CTRLRX", targets=[1, 2], arg_value=np.pi / 2) qc1 = QubitCircuit(6) qc1.add_circuit(qc) # Test if all gates and measurements are added assert len(qc1.gates) == len(qc.gates) # Test if the definitions of user gates are added assert qc1.user_gates == qc.user_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) # Test exception when the operators to be added are not gates or measurements qc.gates[-1] = 0 pytest.raises(TypeError, qc2.add_circuit, qc)