Skip to content

Repository files navigation

lockkernel

PyPI DOI tests License

A population of oscillators with spread frequencies begins to synchronize when the coupling passes a threshold, and the order parameter then grows from zero as a power of the distance above it. That exponent has been derived separately for each case in which it has been asked. This package computes it from one statement: the quantity deciding the onset is the locking kernel W(u) -- the time-averaged projection a single oscillator keeps on the collective field, as a function of its detuning in units of the locked region's width -- and one substitution turns the self-consistency into an exact parametric solution,

chiN(Omega) = Omega / H(Omega),     R(Omega) = H(Omega),
H(Omega)    = Omega * integral p(Omega u) W(u) du,

for ANY frequency distribution and ANY kernel: threshold chiN_c = 1/(p(0) m) with m the kernel mass, exponent beta = 1/(s-1) for a kernel tail W ~ |u|^-s with 1 < s < 3 and beta = 1/2 for s >= 3, the amplitude in closed form, and the order of the transition from the sign of one nonlocal integral. Sweeping Omega traces the branch with no root finding and no cancellation near threshold, so exponents come out at tens of digits, not two.

Version 1.1 adds the lab half, lockkernel.measured: given a MEASURED synchronization branch -- from an experiment, or from a simulation whose kernel is not known -- it fits threshold, exponent and amplitude together with error bars, reads the kernel tail back off the exponent through the same dictionary the theory half proves, plans how many points a target error bar costs, and refuses, with an explanation, whenever the data cannot support the number asked of them.

Install

pip install lockkernel        # NumPy + SciPy + mpmath

The two halves in one example

import numpy as np
import mpmath as mp
from lockkernel import fit_branch, kernel_tail_from_beta, points_for_beta
from lockkernel.kernels import conservative, power_tail, predicted_beta
from lockkernel.lineshapes import lorentzian, gaussian
from lockkernel.parametric import threshold, sweep, extract_beta

mp.mp.dps = 25

# THEORY: exact threshold and exponent for any line and kernel.
line = lorentzian()
print(threshold(line, conservative()))       # chiN_c = 1/(p(0) pi)
print(extract_beta(line, power_tail(2.5),
                   np.linspace(-6, -3, 7))[-1])   # -> 2/3 = 1/(s-1)

# LAB: fit a measured branch -- here, points generated by the exact
# solution stand in for your data; pass your own (chi, R) instead.
pts = sweep(line, conservative(), np.linspace(-4.3, -2.0, 12))
chi = np.array([float(p[0]) for p in pts])
r = np.array([float(p[1]) for p in pts])
fit = fit_branch(chi, r, reference="cavity ensemble run 17, 2026-09-18")
print(fit.chi_c, "+-", fit.sigma_chi_c)     # the measured threshold
print(fit.beta, "+-", fit.sigma_beta)       # the measured exponent

# ... and what the exponent says about the kernel the system has:
s, s_sigma = kernel_tail_from_beta(fit.beta, max(fit.sigma_beta, 0.01))

# Plan the next measurement: points needed for a 1 % exponent error
# bar over two decades of reduced coupling at 5 % scatter.
n, achieved = points_for_beta(0.01, decades=2.0, sigma_log=0.05)

What is inside

  • lineshapes / kernels: frequency distributions (Lorentzian, Gaussian, Student-t, box, and your own) and locking kernels (conservative 1/(1+u^2), Kuramoto, algebraic tails, Gaussian, coupling-spread-averaged heterogeneous kernels) as small declared objects with masses, tails and supports the quadrature can use.
  • parametric: the exact parametric solution -- threshold, branch_point, sweep, extract_beta, the closed-form amplitude along the whole line of exponents, the order-of-transition criterion c_coefficient and fold_interval for hysteretic onsets -- in mpmath arbitrary precision.
  • measured (new in 1.1): fit_branch for measured (chi, R) points with mandatory provenance -- threshold, exponent and amplitude with asymptotic error bars and residual diagnostics; kernel_tail_from_beta, the exact dictionary inverted with error propagation, refusing to name a single tail where beta is consistent with 1/2 and only the class s >= 3 is identified; beta_relative_sigma / points_for_beta, the closed-form error bar of a log-log slope and its exact inversion into measurement effort.
  • cumulant / ensemble / exact: the class-resolved second-cumulant dynamics of the underlying spin problem, principled discretisation of a line into detuning classes (algebraic tails kept, stiff far tail propagated exactly), and exact small-ensemble references (full Hamiltonian, collective-spin and class-symmetric diagonalisation) the solver is tested against.

Refusals, not guesses

Uncited measured data, too few points, couplings out of order, less than a decade of reduced coupling, a threshold the data do not resolve, an exponent consistent with the unidentifiable beta = 1/2 class, an exponent below every kernel's reach: each is refused with the reason and, where one exists, the remedy.

How it is checked

64 tests (Python 3.9-3.14, run in CI on every push). The theory half is held against closed forms at high precision: the parametric branch against two independent closed forms to better than 1e-28 over six decades of locking bandwidth; the exponent formula along a line of kernel tails; closed amplitude values (1, pi/2, 4/3, pi^2/4) on four line shapes; the coefficient c computed two independent ways to 1e-11; the class-resolved solver against exact diagonalisation of the full Hamiltonian. The lab half is checked BY the theory half: fit_branch must recover the threshold and the exponent of branches generated by the exact parametric solution -- conservative kernel (beta = 1) and algebraic tail s = 2.5 (beta = 2/3) -- noiselessly and under seeded noise within its own reported error bars; the planning closed form is held against seeded simulation and its inversion is asserted on both sides.

Honest limits

Recorded rather than hidden: the near-threshold power law is the LEADING behavior, and data taken far above the onset bend away from it -- the decade refusal and the residual diagnostics guard the fit, not the user's range choice; the fit's error bars are the standard asymptotic covariance, honest when the model holds and the noise estimate is right, and stated as such. In the underlying undamped spin problem the truncated cumulant hierarchy is secularly unstable at long times (the module carries physicality diagnostics any long-time use must be gated on), and the time-averaged kernel is an assumption checked against the full dynamics, not a theorem.

Provenance

This package is the maintained distribution of the reference implementation for the locking-kernel universality study (Tanvir-Mahmud-Mahim/locking-kernel-universality, concept DOI 10.5281/zenodo.22696369), whose scripts, archived run records and figures remain with the study. The core modules are carried over unchanged in v1.1.0; the measured module and the packaging are new here. Copyright as in NOTICE.

Support and governance

Written and maintained by Tanvir Mahmud Mahim (Department of Electrical and Electronic Engineering, BRAC University), who reviews every change and takes the final decision on scope and releases. Design questions are discussed in the open in issues and pull requests, and the standing rule of CONTRIBUTING.md binds the maintainer exactly as it binds contributors: a change that touches the physics arrives with a test, and a claim arrives with its source.

Support runs through the issue tracker. Usage questions are welcome alongside bug reports; a docstring that left a unit or a convention unclear is treated as a documentation bug, not user error.

License

Apache-2.0. See LICENSE and NOTICE. Every release of this package is archived on Zenodo under the concept DOI 10.5281/zenodo.22829483, which always resolves to the latest version.

About

Locking kernel universality - exact thresholds, exponents and amplitudes of synchronization transitions from the locking kernel, and fits of measured synchronization branches with error bars and refusals

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages