Skip to content

Lattice kronecker - #556

Open
AndersPride wants to merge 33 commits into
developfrom
lattice_kronecker
Open

Lattice kronecker#556
AndersPride wants to merge 33 commits into
developfrom
lattice_kronecker

Conversation

@AndersPride

Copy link
Copy Markdown
Collaborator

Adds search methods for generators for lattice and kronecker sequences. Also adds and updates methods for finding discrepancies and weighted sum of squared discrepancies for arbitrary sample size, dimension, and coordinate weights. Currently the search methods live in their respective folders in discrete_distribution, but they may belong elsewhere. There is a new demo illustrating these features. Right now, this is not integrated into the kernel class, but that can be future work.

@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 38.99614% with 158 lines in your changes missing coverage. Please review.
✅ Project coverage is 35.89%. Comparing base (ab2b7a6) to head (d87eca5).
⚠️ Report is 95 commits behind head on develop.

Files with missing lines Patch % Lines
...distribution/kronecker/kronecker_search_methods.py 3.03% 96 Missing ⚠️
qmcpy/discrete_distribution/lattice/lattice.py 4.65% 41 Missing ⚠️
qmcpy/discrete_distribution/kronecker/kronecker.py 29.41% 12 Missing ⚠️
...distribution/lattice/lattice_vector_wssd_search.py 90.52% 9 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (ab2b7a6) and HEAD (d87eca5). Click for more details.

HEAD has 5 uploads less than BASE
Flag BASE (ab2b7a6) HEAD (d87eca5)
alltests 6 1
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##           develop     #556       +/-   ##
============================================
- Coverage    88.16%   35.89%   -52.28%     
============================================
  Files          100      103        +3     
  Lines         8081     8332      +251     
============================================
- Hits          7125     2991     -4134     
- Misses         956     5341     +4385     
Flag Coverage Δ
alltests 35.89% <38.99%> (-52.28%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
qmcpy/discrete_distribution/__init__.py 100.00% <100.00%> (ø)
qmcpy/discrete_distribution/kronecker/__init__.py 100.00% <100.00%> (ø)
qmcpy/discrete_distribution/lattice/__init__.py 100.00% <100.00%> (ø)
...distribution/lattice/lattice_vector_wssd_search.py 90.52% <90.52%> (ø)
qmcpy/discrete_distribution/kronecker/kronecker.py 63.72% <29.41%> (ø)
qmcpy/discrete_distribution/lattice/lattice.py 54.49% <4.65%> (-22.55%) ⬇️
...distribution/kronecker/kronecker_search_methods.py 3.03% <3.03%> (ø)

... and 80 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@AndersPride
AndersPride marked this pull request as ready for review July 9, 2026 15:19

@alegresor alegresor 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.

Hi @AndersPride, thanks for submitting this PR, it looks very technically sound! Some suggestions are below

  • I think it is fine to leave your kroneckerr_search_methods.py and lattice_vector_wssd_search.py files where they are for now
  • Try to reuse similar parameter names in your functions as used in other discrete distribution classes
  • Make sure all your functions have docstrings and doctests
  • For the lattice_kronecker_methods.ipynb demo, is the kuo.lattice-39102...txt file in the LDData repo? If so, then you can construct a lattice by passing in the LDData path, see the lattice doctests. Then you can also avoid explicitly saivng this .txt file.
  • Also in the demo, it would be nice to see plots comparing the standard lattice / Kronecker points compared to your new and improved constructions

@@ -0,0 +1,179 @@
import numpy as np
from sympy import gcdex, primerange, prime

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.

sympy is not included in the default requirements for qmcpy. Please import sympy with the functions where it is called so it will not throw an error when users try to import qmcpy without having sympy installed.

Comment thread qmcpy/discrete_distribution/kronecker/kronecker_search_methods.py Outdated
Comment thread qmcpy/discrete_distribution/kronecker/kronecker_search_methods.py Outdated
Comment thread qmcpy/discrete_distribution/lattice/lattice_vector_wssd_search.py Outdated
@@ -363,7 +474,10 @@ def wssd_discrepancy(self, n, weights, k_tilde = None, gamma = None):

def _square_periodic_discrepancies(self, n, k_tilde, gamma):

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.

Maybe this makes more sense as a function in kronecker_search_methods.py?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure if it does or not, since it is used as a method to calculate discrepancy for any Kronecker object, as opposed to being solely focused on search methods.

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.

Let's leave it here for now and we can always move it in the future

@sou-cheng-choi

sou-cheng-choi commented Jul 11, 2026

Copy link
Copy Markdown
Member

@AndersPride The "All Tests" failures can probably be resolved by merging develop branch into your branch.

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.

@AndersPride @alegresor

Is this file available from LDData? Do we need to duplicate it here?

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.

This is not available in LDData, but it would be nice to add it!

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.

@AndersPride @alegresor

Is this file available from LDData? Do we need to duplicate it here?

Comment thread qmcpy/discrete_distribution/lattice/lattice_vector_wssd_search.py Fixed
Comment thread qmcpy/discrete_distribution/lattice/lattice_vector_wssd_search.py Fixed
Comment thread qmcpy/discrete_distribution/lattice/lattice_vector_wssd_search.py Fixed
Comment thread qmcpy/discrete_distribution/kronecker/kronecker_search_methods.py Fixed
@sou-cheng-choi

sou-cheng-choi commented Jul 17, 2026

Copy link
Copy Markdown
Member

@AndersPride @fjhickernell

  1. make doctests_no_docker failed even after merging in develop branch. If you take out [kronecker_search_methods.py (line 4)] np.set_printoptions(precision=17), they should pass. I have commented it out for now. If high precision is needed for a particular display, do it locally in your application code.
  2. I have added demo test file test/booktests/tb_lattice_kronecker_methods.py in a commit. We may edit this file later if the demo takes too long to run.
  3. from qmcpy import * in your demo should import kronecker_search_march_2026 and lattice_vector_wssd_search if you include the right import statements in __init__.py files.
  4. The name kronecker_search_march_2026 is rather unusual. Why do you need to tag it with the month and year information? Likewise, there are references like ANDERS_CBC and anders_cbc without documentation. Please review and revise.
  5. Add Google-style doc string for lattice_vector_wssd_search.
  6. I have also added a unit test file test_dd_lattice_kronecker.py. Please review and revise if necessary.

Changes I have made since @fjhickernell merged develop branch are here.

Comment thread qmcpy/discrete_distribution/kronecker/kronecker_search_methods.py Fixed
sou-cheng-choi and others added 6 commits July 17, 2026 10:48
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Changed variable & function names to be more consistent and descriptive.
Fixed imports where needed and removed a few extraneous lines.
Added docstrings/doctests where needed.
Updated examples in the lattice_kronecker_methods demo to ensure a
reasonable run time.
Comment thread qmcpy/discrete_distribution/lattice/lattice_vector_wssd_search.py Fixed
Anders Pride and others added 2 commits July 28, 2026 16:55
Changed == None to is None

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
@sou-cheng-choi

sou-cheng-choi commented Aug 8, 2026

Copy link
Copy Markdown
Member

@AndersPride @fjhickernell @alegresor

Some doc or unit tests were failing. I have made some minimal changes to address them. Please review them here

@sou-cheng-choi

Copy link
Copy Markdown
Member

@copilot resolve the merge conflicts in this pull request

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

Copilot AI commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Resolved by merging develop into this branch and fixing the two merge conflicts in qmcpy/discrete_distribution/__init__.py and docs/api/discrete_distributions.md in commit e8e82900.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds generator search utilities and new/updated discrepancy + WSSD computations for Lattice and Kronecker sequences, along with tests, docs, and demo assets to illustrate and validate the new functionality.

Changes:

  • Add Lattice expected squared periodic discrepancy and WSSD APIs, plus a CBC-style WSSD-based lattice generating-vector search.
  • Add Kronecker Mobius-transform CBC search utility and a new built-in CBC_MT generating vector option.
  • Add unit tests, booktest coverage for a new demo notebook, and API documentation entries.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
test/test_dd_lattice_kronecker.py Adds unit tests covering the new discrepancy/WSSD APIs and both search methods.
test/booktests/tb_lattice_kronecker_methods.py Adds a notebook regression test with downscaled parameters for CI runtime.
qmcpy/discrete_distribution/lattice/lattice.py Introduces expected_squared_periodic_discrepancies and wssd on Lattice.
qmcpy/discrete_distribution/lattice/lattice_vector_wssd_search.py Adds CBC search routine for a lattice generating vector minimizing WSSD.
qmcpy/discrete_distribution/lattice/init.py Exports lattice_vector_wssd_search from the lattice package.
qmcpy/discrete_distribution/kronecker/kronecker.py Adds "CBC_MT" generating-vector option and updates discrepancy/WSSD internals.
qmcpy/discrete_distribution/kronecker/kronecker_search_methods.py Adds Mobius-transform-based Kronecker generator search method.
qmcpy/discrete_distribution/kronecker/generating_vectors/kron_vector_d-100_N-2exp20_2026_06_01.txt Adds a 100D precomputed Kronecker generating vector data file.
qmcpy/discrete_distribution/kronecker/init.py Exports Kronecker and the new search function from the kronecker package.
qmcpy/discrete_distribution/init.py Re-exports the new lattice/kronecker search functions at qmcpy.discrete_distribution (and thus qmcpy).
docs/api/discrete_distributions.md Documents the new public search utilities in the API docs.
demos/kuo.lattice-39102-1024-1048576.3600.txt Adds a large demo data asset (Kuo lattice data).
Suppressed comments (3)

qmcpy/discrete_distribution/kronecker/kronecker.py:481

  • points is built with shape (n, 1, d), which makes k_tilde_terms have length 1 on the last axis; subsequent slicing k_tilde_terms[..., 1:] then becomes empty and the discrepancy computation breaks. The sample index axis should be the last axis (shape (r, n, d) before applying k_tilde).
    qmcpy/discrete_distribution/kronecker/kronecker_search_methods.py:52
  • sympy may be unavailable (it is not a core dependency). This code should fail fast with an explicit error message rather than raising an AttributeError when sympy is None.
    # search over the first n primes, n = searchsize
    searchspace = np.array(list(sympy.primerange(1, sympy.prime(searchsize)+1)), dtype=np.float64)

qmcpy/discrete_distribution/kronecker/kronecker_search_methods.py:60

  • np.mod does not accept a dtype= argument; this line will raise TypeError when gen_vec_init is provided.
    else:
        gen_vec[0] = np.mod(gen_vec_init, 1,dtype=np.float64)

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +459 to +460
if sample_weights is not None and len(sample_weights) < n_max:
raise ValueError("Length of sample_weights must be equal to n_max")
Comment thread qmcpy/discrete_distribution/lattice/lattice.py Outdated
Comment thread qmcpy/discrete_distribution/lattice/lattice.py
Comment on lines +432 to +436
# get the frequency matrix for how often each kernel evaluation appears (this is always the same and can be precomputed, not done here to avoid adding >1GB txt file to git)
freq_mtx = np.zeros((k_sum.size, n_max), dtype=np.float64)
for i in range(1,n_max):
for j in range(k_sum.size):
if np.floor(i / 2**j) % 2 == 1:

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

As I mentioned in the comment on line 443, this matrix is always the same, and therefore can be precomputed and stored for reference. However, it has (n log n) values, so the file can be quite large. @alegresor @fjhickernell, what would you say is the best approach here?

Comment thread qmcpy/discrete_distribution/lattice/lattice_vector_wssd_search.py
Comment thread qmcpy/discrete_distribution/lattice/lattice_vector_wssd_search.py Outdated
Comment thread qmcpy/discrete_distribution/kronecker/kronecker_search_methods.py
Comment thread qmcpy/discrete_distribution/kronecker/kronecker_search_methods.py

@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.

@AndersPride

I approve this PR. Thank you for your contribution.

  1. It seems there are a few conflicts with develop branch. Please resolve them.
  2. Copilot has made some suggestions. Please evaluate if they are valid.
  3. Please ask @alegresor and @fjhickernell for re-reviews and address their feedback if any before you merge in the work.

@alegresor alegresor 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.

Looks like it's in pretty good shape! A few minor suggestions

  • You have introduced three new generating vectors, the kuo.lattice-39102...txt, the kron_vector_d-100...txt, and the CBCMT = np.array([0.618033988749895,...]). These would all be nice to have in our sister QMCSoftware/LDData repo. I am fine if you want to leave this to a separate PR as it will take some time to spell out new formats for Kronecker vectors in LDData as they will be the first of their kind!
  • Add kron_vector_d-100...txt to the pyproject.toml includes block so it gets included when users pip install qmcpy.
  • Do not import sympy at the top level. Only import exactly where it is needed within the function. sympy is not a requirement for qmcpy, so having it imported at the top level would break things for users. Importing within the function it is used only throws errors when users call that function without sympy.
  • Address merge conflicts
  • Copilot has some other good suggestions.

As we want to finalize QMCPy v2.4 PRs tonight, I think this will be a nice feature for QMCPy v2.5. Please re-request a review from me when you have addressed these small changes, and make sure to also get approval from @fjhickernell before merging.

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.

This is not available in LDData, but it would be nice to add it!

AndersPride and others added 4 commits August 24, 2026 19:18
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Improved docstring consistency
Fixed two instances where a previous approach was not properly updated
- Adds exception handling for import sympy. Prompts user to install
sympy or choose to use the slower, recursive implementation instead.
- Removes kuo.lattice-39102-1024-1048576.3600.txt file from demos and
replaces it with a .npy file in the lattice\generating_vectors folder,
like the other Kuo vector. Also edits lattice.py to accommodate this.
Changes the demo notebook to use this vector, fairer comparison.
- Adds the kronecker vector .txt file to pyproject.toml so that it is
included in the package.
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