Source code for sigmaepsilon.math.linalg.logical

import numpy as np
from numpy import ndarray
import sympy as sy

from .utils import Gram

__all__ = [
    "has_full_row_rank",
    "has_full_column_rank",
    "has_full_rank",
    "is_rectangular_frame",
    "is_normal_frame",
    "is_orthonormal_frame",
    "is_independent_frame",
    "is_hermitian",
    "is_pos_def",
    "is_pos_semidef",
]


[docs] def is_pos_def(arr) -> bool: """ Returns True if the input is positive definite. """ return np.all(np.linalg.eigvals(arr) > 0)
[docs] def is_pos_semidef(arr) -> bool: """ Returns True if the input is positive semi definite. """ return np.all(np.linalg.eigvals(arr) >= 0)
[docs] def is_rectangular_frame(axes: ndarray) -> bool: """ Returns True if a frame is Cartesian. Parameters ---------- axes: numpy.ndarray A matrix where the i-th row is the i-th basis vector. """ assert len(axes.shape) == 2, "Input is not a matrix!" assert axes.shape[0] == axes.shape[1], "Input is not a square matrix!" agram = np.abs(axes @ axes.T) return np.isclose(np.trace(agram), np.sum(agram))
[docs] def is_normal_frame(axes: ndarray) -> bool: """ Returns True if a frame is normal, meaning, that it's base vectors are all of unit length. Parameters ---------- axes: numpy.ndarray A matrix where the i-th row is the i-th basis vector. """ return np.allclose(np.linalg.norm(axes, axis=1), 1.0)
[docs] def is_orthonormal_frame(axes: ndarray) -> bool: """ Returns True if a frame is orthonormal. Parameters ---------- axes: numpy.ndarray A matrix where the i-th row is the i-th basis vector. """ return is_rectangular_frame(axes) and is_normal_frame(axes)
[docs] def is_independent_frame(axes: ndarray, tol: float = 0) -> bool: """ Returns True if a the base vectors of a frame are linearly independent. Parameters ---------- axes: numpy.ndarray A matrix where the i-th row is the i-th basis vector. """ return np.linalg.det(Gram(axes)) > tol
[docs] def is_hermitian(arr: ndarray) -> bool: """ Returns True if the input is a hermitian array. """ shp = arr.shape s0 = shp[0] return all([s == s0 for s in shp[1:]])
[docs] def has_full_row_rank(matrix: ndarray) -> bool: """ Returns `True` if the input matrix has full row rank, ie if all its rows are linearly independent. See also -------- :func:`numpy.linalg.matrix_rank` """ num_rows, num_columns = matrix.shape if num_rows > num_columns: return False rank = np.linalg.matrix_rank(matrix) return rank == num_rows
[docs] def has_full_column_rank(matrix: ndarray) -> bool: """ Returns `True` if the input matrix has full column rank, ie if all its columns are linearly independent. See also -------- :func:`numpy.linalg.matrix_rank` """ num_rows, num_columns = matrix.shape if num_columns > num_rows: return False rank = np.linalg.matrix_rank(matrix) return rank == num_columns
[docs] def has_full_rank(matrix: ndarray | sy.Matrix) -> bool: """ Returns `True` if the input matrix has full rank, `False` otherwise. Parameters ---------- matrix : numpy.ndarray | sympy.Matrix The input matrix. """ if isinstance(matrix, sy.Matrix): return matrix.rank() == min(matrix.shape) else: return np.linalg.matrix_rank(matrix) == min(matrix.shape)