Poly2graph
Automated Non-Hermitian Spectral Graph Construction
Install / Use
/learn @sarinstein-yan/Poly2graphREADME
Poly2Graph
<a target="_blank" href="https://colab.research.google.com/github/sarinstein-yan/poly2graph/blob/main/getting_started.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>
[!NOTE] A companion repository for the dataset and its auxiliary library can be found at the HSG-12M GitHub repo.
Poly2Graph is a Python package for automatic Hamiltonian spectral graph construction. It takes in the characteristic polynomial and returns the spectral graph.
Topological physics is one of the most dynamic and rapidly advancing fields in modern physics. Conventionally, topological classification focuses on eigenstate windings, a concept central to Hermitian topological lattices (e.g., topological insulators). Beyond such notion of topology, we unravel a distinct and diverse graph topology emerging in 1D crystal's energy spectra (under open boundary condition). Particularly, for non-Hermitian crystals, their spectral graphs features a kaleidoscope of exotic shapes like stars, kites, insects, and braids.
<!-- <figure align="center"> <img src="https://raw.githubusercontent.com/sarinstein-yan/poly2graph/main/assets/SGs_demo.png" width="600"> <figcaption style="text-align:left;"> <strong>Poly2Graph pipeline.</strong> <b>(a)</b> Starting from a 1-D crystal Hamiltonian H(z) in momentum space — or, equivalently, its <em>characteristic polynomial</em> P(z,E) = det[ <b>H</b>(z) − E<b>I</b> ]. The crystal’s open-boundary spectrum solely depends on P(z,E). <b>(b)</b> The <em>spectral potential</em> Φ(E) (Ronkin function) is computed from the roots of P(z,E) = 0, following recent advances in non-Bloch band theory. <b>(c)</b> The density of states ρ(E) is obtained as the Laplacian of Φ(E). <b>(d)</b> The spectral graph is extracted from ρ(E) via a morphological computer-vision pipeline. Varying the coefficients of P(z,E) produces diverse graph morphologies in the real domain (d1)–(d3) and imaginary domain (di)–(diii). </figcaption> </figure> --> <p align="center"> <img src="https://raw.githubusercontent.com/sarinstein-yan/poly2graph/main/assets/SGs_demo.png" width="800" alt="Poly2Graph pipeline"> </p><strong>Figure: Poly2Graph Pipeline —</strong> (a) Starting from a 1-D crystal Hamiltonian $H(z)$ in momentum space — or, equivalently, its characteristic polynomial $P(z,E)=\det[\mathbf{H}(z)-E\mathbf{I}]$. The crystal’s open-boundary spectrum solely depends on $P(z,E)$. (b) The spectral potential $\Phi(E)$ (Ronkin function) is computed from the roots of $P(z,E)=0$, following recent advances in non-Bloch band theory. (c) The density of states $\rho(E)$ is obtained as the Laplacian of $\Phi(E)$. (d) The spectral graph is extracted from $\rho(E)$ via a morphological computer-vision pipeline. Varying the coefficients of $P(z,E)$ produces diverse graph morphologies in the real domain (d1)–(d3) and imaginary domain (di)–(diii).
Features
- Poly2Graph
- High-performance
- Fast construction of spectral graph from any one-dimensional models
- Adaptive resolution to reduce floating operation cost and memory usage
- Automatic backend for computation bottleneck. If
tensorflow/torchis available, any device (e.g. '/GPU:0', '/TPU:0', 'cuda:0', etc.) that they support can be used for acceleration.
- Cover generic topological lattices
- Support generic one-band and multi-band models
- Flexible multiple input choices, be they characteristic polynomials or Bloch Hamiltonians; formats include strings,
sympy.Poly, andsympy.Matrix
- Automatic and Robust
- By default, no hyper-parameters are needed. Just input the characteristic of your model and
poly2graphhandles the rest - Automatic spectral boundary inference
- Relatively robust on multiband models that are prone to "component fragmentation"
- By default, no hyper-parameters are needed. Just input the characteristic of your model and
- Helper functionalities generally useful
skeleton2graphmodule: Convert a skeleton image to its graph representationhamiltonianmodule: Conversion among different Hamiltonian representations and efficient computation of a range of properties
- High-performance
Installation
You can install the package via pip:
$ pip install poly2graph
or clone the repository and install it manually:
$ git clone https://github.com/sarinstein-yan/poly2graph.git
$ cd poly2graph
$ pip install -e .
# Or `$ pip install .[dev]` to install the full dependencies
Optionally, if TensorFlow or PyTorch is available, poly2graph will make use of them automatically to accelerate the computation bottleneck. Priority: tensorflow > torch > numpy.
This module is tested on Python >= 3.11.
Check the installation:
import poly2graph as p2g
print(p2g.__version__)
Usage
See the Poly2Graph Tutorial JupyterNotebook.
p2g.SpectralGraph and p2g.CharPolyClass are the two main classes in the package.
p2g.SpectralGraph investigates the spectral graph topology of a specific given characteristic polynomial or Bloch Hamiltonian. p2g.CharPolyClass investigates a class of parametrized characteristic polynomials or Bloch Hamiltonians, and is optimized for generating spectral properties in parallel.
import numpy as np
import networkx as nx
import sympy as sp
import matplotlib.pyplot as plt
# always start by initializing the symbols for k, z, and E
k = sp.symbols('k', real=True)
z, E = sp.symbols('z E', complex=True)
A generic one-band example (p2g.SpectralGraph):
characteristic polynomial:
$$P(E,z) := h(z) - E = z^4 -z -z^{-2} -E$$
Its Bloch Hamiltonian (Fourier transformed Hamiltonian in momentum space) is a scalar function:
$$h(z) = z^4 - z - z^{-2}$$
where the phase factor is defined as $z:=e^{ik}$.
Expressed in terms of crystal momentum $k$:
$$h(k) = e^{4ik} - e^{ik} - e^{-2ik}$$
The valid input formats to initialize a p2g.SpectralGraph object are:
- Characteristic polynomial in terms of
zandE:- as a string of the Poly in terms of
zandE - as a
sympy.Polywith {z,1/z,E} as generators
- as a string of the Poly in terms of
- Bloch Hamiltonian in terms of
korz- as a
sympy.Matrixin terms ofk - as a
sympy.Matrixin terms ofz
- as a
All the following characteristics are valid and will initialize to the same characteristic polynomial and therefore produce the same spectral graph:
char_poly_str = '-z**-2 - E - z + z**4'
char_poly_Poly = sp.Poly(
-z**-2 - E - z + z**4,
z, 1/z, E # generators are z, 1/z, E
)
phase_k = sp.exp(sp.I*k)
char_hamil_k = sp.Matrix([-phase_k**2 - phase_k + phase_k**4])
char_hamil_z = sp.Matrix([-z**-2 - E - z + z**4])
Let us just use the string to initialize and see a set of properties that are computed automatically:
sg = p2g.SpectralGraph(char_poly_str, k=k, z=z, E=E)
Characteristic polynomial:
sg.ChP
<span style="color:#d73a49;font-weight:bold">>>></span> $\text{Poly}{\left( z^{4} - z -\frac{1}{z^{2}} - E, ~ z, \frac{1}{z}, E, ~ domain=\mathbb{Z} \right)}$
Bloch Hamiltonian:
- For one-band model, it is a unique, rank-0 matrix (scalar)
sg.h_k
<span style="color:#d73a49;font-weight:bold">>>></span>
$$\begin{bmatrix}e^{4 i k} - e^{i k} - e^{- 2 i k}\end{bmatrix}$$
sg.h_z
<span style="color:#d73a49;font-weight:bold">>>></span>
$$\begin{bmatrix}- \frac{- z^{6} + z^{3} + 1}{z^{2}}\end{bmatrix}$$
The Frobenius companion matrix of P(E)(z):
- treating
Eas parameter andzas variable - Its eigenvalues are the roots of the characteristic polynomial at a fixed complex energy
E. Thus it is useful to calculate the GBZ (generalized Brillouin zone), the spectral potential (Ronkin function), etc.
sg.companion_E
<span style="color:#d73a49;font-weight:bold">>>></span>
$$\begin{bmatrix}0 & 0 & 0 & 0 & 0 & 1 \ 1 & 0 & 0 & 0 & 0 & 0 \ 0 & 1 & 0 & 0 & 0 & E \ 0 & 0 & 1 & 0 & 0 & 1 \ 0 & 0 & 0 & 1 & 0 & 0 \ 0 & 0 & 0 & 0 & 1 & 0\end{bmatrix}$$
Number of bands & hopping range:
print('Number of bands:', sg.num_bands)
print('Max hopping length to the right:', sg.poly_p)
print('Max hopping length to the left:', sg.poly_q)
<span style="color:#d73a49;font-weight:bold">>>></span>
Number of bands: 1
Max hopping length to the right: 2
Max hopping length to the left: 4
A real-space Hamiltonian of a finite chain and its energy spectrum:
H = sg.real_space_H(
N=40, # number of unit cells
pbc=False, # open boundary conditions
max_dim=500 # maximum dimension of the Hamiltonian matrix (for numerical accuracy)
)
energy = np.linalg.eigvals(H)
fig, ax = plt.subplots(figsize=(3, 3))
ax.plot(energy.real, energy.imag, 'k.', markersize=5)
ax.set(xlabel='Re(E)', ylabel='Im(E)', \
xlim=sg.spectral_square[:2], ylim=sg.spectral_square[2:])
plt.tight_layout(); plt.show()
<p align="center">
<img src="https://raw.githubusercontent.com/sarinstein-yan/poly2graph/main/assets/finite_spectrum_one_band.png" width="300" />
</p>
The Set of Spectral Functions
(whose values plotted on the complex energy square, returned as a 2D array)
-
Density of States (DOS)
Define
Related Skills
next
A beautifully designed, floating Pomodoro timer that respects your workspace.
product-manager-skills
47PM skill for Claude Code, Codex, Cursor, and Windsurf: diagnose SaaS metrics, critique PRDs, plan roadmaps, run discovery, and coach PM career transitions.
devplan-mcp-server
3MCP server for generating development plans, project roadmaps, and task breakdowns for Claude Code. Turn project ideas into paint-by-numbers implementation plans.
