"""Central registry for all anymatrix generators"""
from typing import Any, Dict, List, Optional, Union, Callable
import numpy as np
from scipy import sparse
import warnings
[docs]
class AnyMatrix:
"""
Main interface for anymatrix - generate test matrices by name
Examples:
>>> from matrix_toolkit.anymatrix import AnyMatrix
>>> am = AnyMatrix()
# List all available groups
>>> groups = am.groups()
# List matrices in a group
>>> matrices = am.list('core')
# Generate a matrix
>>> A = am.generate('core/beta', 10)
# Get matrix properties
>>> props = am.properties('core/beta')
# Search for matrices with specific properties
>>> results = am.search(['symmetric', 'positive definite'])
"""
_groups = {}
_matrix_registry = {}
_properties_map = {}
[docs]
def __init__(self):
"""Initialize anymatrix registry"""
self._initialize_registry()
def _initialize_registry(self):
"""Initialize all matrix groups"""
from matrix_toolkit.anymatrix.groups.core import register_core_matrices
from matrix_toolkit.anymatrix.groups.core_extended import register_extended_core_matrices
from matrix_toolkit.anymatrix.groups.gallery import register_gallery_matrices
from matrix_toolkit.anymatrix.groups.hadamard import register_hadamard_matrices
from matrix_toolkit.anymatrix.groups.matlab import register_matlab_matrices
from matrix_toolkit.anymatrix.groups.regtools import register_regtools_matrices
# Register all groups
register_core_matrices(self)
register_extended_core_matrices(self)
register_gallery_matrices(self)
register_hadamard_matrices(self)
register_matlab_matrices(self)
register_regtools_matrices(self)
[docs]
def register_matrix(
self,
group: str,
name: str,
generator: Callable,
properties: List[str],
description: str = ""
):
"""
Register a matrix generator
Args:
group: Group name (e.g., 'core', 'gallery')
name: Matrix name within the group
generator: Function to generate the matrix
properties: List of matrix properties
description: Description of the matrix
"""
matrix_id = f"{group}/{name}"
self._matrix_registry[matrix_id] = {
'generator': generator,
'group': group,
'name': name,
'description': description
}
self._properties_map[matrix_id] = properties
if group not in self._groups:
self._groups[group] = []
if name not in self._groups[group]:
self._groups[group].append(name)
[docs]
def groups(self) -> List[str]:
"""List all available groups"""
return sorted(list(self._groups.keys()))
[docs]
def list(self, group: Optional[str] = None) -> Union[Dict[str, List[str]], List[str]]:
"""
List matrices in a group or all groups
Args:
group: Group name. If None, returns all groups with their matrices
Returns:
List of matrix names or dict of group->matrices
"""
if group is None:
return {g: sorted(matrices) for g, matrices in self._groups.items()}
if group not in self._groups:
raise ValueError(f"Group '{group}' not found. Available: {self.groups()}")
return sorted(self._groups[group])
[docs]
def generate(self, matrix_id: str, *args, **kwargs) -> Any:
"""
Generate a matrix by its ID
Args:
matrix_id: Matrix identifier in format 'group/name'
*args: Positional arguments for the generator
**kwargs: Keyword arguments for the generator
Returns:
Generated matrix
Examples:
>>> am = AnyMatrix()
>>> A = am.generate('core/beta', 10)
>>> B = am.generate('core/fourier', 8)
"""
if matrix_id not in self._matrix_registry:
raise ValueError(
f"Matrix '{matrix_id}' not found. "
f"Use list() to see available matrices."
)
generator = self._matrix_registry[matrix_id]['generator']
try:
return generator(*args, **kwargs)
except Exception as e:
raise RuntimeError(
f"Error generating matrix '{matrix_id}': {e}"
) from e
[docs]
def properties(self, matrix_id: Optional[str] = None) -> Union[List[str], Dict[str, List[str]]]:
"""
Get properties of a matrix or all matrices
Args:
matrix_id: Matrix identifier. If None, returns all matrices with properties
Returns:
List of properties or dict of matrix_id->properties
"""
if matrix_id is None:
return self._properties_map.copy()
if matrix_id not in self._properties_map:
raise ValueError(f"Matrix '{matrix_id}' not found")
return self._properties_map[matrix_id].copy()
[docs]
def search(
self,
properties: List[str],
match_all: bool = True
) -> List[str]:
"""
Search for matrices with specific properties
Args:
properties: List of required properties
match_all: If True, matrix must have all properties.
If False, matrix must have at least one property.
Returns:
List of matrix IDs matching the criteria
Examples:
>>> am = AnyMatrix()
>>> # Find all symmetric matrices
>>> matrices = am.search(['symmetric'])
>>>
>>> # Find matrices that are both symmetric and positive definite
>>> matrices = am.search(['symmetric', 'positive definite'])
"""
results = []
# Normalize property names
normalized_props = [p.lower().strip() for p in properties]
for matrix_id, matrix_props in self._properties_map.items():
matrix_props_normalized = [p.lower().strip() for p in matrix_props]
if match_all:
# All required properties must be present
if all(prop in matrix_props_normalized for prop in normalized_props):
results.append(matrix_id)
else:
# At least one property must be present
if any(prop in matrix_props_normalized for prop in normalized_props):
results.append(matrix_id)
return sorted(results)
[docs]
def help(self, matrix_id: str) -> str:
"""
Get help information for a matrix
Args:
matrix_id: Matrix identifier
Returns:
Help string with description and properties
"""
if matrix_id not in self._matrix_registry:
raise ValueError(f"Matrix '{matrix_id}' not found")
info = self._matrix_registry[matrix_id]
props = self._properties_map.get(matrix_id, [])
help_text = f"Matrix: {matrix_id}\n"
help_text += f"Group: {info['group']}\n"
help_text += f"Name: {info['name']}\n"
help_text += f"\nDescription:\n{info['description']}\n"
help_text += f"\nProperties:\n"
for prop in props:
help_text += f" - {prop}\n"
return help_text
[docs]
def count(self) -> Dict[str, int]:
"""Get count of matrices by group"""
counts = {}
for group, matrices in self._groups.items():
counts[group] = len(matrices)
counts['total'] = len(self._matrix_registry)
return counts
[docs]
def __call__(self, matrix_id: str, *args, **kwargs):
"""Shorthand for generate()"""
return self.generate(matrix_id, *args, **kwargs)
def __repr__(self) -> str:
n_groups = len(self._groups)
n_matrices = len(self._matrix_registry)
return f"AnyMatrix(groups={n_groups}, matrices={n_matrices})"