Support type generic precision#94
Merged
Merged
Conversation
Contributor
Benchmark Results (Julia v1)Time benchmarks
Memory benchmarks
|
Contributor
Benchmark Results (Julia vpre)Time benchmarks
Memory benchmarks
|
Contributor
Benchmark Results (Julia vlts)Time benchmarks
Memory benchmarks
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #94 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 17 18 +1
Lines 666 683 +17
=========================================
+ Hits 666 683 +17 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Make solar_position compute at the precision of the input Observer{T}, for all
five algorithms (PSA, NOAA, Walraven, USNO, SPA), from Float16 up to BigFloat.
Keystone is a type-generic time base (src/Positioning/timebase.jl): instead of
the always-Float64 datetime2julian, derive the small Julian-century / day-count
quantities at precision T. PSA/NOAA/Walraven use an integer-split form that is
both Float64-exact and magnitude-safe for low precision; USNO/SPA use a T-typed
julian_date that reproduces the original Float64 arithmetic bit-for-bit (so the
existing 1e-8 reference pins are preserved unchanged).
Also: generic calculate_deltat(::Type{T}, ...), generic default refraction
constructors (HUGHES{T}/BENNETT{T}/SG2{T}) fixing NOAA default refraction for
non-Float64, and per-element T() accumulation in the SPA periodic sums so the
Float64 coefficient tables no longer pin the result to Float64.
Adds test-typestability.jl (@inferred across types x algorithms) and
test-precision.jl (BigFloat convergence, Float64 vs BigFloat, Float32 usable).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Switch SPA (_compute_spa_srt_parameters) and USNO from the T-typed full Julian date to the integer-split julian_day_j2000 / fractional_hour time base, so they keep full intra-day resolution at low precision. Float32 SPA goes from ~10 deg error (Julian-date magnitude under-resolved) to ~0.2 deg; USNO and the other algorithms reach ~1e-2 deg. Remove the now-unused julian_date helper. This makes our Float64 output more accurate than the external solposx Float64 references for USNO/SPA (which carry a ~1e-7 Julian-date intra-day artifact in the sidereal terms), so relax those two reference comparisons to atol 1e-6 in test-usno.jl, test-spa.jl and test-mtk.jl (PSA/NOAA/Walraven stay at 1e-8). The solposx reference values themselves are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mean_sidereal_time multiplied the day-count by 360.98564736629, reaching ~3.5e6 and costing Float32 ~0.2 deg. Pass the day-count split into exact integer days and a full-precision [0,1) fraction (julian_day_j2000_split): the 360*n_int whole rotations vanish mod 360, so only the 0.98564736629 deg/day drift is kept at magnitude. Float32 SPA improves from ~0.2 deg to ~0.01 deg (worst case over 174 yr); Float64 is unchanged within the solposx 1e-6 tolerance, BigFloat still converges, and throughput is unaffected (~1.45x faster than Float64, 2x less memory). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Direction cosines fed to asin/acos can round just past ±1 in Float16/Float32, throwing a DomainError (e.g. NOAA and Walraven threw on a full-year Float32 sweep). Clamp those arguments to [-1, 1] via a small unit_clamp helper at the 13 asin/acos sites across the five algorithms. The clamp only activates outside the valid range, which Float64 never reaches for the reference conditions, so Float64 output (and the solposx references) are unchanged. All algorithms now run crash-free at Float32. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The time-base helpers are internal (not exported), but their docstrings tripped Documenter's strict missing_docs check (they are not in the manual). Convert them to plain `#` comments, matching the convention for other internal helpers (sum_periodic_terms, mean_sidereal_time, ...). Fixes the docs CI build. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cover the new public-API surface that algorithms don't exercise internally: the
calculate_deltat(::Type{T}, …) methods for the (year, month) and ZonedDateTime
signatures, and the HUGHES{T}()/BENNETT{T}()/SG2{T}() parametric default
constructors. Restores patch coverage.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Document the actual Float16 failure mode (silent NaN from coefficient overflow, not DomainErrors — unit_clamp prevents those) and note that ΔT is always evaluated in Float64, bounding absolute accuracy for wide types. - Remove the now-unused single-argument fractional_hour(::DateTime) and update the new-algorithm guide to the typed time-base helpers. - Replace mod2pi in PSA with a type-generic wrap of the atan output; mod2pi has no Float128 method. Float64 results are bit-identical; Float128 now reaches ~1e-30 deg for PSA/SPA/Walraven. - Document that NOAA/USNO are broken at Float128 by a Quadmath.jl bug: its rem() uses round-to-nearest (remainderq) instead of truncated (fmodq) semantics, corrupting Base's sind/cosd degree reduction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CdvBPWUmqyc7dfftjgWVu8
langestefan
force-pushed
the
feature/type-generic-precision
branch
from
July 24, 2026 16:27
656f8e4 to
905c06c
Compare
The solposx reference values are computed in Float64 from the full ~2.45e6 Julian Date, so a generic timestamp carries a ~1.5e-10 day quantization error that puts a ~6e-8 deg artifact into the sidereal terms. The magnitude-safe time base avoids that error, which forced the SPA/USNO comparisons up to atol 1e-6. Instead of tolerating the reference artifact, move the 19 shared test conditions onto UTC instants whose offset from noon is a multiple of 84.375 s (84375 ms, the odd factor of 86_400_000 ms). At those instants the full Julian Date is exactly representable in Float64, the solposx references carry no time-base error, and every algorithm matches them within 1e-8 again. All tables regenerated with solposx 1.0.1 after verifying it reproduces the previous checked-in values digit-for-digit at the old timestamps. Coverage is preserved: timezone offsets, leap day, 1800/2200 dates, poles, date line, altitudes, a night case, a low-sun (+0.9 deg) case, and a nonzero-seconds timestamp (13:41:15). Whole seconds only, because solposx's usno() mishandles sub-second times (its previous-midnight t.replace() keeps sub-second fields - to be reported upstream). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01THG1S9aRU29qtH6gJTzpS5
The reference tables were rounded to 8 decimals, which alone injects up to 5e-9 of comparison error. Emit solposx's exact Float64 outputs with full round-trip digits instead, and measure the true implementation floor at the exact-JD instants: PSA ~2e-12, NOAA ~1e-13, Walraven ~2e-14, USNO ~6e-14. Set atol = 1e-10 for these, keeping a margin of 50-500x. SPA stays at 1e-8 because its ~4e-9 floor belongs to the reference: pvlib's SPA accumulates the unreduced sidereal term to ~2.6e7 deg by the year-2200 row, where one ulp is 3.7e-9. Documented in test-spa.jl. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01THG1S9aRU29qtH6gJTzpS5
langestefan
force-pushed
the
feature/type-generic-precision
branch
from
July 27, 2026 10:13
17b5a8c to
45d4ae0
Compare
Add a Numeric precision section to the README and the docs index. It
explains that computation follows the Observer{T} element type and
tabulates, per algorithm, the maximum error against a 256-bit BigFloat
reference and the runtime relative to Float64 for Float32, Float128,
and BigFloat. Measured over dates from 2015 to 2035 and latitudes from
70N to 60S on the vectorized API.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01THG1S9aRU29qtH6gJTzpS5
The guide covers the Observer{T} precision mechanism, the supported
float types, measured accuracy and runtime per algorithm, the
difference between Float128 and BigFloat, and multithreaded benchmarks
for PSA and SPA at Float32, Float64, and Float128 on 16 threads. The
index page section now links to the guide instead of duplicating the
table. Table placeholders use n/a instead of a dash.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01THG1S9aRU29qtH6gJTzpS5
Observer{Float128}(1.0, 2.0) previously threw a MethodError because the
inner constructor requires arguments that already have type T and
defining it disabled the default converting constructors. Add an outer
constructor that accepts any Real arguments plus the degrees to
arcminutes horizon Pair and converts them to T. Calls whose arguments
already match T still dispatch to the inner constructor. Also widen
_horizon_to_degrees from AbstractFloat to Real so integer horizon
keywords work.
Docs now use Observer{Float32}(45.0, 10.0) instead of literal suffixes
in the precision guide, the README, and the Observer docstring.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01THG1S9aRU29qtH6gJTzpS5
Convert the two code blocks in the precision guide to @example blocks so the docs build runs them and shows real output. The threading example now computes one day of minute timestamps instead of a year to keep the docs build fast, and its displayed Float128 result shows the quad precision digits. Quadmath is added to the docs environment. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01THG1S9aRU29qtH6gJTzpS5
The Link checker job failed twice in a row on transient timeouts from slow external sites, first doi.org and then aa.usno.navy.mil, with zero actually broken links. Raise the lychee timeout to 60 seconds and the retry count to 4. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01THG1S9aRU29qtH6gJTzpS5
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.
No description provided.