Matrix Properties¶
Matrix Toolkit provides comprehensive property checking for matrices through
the MatrixProperties class.
Supported Properties¶
Symmetry Properties¶
Symmetric¶
A matrix is symmetric if \(A = A^T\).
from matrix_toolkit.anymatrix import MatrixProperties
import numpy as np
A = np.array([[1, 2], [2, 3]])
is_sym = MatrixProperties.is_symmetric(A)
Hermitian¶
A matrix is Hermitian if \(A = A^H\) (conjugate transpose).
A = np.array([[1, 1+2j], [1-2j, 3]])
is_herm = MatrixProperties.is_hermitian(A)
Skew-Symmetric¶
A matrix is skew-symmetric if \(A^T = -A\).
A = np.array([[0, 2], [-2, 0]])
# Check if A^T = -A
is_skew = np.allclose(A.T, -A)
Definiteness Properties¶
Positive Definite¶
A matrix is positive definite if all eigenvalues are positive.
A = np.array([[2, 1], [1, 2]])
is_pd = MatrixProperties.is_positive_definite(A)
This uses Cholesky decomposition for efficient checking.
Orthogonality Properties¶
Orthogonal¶
A matrix \(Q\) is orthogonal if \(Q^T Q = I\).
Q = np.eye(3) # Identity is orthogonal
is_ortho = MatrixProperties.is_orthogonal(Q)
Unitary¶
A matrix \(U\) is unitary if \(U^H U = I\).
U = np.array([[1, 1j], [1j, 1]]) / np.sqrt(2)
is_unitary = MatrixProperties.is_unitary(U)
Structure Properties¶
Diagonal¶
D = np.diag([1, 2, 3])
is_diag = MatrixProperties.is_diagonal(D)
Tridiagonal¶
T = np.diag([1, 2, 3]) + np.diag([1, 1], 1) + np.diag([1, 1], -1)
is_tri = MatrixProperties.is_tridiagonal(T)
Upper/Lower Triangular¶
U = np.triu(np.ones((3, 3)))
is_upper = MatrixProperties.is_upper_triangular(U)
L = np.tril(np.ones((3, 3)))
is_lower = MatrixProperties.is_lower_triangular(L)
Special Structure¶
Toeplitz¶
Constant along diagonals.
from scipy.linalg import toeplitz
T = toeplitz([1, 2, 3, 4])
is_toep = MatrixProperties.is_toeplitz(T)
Circulant¶
Each row is cyclic shift of previous row.
C = np.array([[1, 2, 3],
[3, 1, 2],
[2, 3, 1]])
is_circ = MatrixProperties.is_circulant(C)
Hankel¶
Constant along anti-diagonals.
H = np.array([[1, 2, 3],
[2, 3, 4],
[3, 4, 5]])
is_hank = MatrixProperties.is_hankel(H)
Stochastic Properties¶
Row Stochastic¶
All rows sum to 1, all entries non-negative.
S = np.array([[0.5, 0.5],
[0.3, 0.7]])
is_stoch = MatrixProperties.is_stochastic(S)
Doubly Stochastic¶
Both rows and columns sum to 1.
DS = np.array([[0.5, 0.5],
[0.5, 0.5]])
is_doubly = MatrixProperties.is_doubly_stochastic(DS)
Special Matrix Types¶
Nilpotent¶
\(A^k = 0\) for some positive integer k.
# Jordan block with eigenvalue 0
N = np.array([[0, 1, 0],
[0, 0, 1],
[0, 0, 0]])
is_nilp = MatrixProperties.is_nilpotent(N)
Involutory¶
\(A^2 = I\).
# Swap matrix
I = np.array([[0, 1],
[1, 0]])
is_invol = MatrixProperties.is_involutory(I)
Data Type Properties¶
Sparse¶
from scipy import sparse
S = sparse.random(100, 100, density=0.01)
is_sparse = MatrixProperties.is_sparse(S)
Binary¶
All entries are 0 or 1.
B = np.array([[1, 0, 1],
[0, 1, 0]])
is_bin = MatrixProperties.is_binary(B)
Integer¶
All entries are integers.
I = np.array([[1, 2], [3, 4]])
is_int = MatrixProperties.is_integer(I)
Checking Properties¶
Single Property¶
from matrix_toolkit.anymatrix import MatrixProperties
A = np.array([[1, 2], [2, 3]])
# Check if symmetric
if MatrixProperties.is_symmetric(A):
print("Matrix is symmetric")
Multiple Properties¶
properties = ['symmetric', 'positive definite', 'tridiagonal']
results = MatrixProperties.check_properties(A, properties)
for prop, passed in results.items():
status = "✓" if passed else "✗"
print(f"{status} {prop}")
With Custom Tolerance¶
# Stricter tolerance
is_sym = MatrixProperties.is_symmetric(A, tol=1e-12)
# More lenient
is_ortho = MatrixProperties.is_orthogonal(Q, tol=1e-6)
Automated Testing¶
Using with Anymatrix¶
from matrix_toolkit.anymatrix import AnyMatrix, MatrixProperties
am = AnyMatrix()
# Generate matrix
matrix = am.generate('core/beta', 10)
# Get expected properties
expected_props = am.properties('core/beta')
# Verify all properties
results = MatrixProperties.check_properties(matrix, expected_props)
# Check if all passed
all_passed = all(results.values())
print(f"All properties verified: {all_passed}")
Property Test Suite¶
from matrix_toolkit.anymatrix.testing import run_all_tests
# Run comprehensive property tests
results = run_all_tests(
groups=['core', 'gallery'],
verbose=True,
generate_report=True,
report_file='property_tests.txt'
)
Custom Property Checker¶
You can create custom property checkers:
def is_magic_square(matrix, tol=1e-10):
"""Check if matrix is a magic square"""
if matrix.shape[0] != matrix.shape[1]:
return False
n = matrix.shape[0]
magic_sum = n * (n**2 + 1) / 2
# Check rows
if not np.allclose(matrix.sum(axis=1), magic_sum, atol=tol):
return False
# Check columns
if not np.allclose(matrix.sum(axis=0), magic_sum, atol=tol):
return False
# Check diagonals
if not np.isclose(np.trace(matrix), magic_sum, atol=tol):
return False
if not np.isclose(np.trace(np.fliplr(matrix)), magic_sum, atol=tol):
return False
return True
# Use it
M = am.generate('matlab/magic', 5)
assert is_magic_square(M)
Property Relationships¶
Some properties imply others:
Symmetric + Positive Definite → Invertible
Orthogonal → Invertible, \(\det(Q) = \pm 1\)
Unitary → Normal
Hermitian → Normal
Doubly Stochastic → Row Stochastic
Diagonal → Triangular (both upper and lower)
Example verification:
# If symmetric and positive definite, should be invertible
A = am.generate('core/beta', 10)
assert MatrixProperties.is_symmetric(A)
assert MatrixProperties.is_positive_definite(A)
# Should be invertible
det = np.linalg.det(A)
assert abs(det) > 1e-10
Property Preservation¶
Under Operations¶
Some operations preserve properties:
Sum of symmetric matrices → symmetric
Product of orthogonal matrices → orthogonal
Inverse of positive definite → positive definite
Example:
# Sum of symmetric matrices
A1 = am.generate('core/beta', 10)
A2 = am.generate('gallery/lehmer', 10)
A_sum = A1 + A2
assert MatrixProperties.is_symmetric(A_sum)
Performance Considerations¶
Computational Cost¶
Property checks have different computational costs:
O(n²): Symmetry, structure checks
O(n³): Positive definiteness (Cholesky), orthogonality
O(nk): Nilpotency (k matrix multiplications)
For large matrices:
# Fast checks
is_sym = MatrixProperties.is_symmetric(large_matrix) # O(n²)
is_diag = MatrixProperties.is_diagonal(large_matrix) # O(n²)
# Slower checks
is_pd = MatrixProperties.is_positive_definite(large_matrix) # O(n³)
Sparse Matrix Optimization¶
Property checkers are optimized for sparse matrices:
from scipy import sparse
# Sparse matrix
S = sparse.random(10000, 10000, density=0.001, format='csr')
# Fast for sparse
is_sym = MatrixProperties.is_symmetric(S) # Only checks nnz elements
See Also¶
Working with Anymatrix - Generating matrices with properties
Anymatrix Module - API reference
Property Testing Tutorial - Property testing tutorial
Anymatrix Examples - Examples