Phase 2: PDM, CE, String-Length, MHAOV, TLS - #2
Merged
Merged
Conversation
Stellingwerf (1978) dispersion statistic Theta = s^2 / sigma^2 — a minimization method strong on non-sinusoidal variables (eclipsing binaries, RR Lyrae, sawtooth pulsators). One vectorized kernel serves both backends, numpy (CPU) and cupy (GPU), with Stellingwerf covers for bin-phase robustness. - pdm_theta() vectorized over the period grid; PDMMethod registers with objective_sense=min and a pseudo-Nyquist default frequency grid. - Validated to <1e-9 against a transparent reference implementation; recovers planted sine and eclipser periods. - gpu-info now lists every GPU-capable method. - 6 tests (+1 GPU-gated); ruff and mypy clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two fast, GPU-friendly fold statistics, both minimization methods with numpy (CPU) + cupy (GPU) backends sharing one vectorized kernel: - Conditional Entropy (Graham et al. 2013): 2-D phase-magnitude histogram entropy; robust to sparse, aliased survey sampling. - String-Length (Lafler-Kinman / Dworetsky 1983): folded phase-sorted Euclidean path length; cheap, strong on eclipsing/eccentric shapes. Both validated to <1e-9 against transparent reference implementations and recover planted sine/eclipser periods. Shared pseudo-Nyquist grid helper factored into core.grid (PDM/CE/String-Length). 84 tests (5 GPU-gated); ruff and mypy clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Schwarzenberg-Czerny (1996) AOV F-statistic from a trigonometric-polynomial (truncated Fourier, order H) fit at each trial frequency — maximized at the true frequency and far more sensitive than single-harmonic Lomb-Scargle to sharply non-sinusoidal signals. - aov_power(): the model sum of squares is the least-squares projection norm onto the 2H+1 harmonic basis (mathematically identical to the orthogonal- polynomial method), vectorized over the frequency grid via batched normal equations; numpy (CPU) + cupy (GPU) share one kernel. - Validated to rtol 1e-5 against a per-frequency lstsq reference; recovers a planted eclipser period. Single-band for now (multi-band AOV is a follow-up). - 89 tests (6 GPU-gated); ruff and mypy clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
TLS (transit least squares), reimplemented from scratch as a limb-darkened matched filter: - limb_darkened_template(): quadratic limb-darkening central-transit profile used as the matched-filter kernel (vs BLS's box). - tls_power(): per-period binned matched filter via a batched circular correlation of the folded data with the template across phase and trial durations; returns SDE plus depth/duration/t0/signal-residue. CPU (numpy), vectorized over a transit-width-spaced period grid; GPU kernel is a planned follow-up. - Validated by limb-darkened transit injection-recovery. Also fixes a correctness bug: LightCurve.domain passed as a string (e.g. domain=flux) was not coerced to the Domain enum, so the `is` identity checks in as_flux/as_magnitude failed and already-flux data was re-converted as if it were magnitudes. Domain is now coerced in __post_init__. 94 tests (6 GPU-gated); ruff and mypy clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the five remaining periodograms from the plan, each plugging into the existing
periodogram/batch/CLI machinery with no orchestration changes.Methods (numpy CPU + cupy GPU unless noted)
least-squares trig-polynomial projection (equivalent to the orthogonal-polynomial form).
depth/duration/t0 (CPU only for now; a GPU kernel is a follow-up).
The four minimization methods (PDM/CE/String-Length) and TLS set the correct
objective_sense, so the shared N-best peak finder ranks them properly.Validation
Each method is validated to <1e-9 against a transparent in-test reference implementation,
plus planted-signal recovery. Fold methods alias at period multiples/submultiples, so their
recovery tests bound the period range (standard practice).
Also
Fixes a correctness bug where
LightCurve.domainpassed as a string (e.g.domain=flux)was not coerced to the
Domainenum, so identity checks in the flux/magnitude conversionsfailed and already-flux data was re-converted as magnitudes. Domain is now coerced in
__post_init__.94 tests (6 GPU-gated); ruff + mypy clean.
🤖 Generated with Claude Code