Repository: qutip/qutip-qip

Issue:
Incorrect indexing of `qubits` in `circuit.add_1q_gate`
Hello,  

I noticed what appears to be a typo in the `circuit.add_1q_gate` method when applying the 1q gate to specific qubits indexed in the `qubits` list. This might cause incorrect gate applications if the code is used as-is.

Current code:
https://github.com/qutip/qutip-qip/blob/2ff56326957e6d527362734c13f97dad4a6fbacc/src/qutip_qip/circuit/circuit.py#L300-L303


Proposed Fix:
```
 if qubits is not None: 
     for q_ in qubits: 
         gate = GATE_CLASS_MAP[name]( 
             targets=q_, 
```

Discussion:

Patch:
diff --git a/src/qutip_qip/circuit/circuit.py b/src/qutip_qip/circuit/circuit.py
index b8bc29b..d680241 100644
--- a/src/qutip_qip/circuit/circuit.py
+++ b/src/qutip_qip/circuit/circuit.py
@@ -280,11 +280,7 @@ class QubitCircuit:
         start=0,
         end=None,
         qubits=None,
-        arg_value=None,
-        arg_label=None,
-        classical_controls=None,
-        control_value=None,
-        classical_control_value=None,
+        **kwargs,
     ):
         """
         Adds a single qubit gate with specified parameters on a variable
@@ -294,45 +290,21 @@ class QubitCircuit:
         Parameters
         ----------
         name : string
-            Gate name.
+            Gate name or the :class:`~.operations.Gate` object.
         start : int
             Starting location of qubits.
         end : int
             Last qubit for the gate.
         qubits : list
             Specific qubits for applying gates.
-        arg_value : float
-            Argument value(phi).
-        arg_label : string
-            Label for gate representation.
-        """
-        if qubits is not None:
-            for _, i in enumerate(qubits):
-                gate = GATE_CLASS_MAP[name](
-                    targets=qubits[i],
-                    controls=None,
-                    arg_value=arg_value,
-                    arg_label=arg_label,
-                    classical_controls=classical_controls,
-                    control_value=control_value,
-                    classical_control_value=classical_control_value,
-                )
-                self.gates.append(gate)
-
-        else:
-            if end is None:
-                end = self.N - 1
-            for i in range(start, end + 1):
-                gate = GATE_CLASS_MAP[name](
-                    targets=i,
-                    controls=None,
-                    arg_value=arg_value,
-                    arg_label=arg_label,
-                    classical_controls=classical_controls,
-                    control_value=control_value,
-                    classical_control_value=classical_control_value,
-                )
-                self.gates.append(gate)
+        kwargs : dict
+            Keyword arguments for the gate, except for `targets`.
+            See :class:`~.QubitCircuit.add_gate`.
+        """
+        if qubits is None:
+            qubits = range(start, end + 1)
+        for q in qubits:
+            self.add_gate(name, targets=q, **kwargs)
 
     def add_circuit(self, qc, start=0, overwrite_user_gates=False):
         """
diff --git a/src/qutip_qip/circuit/texrenderer.py b/src/qutip_qip/circuit/texrenderer.py
index c668eee..94818f0 100644
--- a/src/qutip_qip/circuit/texrenderer.py
+++ b/src/qutip_qip/circuit/texrenderer.py
@@ -264,10 +264,12 @@ class TeXRenderer:
             )
 
     @staticmethod
-    def _convert_pdf(file_stem):
+    def _convert_pdf(file_stem, dpi=None):
         """
         'Convert' to pdf: since LaTeX outputs a PDF file, there's nothing to do.
         """
+        if dpi is not None:
+            warnings.warn("argument dpi is ignored for pdf output.")
         with open(file_stem + ".pdf", "rb") as file:
             return file.read()
 


Test patch:
diff --git a/tests/test_circuit.py b/tests/test_circuit.py
index 85eaf79..f79e781 100644
--- a/tests/test_circuit.py
+++ b/tests/test_circuit.py
@@ -138,6 +138,7 @@ class TestQubitCircuit:
         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)
+        qc.add_1q_gate("RX", qubits=[3], arg_value=-1.570796)
 
         # Test explicit gate addition
         assert qc.gates[0].name == "CNOT"
@@ -158,7 +159,12 @@ class TestQubitCircuit:
         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
+        assert qc.gates[6].arg_value == 1.570796
+
+        # Test adding 1 qubit gate on qubits [3] 
+        assert qc.gates[7].name == "RX"
+        assert qc.gates[7].targets == [3]
+        assert qc.gates[7].arg_value == -1.570796
 
         dummy_gate1 = Gate("DUMMY1")
         inds = [1, 3, 4, 6]
@@ -179,6 +185,7 @@ class TestQubitCircuit:
             'RY',       # 8
             'DUMMY1',   # 9
             'RY',       # 10
+            'RX',       # 11
         ]
         actual_gate_names = [gate.name for gate in qc.gates]
         assert actual_gate_names == expected_gate_names
@@ -202,6 +209,7 @@ class TestQubitCircuit:
             'DUMMY1',   # 10
             'RY',       # 11
             'DUMMY2',   # 12
+            'RX',       # 13
         ]
         actual_gate_names = [gate.name for gate in qc.gates]
         assert actual_gate_names == expected_gate_names