Periodic ASEP: two hopping rates¶
The worked bias-scan tutorial separates relaxation and oscillation while keeping the total hopping rate fixed.
Status: precision-generic relaxation-gap library and bethe-asep-pbc frontend implemented.
This extends TASEP to nonnegative right and left hopping rates,
including the symmetric endpoint. It does not enumerate the full spectrum or
implement open reservoirs.
Physical convention and API¶
Particles hop to an empty neighbouring site on a periodic ring at rates r and s.
At least one rate must be positive; they need not sum to one. As in TASEP,
dP/dt=M P, with columns of M summing to zero. Eigenvalues are inverse-time
relaxation rates, not quantum energies. The stationary eigenvalue is zero.
#include <bethe/asep.hpp>
auto state = bethe::asep::relaxation_gap(32, 8, 1.0, 0.5);
if (state.converged && state.gap) {
// Positive decay gap: *state.gap == -state.eigenvalue->real().
// Nonnegative angular frequency: state.eigenvalue->imag().
}
The arithmetic is fp64, long-double, fp128 or explicit MPFR precision. Reflection and particle–hole
symmetry reduce the calculation to \(n =\min (N,L -N)\) and
\(x =\min (r,s)/\max (r,s)\). We select the conjugate eigenvalue with nonnegative
imaginary part, without assigning it a physical momentum in the original sector.
For empty/full sectors there is only a stationary state: stationary_only is
successful, but both gap and eigenvalue are absent.
One-particle/one-hole results are analytic:
At r=s the gap is 4r sin²(pi/L) for every nontrivial filling, with zero
frequency. These analytic cases require no iterative roots. At L=2 both
directions reach the same neighbouring site and their rates add.
Command-line use¶
bethe-asep-pbc 32 --particles 8 --right-rate 1 --left-rate 0.5 --roots
bethe-asep-pbc 64 --particles 32 --left-rate 1 --precision long-double
bethe-asep-pbc 32 --particles 8 --left-rate 0.5 --roots --json rates.json \
--csv-table relaxation=rates.csv --tsv-table roots=roots.tsv
bethe-asep-pbc --references
L and --particles are required. Rates default to right=1, left=0 (TASEP).
The shared --precision choices are fp64, long-double and fp128 when enabled.
With Uni20 MPFR scalars, bits-N and digits-N select explicit arbitrary
precision using normal CPU/provider LU dispatch.
The relaxation schema is shared with TASEP: has_mode, lambda_real,
lambda_imag, gap, frequency, residual, iterations, seed_iterations,
converged, status. Frequency is angular frequency, not cycles per time.
--roots adds index,v_real,v_imag, the scaled coordinates described below.
Metadata records the wave root index and complex wave base needed to reconstruct
z, the input rates, all numerical controls, continuation attempts, seed Newton
updates, last reached rate ratio, provenance and CPU time. Analytic results have
no root rows or wave-base metadata values. Failed iterative calculations have
null root coordinates and null physical observables; they exit 2. Empty/full
sectors succeed with has_mode=false and null observables.
--max-iterations limits each continuation corrector; --max-continuation-steps
limits all attempts. --max-seed-iterations, --max-seed-newton-iterations,
--seed-tolerance and --max-sites control the TASEP seed. --tolerance controls
the ASEP rescaled residual. The two residual normalizations differ: at the exact
TASEP endpoint the reported residual is the seed's logarithmic residual.
All shared output options, including streaming and no-retain
exports, apply. Invalid inputs exit 1 before touching files, including existing
--force targets. References appear only with --references.
Equations and continuation¶
With the larger rate factored out, the Bethe equations are
These are the rate-rescaled equations (66) and (69) of Golinelli–Mallick (2006), using reflection to place the larger rate in the inverse-z term. The starting branch is the existing TASEP first-relaxation solution, not a new independent seed prescription. Adaptive continuation increases x from zero to the requested ratio. Each step solves the coupled logarithmic equations using an analytic Jacobian and the shared recoverable Newton solver.
Near symmetric hopping, n-1 roots approach one. Ordinary z coordinates lose the small bias and can give a converged-looking but inaccurate frequency. We instead store finite scaled coordinates v:
scaled_roots, wave_index, and wave_base=z0-1 expose this representation.
The rescaled residual divides the logarithmic equations by delta and L;
the first-harmonic driving phase is removed analytically. A shared stable
complex \(\log (1+z)\) helper retains tiny increments. The eigenvalue is evaluated
as an analytic finite-wave contribution plus small corrections, preserving
frequencies even when the bias is only a few native epsilons. Root separation
and the translation factor are checked before publishing an observable.
The first TASEP relaxation branch is followed continuously; this is not an exhaustive search proving that no other branch overtakes it at every size and rate. Small-ring full-spectrum comparisons independently check the branch selection. Numerical convergence is not an interval certification.
Budgets and failures¶
Options<Real> supplies tolerance (128 native epsilons), max_iterations
(100 Newton updates per continuation attempt), max_continuation_steps (256
attempts, including rejected ones), and the existing tasep::Options as
seed_options (including its default 256-site work budget). Increasing the
size budget does not guarantee convergence.
iterations counts accepted Newton updates across all attempted stages;
seed_iterations and seed_newton_iterations report the separate seed work.
reached_ratio and residual_norm describe the last successfully reached stage,
not a claim of convergence at the requested rates when continuation fails.
Failure statuses include seed_limit, iteration_limit, continuation_limit,
stalled, and precision_limit. Failed solves never publish a gap or eigenvalue;
retained coordinates are diagnostic only. Invalid parameters and exceeded size
budgets throw. Overflowing physical rates are also rejected rather than reported
as a successful infinite gap.
Reusing a seed across rate queries¶
For many rate pairs at fixed size and filling, prepare the unit-rate TASEP state once:
#include <bethe/asep.hpp>
bethe::asep::PreparedGap<double> const prepared(32, 8);
auto a = prepared.at_rates(1.0, 0.3);
auto b = prepared.at_rates(1.0, 0.9);
The object owns its options and seed. Concurrent const queries borrow that
immutable seed and allocate independent continuation roots, Newton matrices
and diagnostics. Each query starts from the same TASEP state; a difficult
rate pair cannot change another query's starting point or budget. Existing
relaxation_gap calls retain their behavior, including avoiding seed work
for analytic sectors and equal rates. Prefer that direct function for a
single request or an entirely analytic curve.
seed_state() exposes a const view of the preparation result. A failed seed
remains a numerical result, propagated to nonanalytic queries; an analytic
endpoint can still succeed. Invalid preparation controls throw. Returned
seed_iterations and seed_newton_iterations describe the shared seed's
construction, so summing those fields over a curve would overcount preparation
work. Query continuation counters retain their original meaning.
The Async example submits preparation and its
consumer before either is ready. The existing reader-dependent grid retains
the background through completion, limits active/uncollected results and
collects rows in rate order. It waits on operation results; there is no global
scheduler drain. From a build directory configured with
-DBETHE_BUILD_EXAMPLES=ON:
cmake --build . --target bethe-async-asep-example -j2
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 \
./examples/bethe-async-asep-example prepared 32 8 129 8 fp64
Arguments are seed mode (prepared or independent), sites, particles,
points, threads and precision. Zero threads selects direct serial execution;
positive counts use Async, capped by the point count and admission window 32.
The right rate is one and left rates cover [0,0.9] inclusively; a one-point
request uses 0.5. Numerical controls remain the model defaults. The example
retains complete states for printing after completion, so its output storage
grows with the requested point count. Its timing includes preparation,
scheduler and collection but excludes printing. The existing single-request
frontend and physical state family are unchanged.
See measurements and limits.
The example accepts native binary64, long double and configured binary128.
The library also supports explicit MPFR requests through complex arithmetic,
seed selection, Newton controls, continuation and all failure results; the
example's precision selector remains native-only.
Validation and next step¶
ASEP and TASEP share an independent test-only configuration-space Markov matrix builder. Every nontrivial filling at L=2 through 9 is compared against its full spectrum at six hopping ratios, including both endpoints. A separate 90-digit ten-configuration reference checks native precision at L=5, N=2, r=1, s=1/2. All enabled precisions check original multiplicative equations, analytic Jacobian, rate scaling, reflection/particle–hole symmetry, selected rings through 32 sites, failure budgets, and a bias only eight working-precision epsilons from symmetry. Dense diagonalization is never a production fallback.
Prepared and direct queries compare every state field, including complex roots, wave representation, residuals and work counters, across both rate directions, particle-hole sectors, analytic endpoints and failure budgets. Two Async grids share one preparation after submission-local handles disappear, under deferred and one/four-worker scheduling. They retain complete numerical seed failures and preserve the independently successful analytic endpoint.
Frontend regressions additionally cover native rate parsing, rate/reflection
symmetry, analytic and TASEP endpoints, all exposed iteration budgets, tiny bias,
overflow, shared help/reference policy, JSON/CSV/TSV exports, streaming/no-retain
output and invalid-input file protection. bethe-tasep-pbc remains right-only;
its options have not silently changed.
Further work includes other relaxation branches and open-reservoir boundaries; neither is included in this leading periodic mode calculation.
Explicit precision¶
bethe-asep-pbc 32 --particles 8 --left-rate 0.5 --precision bits-160 --roots
With Uni20 MPFR/MPC enabled, bits-N and digits-N reach the TASEP seed,
continuation, cancellation-safe complex logarithms, real-block Newton solve,
scaled roots and diagnostics. Normal Uni20 CPU/provider dispatch supplies LU.
The scalar library requires matching finite precision for both rates and the
continuation/seed controls; it does not change ambient MPFR precision.
using R = uni20::mpreal;
auto p = uni20::Precision::bits(160);
bethe::asep::Options<R> options(p);
bethe::asep::PreparedGap<R> prepared(32, 8, options);
auto state = prepared.at_rates(R(1, p), R(1, p) / 2);
Prepared queries reuse one immutable unit-rate TASEP seed. Each query owns its continuation scratch, so rate grids at different precisions can compose through Async without synchronizing precision defaults. Observe the final grid result; its completion includes every admitted query. The single-request CLI stays serial, and each continuation remains sequential.
Independent ten-state Markov-matrix references test accuracy growth through 256 bits. Tests also retain the tiny-bias drift as the symmetric point is approached, compare real-block Jacobians, and check mixed-precision shared-seed Async results field by field against direct solves, including failed seeds with successful analytic endpoint queries. More arithmetic bits do not remove the existing continuation/seed/Newton work limits or establish completeness beyond the selected relaxation branch.