Skip to content

Fix GBM demo replication statistics and speed up the Gaussian transform - #585

Open
larissensium wants to merge 354 commits into
developfrom
geometric_brownian_motion
Open

Fix GBM demo replication statistics and speed up the Gaussian transform#585
larissensium wants to merge 354 commits into
developfrom
geometric_brownian_motion

Conversation

@larissensium

Copy link
Copy Markdown
Collaborator

Fixed a table in gbm_demo to correctly show results averaged over replications.

sou-cheng-choi and others added 30 commits December 8, 2025 08:54
* Initial plan

* Add error log capture and display in parsl_test_runner.py

Co-authored-by: sou-cheng-choi <18743024+sou-cheng-choi@users.noreply.github.com>

* Simplify error logging by removing redundant stderr checks

Co-authored-by: sou-cheng-choi <18743024+sou-cheng-choi@users.noreply.github.com>

* Add error handling for log file reading operations

Co-authored-by: sou-cheng-choi <18743024+sou-cheng-choi@users.noreply.github.com>

---------

Co-authored-by: alegresor <agsorokin3@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sou-cheng-choi <18743024+sou-cheng-choi@users.noreply.github.com>

@sou-cheng-choi sou-cheng-choi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@larissensium

I have

  • merged in latest changes from develop branch
  • corrected some typos
  • made the paths from QuantLib independent with different seed values in quantlib_util.py
  • added unit tests

Please review and verify the changes.

@JiangruiKang JiangruiKang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The switch to Burley scrambling is the right way to obtain independent randomized-QMC replications, but one reproducibility defect remains at dimensions above the Jaeckel table. The current tests are green because they use n_steps=4; please cover the 32/33-dimensional boundary before merging.

Comment thread demos/GBM/gbm_code/quantlib_util.py Outdated
# Jaeckel direction integers, so changing its `seed` does not create an
# independent replication. Burley2020SobolRsg applies a seeded Owen-style
# scramble; keep the underlying Sobol seed fixed and vary the scramble.
uniform_rsg = ql.Burley2020SobolRsg(dimension, 0, ql.SobolRsg.Jaeckel, seed)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Use a fixed nonzero underlying Sobol seed

QuantLib treats this second argument differently from the replication-specific scramble seed. Jaeckel direction integers are tabulated only through dimension 32; above that, SobolRsg uses this value to generate additional direction integers, and QuantLib defines 0 as a clock-selected random seed. Consequently, two calls with the same public seed can produce different paths when n_steps >= 33 (see lballabio/QuantLib#2732), even though the comment says the underlying seed is fixed. Please use a fixed nonzero value such as 42, vary only scrambleSeed, and add a regression test at n_steps=33 showing that equal scramble seeds reproduce exactly while different scramble seeds remain distinct.

@sou-cheng-choi sou-cheng-choi changed the title Minor fix for gbm_demo Fix GBM demo replication statistics and speed up the Gaussian transform Aug 18, 2026
@sou-cheng-choi

sou-cheng-choi commented Sep 12, 2026

Copy link
Copy Markdown
Member

@JiangruiKang

Thank you for your invaluable suggestion. I have implemented the changes with a unit test test_reproducible_above_direction_integer_table in test_demo_gbm.py. Please re-review when you have a moment.

@larissensium , @alegresor and @JiangruiKang :

Summary of changes:

  1. Numerical Stability and Reproducibility: Fixed the QuantLib Sobol generator seeding (SOBOL_DIRECTION_SEED = 1) to ensure reproducible point sets, resolved the QuantLib replication leak using np.stack(ql_paths), and centralized the covariance calculation function for symmetry and testability.
  2. Methodological Accuracy: Updated QuantLib to default to "exact" GBM evolution, replacing the biased Euler-Maruyama scheme. Implemented statistically rigorous variance calculations by correctly setting ddof=0 for replications and reserving ddof=1 for cross-replication standard error. Increased number of replications from 3 to 8 to reduce noise in results.
  3. Speed: Use ndtri to speed up GBM.
  4. Sampling and Analysis Expansion: Added support for the Halton low-discrepancy sequence in QuantLib, expanding sampler options. Introduced a new construction-ablation feature to isolate and analyze path-construction effects (e.g., PCA vs. BrownianBridge in QMCPy).
  5. Code Robustness and Testing: Increased test coverage, growing test_demo_gbm.py. Refactored utility functions and corrected docstrings to reflect the exact-scheme change.
  6. Updated software versions: Quantlib 1.43, QMCPy 2.4, etc.


def _transform(self, x):
return self.mu + np.einsum("...ij,kj->...ik", norm.ppf(x), self.a)
transformed = ndtri(x) @ self.a.T

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice change! Haven't heard of this ndtri before, but it is suppose to be much faster than norm.ppf

@sou-cheng-choi

Copy link
Copy Markdown
Member

@alegresor

Thanks! ndtri is much faster indeed.

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.

6 participants