Repository: Qiskit/qiskit

Issue:
Incorrect Inner Product Implementation?
I have ran across a circuit called "InnerProduct" in the Qiskit documentation, here: https://qiskit.org/documentation/stubs/qiskit.circuit.library.InnerProduct.html

According to the documentation, this circuit "computes the inner product of two registers". However, I believe this to be blatantly wrong. Is this implementation wrong, or am I missing something?


Discussion:
This circuit is a Boolean function, i.e. it is defined over elements of the field F_2. It computes the inner product of two n-bit arrays. So over F2, the output is either 0 or 1. Since in quantum the circuit has to be unitary (same number of inputs as outputs), you have to choose how to encode this output. This particular circuit is a "phase oracle", i.e. it induces a -1 phase on the amplitude when the output is 1, and no phase when the output is 0. (i.e. the unitary is a diagonal).

You can see that a cascade of CZ gates do these, as this circuit is implemented. 
![image](https://user-images.githubusercontent.com/8622381/119580933-796b9a00-bd8f-11eb-99cf-78edf71aca28.png)


ZZ has the following transfer function:
```
|00> -> |00>
|01> -> |01>
|10> -> |10>
|11> -> -|11>
```
i.e. when the inner product of two bits is 1, it induces a -1 phase. So this circuit does bit-wise inner product, leaving the original input intact, except inducing a -1 phase when the total inner product is 1. (The total inner product is a Boolean sum over the bit-wise inner products).

<img width="765" alt="image" src="https://user-images.githubusercontent.com/8622381/119581583-d87dde80-bd90-11eb-88b0-5032c015ae21.png">


Thanks for bringing this up. The documentation of the class needs more explanation. Right now you have to figure this out based on the fact that it is under `qiskit.circuit.library.boolean_logic`. 

Resolving patch:
diff --git a/qiskit/circuit/library/boolean_logic/inner_product.py b/qiskit/circuit/library/boolean_logic/inner_product.py
--- a/qiskit/circuit/library/boolean_logic/inner_product.py
+++ b/qiskit/circuit/library/boolean_logic/inner_product.py
@@ -18,24 +18,55 @@
 
 
 class InnerProduct(QuantumCircuit):
-    """An n_qubit circuit that computes the inner product of two registers."""
+    r"""A 2n-qubit Boolean function that computes the inner product of
+    two n-qubit vectors over :math:`F_2`.
+
+    This implementation is a phase oracle which computes the following transform.
+
+    .. math::
+
+        \mathcal{IP}_{2n} : F_2^{2n} \rightarrow {-1, 1}
+        \mathcal{IP}_{2n}(x_1, \cdots, x_n, y_1, \cdots, y_n) = (-1)^{x.y}
+
+    The corresponding unitary is a diagonal, which induces a -1 phase on any inputs
+    where the inner product of the top and bottom registers is 1. Otherwise it keeps
+    the input intact.
+
+    .. parsed-literal::
+
+
+        q0_0: ─■──────────
+               │
+        q0_1: ─┼──■───────
+               │  │
+        q0_2: ─┼──┼──■────
+               │  │  │
+        q0_3: ─┼──┼──┼──■─
+               │  │  │  │
+        q1_0: ─■──┼──┼──┼─
+                  │  │  │
+        q1_1: ────■──┼──┼─
+                     │  │
+        q1_2: ───────■──┼─
+                        │
+        q1_3: ──────────■─
+
+
+    Reference Circuit:
+        .. jupyter-execute::
+            :hide-code:
+
+            from qiskit.circuit.library import InnerProduct
+            import qiskit.tools.jupyter
+            circuit = InnerProduct(4)
+            %circuit_library_info circuit
+    """
 
     def __init__(self, num_qubits: int) -> None:
         """Return a circuit to compute the inner product of 2 n-qubit registers.
 
-        This implementation uses CZ gates.
-
         Args:
             num_qubits: width of top and bottom registers (half total circuit width)
-
-        Reference Circuit:
-            .. jupyter-execute::
-                :hide-code:
-
-                from qiskit.circuit.library import InnerProduct
-                import qiskit.tools.jupyter
-                circuit = InnerProduct(5)
-                %circuit_library_info circuit
         """
         qr_a = QuantumRegister(num_qubits)
         qr_b = QuantumRegister(num_qubits)


Test patch: