Repository: Qiskit/qiskit

Issue:
TwoLocal entangling map does not work for numpy integers
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Informations

- **Qiskit version**: 0.17.1
- **Python version**: 3
- **Operating system**: ubuntu 18

### What is the current behavior?
When generating an entangling map by virtue of numpy arrays (e.g. np.arange(num)) it raises a ValueError 
```ValueError: Invalid value of entanglement: [[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]]```



### Steps to reproduce the problem
Minimal working example

```
import qiskit
import numpy as np

L = 6

def create_map(L):
    return [(i,i+1) for i in np.arange(L-1)]

map1 = create_map(L)
print(map1)

map_by_hand1 = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
print(map_by_hand1)

print(map1 == map_by_hand1) # returns True

ansatz = qiskit.circuit.library.TwoLocal(L,"ry","cz",[map_by_hand1],reps=2, insert_barriers=True)
ansatz.draw("mpl") # works

ansatz = qiskit.circuit.library.TwoLocal(L,"ry","cz",[map1],reps=2, insert_barriers=True)
ansatz.draw("mpl") # raises ValueError
```

### What is the expected behavior?
Since map1 == map_by_hand1 is the same value, it is expected that both are viable options to pass as entangling maps.



### Suggested solutions
change the isinstance() check in n_local



Discussion:
Is it fixed?Can I work on it?
I do not believe anyone is looking at this - any PR would be linked back to the issue and there is none. Please, if you'd like to take a look at do so. Again a unit test, as I commented in the the issue you raised.
I tried creating a PR but it shows commits from earlier issue I was working on. How do I get around that? @Cryoris @woodsp-ibm 
You can rebase, starting from the first commit you want to remove (say with the SHA `SHA_FIRST`) and then mark all commits with `drop` that you don't want:
```
git rebase -i SHA_FIRST
```
I am lost here. Can I instead delete my fork and refork and start over? @cryoris

Resolving patch:
diff --git a/qiskit/circuit/library/n_local/n_local.py b/qiskit/circuit/library/n_local/n_local.py
--- a/qiskit/circuit/library/n_local/n_local.py
+++ b/qiskit/circuit/library/n_local/n_local.py
@@ -591,42 +591,62 @@ def get_entangler_map(
         num_i = len(entanglement)
 
         # entanglement is List[str]
-        if all(isinstance(e, str) for e in entanglement):
+        if all(isinstance(en, str) for en in entanglement):
             return get_entangler_map(n, self.num_qubits, entanglement[i % num_i], offset=i)
 
         # entanglement is List[int]
-        if all(isinstance(e, int) for e in entanglement):
-            return [entanglement]
+        if all(isinstance(en, (int, numpy.integer)) for en in entanglement):
+            return [[int(en) for en in entanglement]]
 
         # check if entanglement is List[List]
-        if not all(isinstance(e, (tuple, list)) for e in entanglement):
+        if not all(isinstance(en, (tuple, list)) for en in entanglement):
             raise ValueError("Invalid value of entanglement: {}".format(entanglement))
         num_j = len(entanglement[i % num_i])
 
         # entanglement is List[List[str]]
-        if all(isinstance(e2, str) for e in entanglement for e2 in e):
+        if all(isinstance(e2, str) for en in entanglement for e2 in en):
             return get_entangler_map(
                 n, self.num_qubits, entanglement[i % num_i][j % num_j], offset=i
             )
 
         # entanglement is List[List[int]]
-        if all(isinstance(e2, int) for e in entanglement for e2 in e):
+        if all(isinstance(e2, (int, numpy.int32, numpy.int64)) for en in entanglement for e2 in en):
+            for ind, en in enumerate(entanglement):
+                entanglement[ind] = tuple(map(int, en))
             return entanglement
 
         # check if entanglement is List[List[List]]
-        if not all(isinstance(e2, (tuple, list)) for e in entanglement for e2 in e):
+        if not all(isinstance(e2, (tuple, list)) for en in entanglement for e2 in en):
             raise ValueError("Invalid value of entanglement: {}".format(entanglement))
 
         # entanglement is List[List[List[int]]]
-        if all(isinstance(e3, int) for e in entanglement for e2 in e for e3 in e2):
+        if all(
+            isinstance(e3, (int, numpy.int32, numpy.int64))
+            for en in entanglement
+            for e2 in en
+            for e3 in e2
+        ):
+            for en in entanglement:
+                for ind, e2 in enumerate(en):
+                    en[ind] = tuple(map(int, e2))
             return entanglement[i % num_i]
 
         # check if entanglement is List[List[List[List]]]
-        if not all(isinstance(e3, (tuple, list)) for e in entanglement for e2 in e for e3 in e2):
+        if not all(isinstance(e3, (tuple, list)) for en in entanglement for e2 in en for e3 in e2):
             raise ValueError("Invalid value of entanglement: {}".format(entanglement))
 
         # entanglement is List[List[List[List[int]]]]
-        if all(isinstance(e4, int) for e in entanglement for e2 in e for e3 in e2 for e4 in e3):
+        if all(
+            isinstance(e4, (int, numpy.int32, numpy.int64))
+            for en in entanglement
+            for e2 in en
+            for e3 in e2
+            for e4 in e3
+        ):
+            for en in entanglement:
+                for e2 in en:
+                    for ind, e3 in enumerate(e2):
+                        e2[ind] = tuple(map(int, e3))
             return entanglement[i % num_i][j % num_j]
 
         raise ValueError("Invalid value of entanglement: {}".format(entanglement))


Test patch:
diff --git a/test/python/circuit/library/test_nlocal.py b/test/python/circuit/library/test_nlocal.py
--- a/test/python/circuit/library/test_nlocal.py
+++ b/test/python/circuit/library/test_nlocal.py
@@ -732,6 +732,31 @@ def test_circular_on_same_block_and_circuit_size(self):
 
         self.assertCircuitEqual(two.assign_parameters(parameters), ref)
 
+    def test_circuit_with_numpy_integers(self):
+        """Test if TwoLocal can be made from numpy integers"""
+        num_qubits = 6
+        reps = 3
+        expected_np32 = [
+            (i, j)
+            for i in np.arange(num_qubits, dtype=np.int32)
+            for j in np.arange(num_qubits, dtype=np.int32)
+            if i < j
+        ]
+        expected_np64 = [
+            (i, j)
+            for i in np.arange(num_qubits, dtype=np.int64)
+            for j in np.arange(num_qubits, dtype=np.int64)
+            if i < j
+        ]
+
+        two_np32 = TwoLocal(num_qubits, "ry", "cx", entanglement=expected_np32, reps=reps)
+        two_np64 = TwoLocal(num_qubits, "ry", "cx", entanglement=expected_np64, reps=reps)
+
+        expected_cx = reps * num_qubits * (num_qubits - 1) / 2
+
+        self.assertEqual(two_np32.count_ops()["cx"], expected_cx)
+        self.assertEqual(two_np64.count_ops()["cx"], expected_cx)
+
 
 if __name__ == "__main__":
     unittest.main()