braintools.analysis.graph.spectral_radius

braintools.analysis.graph.spectral_radius#

braintools.analysis.graph.spectral_radius(conn, *, weighted=True, method='auto')#

Compute the largest absolute eigenvalue of the connectivity matrix.

\(\rho(W) = \max_k |\lambda_k(W)|\), which governs, for example, the linear stability of \(x \leftarrow W x\) and the echo-state property of reservoirs. The matrix is treated as directed (not symmetrised).

Parameters:
  • conn (Any) – Square connectivity, rows pre and columns post. The diagonal (self-connections) is kept, because the spectral radius is a property of the matrix. Repeated pairs of a ConnectionResult have their weights summed.

  • weighted (bool) – Use the weights (signed, e.g. inhibitory weights negative), or the binary adjacency matrix.

  • method (str) – 'dense': all eigenvalues with numpy.linalg.eigvals (exact, \(O(N^3)\) time and a dense \(N \times N\) array); 'arpack': the largest-magnitude eigenvalue with ARPACK (sparse); 'auto': dense for at most 512 nodes, ARPACK above.

Returns:

The spectral radius, carrying the weight unit for Quantity weights with weighted=True. 0.0 for a graph without edges or nodes.

Return type:

float | Quantity

Raises:
  • ValueError – If the connectivity is not square or method is unknown.

  • RuntimeError – If ARPACK does not converge.

See also

degree_distribution

Node degrees.

Notes

ARPACK (scipy.sparse.linalg.eigs for the eigenvalue of largest magnitude, Krylov dimension 64, fixed random start vector) only needs sparse matrix-vector products. When one eigenvalue stands out (e.g. non-negative or excitation-dominated weights, the Perron root) it converges in a few iterations and agrees with the dense result to about \(10^{-10}\). When many eigenvalues crowd the boundary of the spectral disc, as for large zero-mean random matrices (circular law), it may return an eigenvalue slightly inside the disc (a relative underestimate of up to about \(10^{-2}\) was observed at \(N = 2 \times 10^4\)); use method='dense' when exactness matters and \(N\) allows. BLAS is limited to one thread during the computation (through threadpoolctl, when installed), which is much faster for the small dense blocks of either method.

Host-only (NumPy/SciPy): not traceable by jax.jit, jax.vmap or jax.grad.

Examples

>>> import brainunit as u
>>> import numpy as np
>>> from braintools.analysis.graph import spectral_radius
>>> w = np.array([[0.0, 2.0], [0.5, 0.0]])  # eigenvalues +-1
>>> spectral_radius(w)
1.0
>>> spectral_radius(w * u.nS)
Quantity(1., "nS")
>>> spectral_radius(w, weighted=False)
1.0