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:
objectImplements 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).Details
Physical setup. In Type IIB compactifications on orientifolds of CY threefolds, the Gukov-Vafa-Witten superpotential is
\[W = \int_X G_3\wedge\Omega_3 = (f - \tau h)^T \Sigma\,\Pi(z)\,,\]where \(G_3 = F_3 - \tau H_3\), \(f = (f_1, f_2)\) are the integer RR-flux quanta, \(h = (h_1, h_2)\) are the integer NSNS-flux quanta, \(\tau = c_0 + \mathrm{i}s\) is the axio-dilaton, and \(\Pi(z)\) is the period vector.
Flux and symplectic conventions. The full flux vector is ordered as
\[\mathtt{flux} = [f_1,\, f_2 \mid h_1,\, h_2]\,,\]each sub-vector of length \(d = h^{1,2}+1 = \texttt{dimension\_H3}\). The symplectic matrix acts as
\[\begin{split}\Sigma = \begin{pmatrix} 0 & \mathbf{1} \\ -\mathbf{1} & 0 \end{pmatrix}\,,\end{split}\]and the D3-tadpole contribution from the fluxes is (Eq. 10 of arXiv:2501.03984)
\[N_{\rm flux} = f^T \Sigma h\,.\]ISD condition and the ISD matrix. A flux configuration is imaginary self-dual (ISD) when \(\star_6 G_3 = \mathrm{i}G_3\), which in components reads (Eq. 21 of arXiv:2501.03984)
\[f = (s\,\Sigma\,\mathcal{M} + c_0\,\mathbf{1})\,h\,,\]where the ISD matrix \(\mathcal{M}\) is constructed from the gauge kinetic matrix \(\mathcal{N} = \mathcal{R} + \mathrm{i}\mathcal{I}\) as (Eq. 22)
\[\begin{split}\mathcal{M} = \begin{pmatrix} -\mathcal{I}^{-1} & \mathcal{I}^{-1}\mathcal{R} \\ \mathcal{R}\mathcal{I}^{-1} & -(\mathcal{I} + \mathcal{R}\mathcal{I}^{-1}\mathcal{R}) \end{pmatrix}.\end{split}\]Bounding box derivation. For any vacuum satisfying \(0 < N_{\rm flux} \leq N_{\max}\) and \(s \geq s_{\min}\), the flux quanta are constrained (Eqs. 27, 31a-b of arXiv:2501.03984)
\[\|h_1\|^2 &\leq \frac{N_{\max}}{s_{\min}\,\tilde\mu_{\min}}\,,\quad \|h_2\|^2 \leq \frac{N_{\max}}{s_{\min}\,\mu_{\min}}\,,\quad \|h\|^2 \leq \frac{2\,\lambda_{\max}\,N_{\max}}{s_{\min}}\,.\]Here the eigenvalue quantities are:
\(\lambda_{\max}\): largest eigenvalue of \(\mathcal{M}\).
\(\mu_{\min/\max}\): extreme eigenvalues of \(-\operatorname{Im}(\mathcal{N})\).
\(\tilde\mu_{\min/\max}\): extreme eigenvalues of \(\operatorname{Im}(\mathcal{N}^{-1})\).
These radii define bounding boxes that, combined with a pre-filter on the dilaton upper bound
\[s_{\max}(h) = \frac{\lambda_{\max}N_{\max}}{\|h\|^2} + \frac{\|h\|^2}{4\,\lambda_{\max}}\,,\]allow systematic exhaustive enumeration (Algorithm 1 of arXiv:2501.03984) via
enumerate_fluxes()or stochastic search viasample_bounded_fluxes().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) providinggauge_kinetic_matrix,ISD_matrix,tadpole,n_fluxes,dimension_H3, andD3_tadpole.sampler (
Any|None) – Ajaxvacua.sampling.data_samplerinstance used for moduli sampling inenumerate_fluxes(). IfNone, moduli must be supplied explicitly tocompute_bounding_box().Nmax (
int|None) – Maximum allowed D3-tadpole charge. Defaults tomodel.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 to10.0. Set to0to disable.safety_mu (
float) – Divisive safety margin on \(\mu_{\min}\) and \(\tilde\mu_{\min}\). Defaults to1.5. Set to1to disable.map_to_fd (
bool) – IfTrueand model hasmap_to_fd, map each vacuum to the fundamental domain (monodromy + SL(2,Z)) before deduplicating and returning. Defaults toFalse.
- 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.
Checks the two global bounds on the \(f_1\) sector using the global eigenvalue extrema \(\tilde\mu_{\min/\max}^{\rm gl}\).
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})\).
Checks the two global bounds on the \(f_2\) sector using the global eigenvalue extrema \(\mu_{\min/\max}^{\rm gl}\).
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})\).
Checks the global bounds on \(\|f\|^2\).
Checks the local bounds on \(\|f\|^2\):
Checks the global bound on \(\|h_1\|^2\):
Checks the local bound on \(\|h_1\|^2\):
Checks the global bound on \(\|h_2\|^2\):
Checks the local bound on \(\|h_2\|^2\):
Checks the global bound on \(\|h\|^2\):
Checks the local bound on \(\|h\|^2\):
Checks the global bounds on \(s\).
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.Evaluates all
bound_*methods using the current local state (set by a priorupdate_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 tolerancetol.compute_eigenvalue_bounds([n_sample, ...])Sample moduli from
samplerand compute global eigenvalue bounds. Results are stored as class attributes and reused by subsequent calls toenumerate_fluxes()andsample_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()viavmap.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
forh(lengthn_fluxes) into its two sub-sector components.Returns the cached bounding box dimensions
(h1_box, h2_box, h_box)set bycompute_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 global eigenvalue bounds to their initial sentinels. After calling this,
enumerate_fluxes()andsample_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().Updates the global eigenvalue extrema from the current local values. Should be called after
update_evs()orupdate_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 callsupdate_global().Attributes
Description:
Trueifcompute_eigenvalue_bounds()(orcompute_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}\).
Details
The two global inequalities are:
\[\begin{split}\tilde\mu_{\min}^{\rm gl} (\|f_1\|^2 + \tfrac{3}{4}\|h_1\|^2) - \tilde\mu_{\max}^{\rm gl}\sqrt{\|f_1\|^2\|h_1\|^2} &\leq s_{\max}\,N_{\max} \quad\text{(b3)}\,,\\ \tilde\mu_{\min}^{\rm gl} (\|\tilde f_1\|^2 + \tfrac{3}{4}\|h_1\|^2) &\leq s_{\max}\,N_{\max} \quad\text{(b4)}\,.\end{split}\]- Returns:
Tuple[Tuple[bool, bool], str] – Two bounds
(b3, b4)andlabel ``”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})\).
Details
The four local inequalities are:
\[\begin{split}\tilde\mu_{\min}\,\|\tilde f_1\|^2 &\leq s\,N_{\rm flux} \quad\text{(b1)}\,,\\ \tilde\mu_{\min}({\|f_1\|^2 + c_0^2\|h_1\|^2}) - 2|c_0|\tilde\mu_{\max}\sqrt{\|f_1\|^2\|h_1\|^2} &\leq s\,N_{\rm flux} \quad\text{(b2)}\,,\\ \tilde\mu_{\min}({\|f_1\|^2 + (c_0^2+\tfrac{3}{4})\|h_1\|^2}) - 2|c_0|\tilde\mu_{\max}\sqrt{\|f_1\|^2\|h_1\|^2} &\leq s\,N_{\rm flux} \quad\text{(b5)}\,,\\ \tilde\mu_{\min}({\|\tilde f_1\|^2 + (c_0^2+\tfrac{3}{4})\|h_1\|^2}) &\leq s\,N_{\rm flux} \quad\text{(b6)}\,.\end{split}\]- 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}\).
Details
The two global inequalities are:
\[\begin{split}\mu_{\min}^{\rm gl}(\|f_2\|^2 + \tfrac{3}{4}\|h_2\|^2) - \mu_{\max}^{\rm gl}\sqrt{\|f_2\|^2\|h_2\|^2} &\leq s_{\max}\,N_{\max} \quad\text{(b3)}\,,\\ \mu_{\min}^{\rm gl}(\|\tilde f_2\|^2 + \tfrac{3}{4}\|h_2\|^2) &\leq s_{\max}\,N_{\max} \quad\text{(b4)}\,.\end{split}\]- Returns:
Tuple[Tuple[bool, bool], str] – Two bounds
(b3, b4)andlabel ``”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})\).
Details
The four local inequalities are:
\[\begin{split}\mu_{\min}\,\|\tilde f_2\|^2 &\leq s\,N_{\rm flux} \quad\text{(b1)}\,,\\ \mu_{\min}(\|f_2\|^2 + c_0^2\|h_2\|^2) - 2|c_0|\mu_{\max}\sqrt{\|f_2\|^2\|h_2\|^2} &\leq s\,N_{\rm flux} \quad\text{(b2)}\,,\\ \mu_{\min}(\|f_2\|^2 + (c_0^2+\tfrac{3}{4})\|h_2\|^2) - \mu_{\max}|c_0|\sqrt{\|f_2\|^2\|h_2\|^2} &\leq s\,N_{\rm flux} \quad\text{(b5)}\,,\\ \mu_{\min}(\|\tilde f_2\|^2 + (c_0^2+\tfrac{3}{4})\|h_2\|^2) &\leq s\,N_{\rm flux} \quad\text{(b6)}\,.\end{split}\]- 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:
Trueifcompute_eigenvalue_bounds()(orcompute_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 everybound_*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 length2 * 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 asevs_batchto 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,);Truewhere all boundspass.
- Return type:
Array
- check_bounds_flat()#
Evaluates all
bound_*methods using the current local state (set by a priorupdate_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)\).
Details
The bounding box radii are derived from the global versions of the eigenvalue inequalities of arXiv:2501.03984 (Eqs. 27 and 31a-b). For a flux vacuum with \(0 < N_{\rm flux} \leq N_{\max}\) and \(s \geq s_{\min}\), each sub-vector of the NSNS-flux satisfies
\[\begin{split}\|h_1\|^2 &\leq \frac{N_{\max}}{s_{\min}\,\tilde\mu_{\min}^{\rm gl}} \quad\Longrightarrow\quad h_{1,\rm box} = \sqrt{\frac{N_{\max}}{s_{\min}\,\tilde\mu_{\min}^{\rm gl}}}\,,\\ \|h_2\|^2 &\leq \frac{N_{\max}}{s_{\min}\,\mu_{\min}^{\rm gl}} \quad\Longrightarrow\quad h_{2,\rm box} = \sqrt{\frac{N_{\max}}{s_{\min}\,\mu_{\min}^{\rm gl}}}\,,\\ \|h\|^2 &\leq \frac{2\,\lambda_{\max}^{\rm gl}\,N_{\max}}{s_{\min}} \quad\Longrightarrow\quad h_{\rm box} = \sqrt{\frac{2\,\lambda_{\max}^{\rm gl}\,N_{\max}}{s_{\min}}}\,.\end{split}\]The three radii implement a combined ellipsoidal constraint: each candidate \(h = (h_1, h_2)\) must satisfy all three simultaneously. Enumeration of integer lattice points inside this region is performed by
get_h_candidates()(small boxes) or the streaming generator_iter_h_chunks_streaming()(large boxes).The dilaton upper bound is also set:
\[s_{\max} = \lambda_{\max}^{\rm gl}\,N_{\max}\,.\]Eigenvalues are computed using the JIT-compiled vmapped kernel
_compute_evs_and_M_vmap(), which also caches the full ISD matrices \(\mathcal{M}(z_j)\) for subsequent use in the ISD completion step ofenumerate_fluxes().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)— themaximum :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 tolerancetol.Warm-starts from any prior call: if
lambda_max_glis 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_fluxesinstance (sampler) is used to draw moduli samples.- Parameters:
batch_size (
int) – Number of moduli points sampled per batch. Defaults to100.max_batches (
int) – Stop even if not converged after this many batches. A warning is issued. Defaults to500.tol (
float) – Relative convergence threshold on \(\lambda_{\rm max}\). Defaults to1e-3.min_batches (
int) – Always run at least this many batches before checking convergence. Defaults to10.verbose (
bool) – Print per-batch progress. Defaults toTrue.
- Returns:
Tuple[float, float, float] –
(h1_box, h2_box, h_box)— sameas :func:`compute_bounding_box`.
- Raises:
ValueError – If no
samplerhas been set.- Return type:
Tuple[float,float,float]
- compute_eigenvalue_bounds(n_sample=100000, rns_key=None, verbose=True)#
Sample moduli from
samplerand compute global eigenvalue bounds. Results are stored as class attributes and reused by subsequent calls toenumerate_fluxes()andsample_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 to100_000.rns_key (Any, optional) – JAX PRNG key for reproducible sampling.
verbose (
bool) – Print progress. Defaults toTrue.
- Returns:
Tuple[float, float, float] –
(h1_box, h2_box, h_box)— thebounding 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()viavmap.- Parameters:
moduli_batch (
Array) – Batch of moduli, shape(N, h^{1,2}).- Returns:
Tuple – Each element is an array of shape
(N,)corresponding toone 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.
Details
The algorithm proceeds in up to 6 steps:
Step 1 — Bounding box. Sample \(n_{\rm sample}\) moduli points, compute global eigenvalue extrema \((\lambda_{\max}, \mu_{\min}, \tilde\mu_{\min})\), and derive bounding radii \(h_{1,\rm box}\), \(h_{2,\rm box}\), \(h_{\rm box}\) (Eqs. 27, 31 of arXiv:2501.03984; see
compute_bounding_box()). Also tightensdil_minto the sampler’s lower dilaton bound.Step 2 — Enumeration / streaming. If the box contains at most
max_h_candidatesvectors, all integer \(h\) are materialised viaget_h_candidates(). For larger boxes, the h2-outer streaming generator_iter_h_chunks_streaming()is used, which keeps only one \(h_2\)-slice in memory at a time.Step 3 — s_max pre-filter. Before ISD completion, each \(h\) is checked against the per-\(h\) dilaton ceiling
\[s_{\max}(h) = \frac{\lambda_{\max}\,N_{\max}}{\|h\|^2} + \frac{\|h\|^2}{4\,\lambda_{\max}}\,.\]Candidates with \(s_{\max}(h) < s_{\min}\) cannot host any vacuum in the sampler’s patch and are dropped immediately, typically reducing the candidate count by 40–80 %.
Steps 4–5 — ISD completion and bounds checking. For each surviving \(h\), the RR-flux is completed as (Eq. 21 of arXiv:2501.03984)
\[f = \mathrm{round}\!\bigl( s\,\mathcal{M}(z_j)\,\Sigma\,h + c_0\,h \bigr)\]at up to
n_isd_per_hsampled moduli points \(\{z_j, \tau_j\}\) using the vmapped JIT kernel_process_h_all_moduli_jit(). The full flux \([f \mid h]\) is checked against all local and global bounds simultaneously. A candidate is kept if it passes at any of then_isd_per_hmoduli points.Step 6 (optional) — Newton refinement. When
refine=True, each candidate is Newton-refined to solve \(D_I W = 0\) exactly (seenewton_refine_batch()), then filtered for convergence and patch membership, and deduplicated by flux vector.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. Userefine=Truefor 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:
Sample \(n_{\rm sample}\) moduli points from
samplerand compute global eigenvalue bounds.Enumerate all integer \(h\) vectors in the bounding box via
get_h_candidates().Pre-filter \(h\) candidates by the global norm bound \(\|h\|^2 \leq h_{\rm box}^2\).
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 ton_isd_per_hsampled moduli points.Retain
[f | h]pairs satisfying the D3-tadpole constraint and all local eigenvalue bounds (viacheck_bounds_batch()).(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 to10_000_000. Set toNoneto 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 toFalseto skip the prompt (e.g. in scripts/cluster jobs). Defaults toTrue.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 samplesn_isd_per_hpoints 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 toNone(use the main sampler’s full range).verbose (
bool) – Print progress with timing. Defaults toTrue.rns_key (
Any|None) – Random number key for reproducible sampling. Passed tosampler.get_complex_moduli()andsampler.get_complex_tau(). Whenuse_jax=Trueon the sampler, this should be a JAX PRNG key.refine (
bool) – IfTrue, Newton-refine candidates to solve \(D_I W = 0\) exactly and filter by convergence and patch membership. Defaults toFalse.return_moduli (
bool) – IfTrue, return aList[dict]with keys"flux","moduli","tau"even whenrefine=False. Defaults toFalse.newton_tol (
float) – Residual tolerance for Newton convergence. Defaults to1e-10.newton_max_iters (
int) – Maximum Newton iterations. Defaults to100.newton_step_size (
float) – Step size for Newton’s method. Defaults to1.0(full Newton steps, quadratic convergence).use_linearised_shifts (
bool) – IfTrue, replaces the fixed-moduli ISD completion with iteratedlinearised_shifts_H()calls (seeisd_refine_batch()). The moduli are moved to be self-consistent with each \(h\), matching the algorithm of arXiv:2501.03984. Requiresmodelto be aFluxVacuaFinderinstance. Defaults toFalse.n_isd_iters (
int) – Number oflinearised_shifts_H()iterations whenuse_linearised_shifts=True. Defaults to5.
- Returns:
List[np.ndarray] – When
refine=Falseand``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=Trueorreturn_moduli=True,each entry is a dict with keys ``”flux”``, ``”moduli”``,
``”tau”`` (and
"residual"whenrefine=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
samplerhas 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 length2 * n_fluxes.- Returns:
Tuple[ndarray, ndarray] –
(f, h)each of lengthn_fluxes.- Return type:
Tuple[ndarray,ndarray]
- get_flux_split(flux_half)#
Splits a half-flux vector
forh(lengthn_fluxes) into its two sub-sector components.- Parameters:
flux_half (
ndarray) – Half-flux vector of lengthn_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 bycompute_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 exceedsmax_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.Details
Follows the algorithm of
run_hscan_34.py(arXiv:2501.03984):Init step — for each \(h\), construct \([0 \mid h]\) and evaluate
linearised_shifts()(mode"Hflux",return_flag=True) at every moduli starting point. The inner vmap runs overn_ptsstarting points; the outer vmap runs overh_sub_batchh-vectors.Iteration — apply
linearised_shifts()to the per-point(m, t, f)triples from the previous step. After each step, the returnedflagsboolean array(h_sub_batch, n_pts)indicates which pairs still satisfy the Kähler-cone, tadpole, and user constraints.Early stopping — if after ≥ 5 iterations no flag is
Trueacross the entire sub-batch, iteration stops (no candidate is converging).Peak memory is
O(h_sub_batch × n_pts × matrix_size)per sub-batch.- 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 to10.h_sub_batch (
int) – h-vectors per vmapped sub-batch. Defaults to200.constraints (Callable, optional) – Extra constraint function
(moduli, tau, flux) → bool. Passed tolinearised_shifts(). Defaults toNone(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:
database=<CYDatabase>: write the merged results as a session-tier batch viastringforge.lcs_database.LCSDatabase.vacua_writer(). The results are queryable viaquery_vacua()but not yet permanent.designate=True(requiresdatabase,label,committed_by): additionally promote the merged results to the permanent vault viastringforge.lcs_database.LCSDatabase.designate_vacua(). The results are retrievable viaload_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) – IfTrueand model hasmap_to_fd, map each vacuum to the fundamental domain before deduplicating. Defaults toFalse.designate (
bool) – If True, also promote the merged results to the permanent vault viadesignate_vacua(). Requires database, label, and committed_by.label (
str) – Designation label (required whendesignate=True).committed_by (
str) – Contributor identifier (required whendesignate=True).validate_before_designate (
bool) – Runvalidate_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.Details
Newton’s method minimises \(\sum_I |D_I W|^2\) by stepping in the direction of the F-term residual. The implementation wraps
FluxEFT._newton_method_flux_vacua_complex()inmode="SUSY", which uses the full Jacobian of the F-term system.With
step_size=1.0(the default) each step is a full Newton step giving locally quadratic convergence near a SUSY minimum. Reducestep_size(e.g. to0.1) for non-SUSY or unstable cases.The residual \(\sum |D_I W|\) is used for convergence checking: a candidate is considered converged when
residual < tol.- 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.0gives quadratic convergence near a SUSY vacuum; use0.1for non-SUSY. Defaults to0.1.tol (
float) – Convergence tolerance on \(\sum |D_I W|\). Defaults to1e-10.max_iters (
int) – Maximum number of Newton iterations. Defaults to100.
- 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 againsttolto 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()andsample_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:
Sample \(n_{\rm sample}\) moduli points and compute global eigenvalue bounds (identical to
enumerate_fluxes()Step 1).Loop over batches of \(n_{\rm batch}\) randomly sampled \(h\) vectors (drawn uniformly from the bounding ellipsoid).
For each batch, ISD-complete at \(n_{\rm mod}\) moduli points and check all bounds via the JIT-compiled kernel.
Accumulate valid flux vectors until \(n_{\rm target}\) are found or \(\text{max\_batches}\) are exhausted.
(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=Falseare 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. Userefine=Trueto Newton-solve \(D_I W = 0\) and obtain actual vacua.- Parameters:
n_target (
int) – Target number of results to collect. Withrefine=Falsethis counts raw flux candidates; withrefine=Trueit counts converged, in-patch SUSY vacua. The search stops early once this many are found. Defaults to1000.n_batch (
int) – Number of \(h\) vectors to sample per batch. Larger batches amortise JIT overhead but use more memory. Defaults to50_000.n_sample (
int) – Number of moduli points for computing global eigenvalue bounds. Defaults to500.n_mod (
int) – Number of moduli points for ISD completion per batch. Defaults to20.max_batches (
int) – Maximum number of sampling batches before stopping. Defaults to100.verbose (
bool) – Print progress with timing. Defaults toTrue.rns_key (
Any|None) – JAX PRNG key for moduli/tau sampling.seed (
int|None) – NumPy seed for h-vector sampling. Defaults toNone(non-reproducible).refine (
bool) – IfTrue, Newton-refine each batch’s candidates immediately and count only converged+in-patch solutions towardn_target. Guarantees at leastn_targettrue \(D_I W = 0\) solutions (or as many as can be found withinmax_batches). Defaults toFalse.return_moduli (
bool) – IfTrue, return aList[dict]with keys"flux","moduli","tau"even whenrefine=False. Defaults toFalse.newton_tol (
float) – Newton convergence tolerance. Defaults to1e-10.newton_max_iters (
int) – Maximum Newton iterations. Defaults to100.newton_step_size (
float) – Newton step size. Defaults to1.0(full Newton steps, quadratic convergence).use_linearised_shifts (
bool) – IfTrue, replaces the fixed-moduli ISD completion with iteratedlinearised_shifts()calls (seeisd_refine_batch()) with flag-based early stopping. Requiresmodelto be aFluxVacuaFinderinstance. Defaults toFalse.n_isd_iters (
int) – Maximumlinearised_shifts()iterations whenuse_linearised_shifts=True. Defaults to5.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 asenumerate_fluxes()). Defaults toNone(use the sampler’s full range).constraints (
Optional[Callable]) – Extra constraint function(moduli, tau, flux) → boolpassed tolinearised_shifts()whenuse_linearised_shifts=True. Defaults toNone.
- Returns:
List[np.ndarray] – When
refine=Falseand``return_moduli=False``, valid flux vectors ``[f | h]`` of
length ``2 * n_fluxes``.
List[dict] – When
refine=Trueorreturn_moduli=True,each entry is a dict with keys ``”flux”``, ``”moduli”``,
``”tau”`` (and
"residual"whenrefine=True)
- Raises:
ValueError – If no
samplerhas 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()orupdate_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 callsupdate_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 length2 * n_fluxes.
- Return type:
None