jaxvacua.flux_bounding.bounded_fluxes#

class bounded_fluxes(model, sampler=None, Nmax=None, dil_min=None, safety_lambda=10.0, safety_mu=1.5, map_to_fd=False)#

Bases: object

Implements the flux-bounding algorithm of arXiv:2501.03984 for systematic enumeration of Type IIB flux vacua in finite regions of moduli space. Integrates with a model class (jaxvacua.flux_eft.FluxEFT) and optionally a sampler (jaxvacua.sampling.data_sampler).

Note

All eigenvalue bounds are computed globally over the sampled moduli region; tighter local bounds (evaluated at each modulus point individually) are also checked inside the JIT-compiled kernel _process_h_all_moduli_jit().

__init__(model, sampler=None, Nmax=None, dil_min=None, safety_lambda=10.0, safety_mu=1.5, map_to_fd=False)#

Initialises the bounded-fluxes class.

Parameters:
  • model (Any) – A model object (e.g. jaxvacua.flux_eft.FluxEFT) providing gauge_kinetic_matrix, ISD_matrix, tadpole, n_fluxes, dimension_H3, and D3_tadpole.

  • sampler (Any | None) – A jaxvacua.sampling.data_sampler instance used for moduli sampling in enumerate_fluxes(). If None, moduli must be supplied explicitly to compute_bounding_box().

  • Nmax (int | None) – Maximum allowed D3-tadpole charge. Defaults to model.D3_tadpole.

  • dil_min (float | None) – Minimum value of \(s = \operatorname{Im}(\tau)\). Defaults to \(\sqrt{3}/2\), the boundary of the \(\mathrm{SL}(2,\mathbb{Z})\) fundamental domain.

  • safety_lambda (float) – Additive safety margin on \(\lambda_{\max}\). Defaults to 10.0. Set to 0 to disable.

  • safety_mu (float) – Divisive safety margin on \(\mu_{\min}\) and \(\tilde\mu_{\min}\). Defaults to 1.5. Set to 1 to disable.

  • map_to_fd (bool) – If True and model has map_to_fd, map each vacuum to the fundamental domain (monodromy + SL(2,Z)) before deduplicating and returning. Defaults to False.

model#

The compactification model.

sampler#

Optional moduli sampler.

Nmax#

Maximum allowed D3-tadpole.

Type:

int

dil_min#

Lower bound on \(s\).

Type:

float

dil_max#

Upper bound on \(s\) (set after compute_bounding_box()).

Type:

float | None

n_fluxes#

Length of half the full flux vector, \(2(h^{1,2}+1)\).

Type:

int

dimension_H3#

Dimension of the \(A\)-cycle flux sector, \(h^{1,2}+1\).

Type:

int

lambda_max_gl#

Global maximum eigenvalue of \(\mathcal{M}\).

Type:

float

mu_min_gl#

Global minimum eigenvalue of \(-\operatorname{Im}(\mathcal{N})\).

Type:

float

mu_max_gl#

Global maximum eigenvalue of \(-\operatorname{Im}(\mathcal{N})\).

Type:

float

tilde_mu_min_gl#

Global minimum eigenvalue of \(\operatorname{Im}(\mathcal{N}^{-1})\).

Type:

float

tilde_mu_max_gl#

Global maximum eigenvalue of \(\operatorname{Im}(\mathcal{N}^{-1})\).

Type:

float

Methods

__init__(model[, sampler, Nmax, dil_min, ...])

Initialises the bounded-fluxes class.

bound_f1_global()

Checks the two global bounds on the \(f_1\) sector using the global eigenvalue extrema \(\tilde\mu_{\min/\max}^{\rm gl}\).

bound_f1_local()

Checks the four local bounds on the \(f_1\) sector derived from the ISD condition (arXiv:2501.03984). Uses \(\tilde f_1 = f_1 - c_0 h_1\) and \(\tilde\mu_{\min/\max}\) — the extreme eigenvalues of \(\operatorname{Im}(\mathcal{N}^{-1})\).

bound_f2_global()

Checks the two global bounds on the \(f_2\) sector using the global eigenvalue extrema \(\mu_{\min/\max}^{\rm gl}\).

bound_f2_local()

Checks the four local bounds on the \(f_2\) sector derived from the ISD condition (arXiv:2501.03984). Uses \(\tilde f_2 = f_2 - c_0 h_2\) and \(\mu_{\min/\max}\) — the extreme eigenvalues of \(-\operatorname{Im}(\mathcal{N})\).

bound_f_global()

Checks the global bounds on \(\|f\|^2\).

bound_f_local()

Checks the local bounds on \(\|f\|^2\):

bound_h1_global()

Checks the global bound on \(\|h_1\|^2\):

bound_h1_local()

Checks the local bound on \(\|h_1\|^2\):

bound_h2_global()

Checks the global bound on \(\|h_2\|^2\):

bound_h2_local()

Checks the local bound on \(\|h_2\|^2\):

bound_h_global()

Checks the global bound on \(\|h\|^2\):

bound_h_local()

Checks the local bound on \(\|h\|^2\):

bound_s_global()

Checks the global bounds on \(s\).

bound_s_local()

Checks the local bounds on \(s = \operatorname{Im}(\tau)\):

check_bounds(moduli, tau, flux)

Checks all eigenvalue bounds for a given flux configuration.

check_bounds_batch(evs_batch, tau_batch, ...)

JIT-compiled, vmapped bound checking for a batch of flux candidates. Replaces the per-candidate Python loop over update_local() + check_bounds_flat() with a single vectorized JAX call.

check_bounds_flat()

Evaluates all bound_* methods using the current local state (set by a prior update_local() call) and returns an aggregate pass/fail flag alongside the detailed results.

compute_bounding_box(moduli_sample[, tau_sample])

Computes global eigenvalue bounds over a sample of moduli points and returns the bounding box dimensions for the NSNS-flux vector \(h = (h_1, h_2)\).

compute_bounding_box_converged([batch_size, ...])

Iterative version of compute_bounding_box() that keeps sampling moduli batches until the running maximum eigenvalue \(\lambda_{\rm max}\) has converged to relative tolerance tol.

compute_eigenvalue_bounds([n_sample, ...])

Sample moduli from sampler and compute global eigenvalue bounds. Results are stored as class attributes and reused by subsequent calls to enumerate_fluxes() and sample_bounded_fluxes(), which will skip re-computation.

compute_evs(moduli)

Computes the eigenvalue quantities at a single moduli point.

compute_evs_vmap(moduli_batch)

Batched version of compute_evs() via vmap.

compute_norm(v)

Computes the squared Euclidean norm \(\|v\|^2 = v \cdot v\).

compute_tadpole_batch(flux_batch)

Batched tadpole computation via vmap.

enumerate_fluxes([n_sample, n_isd_per_h, ...])

Main flux enumeration algorithm (Algorithm 1 of arXiv:2501.03984).

export_cluster_job(output_dir[, mode, ...])

Export the flux search pipeline to disk for cluster-parallel execution.

get_fh(flux)

Splits the full flux vector into its RR- and NSNS-flux components.

get_flux_split(flux_half)

Splits a half-flux vector f or h (length n_fluxes) into its two sub-sector components.

get_h_box()

Returns the cached bounding box dimensions (h1_box, h2_box, h_box) set by compute_bounding_box().

get_h_candidates([max_candidates])

Enumerates all integer NSNS-flux vectors \(h = (h_1, h_2)\) inside the bounding box computed by compute_bounding_box(), pre-filtered by the \(L^2\)-norm constraints on \(h_1\) and \(h_2\) separately.

get_nflux(flux)

Computes the D3-tadpole charge \(N_{\rm flux}\) for a flux vector.

get_subvector(flux)

Splits the full flux vector into all four sub-components \((h_1, h_2, f_1, f_2)\).

in_patch_batch(moduli_batch, tau_batch)

Vmapped patch-membership check.

isd_refine_batch(h_batch, moduli_pts, tau_pts)

ISD-refinement for a batch of NSNS-flux candidates via iterated linearised_shifts() calls with flag-based early stopping.

merge_cluster_results(output_dir[, model, ...])

Merge results from all cluster workers, deduplicate, optionally Newton-refine, and optionally write to the vacua database.

newton_refine_batch(moduli_batch, tau_batch, ...)

JIT-compiled, vmapped Newton refinement for a batch of flux candidates. Solves \(D_I W = 0\) simultaneously for all (moduli, tau, flux) triples.

precompute_isd_data(moduli_pts)

Precompute ISD-matrix and its derivatives at a batch of moduli starting points. These quantities depend only on moduli, not on the h-flux, so they can be computed once and reused for all h-vectors in the init step.

process_chunk_from_disk(output_dir, ...[, ...])

Process a single h-chunk from disk using a reconstructed pipeline. Designed to be called from a cluster worker script.

reset_eigenvalue_bounds()

Reset global eigenvalue bounds to their initial sentinels. After calling this, enumerate_fluxes() and sample_bounded_fluxes() will recompute bounds from scratch.

sample_bounded_fluxes([n_target, n_batch, ...])

Stochastic flux search guided by the eigenvalue bounds of arXiv:2501.03984.

update_evs(moduli)

Computes eigenvalues at moduli, sets the local eigenvalue attributes, and updates the global extrema via update_global().

update_global()

Updates the global eigenvalue extrema from the current local values. Should be called after update_evs() or update_local().

update_local(moduli, tau, flux)

Updates the full local state — eigenvalues, axio-dilaton components, and flux norms — for a given point (moduli, tau, flux). Also calls update_global().

Attributes

bounds_initialized

Description: True if compute_eigenvalue_bounds() (or compute_bounding_box()) has been called at least once.

bound_f1_global()#

Checks the two global bounds on the \(f_1\) sector using the global eigenvalue extrema \(\tilde\mu_{\min/\max}^{\rm gl}\).

Returns:
  • Tuple[Tuple[bool, bool], str] – Two bounds (b3, b4) and

  • label ``”f1 global”``.

Return type:

Tuple[Tuple[bool, bool], str]

bound_f1_local()#

Checks the four local bounds on the \(f_1\) sector derived from the ISD condition (arXiv:2501.03984). Uses \(\tilde f_1 = f_1 - c_0 h_1\) and \(\tilde\mu_{\min/\max}\) — the extreme eigenvalues of \(\operatorname{Im}(\mathcal{N}^{-1})\).

Returns:
  • Tuple[Tuple[bool, bool, bool, bool], str]

  • Four bounds `` (b1, b2, b5, b6)

Return type:

Tuple[Tuple[bool, ...], str]

bound_f2_global()#

Checks the two global bounds on the \(f_2\) sector using the global eigenvalue extrema \(\mu_{\min/\max}^{\rm gl}\).

Returns:
  • Tuple[Tuple[bool, bool], str] – Two bounds (b3, b4) and

  • label ``”f2 global”``.

Return type:

Tuple[Tuple[bool, bool], str]

bound_f2_local()#

Checks the four local bounds on the \(f_2\) sector derived from the ISD condition (arXiv:2501.03984). Uses \(\tilde f_2 = f_2 - c_0 h_2\) and \(\mu_{\min/\max}\) — the extreme eigenvalues of \(-\operatorname{Im}(\mathcal{N})\).

Returns:
  • Tuple[Tuple[bool, bool, bool, bool], str]

  • Four bounds `` (b1, b2, b5, b6)

Return type:

Tuple[Tuple[bool, ...], str]

bound_f_global()#

Checks the global bounds on \(\|f\|^2\).

Returns:
  • Tuple[Tuple[bool, bool, bool], str]

  • Three bounds and label ``”f global”``.

Return type:

Tuple[Tuple[bool, bool, bool], str]

bound_f_local()#

Checks the local bounds on \(\|f\|^2\):

\[\frac{s\,N_{\rm flux}}{\lambda_{\max}} \leq \|f\|^2 \leq \frac{\lambda_{\max}^2 N_{\rm flux}^2}{\|h\|^2} \Bigl(1 + \frac{c_0^2}{s^2}\Bigr)\,.\]
Returns:

Tuple[Tuple[bool, bool], str] – Two bounds and label "f local".

Return type:

Tuple[Tuple[bool, bool], str]

bound_h1_global()#

Checks the global bound on \(\|h_1\|^2\):

\[s_{\min}\,\tilde\mu_{\min}^{\rm gl}\,\|h_1\|^2 \leq N_{\max}\,.\]
Returns:

Tuple[bool, str](satisfied, "h1 global").

Return type:

Tuple[bool, str]

bound_h1_local()#

Checks the local bound on \(\|h_1\|^2\):

\[s\,\tilde\mu_{\min}\,\|h_1\|^2 \leq N_{\rm flux}\,.\]
Returns:

Tuple[bool, str](satisfied, "h1 local").

Return type:

Tuple[bool, str]

bound_h2_global()#

Checks the global bound on \(\|h_2\|^2\):

\[s_{\min}\,\mu_{\min}^{\rm gl}\,\|h_2\|^2 \leq N_{\max}\,.\]
Returns:

Tuple[bool, str](satisfied, "h2 global").

Return type:

Tuple[bool, str]

bound_h2_local()#

Checks the local bound on \(\|h_2\|^2\):

\[s\,\mu_{\min}\,\|h_2\|^2 \leq N_{\rm flux}\,.\]
Returns:

Tuple[bool, str](satisfied, "h2 local").

Return type:

Tuple[bool, str]

bound_h_global()#

Checks the global bound on \(\|h\|^2\):

\[\|h\|^2 \leq \frac{N_{\max}\,\lambda_{\max}^{\rm gl}}{s_{\min}}\,.\]
Returns:

Tuple[bool, str](satisfied, "h global").

Return type:

Tuple[bool, str]

bound_h_local()#

Checks the local bound on \(\|h\|^2\):

\[\|h\|^2 \leq \frac{N_{\rm flux}\,\lambda_{\max}}{s}\,.\]
Returns:

Tuple[bool, str](satisfied, "h local").

Return type:

Tuple[bool, str]

bound_s_global()#

Checks the global bounds on \(s\).

Returns:

Tuple[Tuple[bool, bool], str] – Two bounds and label "s global".

Return type:

Tuple[Tuple[bool, bool], str]

bound_s_local()#

Checks the local bounds on \(s = \operatorname{Im}(\tau)\):

\[s_{\min} \leq s \leq \lambda_{\max} N_{\rm flux}\,,\quad s \leq \frac{\lambda_{\max} N_{\rm flux}}{\|h\|^2} + \frac{\|h\|^2}{4\,\lambda_{\max}}\,.\]
Returns:
  • Tuple[Tuple[bool, bool, bool], str]

  • Three bounds and label ``”s local”``.

Return type:

Tuple[Tuple[bool, bool, bool], str]

property bounds_initialized: bool#

Description: True if compute_eigenvalue_bounds() (or compute_bounding_box()) has been called at least once.

check_bounds(moduli, tau, flux)#

Checks all eigenvalue bounds for a given flux configuration.

Calls update_local() to refresh the local state and then evaluates every bound_* method.

Parameters:
  • moduli (Array) – Complex structure moduli, shape (h^{1,2},).

  • tau (complex) – Axio-dilaton \(\tau = c_0 + \mathrm{i}\,s\).

  • flux (Array) – Full flux vector [f \mid h] of length 2 * n_fluxes.

Returns:
  • List[Tuple] – One entry per bound_* method of the form

  • `` (result, label)

  • bools.

Return type:

List[Tuple]

check_bounds_batch(evs_batch, tau_batch, flux_batch, lambda_max_gl, mu_min_gl, mu_max_gl, tilde_mu_min_gl, tilde_mu_max_gl, dil_min, dil_max, Nmax)#

JIT-compiled, vmapped bound checking for a batch of flux candidates. Replaces the per-candidate Python loop over update_local() + check_bounds_flat() with a single vectorized JAX call.

Eigenvalues must be pre-computed via compute_evs_vmap() and passed as evs_batch to avoid redundant recomputation. All global parameters are passed explicitly so the function is a pure module-level JIT kernel.

Parameters:
  • evs_batch (Tuple) – Pre-computed eigenvalue 5-tuple, each component of shape (N,): \((\lambda_{\max}, \mu_{\min}, \mu_{\max}, \tilde\mu_{\min}, \tilde\mu_{\max})\).

  • tau_batch (Array) – Axio-dilaton values, shape (N,).

  • flux_batch (Array) – Full flux vectors \([f \mid h]\), shape (N, 2 \times \texttt{n\_fluxes}).

  • lambda_max_gl (float) – Global maximum eigenvalue of \(\mathcal{M}\).

  • mu_min_gl (float) – Global minimum eigenvalue of \(-\operatorname{Im}(\mathcal{N})\).

  • mu_max_gl (float) – Global maximum eigenvalue of \(-\operatorname{Im}(\mathcal{N})\).

  • tilde_mu_min_gl (float) – Global minimum eigenvalue of \(\operatorname{Im}(\mathcal{N}^{-1})\).

  • tilde_mu_max_gl (float) – Global maximum eigenvalue of \(\operatorname{Im}(\mathcal{N}^{-1})\).

  • dil_min (float) – Lower bound \(s_{\min}\).

  • dil_max (float) – Upper bound \(s_{\max}\).

  • Nmax (float) – Maximum tadpole \(N_{\max}\).

Returns:
  • Array – Boolean array of shape (N,); True where all bounds

  • pass.

Return type:

Array

check_bounds_flat()#

Evaluates all bound_* methods using the current local state (set by a prior update_local() call) and returns an aggregate pass/fail flag alongside the detailed results.

Returns:
  • Tuple[bool, List[Tuple]](all_pass, results) where

  • *all_pass* is ``True`` iff every individual bound is satisfied.

Return type:

Tuple[bool, List[Tuple]]

compute_bounding_box(moduli_sample, tau_sample=None)#

Computes global eigenvalue bounds over a sample of moduli points and returns the bounding box dimensions for the NSNS-flux vector \(h = (h_1, h_2)\).

Note

Call compute_bounding_box_converged() to automatically iterate until the running maximum \(\lambda_{\max}\) has stabilised to a relative tolerance, giving a tighter box.

Parameters:
  • moduli_sample (Array) – Complex structure moduli sample, shape (N, h^{1,2}).

  • tau_sample (Array | None) – Axio-dilaton sample, shape (N,). Currently unused; reserved for future s-dependent refinement.

Returns:
  • Tuple[float, float, float](h1_box, h2_box, h_box) — the

  • maximum :math:`L^2` norms allowed for :math:`h_1`, :math:`h_2`,

  • and :math:`h` respectively.

Raises:

ValueError – If all sampled eigenvalues are NaN (model not implemented for the chosen limit or moduli point).

Return type:

Tuple[float, float, float]

compute_bounding_box_converged(batch_size=100, max_batches=500, tol=0.001, min_batches=10, verbose=True)#

Iterative version of compute_bounding_box() that keeps sampling moduli batches until the running maximum eigenvalue \(\lambda_{\rm max}\) has converged to relative tolerance tol.

Warm-starts from any prior call: if lambda_max_gl is already non-zero (i.e. a previous call already established an estimate), the first batch updates from that starting point.

The sampler attached to this bounded_fluxes instance (sampler) is used to draw moduli samples.

Parameters:
  • batch_size (int) – Number of moduli points sampled per batch. Defaults to 100.

  • max_batches (int) – Stop even if not converged after this many batches. A warning is issued. Defaults to 500.

  • tol (float) – Relative convergence threshold on \(\lambda_{\rm max}\). Defaults to 1e-3.

  • min_batches (int) – Always run at least this many batches before checking convergence. Defaults to 10.

  • verbose (bool) – Print per-batch progress. Defaults to True.

Returns:
  • Tuple[float, float, float](h1_box, h2_box, h_box) — same

  • as :func:`compute_bounding_box`.

Raises:

ValueError – If no sampler has been set.

Return type:

Tuple[float, float, float]

compute_eigenvalue_bounds(n_sample=100000, rns_key=None, verbose=True)#

Sample moduli from sampler and compute global eigenvalue bounds. Results are stored as class attributes and reused by subsequent calls to enumerate_fluxes() and sample_bounded_fluxes(), which will skip re-computation.

Call this method once (with a large n_sample, e.g. 1M) before running any scans. The eigenvalue extrema accumulate over repeated calls (monotone min/max), so calling this multiple times only tightens the bounds.

Parameters:
  • n_sample (int) – Number of moduli points to sample. Defaults to 100_000.

  • rns_key (Any, optional) – JAX PRNG key for reproducible sampling.

  • verbose (bool) – Print progress. Defaults to True.

Returns:
  • Tuple[float, float, float](h1_box, h2_box, h_box) — the

  • bounding box dimensions for :math:`h`.

Return type:

Tuple[float, float, float]

compute_evs(moduli)#

Computes the eigenvalue quantities at a single moduli point.

Parameters:

moduli (Array) – Complex structure moduli, shape (h^{1,2},).

Returns:
  • Tuple(lambda_max, mu_min, mu_max, tilde_mu_min, tilde_mu_max)

  • where the entries are the largest eigenvalue of :math:`mathcal{M}`,

  • the extreme eigenvalues of :math:`-operatorname{Im} (mathcal{N})

  • and the extreme eigenvalues of

  • :math:`operatorname{Im} (mathcal{N}^{-1})

Return type:

Tuple

compute_evs_vmap(moduli_batch)#

Batched version of compute_evs() via vmap.

Parameters:

moduli_batch (Array) – Batch of moduli, shape (N, h^{1,2}).

Returns:
  • Tuple – Each element is an array of shape (N,) corresponding to

  • one of the five eigenvalue quantities.

Return type:

Tuple

compute_norm(v)#

Computes the squared Euclidean norm \(\|v\|^2 = v \cdot v\).

Parameters:

v (ndarray) – Real (sub-)vector.

Returns:

float – Squared norm \(\|v\|^2\).

Return type:

float

compute_tadpole_batch(flux_batch)#

Batched tadpole computation via vmap.

Parameters:

flux_batch (Array) – Batch of flux vectors, shape (N, 2*n_fluxes).

Returns:

Array – Tadpole values, shape (N,).

Return type:

Array

enumerate_fluxes(n_sample=500, n_isd_per_h=20, max_h_candidates=10000000, verbose=True, rns_key=None, refine=False, return_moduli=False, newton_tol=1e-10, newton_max_iters=100, newton_step_size=1.0, confirm_streaming=True, moduli_regions=None, use_linearised_shifts=False, n_isd_iters=5, n_moduli_batches=1, constraints=None, chunk_size=None)#

Main flux enumeration algorithm (Algorithm 1 of arXiv:2501.03984).

Systematically constructs Type IIB flux vacua in a finite region of moduli space by exhaustively enumerating all integer NSNS-flux vectors \(h\) inside the eigenvalue-based bounding box.

Note

With refine=False, returned fluxes satisfy the ISD bounds and tadpole constraint but are not exact SUSY vacua: the continuous ISD completion is rounded to integers and \(D_I W \neq 0\) in general. Use refine=True for exact vacua.

Note

For problems where the full enumeration is infeasible (very large \(N_{\max}\) or \(h^{1,2}\)), use sample_bounded_fluxes() instead, which randomly samples \(h\) vectors from the bounding box.

Systematically constructs Type IIB flux vacua in a finite region of moduli space via the following steps:

  1. Sample \(n_{\rm sample}\) moduli points from sampler and compute global eigenvalue bounds.

  2. Enumerate all integer \(h\) vectors in the bounding box via get_h_candidates().

  3. Pre-filter \(h\) candidates by the global norm bound \(\|h\|^2 \leq h_{\rm box}^2\).

  4. For each surviving \(h\), compute the ISD-projected RR-flux

    \[f \approx \bigl(s\,\mathcal{M}(z,\bar z)\,\Sigma + c_0\bigr)\,h\]

    (rounded to integers) via jaxvacua.sampling.data_sampler.ISD_sampling() at up to n_isd_per_h sampled moduli points.

  5. Retain [f | h] pairs satisfying the D3-tadpole constraint and all local eigenvalue bounds (via check_bounds_batch()).

  6. (Optional, refine=True) Newton-refine each candidate to solve \(D_I W = 0\) exactly, then verify that the solution lies inside the sampler’s moduli patch and deduplicate.

Parameters:
  • n_sample (int) – Number of moduli points to sample for computing global bounds. Defaults to 500.

  • n_isd_per_h (int) – Maximum number of moduli sample points tried per \(h\) candidate for ISD completion. Defaults to 20.

  • max_h_candidates (int) – Threshold above which the bounding box is considered “large” and streaming mode is activated automatically (h2-outer enumeration, no full materialisation). Defaults to 10_000_000. Set to None to always use the standard (non-streaming) path.

  • confirm_streaming (bool) – When streaming mode is triggered, print runtime/memory estimates and ask for interactive confirmation before proceeding. Set to False to skip the prompt (e.g. in scripts/cluster jobs). Defaults to True.

  • moduli_regions (Optional[List[Tuple[float, float]]]) – List of (lo, hi) intervals for the imaginary part of the complex structure moduli. When provided, the ISD kernel samples n_isd_per_h points from each region in turn and the combined sample is used for ISD completion, increasing the chance of finding vacua spread across the moduli space. Example: [(1., 2.), (2., 3.), (3., 4.)]. Defaults to None (use the main sampler’s full range).

  • verbose (bool) – Print progress with timing. Defaults to True.

  • rns_key (Any | None) – Random number key for reproducible sampling. Passed to sampler.get_complex_moduli() and sampler.get_complex_tau(). When use_jax=True on the sampler, this should be a JAX PRNG key.

  • refine (bool) – If True, Newton-refine candidates to solve \(D_I W = 0\) exactly and filter by convergence and patch membership. Defaults to False.

  • return_moduli (bool) – If True, return a List[dict] with keys "flux", "moduli", "tau" even when refine=False. Defaults to False.

  • newton_tol (float) – Residual tolerance for Newton convergence. Defaults to 1e-10.

  • newton_max_iters (int) – Maximum Newton iterations. Defaults to 100.

  • newton_step_size (float) – Step size for Newton’s method. Defaults to 1.0 (full Newton steps, quadratic convergence).

  • use_linearised_shifts (bool) – If True, replaces the fixed-moduli ISD completion with iterated linearised_shifts_H() calls (see isd_refine_batch()). The moduli are moved to be self-consistent with each \(h\), matching the algorithm of arXiv:2501.03984. Requires model to be a FluxVacuaFinder instance. Defaults to False.

  • n_isd_iters (int) – Number of linearised_shifts_H() iterations when use_linearised_shifts=True. Defaults to 5.

Returns:
  • List[np.ndarray] – When refine=False and

  • ``return_moduli=False``, valid flux vectors ``[f | h]`` of

  • length ``2 * n_fluxes`` satisfying the tadpole constraint and

  • all local eigenvalue bounds.

  • List[dict] – When refine=True or return_moduli=True,

  • each entry is a dict with keys ``”flux”``, ``”moduli”``,

  • ``”tau”`` (and "residual" when refine=True)

  • the integer flux vector, an associated moduli point

  • :math:`z^*`, axio-dilaton :math:`\tau^*`, and (if refined)

  • the F-term residual.

Raises:

ValueError – If no sampler has been provided.

Return type:

list

export_cluster_job(output_dir, mode='enumerate', chunk_size=100000, n_total_samples=5000000, seed=42, n_sample=500, n_isd_per_h=20, moduli_regions=None, use_linearised_shifts=False, n_isd_iters=5, generate_slurm=False, slurm_opts=None, verbose=True)#

Export the flux search pipeline to disk for cluster-parallel execution.

Precomputes the ISD pipeline, generates pre-filtered h-chunks, and saves everything so that each chunk can be processed independently by a cluster worker via process_chunk_from_disk().

Parameters:
  • output_dir (str) – Directory to write pipeline, chunks, and scripts.

  • mode (str) – "enumerate" for exhaustive search, "sample" for stochastic importance sampling.

  • chunk_size (int) – Target h-vectors per chunk file.

  • n_total_samples (int) – Total h-vectors to generate in sample mode.

  • seed (int) – Base random seed for sample mode.

  • n_sample (int) – Moduli points for eigenvalue bounds.

  • n_isd_per_h (int) – Moduli points per h-vector for ISD completion.

  • moduli_regions – Optional list of (lo, hi) moduli bands.

  • use_linearised_shifts (bool) – Use linearised_shifts pipeline.

  • n_isd_iters (int) – Iterations for linearised_shifts.

  • generate_slurm (bool) – Generate SLURM array job script.

  • slurm_opts (dict) – Override SLURM directives.

  • verbose (bool) – Print progress.

Returns:
  • dict – Summary with keys n_chunks, output_dir,

  • ``estimated_disk_mb``, ``n_h_total``.

Return type:

dict

get_fh(flux)#

Splits the full flux vector into its RR- and NSNS-flux components.

Parameters:

flux (Array) – Full flux vector [f \mid h] of length 2 * n_fluxes.

Returns:

Tuple[ndarray, ndarray](f, h) each of length n_fluxes.

Return type:

Tuple[ndarray, ndarray]

get_flux_split(flux_half)#

Splits a half-flux vector f or h (length n_fluxes) into its two sub-sector components.

Parameters:

flux_half (ndarray) – Half-flux vector of length n_fluxes.

Returns:
  • Tuple[ndarray, ndarray](flux_1, flux_2) each of length

  • ``dimension_H3``.

Return type:

Tuple[ndarray, ndarray]

get_h_box()#

Returns the cached bounding box dimensions (h1_box, h2_box, h_box) set by compute_bounding_box().

Returns:
  • Tuple[float, float, float] – Bounding box \(L^2\) radii for

  • :math:`h_1`, :math:`h_2`, and :math:`h`.

Raises:

RuntimeError – If compute_bounding_box() has not been called.

Return type:

Tuple[float, float, float]

get_h_candidates(max_candidates=1000000)#

Enumerates all integer NSNS-flux vectors \(h = (h_1, h_2)\) inside the bounding box computed by compute_bounding_box(), pre-filtered by the \(L^2\)-norm constraints on \(h_1\) and \(h_2\) separately.

Note

This method materialises the full candidate array in memory. For large boxes (many millions of candidates) use the streaming path in enumerate_fluxes() (activated automatically when the estimated count exceeds max_h_candidates), or use _iter_h_chunks_streaming() directly.

Parameters:

max_candidates (int | None) – Emit a warning if the unfiltered box contains more than this many candidate vectors.

Returns:
  • np.ndarray – Integer array of shape (N_candidates, n_fluxes),

  • where each row is one candidate :math:`h = [h_1 mid h_2]` with

  • :math:`|h_1|^2 leq h_{1,rm box}^2` and

  • :math:`|h_2|^2 leq h_{2,rm box}^2`.

Raises:

RuntimeError – If compute_bounding_box() has not been called.

Return type:

ndarray

get_nflux(flux)#

Computes the D3-tadpole charge \(N_{\rm flux}\) for a flux vector.

Parameters:

flux (Array) – Full flux vector [f \mid h].

Returns:

float – D3-tadpole charge \(N_{\rm flux}\).

Return type:

float

get_subvector(flux)#

Splits the full flux vector into all four sub-components \((h_1, h_2, f_1, f_2)\).

Parameters:

flux (Array) – Full flux vector [f \mid h].

Returns:

Tuple[ndarray, ndarray, ndarray, ndarray](h1, h2, f1, f2).

Return type:

Tuple

in_patch_batch(moduli_batch, tau_batch)#

Vmapped patch-membership check.

Parameters:
  • moduli_batch (Array) – Shape (N, h^{1,2}).

  • tau_batch (Array) – Shape (N,).

Returns:

Array – Boolean array of shape (N,).

Return type:

Array

isd_refine_batch(h_batch, moduli_pts, tau_pts, n_iters=10, h_sub_batch=200, constraints=None)#

ISD-refinement for a batch of NSNS-flux candidates via iterated linearised_shifts() calls with flag-based early stopping.

Parameters:
  • h_batch (Array) – NSNS-flux candidates, (n_h, n_fluxes).

  • moduli_pts (Array) – Starting moduli, (n_pts, h12).

  • tau_pts (Array) – Starting axio-dilatons, (n_pts,).

  • n_iters (int) – Maximum linearised-shifts iterations. Defaults to 10.

  • h_sub_batch (int) – h-vectors per vmapped sub-batch. Defaults to 200.

  • constraints (Callable, optional) – Extra constraint function (moduli, tau, flux) bool. Passed to linearised_shifts(). Defaults to None (only hyperplane + tadpole checks).

Returns:

Tuple[np.ndarray, np.ndarray, np.ndarray]

  • mod_out — shape (n_h, n_pts, h12).

  • tau_out — shape (n_h, n_pts).

  • flux_out — shape (n_h, n_pts, 2*n_fluxes).

Return type:

Tuple[ndarray, ndarray, ndarray]

classmethod merge_cluster_results(output_dir, model=None, sampler=None, refine=False, newton_tol=1e-10, newton_max_iters=100, newton_step_size=1.0, return_moduli=True, database=None, method='enumerate_cluster', tags=None, verbose=True, map_to_fd=False, designate=False, label=None, committed_by=None, validate_before_designate=True)#

Merge results from all cluster workers, deduplicate, optionally Newton-refine, and optionally write to the vacua database.

Two levels of database integration:

  1. database=<CYDatabase>: write the merged results as a session-tier batch via stringforge.lcs_database.LCSDatabase.vacua_writer(). The results are queryable via query_vacua() but not yet permanent.

  2. designate=True (requires database, label, committed_by): additionally promote the merged results to the permanent vault via stringforge.lcs_database.LCSDatabase.designate_vacua(). The results are retrievable via load_local_vacua().

Parameters:
  • output_dir (str) – Directory containing results/ subdirectory.

  • model – FluxEFT instance (needed for refine or database write).

  • sampler – data_sampler instance (needed for in-patch checking).

  • refine (bool) – Newton-refine the merged results.

  • newton_tol (float) – Newton convergence tolerance.

  • newton_max_iters (int) – Max Newton iterations.

  • newton_step_size (float) – Newton step size.

  • return_moduli (bool) – Include moduli/tau in output dicts.

  • database – Optional CYDatabase instance for writing results.

  • method (str) – Method label for database catalog.

  • tags (list) – Searchable tags for database catalog.

  • verbose (bool) – Print progress.

  • map_to_fd (bool) – If True and model has map_to_fd, map each vacuum to the fundamental domain before deduplicating. Defaults to False.

  • designate (bool) – If True, also promote the merged results to the permanent vault via designate_vacua(). Requires database, label, and committed_by.

  • label (str) – Designation label (required when designate=True).

  • committed_by (str) – Contributor identifier (required when designate=True).

  • validate_before_designate (bool) – Run validate_vacua() before designation. Defaults to True.

Returns:

list – Merged results as list of dicts.

Return type:

list

newton_refine_batch(moduli_batch, tau_batch, flux_batch, step_size=0.1, tol=1e-10, max_iters=100)#

JIT-compiled, vmapped Newton refinement for a batch of flux candidates. Solves \(D_I W = 0\) simultaneously for all (moduli, tau, flux) triples.

Parameters:
  • moduli_batch (Array) – Starting complex structure moduli, shape (N, h^{1,2}).

  • tau_batch (Array) – Starting axio-dilaton, shape (N,).

  • flux_batch (Array) – Full flux vectors \([f \mid h]\), shape (N, 2 \times \texttt{n\_fluxes}).

  • step_size (float) – Newton step size. 1.0 gives quadratic convergence near a SUSY vacuum; use 0.1 for non-SUSY. Defaults to 0.1.

  • tol (float) – Convergence tolerance on \(\sum |D_I W|\). Defaults to 1e-10.

  • max_iters (int) – Maximum number of Newton iterations. Defaults to 100.

Returns:

Tuple[Array, Array, Array]

  • moduli_out — converged moduli, shape (N, h^{1,2}).

  • tau_out — converged axio-dilaton, shape (N,).

  • residuals — final \(\sum |D_I W|\), shape (N,); compare against tol to identify converged vacua.

Return type:

Tuple[Array, Array, Array]

precompute_isd_data(moduli_pts)#

Precompute ISD-matrix and its derivatives at a batch of moduli starting points. These quantities depend only on moduli, not on the h-flux, so they can be computed once and reused for all h-vectors in the init step.

Parameters:

moduli_pts (Array) – Complex structure moduli, shape (n_pts, h12).

Returns:

Tuple[Array, Array, Array]

  • M0_all — ISD matrices, shape (n_pts, n_fl, n_fl).

  • dM_all\(\partial_z \mathcal{M}\), shape (n_pts, n_fl, n_fl, h12).

  • dM_c_all\(\partial_{\bar z} \mathcal{M}\), shape (n_pts, n_fl, n_fl, h12).

Return type:

Tuple[Array, Array, Array]

static process_chunk_from_disk(output_dir, chunk_id, model, sampler=None, verbose=True)#

Process a single h-chunk from disk using a reconstructed pipeline. Designed to be called from a cluster worker script.

Parameters:
  • output_dir (str) – Directory with pipeline.npz, config.json, chunks/.

  • chunk_id (int) – Index of the chunk to process.

  • model – A reconstructed FluxEFT or FluxVacuaFinder instance.

  • sampler – Optional data_sampler (only for linearised_shifts mode).

  • verbose (bool) – Print progress.

Return type:

None

reset_eigenvalue_bounds()#

Reset global eigenvalue bounds to their initial sentinels. After calling this, enumerate_fluxes() and sample_bounded_fluxes() will recompute bounds from scratch.

Return type:

None

sample_bounded_fluxes(n_target=1000, n_batch=50000, n_sample=500, n_mod=20, max_batches=100, verbose=True, rns_key=None, seed=None, refine=False, return_moduli=False, newton_tol=1e-10, newton_max_iters=100, newton_step_size=1.0, use_linearised_shifts=False, n_isd_iters=5, n_moduli_batches=1, moduli_regions=None, constraints=None)#

Stochastic flux search guided by the eigenvalue bounds of arXiv:2501.03984.

Unlike enumerate_fluxes(), which exhaustively enumerates all integer \(h\) vectors inside the bounding box, this method randomly samples \(h\) vectors from within the box and ISD-completes them. It scales to arbitrarily large \(N_{\max}\) and higher \(h^{1,2}\) where full enumeration is infeasible.

Algorithm:

  1. Sample \(n_{\rm sample}\) moduli points and compute global eigenvalue bounds (identical to enumerate_fluxes() Step 1).

  2. Loop over batches of \(n_{\rm batch}\) randomly sampled \(h\) vectors (drawn uniformly from the bounding ellipsoid).

  3. For each batch, ISD-complete at \(n_{\rm mod}\) moduli points and check all bounds via the JIT-compiled kernel.

  4. Accumulate valid flux vectors until \(n_{\rm target}\) are found or \(\text{max\_batches}\) are exhausted.

  5. (Optional, refine=True) Newton-refine each batch immediately, accumulate converged+in-patch vacua, and stop once \(n_{\rm target}\) actual vacua have been found.

Note

Candidates returned with refine=False are not exact SUSY vacua: \(f\) is the continuous ISD completion at a sampled modulus, rounded to the nearest integer. \(D_I W \neq 0\) at the returned modulus is therefore expected. Use refine=True to Newton-solve \(D_I W = 0\) and obtain actual vacua.

Parameters:
  • n_target (int) – Target number of results to collect. With refine=False this counts raw flux candidates; with refine=True it counts converged, in-patch SUSY vacua. The search stops early once this many are found. Defaults to 1000.

  • n_batch (int) – Number of \(h\) vectors to sample per batch. Larger batches amortise JIT overhead but use more memory. Defaults to 50_000.

  • n_sample (int) – Number of moduli points for computing global eigenvalue bounds. Defaults to 500.

  • n_mod (int) – Number of moduli points for ISD completion per batch. Defaults to 20.

  • max_batches (int) – Maximum number of sampling batches before stopping. Defaults to 100.

  • verbose (bool) – Print progress with timing. Defaults to True.

  • rns_key (Any | None) – JAX PRNG key for moduli/tau sampling.

  • seed (int | None) – NumPy seed for h-vector sampling. Defaults to None (non-reproducible).

  • refine (bool) – If True, Newton-refine each batch’s candidates immediately and count only converged+in-patch solutions toward n_target. Guarantees at least n_target true \(D_I W = 0\) solutions (or as many as can be found within max_batches). Defaults to False.

  • return_moduli (bool) – If True, return a List[dict] with keys "flux", "moduli", "tau" even when refine=False. Defaults to False.

  • newton_tol (float) – Newton convergence tolerance. Defaults to 1e-10.

  • newton_max_iters (int) – Maximum Newton iterations. Defaults to 100.

  • newton_step_size (float) – Newton step size. Defaults to 1.0 (full Newton steps, quadratic convergence).

  • use_linearised_shifts (bool) – If True, replaces the fixed-moduli ISD completion with iterated linearised_shifts() calls (see isd_refine_batch()) with flag-based early stopping. Requires model to be a FluxVacuaFinder instance. Defaults to False.

  • n_isd_iters (int) – Maximum linearised_shifts() iterations when use_linearised_shifts=True. Defaults to 5.

  • moduli_regions (Optional[List[Tuple[float, float]]]) – List of (lo, hi) intervals for Im(z). The Cartesian product across all \(h^{1,2}\) moduli dimensions is used to build the ISD starting-point set (same logic as enumerate_fluxes()). Defaults to None (use the sampler’s full range).

  • constraints (Optional[Callable]) – Extra constraint function (moduli, tau, flux) bool passed to linearised_shifts() when use_linearised_shifts=True. Defaults to None.

Returns:
  • List[np.ndarray] – When refine=False and

  • ``return_moduli=False``, valid flux vectors ``[f | h]`` of

  • length ``2 * n_fluxes``.

  • List[dict] – When refine=True or return_moduli=True,

  • each entry is a dict with keys ``”flux”``, ``”moduli”``,

  • ``”tau”`` (and "residual" when refine=True)

Raises:

ValueError – If no sampler has been provided.

Return type:

list

update_evs(moduli)#

Computes eigenvalues at moduli, sets the local eigenvalue attributes, and updates the global extrema via update_global().

Parameters:

moduli (Array) – Complex structure moduli, shape (h^{1,2},).

Return type:

None

update_global()#

Updates the global eigenvalue extrema from the current local values. Should be called after update_evs() or update_local().

Maintains running maximum/minimum of \(\lambda_{\max}\), \(\mu_{\min/\max}\), and \(\tilde\mu_{\min/\max}\) across all moduli points seen so far. These global extrema are used to compute the bounding box radii in compute_bounding_box().

Return type:

None

update_local(moduli, tau, flux)#

Updates the full local state — eigenvalues, axio-dilaton components, and flux norms — for a given point (moduli, tau, flux). Also calls update_global().

Parameters:
  • moduli (Array) – Complex structure moduli, shape (h^{1,2},).

  • tau (complex) – Axio-dilaton \(\tau = c_0 + \mathrm{i}\,s\).

  • flux (Array) – Full flux vector [f \mid h] of length 2 * n_fluxes.

Return type:

None