Skip to content

Conversation

williamjameshandley
Copy link

@williamjameshandley williamjameshandley commented Sep 3, 2025

This PR implements maximum iteration limits and acceptance handling for slice sampling to address infinite loop issues and improve robustness.

Changes

Core Implementation

  • Add maximum step limits: Implement max_steps (stepping-out) and max_shrinkage (shrinking) parameters following Radford Neal's slice sampling algorithm
  • Add acceptance handling: Include is_accepted boolean in SliceInfo and proper acceptance logic using static_binomial_sampling
  • Prevent infinite loops: Bound both stepping-out and shrinking phases to avoid hanging

Parameter Improvements

  • Better naming: Use max_steps and max_shrinkage for clarity
  • Consistent defaults: max_steps=10, max_shrinkage=100 across both slice sampling and nested slice sampling
  • Function organization: Rename internal functions to step_body_fun/step_cond_fun and shrink_body_fun/shrink_cond_fun

Nested Sampling Integration

  • Full parameter support: Both NSS functions (build_kernel and as_top_level_api) now accept step limit parameters
  • Consistent interface: Same parameter names and defaults across slice sampling and nested slice sampling modules

Issues Addressed

Closes #20 - Slice sampler infinite loop in horizontal_slice function

  • Implements bounded stepping-out and shrinking phases
  • Prevents indefinite loops that cause sampling sessions to hang

Closes #23 - Add max iterations limit to slice sampler while loops

  • Adds configurable max_steps and max_shrinkage parameters
  • Follows jaxopt pattern for bounded iterations with graceful failure handling

Closes #32 - Add acceptance boolean to slice sampling for handling failure modes

  • Implements is_accepted boolean in SliceInfo with proper acceptance/rejection logic
  • Uses static_binomial_sampling following BlackJAX patterns from other MCMC methods
  • Provides graceful degradation when step limits are reached
  • Implements maximum iteration limits for both stepping-out and shrinking phases

Implementation Details

Maximum Step Logic

  • Stepping-out: Uses Neal's bounded approach where j and k counters limit expansion in each direction
  • Shrinking: Limits iterations with s_steps < max_shrinkage + 1 condition to allow exactly max_shrinkage attempts
  • Acceptance: Accepts proposals that find valid points within step limits, rejects otherwise

Backward Compatibility

  • Default parameters maintain existing behavior for users not specifying limits
  • All existing APIs preserved with new optional parameters
  • Internal m parameter kept in horizontal_slice to maintain Neal's notation

Testing

This implementation has been tested to ensure:

  • max_shrinkage=1 works correctly (previously failed)
  • Step counting semantics are proper (iterations vs attempts)
  • Acceptance logic properly handles boundary cases

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

williamjameshandley and others added 4 commits September 3, 2025 15:36
Add parameter m (default=10) to control maximum expansion steps during
the stepping-out phase, following Radford Neal's slice sampling algorithm.
This prevents infinite loops when the slice extends indefinitely and
ensures computational efficiency by bounding the interval expansion.

- Add m parameter to build_kernel() and build_hrss_kernel()
- Modify stepping-out loop to use bounded counters j and k
- Remove unused d field from SliceInfo for cleaner interface
- Update horizontal_slice() to implement Neal's bounded expansion

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Correct the shrinking loop condition to use max_shrink_steps+1, ensuring
that max_shrink_steps represents the actual number of shrinking attempts
allowed rather than the loop counter limit. This fixes the issue where
max_shrink_steps=1 would incorrectly reject all proposals that required
any shrinking iterations.

- Update shrink_cond_fun to allow exactly max_shrink_steps iterations
- Fix acceptance condition to properly handle step count semantics
- Add static_binomial_sampling for proper proposal acceptance/rejection

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Rename parameters for better clarity:
- max_steps_out → max_steps (stepping-out phase limit)
- max_shrink_steps → max_shrinkage (shrinking phase limit)

Update function names in horizontal_slice for better organization:
- body_fun → step_body_fun (stepping-out procedure)
- cond_fun → step_cond_fun (stepping-out condition)

Fix docstring parameter descriptions to match actual function signature.
Update both slice sampling (ss.py) and nested slice sampling (nss.py)
modules for consistency with defaults max_steps=10, max_shrinkage=100.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@yallup
Copy link
Collaborator

yallup commented Sep 5, 2025

This also in practice fixes #30 for the default delete function. Outer loop boilerplate needs adjusting to respect the return of a duplicated sample (failed constrained sample) as a signal for early termination

@yallup yallup merged commit 4044b05 into nested_sampling Sep 11, 2025
@yallup yallup deleted the slice_acceptance branch September 11, 2025 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants