Eigenvalues Everywhere#

The eigenvalue problem \(Av = \lambda v\) is one of the few pieces of mathematics that shows up, essentially unchanged, in three completely unrelated corners of mathematicskit: as the core linear-algebra decomposition in mathematicskit.linalg, as the tool that reveals a graph’s community structure in mathematicskit.graph_theory, and as the classification scheme for a dynamical system’s fixed points in mathematicskit.ode_dynamics.

Eigenvalues as a decomposition#

eigen_symmetric() computes the full eigendecomposition of a symmetric matrix directly:

import numpy as np
from mathematicskit.linalg import eigen_symmetric

A = np.array([[2.0, 1.0], [1.0, 2.0]])
result = eigen_symmetric(A)
print(result.eigenvalues)
# [1. 3.]

Eigenvalues as graph structure#

A graph’s Laplacian \(L = D - A\) (degree matrix minus adjacency matrix) is always symmetric positive semi-definite, so spectral_analysis() can apply the very same symmetric eigendecomposition to it. For a 6-cycle, the Laplacian eigenvalues have the closed form \(2 - 2\cos(2\pi k/6)\):

from mathematicskit.graph_theory import spectral_analysis
from mathematicskit.graph_theory.utils.generators import cycle_graph

g = cycle_graph(6)
spec = spectral_analysis(g)
print(np.round(spec.eigenvalues, 6))
# [0. 1. 1. 3. 3. 4.]
print(spec.algebraic_connectivity)
# 0.9999999999999994 -- the second-smallest eigenvalue, positive since the graph is connected

The smallest eigenvalue is always exactly 0 (the all-ones vector is always an eigenvector); the second-smallest – the algebraic connectivity – is positive if and only if the graph is connected at all, and the corresponding eigenvector’s sign pattern is exactly what plot_spectral_bipartition() uses to split the graph into two communities.

Eigenvalues as stability classification#

A 2D linear system’s fixed point is classified entirely by its Jacobian’s eigenvalues: classify_fixed_point_2d() computes them via the closed-form trace-determinant formula (equivalent to numpy.linalg.eigvals(), just without forming the general complex-eigenvalue machinery for a case this simple) and reads off the qualitative behavior directly from their sign:

from mathematicskit.ode_dynamics.systems.stability import classify_fixed_point_2d

J = np.array([[-1.0, 0.0], [0.0, -2.0]])
result = classify_fixed_point_2d(J)
print(result.classification, result.eigenvalues)
# stable node [-1.+0.j -2.+0.j]

Both eigenvalues negative means every nearby trajectory decays toward the fixed point – a stable node, the same qualitative conclusion mathematicskit.linalg’s eigenvalue sign would give for the stability of any linear system \(\dot x = Jx\), and the same computation mathematicskit.graph_theory uses to certify a graph is connected, just applied to a different matrix each time.

See Also#