EigenValues
Represents the eigenvalues of a square matrix.
Parameters
| Field | Type | Description |
|---|---|---|
data | np.ndarray | list | tuple | Array-like data of shape (N,), N >= 1, with a dtype in the allowlist below, converted to a NumPy array. |
Raises
| Exception | Condition |
|---|---|
TypeError | data can't be converted into a uniform array (e.g. ragged nested lists) |
ValueError | The resulting dtype is unsupported (see Supported Dtypes below), data isn't 1-D, data is empty (size == 0), or it contains a non-finite value (NaN/Inf) |
Supported Dtypes
Inherited unchanged from Array:
| Category | Dtypes |
|---|---|
| Boolean | bool |
| Signed / unsigned integer | int8…int64, uint8…uint64 |
| Floating-point | float16, float32, float64 |
| Complex | complex64, complex128 |
object, structured, and datetime64 dtypes are not supported.
Attributes
| Attribute | Type | Description |
|---|---|---|
data | np.ndarray | The wrapped 1-D array, shape (N,). Reading it returns a copy, so mutating the result doesn't affect the EigenValues. Note: assigning .data = ... re-validates only the dtype (inherited from Array) — it does not re-check the 1-D / non-empty / finite constraints enforced at construction, so it's possible to end up with a mutated instance that no longer satisfies them. Use the constructor, copy(), or coerce() when full re-validation matters. |
shape | tuple[int] | (N,). |
ndim | int | Always 1. |
dtype | np.dtype | Dtype of the array as constructed — not forced to float32. |
size | int | N. |
Methods
| Method | Description |
|---|---|
to_numpy(copy=True) | Returns the array as np.ndarray. Pass copy=False to get a reference to the internal array instead — faster for large data, but mutating it mutates the EigenValues too. |
copy() | Returns a new EigenValues with an independent copy of the data, re-validated through the constructor. |
EigenValues.coerce(value) | Returns value unchanged if it's already an EigenValues; otherwise wraps a np.ndarray/list/tuple into one via the constructor (full validation). Raises TypeError for any other input. |
is_positive_semidefinite(atol=None) | True if every eigenvalue is >= -atol. atol defaults to 100 * eps(dtype) (using float64 eps when the dtype isn't a floating-point kind). |
is_positive_definite(atol=None) | True if every eigenvalue is > atol, using the same default atol as is_positive_semidefinite. |
condition_number (property) | max|λ| / min|λ| over the stored eigenvalues. Raises ZeroDivisionError if any eigenvalue's magnitude is exactly 0 (singular matrix). |
Operators
| Operation | Behavior |
|---|---|
e1 == e2 | True only if other is also an EigenValues with the same dtype, shape, and values (NaN counts as equal to NaN here). False for anything else. |
len(e) | Number of stored eigenvalues, N. |
np.asarray(e) | Works directly — NumPy functions (e.g. np.sum, np.abs) accept an EigenValues in place of an np.ndarray. Always returns a copy; use to_numpy(copy=False) for a zero-copy view. |
hash(e) | Not supported — an EigenValues can't be used as a dict key or set member. |
Visualization
datatypes.visualize(eigenvalues, entity_path=...) logs the values as text (rr.TextLog) — it shares this handler with Array, Mat2x2, Mat3x3, and Mat4x4. A bar chart was deliberately not used: with the handful of eigenvalues typical of these matrices, it would render as a couple of undifferentiated solid blocks and convey less than the printed array. No label handler is registered for EigenValues — passing label to visualize() has no effect for it.
Example
python
"""Demonstrates the Telekinesis EigenValues datatype."""
import time
import numpy as np
from loguru import logger
import rerun as rr
from telekinesis import datatypes
def eigenvalues_example():
"""Demonstrate creation, inspection, visualization, update, positive-definiteness checks, NumPy interop, and serialization."""
# ======================= Create ============================================
matrix = np.array([[2.0, 1.0], [1.0, 2.0]], dtype=np.float32)
w, _ = np.linalg.eigh(matrix)
eigenvalues = datatypes.EigenValues(w)
logger.info(f"Input eigenvalues: {w}")
logger.info(f"Original EigenValues: {eigenvalues}")
# ======================= Inspect ===========================================
data = eigenvalues.data
shape = eigenvalues.shape
size = eigenvalues.size
dtype = eigenvalues.dtype
ndim = eigenvalues.ndim
numpy_array = eigenvalues.to_numpy()
eigenvalues_copy = eigenvalues.copy()
logger.info(
f"shape={shape}, "
f"size={size}, "
f"ndim={ndim}, "
f"dtype={dtype}"
)
logger.info(f"Data: {data}")
logger.info(f"NumPy array: {numpy_array}")
logger.info(f"Copied EigenValues: {eigenvalues_copy}")
# ======================= Visualize =========================================
rr.init("eigenvalues_example", spawn=True)
datatypes.visualize(eigenvalues, entity_path="/EigenValues", label="Original EigenValues")
# ======================= Update ============================================
new_w, _ = np.linalg.eigh(np.array([[5.0, 2.0], [2.0, 5.0]], dtype=np.float32))
eigenvalues.data = new_w
logger.info(f"Updated EigenValues: {eigenvalues}")
datatypes.visualize(
eigenvalues, entity_path="/EigenValues/updated", label="Updated EigenValues"
)
# ======================= Checks ============================================
positive_definite = eigenvalues.is_positive_definite()
positive_semidefinite = eigenvalues.is_positive_semidefinite()
condition_number = eigenvalues.condition_number
logger.info(
f"is_positive_definite={positive_definite}, "
f"is_positive_semidefinite={positive_semidefinite}, "
f"condition_number={condition_number}"
)
# ======================= NumPy Interop =====================================
spectral_radius = np.max(np.abs(eigenvalues))
logger.info(f"Spectral radius (max |eigenvalue|): {spectral_radius}")
# ======================= Serialize / Deserialize ===========================
start = time.perf_counter()
serialized = datatypes.serialize(eigenvalues)
serialization_ms = (time.perf_counter() - start) * 1000
start = time.perf_counter()
deserialized = datatypes.deserialize(serialized)["param_0"]
deserialization_ms = (time.perf_counter() - start) * 1000
logger.info(f"Deserialized EigenValues: {deserialized}")
logger.info(f"Round-trip successful: {deserialized == eigenvalues}")
logger.info(f"Serialization time: {serialization_ms:.3f} ms")
logger.info(f"Deserialization time: {deserialization_ms:.3f} ms")
if __name__ == "__main__":
eigenvalues_example()See also EigenVectors and Array.

