Repository: Qiskit/qiskit

Issue:
inconsistency between CU1 and CU3 gate definitions
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues to confirm this idea does not exist. -->

### What is the expected enhancement?

This is not a bug or enhancement request as such, but seems like an internal inconsistency in Qiskit's gate definitions.
In [the gate definitions](https://github.com/Qiskit/qiskit-tutorials/blob/master/qiskit/terra/summary_of_quantum_operations.ipynb), U1 is defined as [1,0,0,e^(iλ)], while an Rz is a [e^(-iλ/2),0,0,e^(iλ/2)].

U3 is defined in the docs similarly to U1 - ie. a U3 is a U1*Ry*U1. Therefore, a U3(0,0,a) = U1(a). However, CU3 is defined in the docs in such a way that CU3(0,0,a) != CU1(a). CU3 is instead defined using the Rz definition, rather than the U1.

So: 
U3(0,0,a) = U1(a)
CU3(0,0,a) != CU1(a)

This is a confusing set of definitions. I assume that these definitions were a conscious decision, and that you are aware of the inconsistency, but I don't understand why?
I hope this hasn't been asked already - I couldn't find a duplicate.


Discussion:
It seems our current definition of a CU3 gate (using the gate decomposition) is incorrect if we want it to be CU3(a,b,c) = |0X0| ⊗ iden + |1X1| ⊗ U3(a, b, c)
where
U3 = cos(a/2)  |0X0| - exp(ic)sin(a/2) |0X1| + exp(ib) * sin(a/2) |1X0| + exp(i(b+c) cos(a/2)

Currently we define the unrolling for `Cu3Gate.definition` as
```python
Cu3Gate(a, b, c).definition = [
     (U1Gate((self.params[2] - self.params[1]) / 2), [q[1]], []),
    (CnotGate(), [q[0], q[1]], []),
    (U3Gate(-self.params[0] / 2, 0, -(self.params[1] + self.params[2]) / 2), [q[1]], []),
    (CnotGate(), [q[0], q[1]], []),
    (U3Gate(self.params[0] / 2, self.params[1], 0), [q[1]], [])
]
```

which returns a matrix

|0X0| ⊗ iden + exp(-i(b+c)/2) *  |1X1| ⊗ U3(a, b, c)

If we changed the definition to append an additional U1 gate `U1Gate((b+c)/2)` we would get the correct matrix:

```python
Cu3Gate(a, b, c).definition = [
     (U1Gate((self.params[2] - self.params[1]) / 2), [q[1]], []),
    (CnotGate(), [q[0], q[1]], []),
    (U3Gate(-self.params[0] / 2, 0, -(self.params[1] + self.params[2]) / 2), [q[1]], []),
    (CnotGate(), [q[0], q[1]], []),
    (U3Gate(self.params[0] / 2, self.params[1], 0), [q[1]], []),
    (U1Gate((self.params[1] + self.params[2]) / 2), [qr[0]], [])
]
```
gives the matrix

|0X0| ⊗ iden + |1X1| ⊗ U3(a, b, c)

Resolving patch:
diff --git a/qiskit/extensions/standard/cu3.py b/qiskit/extensions/standard/cu3.py
--- a/qiskit/extensions/standard/cu3.py
+++ b/qiskit/extensions/standard/cu3.py
@@ -33,7 +33,7 @@ def __init__(self, theta, phi, lam):
     def _define(self):
         """
         gate cu3(theta,phi,lambda) c, t
-        { u1((lambda-phi)/2) t; cx c,t;
+        { u1((lambda+phi)/2) c; u1((lambda-phi)/2) t; cx c,t;
           u3(-theta/2,0,-(phi+lambda)/2) t; cx c,t;
           u3(theta/2,phi,0) t;
         }
@@ -41,6 +41,7 @@ def _define(self):
         definition = []
         q = QuantumRegister(2, "q")
         rule = [
+            (U1Gate((self.params[2] + self.params[1]) / 2), [q[0]], []),
             (U1Gate((self.params[2] - self.params[1]) / 2), [q[1]], []),
             (CnotGate(), [q[0], q[1]], []),
             (U3Gate(-self.params[0] / 2, 0, -(self.params[1] + self.params[2]) / 2), [q[1]], []),


Test patch:
diff --git a/test/python/transpiler/test_unroller.py b/test/python/transpiler/test_unroller.py
--- a/test/python/transpiler/test_unroller.py
+++ b/test/python/transpiler/test_unroller.py
@@ -191,6 +191,7 @@ def test_unroll_all_instructions(self):
         ref_circuit.u3(0, 0, -pi/4, qr[0])
         ref_circuit.u3(0, 0, pi/4, qr[1])
         ref_circuit.cx(qr[1], qr[0])
+        ref_circuit.u3(0, 0, 0.05, qr[1])
         ref_circuit.u3(0, 0, pi/4, qr[2])
         ref_circuit.u3(pi/2, 0, pi, qr[2])
         ref_circuit.cx(qr[2], qr[0])