cirq.kak_vector(unitary: Union[Iterable[numpy.ndarray], numpy.ndarray], *, rtol: float = 1e-05, atol: float = 1e-08, check_preconditions: bool = True) → numpy.ndarray[source]

Compute the KAK vectors of one or more two qubit unitaries.

Any 2 qubit unitary may be expressed as

$$ U = k_l A k_r $$
where $k_l, k_r$ are single qubit (local) unitaries and
$$ A= \exp \left(i \sum_{s=x,y,z} k_s \sigma_{s}^{(0)} \sigma_{s}^{(1)} \right) $$
The vector entries are ordered such that
$$ 0 ≤ |k_z| ≤ k_y ≤ k_x ≤ π/4 $$
if $k_x$ = π/4, $k_z \geq 0$.
  • unitary – A unitary matrix, or a multi-dimensional array of unitary matrices. Must have shape (…, 4, 4), where the last two axes are for the unitary matrix and other axes are for broadcasting the kak vector computation.

  • rtol – Per-matrix-entry relative tolerance on equality. Used in unitarity check of input.

  • atol – Per-matrix-entry absolute tolerance on equality. Used in unitarity check of input. This also determines how close $k_x$ must be to π/4 to guarantee $k_z$ ≥ 0. Must be non-negative.

  • check_preconditions – When set to False, skips verifying that the input is unitary in order to increase performance.


The KAK vector of the given unitary or unitaries. The output shape is the same as the input shape, except the two unitary matrix axes are replaced by the kak vector axis (i.e. the output has shape unitary.shape[:-2] + (3,)).


The appendix section of “Lower bounds on the complexity of simulating quantum gates”.


>>> cirq.kak_vector(np.eye(4))
array([0., 0., 0.])
>>> unitaries = [cirq.unitary(cirq.CZ),cirq.unitary(cirq.ISWAP)]
>>> cirq.kak_vector(unitaries) * 4 / np.pi
array([[ 1.,  0., -0.],
       [ 1.,  1.,  0.]])