Working with Anymatrix¶
Anymatrix provides programmatic generation of test matrices with well-defined mathematical properties, inspired by the MATLAB anymatrix toolbox.
Overview¶
The anymatrix module includes 65+ test matrices organized into 5 groups:
core (45+ matrices): Miscellaneous test matrices
gallery (6 matrices): Classic MATLAB gallery matrices
hadamard (2 matrices): Hadamard and Walsh matrices
matlab (8 matrices): Standard MATLAB test matrices
regtools (5 matrices): Regularization problem matrices
Getting Started¶
Initialize Anymatrix¶
from matrix_toolkit.anymatrix import AnyMatrix
am = AnyMatrix()
Explore Available Matrices¶
List all groups:
groups = am.groups()
print(groups)
# ['core', 'gallery', 'hadamard', 'matlab', 'regtools']
List matrices in a group:
core_matrices = am.list('core')
print(f"Core group has {len(core_matrices)} matrices")
print(core_matrices[:10])
Get matrix count:
counts = am.count()
print(counts)
# {'core': 45, 'gallery': 6, 'hadamard': 2, 'matlab': 8,
# 'regtools': 5, 'total': 66}
Generating Matrices¶
Basic Generation¶
Generate a matrix by its ID (format: ‘group/name’):
# Beta matrix (symmetric positive definite)
beta = am.generate('core/beta', 10)
print(f"Shape: {beta.shape}")
# Fourier matrix (unitary)
fourier = am.generate('core/fourier', 8)
# Hilbert matrix (ill-conditioned)
hilbert = am.generate('matlab/hilbert', 5)
Shorthand Syntax¶
You can also use the callable syntax:
# These are equivalent
A = am.generate('core/beta', 10)
A = am('core/beta', 10)
Matrix with Parameters¶
Some matrices accept additional parameters:
# KMS matrix with different rho values
kms1 = am.generate('gallery/kms', 10, rho=0.5)
kms2 = am.generate('gallery/kms', 10, rho=0.9)
# Indefinite matrix with k negative eigenvalues
indef = am.generate('core/indef', 20, k=5)
# Wilkinson matrix (W+ or W-)
w_plus = am.generate('matlab/wilkinson', 21, mode='plus')
w_minus = am.generate('matlab/wilkinson', 21, mode='minus')
Matrix Properties¶
Viewing Properties¶
Get properties of a specific matrix:
props = am.properties('core/beta')
print(props)
# ['symmetric', 'positive definite']
Get properties of all matrices:
all_props = am.properties()
for matrix_id, props in list(all_props.items())[:5]:
print(f"{matrix_id}: {props}")
Verifying Properties¶
from matrix_toolkit.anymatrix import MatrixProperties
# Generate a matrix
matrix = am.generate('core/beta', 10)
# Check individual properties
is_sym = MatrixProperties.is_symmetric(matrix)
is_pd = MatrixProperties.is_positive_definite(matrix)
print(f"Symmetric: {is_sym}")
print(f"Positive Definite: {is_pd}")
Check multiple properties at once:
expected_props = am.properties('core/beta')
results = MatrixProperties.check_properties(matrix, expected_props)
for prop, passed in results.items():
status = "✓" if passed else "✗"
print(f"{status} {prop}")
Searching Matrices¶
Search by Properties¶
Find matrices with specific properties:
# Find all symmetric matrices
symmetric = am.search(['symmetric'])
print(f"Found {len(symmetric)} symmetric matrices")
# Find symmetric AND positive definite
sym_pd = am.search(['symmetric', 'positive definite'])
print(sym_pd[:10])
Match Any vs. All¶
By default, search requires ALL properties to match:
# Must have BOTH properties
result = am.search(['symmetric', 'positive definite'], match_all=True)
To match ANY property:
# Can have EITHER property
result = am.search(['symmetric', 'orthogonal'], match_all=False)
Getting Help¶
Matrix Documentation¶
Get detailed information about a matrix:
help_text = am.help('core/fourier')
print(help_text)
Output:
Matrix: core/fourier
Group: core
Name: fourier
Description:
Discrete Fourier transform matrix
Properties:
- unitary
- symmetric
Matrix Groups Reference¶
Core Group¶
The core group contains miscellaneous test matrices:
Symmetric Positive Definite
beta- Beta matrixwilson- Wilson matrix
Nilpotent
nilpot_triang- Upper triangular nilpotentnilpot_tridiag- Tridiagonal nilpotent (Jordan block)creation- Creation operator (quantum mechanics)
Stochastic
stoch_cesaro- Cesaro matrix (row stochastic)stoch_compan- Stochastic companion matrixstoch_perfect- Doubly stochastic shufflestoch_revtri- Upper triangular stochasticsymmstoch- Symmetric doubly stochastic
Structured
circul_binom- Circulant with binomial coefficientsblockcirc- Block circulantperfect_shuffle- Perfect shuffle permutationvecperm- Vec-permutation matrixcollatz- Collatz conjecture matrix
Orthogonal
fourier- Discrete Fourier transformblockhouse- Block Householderhess_orth- Orthogonal Hessenbergorthog_cauchy- From Cauchy matrixuptraporth- Upper trapezoidal orthogonalunitary_eye- Unitary with unit eigenvalues
Special Constructions
gfpp- Large growth factor for Gaussian eliminationindef- Symmetric indefinitetotally_nonneg- Totally nonnegativerschur- Random Schur decompositionsoules- With prescribed eigenvalues
Gallery Group¶
Classic MATLAB gallery matrices:
lehmer- Lehmer matrix (A[i,j] = min(i,j)/max(i,j))minij- MIN(i,j) matrixmoler- Moler matrixpei- Pei matrix (alpha*I + ones)clement- Clement tridiagonalkms- Kac-Murdock-Szego Toeplitz matrix
Example:
# Generate Lehmer matrix
L = am.generate('gallery/lehmer', 10)
# It's symmetric and positive definite
assert MatrixProperties.is_symmetric(L)
assert MatrixProperties.is_positive_definite(L)
Hadamard Group¶
Hadamard matrices and variants:
hadamard- Standard Hadamard matrix (order must be power of 2)walsh- Walsh-Hadamard matrix (sequency ordered)
Example:
# Generate Hadamard matrix
H = am.generate('hadamard/hadamard', 16)
# Rows are orthogonal (after normalization)
assert MatrixProperties.is_orthogonal(H / np.sqrt(16))
MATLAB Group¶
Standard MATLAB test matrices:
magic- Magic square (rows, columns, diagonals sum to same value)pascal- Pascal matrix (binomial coefficients)rosser- Rosser eigenvalue test matrixwilkinson- Wilkinson W+ or W- matriceshilbert- Hilbert matrix (notoriously ill-conditioned)invhilb- Exact inverse of Hilbert matrixfrank- Frank matrix (det = 1)companion- Companion matrix of a polynomial
Example:
# Magic square
M = am.generate('matlab/magic', 5)
# All rows, columns, and diagonals sum to same value
magic_sum = M.sum(axis=0)[0]
assert np.allclose(M.sum(axis=0), magic_sum)
assert np.allclose(M.sum(axis=1), magic_sum)
# Hilbert and its inverse
H = am.generate('matlab/hilbert', 5)
InvH = am.generate('matlab/invhilb', 5)
# Verify they're inverses
assert np.allclose(H @ InvH, np.eye(5))
Regtools Group¶
Matrices from regularization problems (discrete ill-posed problems):
deriv2- Second derivative operator (discrete Laplacian)shaw- Shaw 1D image restoration problemphillips- Phillips image deblurring problemblur- Gaussian blur matrix for deconvolutiongravity- Gravity surveying problem
These return tuples of (A, b, x_true) for test problems:
# Shaw problem
A, b, x_true = am.generate('regtools/shaw', 50)
# Solve with regularization
from scipy.linalg import lstsq
x_lstsq = lstsq(A, b)[0]
# Compare to true solution
error = np.linalg.norm(x_lstsq - x_true)
print(f"Reconstruction error: {error:.2e}")
Advanced Usage¶
Custom Tolerance¶
Adjust tolerance for property checking:
# Stricter tolerance
is_sym = MatrixProperties.is_symmetric(matrix, tol=1e-12)
# More lenient
is_ortho = MatrixProperties.is_orthogonal(Q, tol=1e-6)
Batch Generation¶
Generate multiple matrices efficiently:
matrices = {}
for size in [10, 20, 50, 100]:
matrices[size] = am.generate('core/beta', size)
# Verify properties for all
for size, matrix in matrices.items():
props = am.properties('core/beta')
results = MatrixProperties.check_properties(matrix, props)
print(f"Size {size}: {all(results.values())}")
Working with Sparse Matrices¶
Some matrices return sparse formats:
# These are sparse by default
sparse_matrices = [
'core/perfect_shuffle',
'core/collatz',
'core/vecperm',
'regtools/deriv2',
]
for matrix_id in sparse_matrices:
mat = am.generate(matrix_id, 100)
if hasattr(mat, 'nnz'):
density = mat.nnz / (mat.shape[0] * mat.shape[1])
print(f"{matrix_id}: density = {density:.3%}")
Integration with SciPy¶
Anymatrix matrices work seamlessly with SciPy:
import scipy.linalg as la
import scipy.sparse.linalg as spla
# Dense matrix operations
A = am.generate('core/beta', 100)
eigenvalues = la.eigvals(A)
# Sparse matrix operations
L = am.generate('regtools/deriv2', 1000)
eigenvalues_sparse = spla.eigs(L, k=10, which='SM')
Best Practices¶
Choose Appropriate Size: Start with small sizes for testing
Verify Properties: Always check that generated matrices have expected properties
Use Correct Group/Name: Use
am.list()to find exact matrix namesCheck Documentation: Use
am.help()to understand matrix parametersHandle Sparse Matrices: Be aware which matrices return sparse format
Set Random Seeds: For reproducible random matrices
See Also¶
Matrix Properties - Detailed guide on matrix properties
Anymatrix Module - Complete API reference
Anymatrix Examples - More examples
Property Testing Tutorial - Property testing tutorial