Repository: Qiskit/qiskit

Issue:
U†U ≠ I, AE circuit inverse broken by terra 16.2 
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information


Qiskit Software | Version
-- | --
Qiskit | 0.23.6
Terra | 0.16.4
Aer | 0.7.5
Ignis | 0.5.2
Aqua | 0.8.2
IBM Q Provider | 0.11.1

Python | 3.7.3 (default, Mar 27 2019, 16:54:48)  [Clang 4.0.1 (tags/RELEASE_401/final)]
OS | Darwin
CPUs | 4
Memory (Gb) | 16.0
Fri Feb 26 13:52:49 2021 CST

### What is the current behavior?
After qiskit-terra 16.1, applying an Amplitude Estimation circuit, followed immediately by it's inverse fails to return me to the same initial state. 


### Steps to reproduce the problem

```
import sys
import numpy as np
import qiskit
from qiskit import QuantumRegister, QuantumCircuit, Aer, execute, ClassicalRegister
from qiskit.aqua.algorithms import AmplitudeEstimation
from qiskit.aqua.operators import CircuitOp, Zero, One
from qiskit.tools.visualization import plot_histogram
import matplotlib.pyplot as plt

theta = 0.65
m = 5 #number of evaluation qubits

q = QuantumRegister(1, 'q') # objective qubit
ae_q = QuantumRegister(m, 'm') # AE output register
c = ClassicalRegister(m, 'c')
qc = QuantumCircuit(q, ae_q)#, c)

# State preparation circuit
qc2 = QuantumCircuit(q) 
qc2.ry(theta, q[0])

# Forward AE
ae = AmplitudeEstimation(m, state_preparation=qc2, objective_qubits=[0])
ae_inst = ae.construct_circuit().to_instruction()
qc.append(ae_inst, list(ae_q) + list(q))

#Reverse AE
ae_inst_r = ae.construct_circuit().inverse().to_instruction()
qc.append(ae_inst_r, list(ae_q) + list(q))

#qc.measure(ae_q, c)
qc.decompose().draw()
qc_op = CircuitOp(qc)
print("<0|U^dg U|0> = {}".format((~Zero @  qc_op @ Zero).eval()))
print("<0|U^dg U|0> = {}".format((~Zero @ (qc_op @ Zero).eval()).eval()))
print("<0|U^dg U|0> = {}".format(((~Zero @ qc_op).eval() @ Zero).eval()))

import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
```
Output:
```
<0|U^dg U|0> = (0.99999999999999+6.514e-15j)
<0|U^dg U|0> = 0j
<0|U^dg U|0> = (0.99999999999999+6.514e-15j)
```

### What is the expected behavior?

```
<0|U^dg U|0> = (0.99999999999999+6.221e-15j)
<0|U^dg U|0> = (0.99999999999999-6.221e-15j)
<0|U^dg U|0> = (0.99999999999999+6.221e-15j)
```

When run with:


Qiskit Software | Version
-- | --
Qiskit | 0.23.6
**Terra** | **0.16.1**
Aer | 0.7.5
Ignis | 0.5.2
Aqua | 0.8.2
IBM Q Provider | 0.11.1

Python | 3.7.3 (default, Mar 27 2019, 16:54:48)  [Clang 4.0.1 (tags/RELEASE_401/final)]
OS | Darwin
CPUs | 4
Memory (Gb) | 16.0
Fri Feb 26 13:55:18 2021 CST




### Suggested solutions

I would first look into why evaluating <0| U†U does not equal the conj-transpose of U†U|0> when computed via Opflow (as shown above). Note that if you do not use Opflow, and instead execute the circuit directly, you will see the same error. I was only able to get the correct output by fiddling with the order in which Opflow was evaluating terms.





Discussion:

Resolving patch:
diff --git a/qiskit/circuit/instruction.py b/qiskit/circuit/instruction.py
--- a/qiskit/circuit/instruction.py
+++ b/qiskit/circuit/instruction.py
@@ -333,7 +333,8 @@ def inverse(self):
                                 num_qubits=self.num_qubits,
                                 params=self.params.copy())
 
-        inverse_gate.definition = QuantumCircuit(*self.definition.qregs, *self.definition.cregs)
+        inverse_gate.definition = QuantumCircuit(*self.definition.qregs, *self.definition.cregs,
+                                                 global_phase=-self.definition.global_phase)
         inverse_gate.definition._data = [(inst.inverse(), qargs, cargs)
                                          for inst, qargs, cargs in reversed(self._definition)]
 


Test patch:
diff --git a/test/python/circuit/test_instructions.py b/test/python/circuit/test_instructions.py
--- a/test/python/circuit/test_instructions.py
+++ b/test/python/circuit/test_instructions.py
@@ -323,6 +323,17 @@ def test_inverse_empty(self):
         empty_gate = empty_circ.to_instruction()
         self.assertEqual(empty_gate.inverse().definition, empty_gate.definition)
 
+    def test_inverse_with_global_phase(self):
+        """test inverting instruction with global phase in definition."""
+        q = QuantumRegister(1)
+        circ = QuantumCircuit(q, name='circ', global_phase=np.pi / 3)
+        circ.x(q)
+        gate = circ.to_instruction()
+        circ = QuantumCircuit(q, name='circ', global_phase=-np.pi / 3)
+        circ.x(q)
+        gate_inverse = circ.to_instruction()
+        self.assertEqual(gate.inverse().definition, gate_inverse.definition)
+
     def test_no_broadcast(self):
         """See https://github.com/Qiskit/qiskit-terra/issues/2777
         When creating custom instructions, do not broadcast parameters"""