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.