Spectral structure similarity

vibeqc.similarity.spectral_fingerprint(symbols, coordinates_angstrom) computes four physics-inspired graph spectra. A native Molecule or PeriodicSystem can instead be passed alone; native atom positions are converted from bohr. No SCF calculation, energy inference or external QC package is involved.

from vibeqc.similarity import spectral_fingerprint, similarity, channel_similarity
first = spectral_fingerprint(["H", "H"], [[0, 0, 0], [0.74, 0, 0]])
second = spectral_fingerprint(["H", "H"], [[0, 0, 0], [0.80, 0, 0]])
print(similarity(first, second), channel_similarity(first, second))
payload = first.to_dict()

The implementation follows Toney et al., Chemical Science (2026), DOI 10.1039/d6sc06309h, equations 3-9, and SpectralScore commit89301c3. Its MIT atomic table and license are bundled. The reference implementation scales distances by summed covalent radii except for the steric channel, uses raw properties and Frobenius-normalises each adjacency. These concrete reference choices are retained. The default n_eigs=16 is explicit and restricted to 1..128.

  • variant="toney2026": per channel, the second-smallest eigenvalue followed by the remaining eigenvalues descending, truncated/zero-padded. This is the upstream-compatible 64-value layout in paper order: electrostatic, bonding, steric, dispersion. Float64 replaces upstream float32 arithmetic.

  • variant="quantile-scale" (default): exclude the trivial first eigenvalue, divide by mean degree (trace Laplacian / atom count), and sample 16 midpoint quantiles. Append log RMS raw pair weight within each channel. This is the explicitly distinguished size-normalised extension, not a formula from the cited paper. It removes padding-driven size separation and distinguishes diatomics. The complete vector has 68 values.

  • Optional nonnegative size_weight appends size_weight * log(atom_count) for the quantile-scale variant only. It contributes to overall similarity; per-channel scores deliberately exclude this global term.

Similarity is 1/(1+Euclidean distance) for both the complete vector and each channel. Only equal variants, resolutions, scale/size parameters and atomic table identities are comparable. A single atom uses the upstream property-first zero-padded special case (Z, electronegativity, vdW radius, polarizability); its quantile-scale scale components are zero because no pair exists.

Consumer contract

to_dict() emits vibeqc.spectral-fingerprint/1, exact channel ordering, variant and parameters, four channel vectors, optional size component, atom count, SHA256 of canonical element/coordinate input, finite-cluster periodic flag, table SHA256 and the toney2026physics citation/DOI. The citation database also routes extra_methods=["spectral_fingerprint"] to that paper. Consumers must retain and display the producer variant/parameters; they must not replace vectors with a recomputation using different defaults. from_dict() checks schema, shapes, finite values, size component, table and citation identity. The JSON payload can be carried as a vendor member alongside the corresponding QVF structure without introducing a new core QVF kind.

Limits

Dense complete graphs support 1..1000 atoms; larger structures are refused rather than silently adopting the upstream sparse 10-angstrom cutoff. Empty, coincident, nonfinite or unsupported-element geometries are refused. The upstream table’s zero convention for unavailable properties is retained and recorded. A periodic unit cell is treated as a finite cluster, with no images; it is not a periodic fingerprint. Same-element bonding weights do not decay with distance because their electronegativity difference is zero. Charge, spin, wavefunction and bonding state are not additional inputs. Equal vectors are not identity, duplicate-geometry or electronic-state proofs.

Focused invariance and refusal tests do not replace full reference-set qualification (interpretable pairs, BOS-TMC and seeded QM9 parity; diatomic, size-ladder and collision checks). Those criteria are recorded separately.