Repository: Qiskit/qiskit

Issue:
Approximate quantum compiler (AQC) returns a wrong circuit when the unitary has a determinant −1
### Environment

- **Qiskit Terra version**: 0.22.3
- **Python version**: 3.9.5
- **Operating system**: Windows 10


### What is happening?

When the approximate quantum compiler (AQC) is used to synthesis a unitary which has a determinant −1 (e.g., an "odd parity" permutation matrix), a warning message is displayed:
```
[...]synthesis\aqc\aqc.py:83: RuntimeWarning: invalid value encountered in power
  su_matrix = target_matrix / np.power(target_det, (1 / matrix_dim))
```
then it continues its work and generates a circuit. The unitary of the generated circuit, however, is not an approximation to the original one.


### How can we reproduce the issue?

```python
unitary = np.ndarray(shape=(8, 8), buffer=np.array([
    [0, 1, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 1, 0, 0, 0, 0],
    [0, 0, 1, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 1, 0, 0, 0],
    [1, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 1, 0, 0],
    [0, 0, 0, 0, 0, 0, 1, 0],
    [0, 0, 0, 0, 0, 0, 0, 1],
], dtype=int), dtype=int)

num_qubits = 3

cnots = make_cnot_network(num_qubits = num_qubits, network_layout = 'spin', connectivity_type = 'full', depth = 0)

optimizer = L_BFGS_B()
aqc = AQC(optimizer)
approximate_circuit = CNOTUnitCircuit(num_qubits=num_qubits, cnots=cnots)
approximating_objective = DefaultCNOTUnitObjective(num_qubits=num_qubits, cnots=cnots)

aqc.compile_unitary(
    target_matrix=unitary,
    approximate_circuit=approximate_circuit,
    approximating_objective=approximating_objective,
)

approx_matrix = Operator(approximate_circuit).data
error = 0.5 * (np.linalg.norm(approx_matrix - unitary, "fro") ** 2)

print(error)
array_to_latex(approx_matrix)
```

### What should happen?

The code must take this case into account

### Any suggestions?

The root cause of this wrong behavior is this line of code:
```
su_matrix = target_matrix / np.power(target_det, (1 / matrix_dim))
```
As per numpy.power documentation:

> Negative values raised to a non-integral value will return `nan`. To get complex results, cast the input to `complex`.

The issue can be simply fixed by replacing this line with:
```
su_matrix = target_matrix / np.power(target_det, (1 / matrix_dim), dtype=complex)
```



Discussion:
Thanks @EgrettaThula for finding this bug, would you like to make a PR to implement your suggestion? You would just have to make the change you suggest, and add a test case.
I'll work on it.

Resolving patch:
diff --git a/qiskit/transpiler/synthesis/aqc/aqc.py b/qiskit/transpiler/synthesis/aqc/aqc.py
--- a/qiskit/transpiler/synthesis/aqc/aqc.py
+++ b/qiskit/transpiler/synthesis/aqc/aqc.py
@@ -87,7 +87,7 @@ def compile_unitary(
         # check if it is actually a special unitary matrix
         target_det = np.linalg.det(target_matrix)
         if not np.isclose(target_det, 1):
-            su_matrix = target_matrix / np.power(target_det, (1 / matrix_dim))
+            su_matrix = target_matrix / np.power(target_det, (1 / matrix_dim), dtype=complex)
             global_phase_required = True
         else:
             su_matrix = target_matrix


Test patch:
diff --git a/test/python/transpiler/aqc/test_aqc.py b/test/python/transpiler/aqc/test_aqc.py
--- a/test/python/transpiler/aqc/test_aqc.py
+++ b/test/python/transpiler/aqc/test_aqc.py
@@ -92,6 +92,39 @@ def test_aqc_fastgrad(self):
         error = 0.5 * (np.linalg.norm(approx_matrix - target_matrix, "fro") ** 2)
         self.assertTrue(error < 1e-3)
 
+    def test_aqc_determinant_minus_one(self):
+        """
+        Tests AQC on a matrix with determinant −1.
+        """
+        seed = 12345
+
+        num_qubits = int(3)
+        cnots = make_cnot_network(
+            num_qubits=num_qubits, network_layout="spin", connectivity_type="full", depth=0
+        )
+
+        optimizer = L_BFGS_B(maxiter=200)
+        aqc = AQC(optimizer=optimizer, seed=seed)
+
+        target_matrix = np.eye(2**num_qubits, dtype=int)
+        # Make a unitary with determinant −1 by swapping any two columns
+        target_matrix[:, 2], target_matrix[:, 3] = target_matrix[:, 3], target_matrix[:, 2].copy()
+
+        approximate_circuit = CNOTUnitCircuit(num_qubits, cnots)
+        approximating_objective = DefaultCNOTUnitObjective(num_qubits, cnots)
+
+        aqc.compile_unitary(
+            target_matrix=target_matrix,
+            approximate_circuit=approximate_circuit,
+            approximating_objective=approximating_objective,
+            initial_point=INITIAL_THETAS,
+        )
+
+        approx_matrix = Operator(approximate_circuit).data
+
+        error = 0.5 * (np.linalg.norm(approx_matrix - target_matrix, "fro") ** 2)
+        self.assertTrue(error < 1e-3)
+
 
 if __name__ == "__main__":
     unittest.main()