Skip to content

MPMC: default loss_fn='L2star' is not shift-invariant but default randomize='shift' is a mod-1 shift #579

Description

@zitterbewegung

System information

  • OS Platform and Distribution: macOS 26.5.2 (arm64)
  • Are you using google COLAB notebook: No
  • Browser if using Jupyter: n/a
  • Browser version if using Jupyter: n/a
  • Mobile device: n/a
  • QMCPy installed from (source or binary): source
  • QMCPy version: 2.3 (develop @ a774f3a1297b982f2544742e8c691e035c9fc0a7)
  • Python version: 3.12.13
  • Installed using virtualenv? pip? conda?: uv venv + pip
  • GCC or Windows C Compiler version: Apple clang (Xcode CLT)
    Describe the problem
    MPMC's two defaults are mutually incompatible:
  • loss_fn='L2star' — the anchored (Warnock) L2 star discrepancy, which is
    not invariant under a mod-1 shift;
  • randomize='shift' — a mod-1 shift.
    So the design is optimised in one configuration and consumed in another: MPMC
    minimises an origin-anchored criterion, and then the default randomisation
    translates the points, degrading the very quantity that was optimised.
    QMCPy already ships an objective that does not have this problem. L2per
    depends only on pairwise differences mod 1 and is therefore exactly
    shift-invariant. It is neither the default nor, as far as we could find,
    documented as the objective to use with shift randomisation.
    Logs / Any other info
    Ratio of discrepancy after a random mod-1 shift to before, median over 8
    randomisations, 64 points (an independent sweep from the reproducer below, so
    L2star at d=4 reads 1.209 there and 1.176 here -- different shift draws, same
    conclusion) (measured at dimensions where these objectives are
    numerically well conditioned):
objective d=2 d=4 d=8
L2star (default) 1.318 1.209 1.076
L2ctr 1.456 1.049 0.978
L2sym 1.354 1.017 1.002
L2mix 1.158 1.150 1.030
L2ext 1.003 1.006 0.986
L2per 1.000 1.000 1.000

L2per is exact to floating point; it is the only objective of the six with
that property. For designs that were trained against L2star the penalty is
larger than the table above suggests (we measured x1.7–x2.2), because training
actively exploits the anchoring that the shift then destroys.
In our benchmarks, training on L2per instead of the default L2star reduced
held-out integration error by 55% on 10 of 10 standard QMCPy problems
(Keister, Genz family, Asian call, Box–Integral, Ishigami), replicated across 3
input constructions x 2 dimensions x 3 seeds without exception.

To Reproduce

import numpy as np, torch, qmcpy
from qmcpy.discrete_distribution.mpmc.utils import L2star, L2per
rng = np.random.default_rng(0)
for name, fn in (("L2star", L2star), ("L2per", L2per)):
 ratios = []
 for k in range(8):
 x = qmcpy.DigitalNetB2(dimension=4, randomize="LMS DS",
 seed=100 + k).gen_samples(64)
 t = torch.as_tensor(x, dtype=torch.float64)[None]
 before = float(fn(t)[0])
 shifted = np.mod(x + rng.random(4), 1.0)
 after = float(fn(torch.as_tensor(shifted, dtype=torch.float64)[None])[0])
 ratios.append(after / before)
 print(f"{name:8s} shift ratio (median of 8): {np.median(ratios):.3f}")

Output:

L2star shift ratio (median of 8): 1.176
L2per shift ratio (median of 8): 1.000

Expected behavior
The default objective and the default randomisation should be compatible —
either loss_fn should default to a shift-invariant discrepancy when
randomize='shift', or the objective/randomisation pairing should be documented
and a mismatch warned about.
Additional context
The MPMC authors observed the symptom without identifying the cause. In the
supplementary material of Rusch, Kirk, Bronstein, Lemieux and Rus (PNAS 121(40),
2024), section D.1:

"for large N = 1024 ... MPMC with random shifting appears to perform worse
than MPMC without random shifting. This highlights the importance of
developing suitable randomization techniques specifically tailored for MPMC,
a topic we plan to focus on in future research."
Choosing a shift-invariant objective appears to be that technique, and it
already exists in the codebase — no new machinery is required.
Happy to open a PR switching the default (or adding a compatibility warning)
plus a regression test asserting L2per is shift-invariant and L2star is not.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions