# givens_decomposition

### givens_decomposition(unitary)

Decomposes a unitary matrix into Givens rotations and diagonal phases.

The $n \times n$ unitary matrix, $U$, can be decomposed into a diagonal matrix,
$D$, and sequence of $2 \times 2$ Givens rotations, $G$, acting on adjacent
indices. This algorithm <sup>[1](#id2)</sup> requires at most $n (n-1) / 2$ such Givens rotations.

Each Givens rotation is defined by a 4-tuple, `(c, s, i, j)`, with:

* `c`: the real-valued cosine
* `s`: the complex-valued sine
* `i`: the first row index
* `j`: the second row index

which result in a matrix of the form:

$$
\begin{pmatrix}
c & s \\
-s^\dagger & c
\end{pmatrix}
$$

* **Parameters:**
  **unitary** – the unitary matrix, $U$, to be decomposed.
* **Returns:**
  A 2-tuple consisting of
  * the sequence of Givens rotations represented as 4-tuples as explained above
  * the vector of complex phases of the diagonal matrix, $D$

The original unitary is recovered by processing the returned rotations in reverse order and
right-multiplying the diagonal matrix by the element-wise complex conjugate of each rotation
matrix $G_k$ (as defined above). That is, for $N$ returned rotations,

$$
U = D \cdot \overline{G_N} \cdot \overline{G_{N-1}} \cdots \overline{G_1},
$$

where $\overline{G_k}$ denotes element-wise conjugation (not the conjugate transpose) and
each $G_k$ acts only on rows/columns $i$ and $j$ of its rotation.

```pycon
>>> import numpy as np
>>> from qiskit_fermions.linalg import givens_decomposition
>>> unitary = np.array([[0.6, 0.8j], [0.8, -0.6j]], dtype=complex)
>>> rotations, phases = givens_decomposition(unitary)
>>> reconstructed = np.diag(phases).astype(complex)
>>> for c, s, i, j in rotations[::-1]:
...     givens_mat = np.eye(2, dtype=complex)
...     givens_mat[np.ix_((i, j), (i, j))] = [[c, s], [-s.conjugate(), c]]
...     reconstructed = reconstructed @ givens_mat.conj()
>>> bool(np.allclose(reconstructed, unitary))
True
```

* <a id='id2'>**[1]**</a> W. R. Clements et al., Optimal design for universal multiport interferometers, Optica 3, 1460-1465 (2016), [doi:10.1364/OPTICA.3.001460](https://doi.org/10.1364/OPTICA.3.001460).
