Repository navigation
fix(contrib.hsgp): normalize multidimensional rational quadratic spectra - #2374
mottopanikeiku wants to merge 2 commits into
Conversation
|
I will wait until #2365 is mreged |
|
Sounds good. Once #2365 is merged I'll rebase this onto its log-density helper and re-run the tests. |
I corrected the dimension-dependent normalization of the rational quadratic spectral density, including its zero-frequency limit. I added independent Gamma-mixture quadrature checks and non-unit-lengthscale covariance regressions, and updated the documented formulas. Assisted-by: Claude Assisted-by: GPT-6 Astra Signed-off-by: mottopanikeiku <176798723+mottopanikeiku@users.noreply.github.com>
2c79c5a to
8e9543d
Compare
|
rebased onto master now that #2365 is in (8e9543d). the fix now lives in #2365's |
Benchmark reportthis PR run time: unchanged across 32 benchmarks
- compile time: 1 slower, 0 fasterSignificant changes (1) ──────── run time ─────── ────── compile time ──────
benchmark baseline this PR Δ baseline this PR Δ
────────────────────────────────────────────────────────────────────────────────────────
- predictive_forward_sampling 389.2 ms 388.7 ms -0.1% 99.6 ms 144.4 ms +45.0%Red is slower, green is faster; a row is coloured by the worse of its two columns. A delta in parentheses cleared the threshold on a measurement below the resolution floor, so it is shown without being called a change. † marks a benchmark that could not be compared — see below. Full results
|
| baseline | this PR | |
|---|---|---|
| ref | master |
fix-hsgp-rq-normalization |
| commit | 3d990ab7 |
a290139c |
| numpyro | 0.22.0 | 0.22.0 |
| jax | 0.12.0.1 | 0.12.0.1 |
| backend | cpu | cpu |
| python | 3.14.4 | 3.14.4 |
Runner: Linux-7.0.0-1017-azure-x86_64-with-glibc2.43, 4 CPUs.
Produced by this benchmark run.
juanitorduz
left a comment
There was a problem hiding this comment.
trim the oversized basis counts in the new covariance cases. I found no blocking issues.
Reduce the added two-dimensional cases to 48x48 and 20x20 bases without changing the existing one-percent tolerance. Validation: 55 focused RQ tests passed; all 11 covariance cases passed with x64; independent covariance smoke and Ruff checks passed. Assisted-by: Claude Assisted-by: GPT-6 Astra Signed-off-by: mottopanikeiku <176798723+mottopanikeiku@users.noreply.github.com>
|
trimmed the new covariance cases to |
antonsoo
left a comment
There was a problem hiding this comment.
Checked a290139 against 3d990ab on CPU, Python 3.14.7 / JAX 0.10.2.
Independent Gamma-mixture quadrature agrees with the spectrum and its first two length derivatives in 36 cases across 1D/2D/3D. The largest scaled error in x64 is 1.1e-13.
I also conditioned the public HSGP model on 96 recorded DWD station temperatures and predicted 64 other stations, comparing both parameterizations with independent dense RQ conditioning. With fixed amplitude 1.7, mixture 3 and length 0.4:
| quantity | base | head | dense reference |
|---|---|---|---|
| mean prior variance | 4.24999 | 1.70000 | 1.7 |
| maximum prediction difference from dense | 0.26050 | 5.3e-7 | 0 |
| maximum posterior variance difference | 0.55981 | 1.7e-7 | 0 |
Length 1.8 also recovers the specified prior and predictions. All three 1D covariance/posterior controls are bit-identical between trees. Float32 checks remain finite: covariance-conditioned means differ from dense by at most 2.2e-4, and public model means match those within 2.1e-4, in standardized temperature units. The head HSGP suite passes 161 tests in x64; 10 of the 18 new normalization cases fail numerically on the base.
Script, pinned data provenance and reports. These are fixed-hyperparameter numerical checks, not forecast-quality or scale-mixture-gradient evidence. Accelerators and the full repository suite were not tested.
juanitorduz
left a comment
There was a problem hiding this comment.
The fix is correct. I checked it against a Gamma-mixture derivation and confirmed squared-exponential and Matérn don't have the same bug. Two test trims:
- Drop
length=1.0fromtest_spectral_density_rational_quadratic_normalization. At unit length the regular branch can't see the ℓ^{1−D} error, and the 0.5 and 2.0 cases already cover the S(0) error. - Drop the
2d,length=0.5/[48,48]covariance case. The normalization test already pins that density; keep2d,length=2.0as the end-to-end check.
Also, a small correction to the PR body: the S(0) branch is never used by hsgp_rational_quadratic, because the HSGP frequencies are all > 0. Only the regular-branch error changes the HSGP prior.
spectral_density_rational_quadraticmultiplies bya * (2 * scale_mixture)**((dim - 1) / 2)where the D-dimensional Fourier transform needsa**dim(witha = sqrt(2 * scale_mixture) * length), so fordim > 1the density is off by a factorlength**(1 - dim). The zero-frequency branch already hasa**dimbut adds the same extra(2 * scale_mixture)**((dim - 1) / 2)factor. These densities are the basis-coefficient variances inhsgp_rational_quadratic, so the prior itself is wrong. The existing covariance tests all uselength=1, where the first error vanishes. I found this by reading and testing the code.The fix is in
_log_spectral_density_rational_quadratic, the log-density helper from #2365: I dropped the extra dimension factor from both branches, usedim * log(a)in the regular branch, and corrected both formulas in the docstring. 1-D values, thetinyfloor and the safe argument atw = 0don't change.Tests:
test_spectral_density_rational_quadratic_normalizationchecks the density in 1, 2 and 3 dimensions, for length 0.5/1/2, at zero and nonzero frequency. The reference is independent of the implementation: SciPy quadrature of the RBF spectral density against the Gamma mixing distribution that defines the RQ kernel.RationalQuadratic).pytest test/contrib/hsgpgives 161 passed, andtest_spectral_densities.pywithJAX_ENABLE_X64=1gives 70 passed.tyand the license-header check pass.I made this PR and directed its development, with AI assistance from Claude and GPT-6 Astra.