بنقرة واحدة
develop-bound
Guide for adding a new bounding method to JNesty.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Guide for adding a new bounding method to JNesty.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
JNesty code architecture — modules, data flow, key data structures, JAX patterns, and demo scripts.
Diagnosing convergence problems, poor acceptance rates, and incorrect results in JNesty.
Guide for adding a new internal sampler (proposal strategy) to JNesty.
JNesty usage guide — public API, parameters, results access, FITS I/O, bounding methods, tuning, and plotting.
استنادا إلى تصنيف SOC المهني
| name | /develop-bound |
| description | Guide for adding a new bounding method to JNesty. |
Bounding methods live in src/jnesty/bounding.py. Each implements the Bound interface and is registered in BOUND_REGISTRY for lookup by string name.
The core NS loop in src/jnesty/sampler.py calls bound_obj.fit() to update the bound, bound_obj.get_axes() for proposal generation, and optionally uses bound-specific state for multi-ellipsoid proposals.
class Bound:
"""Base class for bounding distributions."""
def __init__(self, ndim, **kwargs):
self.ndim = ndim
def fit(self, points):
"""Fit the bound to live points. Returns self."""
raise NotImplementedError
def sample(self, key, n=1):
"""Sample point(s) from the bound."""
raise NotImplementedError
def get_axes(self):
"""Return (ndim, ndim) axes matrix for proposal generation."""
raise NotImplementedError
def contains(self, point):
"""Check if point is inside the bound."""
raise NotImplementedError
'none')fit(): no-opget_axes(): identity matrixsample(): uniform from [0,1]^ndim'single')fit(): covariance eigenvalue decompositionget_axes(): eigenvectors scaled by sqrt(eigenvalues)'multi')fit(): delegates to fit_multi_ellipsoid() from multi_ellipsoid.pyMultiEllipsoidState NamedTupleget_axes(): axes of the largest-volume ellipsoidget_walk_schedule(rwalk_K): Bresenham interleaving of ellipsoid indicesqueue_size=8) by defaultThe bound is used in several places in src/jnesty/sampler.py:
bound_obj.fit(live_x) after Phase 1 completesbound_axes = bound_obj.get_axes() for rwalk proposalsestimate_batch_size_from_memory() uses bound_axes for probefit_multi_ellipsoid(live_x_cur, ...) between chunksFor multi-ellipsoid, the chunked loop mode is activated when use_chunked_loop = True (bound is 'multi' and bound_update_interval > 0). The loop runs chunks of bound_update_interval likelihood calls, then refits the bound between chunks.
The bound state is packed into the flat tuple that lax.while_loop carries:
bound_axes — (ndim, ndim) axes matrixme_axes — (max_ellipsoids, ndim, ndim) multi-ellipsoid axesme_logvol_ells — (max_ellipsoids,) multi-ellipsoid log-volumescalls_at_update — total_calls at last bound update (for chunk timing)total_calls — total likelihood calls (non-resetting)Queue mode adds indices 18-22 for the candidate queue.
A new bound that needs additional state in the loop must extend this tuple and update the packing/unpacking in sampler.py.
At bound updates (chunk boundaries), hist_accept (index 11) and hist_total (index 12) are reset to 0. This matches Dynesty's behavior: scale adapts quickly to the new bound shape.
Add your class to src/jnesty/bounding.py:
class MyBound(Bound):
def __init__(self, ndim, **kwargs):
super().__init__(ndim, **kwargs)
# Your initialization
def fit(self, points):
# Fit to live points
return self
def sample(self, key, n=1):
# Sample from the bound
pass
def get_axes(self):
# Return (ndim, ndim) axes for proposals
pass
def contains(self, point):
# Check membership
pass
Add to BOUND_REGISTRY:
BOUND_REGISTRY = {
'none': UnitCube,
'single': SingleEllipsoid,
'multi': MultiEllipsoidBound,
'mybound': MyBound, # Add this
}
If your bound needs periodic refitting or custom state carried through lax.while_loop:
sampler.pyuse_chunked_loop branch similar to multi-ellipsoidbody_fn_q) if queue support is neededIf your bound is stateless or only needs initial fitting, no changes to sampler.py are needed — the factory handles it.
python -m py_compile src/jnesty/bounding.pyBoundfit, sample, get_axes, containsBOUND_REGISTRYNestedSampler.__init__ accepts the new bound string