Skip to content

is_circulant

Checks if the matrix is circulant.

is_circulant

is_circulant(mat: ndarray) -> bool

Determine if matrix is circulant 1.

A circulant matrix is a square matrix in which all row vectors are composed of the same elements and each row vector is rotated one element to the right relative to the preceding row vector.

Parameters:

  • mat (ndarray) –

    Matrix to check the circulancy of.

Returns:

  • bool

    Return True if mat is circulant; False otherwise.

Examples:

Consider the following matrix:

\[ C = \begin{pmatrix} 4 & 1 & 2 & 3 \\ 3 & 4 & 1 & 2 \\ 2 & 3 & 4 & 1 \\ 1 & 2 & 3 & 4 \end{pmatrix} \]

As can be seen, this matrix is circulant. We can verify this in |toqito⟩ as

import numpy as np
from toqito.matrix_props import is_circulant

mat = np.array([[4, 1, 2, 3], [3, 4, 1, 2], [2, 3, 4, 1], [1, 2, 3, 4]])

print(is_circulant(mat))
True

References

1 Wikipedia. Circulant matrix. link.

Source code in toqito/matrix_props/is_circulant.py
def is_circulant(mat: np.ndarray) -> bool:
    r"""Determine if matrix is circulant [@wikipediacirculant].

    A circulant matrix is a square matrix in which all row vectors are composed
    of the same elements and each row vector is rotated one element to the right
    relative to the preceding row vector.

    Args:
        mat: Matrix to check the circulancy of.

    Returns:
        Return `True` if `mat` is circulant; `False` otherwise.

    Examples:
        Consider the following matrix:

        \[
            C = \begin{pmatrix}
                    4 & 1 & 2 & 3 \\
                    3 & 4 & 1 & 2 \\
                    2 & 3 & 4 & 1 \\
                    1 & 2 & 3 & 4
                \end{pmatrix}
        \]

        As can be seen, this matrix is circulant. We can verify this in
        `|toqito⟩` as

        ```python exec="1" source="above" result="text"
        import numpy as np
        from toqito.matrix_props import is_circulant

        mat = np.array([[4, 1, 2, 3], [3, 4, 1, 2], [2, 3, 4, 1], [1, 2, 3, 4]])

        print(is_circulant(mat))
        ```

    """
    n, m = mat.shape
    if n != m:
        return False

    for i in range(n - 1):
        row = mat[i + 1]
        shifted = np.roll(mat[i], 1)
        if not np.allclose(row, shifted):
            return False
    return True