Source code for mathematicskit.linalg.utils.matrix_utils
"""Small matrix-generation and norm helpers used across mathematicskit.linalg's
systems/ modules and tests -- supporting numerics, not models themselves.
"""
from __future__ import annotations
import numpy as np
__all__ = ["random_spd_matrix", "frobenius_norm", "is_symmetric"]
[docs]
def random_spd_matrix(n: int, seed: int = 0, condition_scale: float = 1.0) -> np.ndarray:
r"""Generate a random symmetric positive-definite matrix.
Constructs :math:`A = M^T M + \epsilon I` for a random :math:`M`,
which is SPD for any nonsingular :math:`M` (:math:`x^T A x = \|Mx\|^2
+ \epsilon\|x\|^2 > 0` for :math:`x \neq 0`); `condition_scale` scales
:math:`M`'s entries to make the resulting matrix better- or
worse-conditioned for stability demonstrations.
Parameters
----------
n : int
Matrix size.
seed : int
Random seed, for reproducibility.
condition_scale : float
Multiplies the generating matrix's entries.
Returns
-------
ndarray, shape (n, n)
Examples
--------
>>> import numpy as np
>>> A = random_spd_matrix(4, seed=1)
>>> np.allclose(A, A.T)
True
>>> bool(np.all(np.linalg.eigvalsh(A) > 0))
True
"""
rng = np.random.default_rng(seed)
m = condition_scale * rng.normal(size=(n, n))
return m.T @ m + 0.1 * np.eye(n)
[docs]
def frobenius_norm(a: np.ndarray) -> float:
r"""Frobenius norm :math:`\|A\|_F = \sqrt{\sum_{ij} A_{ij}^2}`, via :func:`numpy.linalg.norm`.
Parameters
----------
a : ndarray
Returns
-------
float
Examples
--------
>>> import numpy as np
>>> round(frobenius_norm(np.array([[3.0, 0.0], [0.0, 4.0]])), 6)
5.0
"""
a = np.asarray(a, dtype=np.float64)
return float(np.linalg.norm(a, ord="fro"))
[docs]
def is_symmetric(a: np.ndarray, atol: float = 1e-10) -> bool:
"""Check whether a matrix is (numerically) symmetric.
Parameters
----------
a : ndarray, shape (n, n)
atol : float
Returns
-------
bool
Examples
--------
>>> import numpy as np
>>> is_symmetric(np.array([[1.0, 2.0], [2.0, 1.0]]))
True
"""
a = np.asarray(a, dtype=np.float64)
return bool(np.allclose(a, a.T, atol=atol))