Source code for toqito.matrix_props.is_ldoi

"""Check if a quantum state is LDOI (Local Diagonal Orthogonal Invariant)."""

import numpy as np

from toqito.channels import ldot_channel


[docs] def is_ldoi(mat: np.ndarray, rtol: float = 1e-05, atol: float = 1e-08) -> bool: r"""Check if a quantum state is LDOI (Local Diagonal Orthogonal Invariant). A matrix \(A \in \mathcal{L}(\mathcal{X} \otimes \mathcal{Y})\) is called *local diagonal orthogonal invariant* (LDOI) if \(\Phi_O(A) = A\), where \(\Phi_O\) is the local diagonal orthogonal twirl map defined as: \[ \Phi_O(A) = \frac{1}{2^n} \sum_{O \in \text{DO}(\mathcal{X})} (O \otimes O) A (O \otimes O) \] where \(\text{DO}(\mathcal{X})\) is the set of diagonal matrices with entries \(\pm 1\). LDOI states include many important families such as Werner states, isotropic states, X-states, and mixtures of Dicke states. This function efficiently checks the LDOI property using the standard basis representation. Examples: X-states are examples of 2-qubit LDOI states: ```python exec="1" source="above" from toqito.matrix_props import is_ldoi import numpy as np # Example X-state x_state = np.array([[1, 0, 0, 2], [0, 3, 4, 0], [0, 5, 6, 0], [7, 0, 0, 8]]) print(is_ldoi(x_state)) ``` All diagonal states are LDOI: ```python exec="1" source="above" from toqito.matrix_props import is_ldoi import numpy as np diagonal_state = np.diag([1, 2, 3, 4]) print(is_ldoi(diagonal_state)) ``` Non-LDOI states return False: ```python exec="1" source="above" from toqito.matrix_props import is_ldoi import numpy as np # Random non-LDOI state non_ldoi = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) print(is_ldoi(non_ldoi)) ``` Args: mat: A matrix representing a quantum state. rtol: Relative tolerance parameter (default: 1e-05). atol: Absolute tolerance parameter (default: 1e-08). Returns: True if the matrix is LDOI, False otherwise. """ if mat.ndim != 2 or mat.shape[0] != mat.shape[1]: raise ValueError("Input matrix must be square.") # A matrix is LDOI if Φ_O(mat) = mat ldot_result = ldot_channel(mat) return np.allclose(ldot_result, mat, rtol=rtol, atol=atol)