Repository: Qiskit/qiskit

Issue:
Operator(circuit) does not return the correct unitary
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

-Qiskit Terra version:  0.8.1
-Python version: 3.7.2
-Operating system: MacOS Mojave

### What is the current behavior?

The data stored in Operator(circuit).data (with Operator imported from qiskit.quantum_info
) seems not to correspond to the right unitary for certain circuits.

### Steps to reproduce the problem

Choose the following circuit:

qasm = 'OPENQASM 2.0;'
qasm += 'include "qelib1.inc";'
qasm += 'qreg q[3];'
qasm += 'creg c[3];'
qasm += 'rx(3.141592653589793) q[2];'
qasm += 'ry(0.294524311274043) q[2];'
qasm += 'cx q[0],q[2];'
qasm += 'ry(-0.0981747704246810) q[2];'
qasm += 'cx q[1],q[2];'
qasm += 'ry(0.0981747704246810) q[2];'
qasm += 'cx q[0],q[2];'
qasm += 'ry(-3.141592653589793) q[2];'
circuit = QuantumCircuit.from_qasm_str(qasm)

One finds a different result [than the one found by(Operator(circuit).data] using the unitary_simulator:

simulator = BasicAer.get_backend('unitary_simulator')
result = execute(circuit, simulator).result()
unitary = result.get_unitary(circuit)
matrix_equal(Operator(circuit).data, unitary, ignore_phase=True)

The last line returns False.



Discussion:
This does indeed look like a bug in the operator class.  The numerical values appear to be correct, but the indices are not.  So it seems that there is some array manipulations that are not correct.
To make reproducing easier, here is the circuit:
```python
q = QuantumRegister(3, 'q')
c = ClassicalRegister(3, 'c')
qc = QuantumCircuit(q, c)
qc.rx(3.141592653589793, q[2])
qc.ry(0.294524311274043, q[2])
qc.cx(q[0], q[2])
qc.ry(-0.0981747704246810, q[2])
qc.cx(q[1], q[2])
qc.ry(0.0981747704246810, q[2])
qc.cx(q[0], q[2])
qc.ry(-3.141592653589793, q[2])
```
Looks like the single qubit gate is getting applied to the wrong index, but only for rx, ry, rz.
If I run the following circuit with some debugging prints added the last three are getting applied to `q[0]` instead of `q[2]`. 

```python
q = QuantumRegister(3, 'q')
qc = QuantumCircuit(q)
qc.iden(q[2])
qc.x(q[2])
qc.y(q[2])
qc.z(q[2])
qc.h(q[2])
qc.s(q[2])
qc.sdg(q[2])
qc.t(q[2])
qc.tdg(q[2])
qc.u1(0.2, q[2])
qc.u2(0.1, 0.2, q[2])
qc.u3(0.1, 0.2, 0.3, q[2])
qc.rz(0.294524311274043, q[2])
qc.ry(0.294524311274043, q[2])
qc.rz(0.294524311274043, q[2])
```

My guess is there is a bug in how `Operator` unrolls gates without a matrix def. I'll look into a fix.

Resolving patch:
diff --git a/qiskit/quantum_info/operators/channel/superop.py b/qiskit/quantum_info/operators/channel/superop.py
--- a/qiskit/quantum_info/operators/channel/superop.py
+++ b/qiskit/quantum_info/operators/channel/superop.py
@@ -474,7 +474,9 @@ def _append_instruction(self, obj, qargs=None):
                             'Cannot apply instruction with classical registers: {}'
                             .format(instr.name))
                     # Get the integer position of the flat register
-                    new_qargs = [tup.index for tup in qregs]
+                    new_qargs = qargs
+                    if new_qargs is None:
+                        new_qargs = [tup.index for tup in qregs]
                     self._append_instruction(instr, qargs=new_qargs)
         else:
             raise QiskitError('Input is not an instruction.')
diff --git a/qiskit/quantum_info/operators/operator.py b/qiskit/quantum_info/operators/operator.py
--- a/qiskit/quantum_info/operators/operator.py
+++ b/qiskit/quantum_info/operators/operator.py
@@ -462,7 +462,9 @@ def _append_instruction(self, obj, qargs=None):
                             'Cannot apply instruction with classical registers: {}'.format(
                                 instr.name))
                     # Get the integer position of the flat register
-                    new_qargs = [tup.index for tup in qregs]
+                    new_qargs = qargs
+                    if new_qargs is None:
+                        new_qargs = [tup.index for tup in qregs]
                     self._append_instruction(instr, qargs=new_qargs)
         else:
             raise QiskitError('Input is not an instruction.')


Test patch:
diff --git a/test/python/quantum_info/operators/test_operator.py b/test/python/quantum_info/operators/test_operator.py
--- a/test/python/quantum_info/operators/test_operator.py
+++ b/test/python/quantum_info/operators/test_operator.py
@@ -57,11 +57,13 @@ def rand_matrix(cls, rows, cols=None, real=False):
 
     def simple_circuit_no_measure(self):
         """Return a unitary circuit and the corresponding unitary array."""
-        qr = QuantumRegister(2)
+        qr = QuantumRegister(3)
         circ = QuantumCircuit(qr)
         circ.h(qr[0])
         circ.x(qr[1])
-        target = Operator(np.kron(self.UX, self.UH))
+        circ.ry(np.pi / 2, qr[2])
+        y90 = (1 / np.sqrt(2)) * np.array([[1, -1], [1, 1]])
+        target = Operator(np.kron(y90, np.kron(self.UX, self.UH)))
         return circ, target
 
     def simple_circuit_with_measure(self):