Skip to content

feat(qmc): add Lattice quasi-Monte Carlo sampler - #249

Open
Samuel-Vangu wants to merge 4 commits into
esa:developfrom
Samuel-Vangu:feat/add-lattice-sampler
Open

feat(qmc): add Lattice quasi-Monte Carlo sampler#249
Samuel-Vangu wants to merge 4 commits into
esa:developfrom
Samuel-Vangu:feat/add-lattice-sampler

Conversation

@Samuel-Vangu

Copy link
Copy Markdown

feat(qmc): add Lattice quasi-Monte Carlo sampler

Description

Summary of changes

  • Adds a randomly shifted rank-1 lattice quasi-Monte Carlo sampler, shaped like RNG (and mirroring the existing Sobol sampler), that plugs into MonteCarlo.integrate via the existing rng= slot.
  • Points are generated from a component-by-component (CBC) generating vector (lattice-33002-1024-1048576.9125, from Frances Y. Kuo's Lattice Rule Generating Vectors collection, order-3 weights, dimensions up to 9125, sample sizes from 1024 to 1048576) as x_i = frac(i * z / N).
  • A random shift modulo one is applied on every call to uniform to keep the QMC estimator unbiased. With a fixed seed, the shift is reproducible across calls; without one, each call draws its own independent shift.
  • torch backend only for now — the modular arithmetic and shift use torch.Generator/tensor ops directly; there is no SciPy/other-backend path like Sobol's, since scipy.stats.qmc has no rank-1 lattice rule.
  • Sample points are constants, so autodiff through the integrand and domain is preserved exactly as with plain Monte Carlo (and with Sobol).
  • Exposed as torchquad.Lattice.

Addresses #140 (MonteCarlo path; VEGAS and JIT support to follow). Motivated by the QMC request in #217.

Resolved Issues

How Has This Been Tested?

  • Analytic accuracy on a smooth integrand
  • Lattice beating plain Monte Carlo at equal N
  • Seed reproducibility (fixed seed ⇒ identical result)
  • Torch gradient-flow check (autodiff survives through the integral)
  • Closed-form check: unshifted points match frac(i*z/N) computed independently from the on-disk generating vector
  • Shift behaviour: same seed reproduces the shift across calls; no seed draws an independent shift each call; shift=False ignores the seed entirely
  • Input validation: N/dim range checks, power-of-two warning, whole-number/bool type checks

Related Pull Requests

@Samuel-Vangu

Copy link
Copy Markdown
Author

Hi @gomezzz, could you please trigger the CI for this PR when you have time? Thank you!

@Samuel-Vangu
Samuel-Vangu force-pushed the feat/add-lattice-sampler branch from 185ce3a to a420f26 Compare July 30, 2026 11:33
@Samuel-Vangu

Copy link
Copy Markdown
Author

@gomezzz, pushed a few fixes (ruff formatting + moving import torch local to
Lattice.uniform) — could you trigger the CI again when you get a chance? Thanks!

@Samuel-Vangu

Copy link
Copy Markdown
Author

Hi @gomezzz, sorry for the back-and-forth — pushed another fix, could you trigger CI once more when you get a chance? Thanks for your patience!

@Samuel-Vangu

Copy link
Copy Markdown
Author

Hi @gomezzz, pushed pydoclint fixes , could you approve/trigger CI when you get a chance? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant