Skip to content

Add an Interpolated algorithm for fast repeated evaluation - #117

Merged
langestefan merged 10 commits into
mainfrom
feature/interpolated-position
Jul 28, 2026
Merged

Add an Interpolated algorithm for fast repeated evaluation#117
langestefan merged 10 commits into
mainfrom
feature/interpolated-position

Conversation

@langestefan

@langestefan langestefan commented Jul 28, 2026

Copy link
Copy Markdown
Member

Summary

Dense time series are the common case in PV work, and SPA spends about 2 µs per query. This PR adds an Interpolated wrapper that precomputes cubic B-splines of SPA's geocentric solar coordinates over a fixed time span and reconstructs topocentric positions analytically, giving a ~10x speedup at ~1e-10° accuracy with zero allocations per query.

Design in brief:

  • The computation is split at the geocentric/topocentric boundary. Four observer independent series are interpolated against Float64 days since J2000: unwrapped right ascension, declination, the radius vector, and the equation of the equinoxes. Everything fast or observer dependent stays closed form: sidereal time comes from the existing magnitude safe mean_sidereal_time, and the topocentric half runs through _spa_topocentric, extracted verbatim from SPA in the first commit, so both paths share the exact same code (the :fallback test asserts bit equality).
  • One interpolant serves every observer, so a single instance can be shared across a whole simulation grid, and it is immutable so evaluation is thread safe and composes with the OhMyThreads extension.
  • Spline construction lives in a new Interpolations.jl package extension (weak dep, matching the Makie/OhMyThreads/MTK pattern); the struct, evaluation, out_of_range handling, and solar_rate live in the core package with no new hard dependencies. Constructing without the extension loaded gives a clear error.
  • out_of_range = :error (default) throws on queries outside tspan because a silent fallback would be a hard to notice 10x slowdown; :fallback opts into calling the wrapped SPA instead.
  • New solar_rate returns d(azimuth)/dt and d(elevation)/dt in degrees per hour via a wrap aware central finite difference over the fast path, for tracker control and slew rate limits.

Measured (Ryzen 7 8845HS, 16 threads)

Quantity Value
Max error vs direct SPA, 1 y and 10 y spans, 10 observers 85°S to 85°N ~4e-11°
Scalar query 0.19 µs vs 1.92 µs for SPA (9.9x)
Allocations per query 0
Construction, 1 year at Hour(1) 3.1 ms
Construction, 10 years 36 ms
solar_rate vs SPA finite difference max deviation 3e-8 °/h

Docs

New guide guides/interpolation.md with executed construction, accuracy, benchmark, and solar_rate examples, plus docstring entries and a note on the positioning page.

Test plan

  • New test/extensions/test-interpolations.jl: accuracy vs direct SPA over 1 y and 10 y spans (measured maxima logged), refraction parity, out of range :error/:fallback, batch/in-place/table/OhMyThreads paths, ZonedDateTime tspan and queries, solar_rate vs finite difference of direct SPA, zero allocation and @inferred checks, Observer{Float32} result type
  • Full Pkg.test() green locally, including Aqua, JET, and type stability
  • julia --project=docs docs/make.jl builds clean

🤖 Generated with Claude Code

langestefan and others added 3 commits July 28, 2026 12:05
Pure code motion: _spa_topocentric now holds the hour angle, parallax,
elevation, and azimuth steps so another algorithm can reconstruct
positions from a given geocentric state through the exact same code.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wg3j4XXUooMvDgUpRajxTq
Interpolated wraps SPA with cubic B-splines of its geocentric right
ascension, declination, radius vector, and equation of the equinoxes on
a uniform time grid, then reconstructs topocentric positions through the
shared _spa_topocentric path. Sidereal time stays closed form, so the
only error is the spline error of four smooth series, about 1e-10
degrees at the default one hour step, and one interpolant serves every
observer. Scalar evaluation is allocation free and about 10x faster
than direct SPA.

Construction lives in a new Interpolations.jl package extension; the
struct, evaluation, out_of_range handling (:error or :fallback), and
the finite difference solar_rate live in the core package.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wg3j4XXUooMvDgUpRajxTq
Adds a guide with executed construction, accuracy, benchmark, and
solar_rate examples, registers it in the docs pages, and lists the
wrapper on the positioning page with docstring entries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wg3j4XXUooMvDgUpRajxTq
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results (Julia vlts)

Time benchmarks
main e5eb838... main / e5eb838...
ours/n=100/NOAA 0.0423 ± 0.00049 ms 0.0422 ± 0.00039 ms 1 ± 0.015
ours/n=100/PSA 0.0174 ± 0.0001 ms 0.0175 ± 0.00012 ms 0.998 ± 0.0089
ours/n=100/SPA 0.293 ± 0.0078 ms 0.294 ± 0.008 ms 0.997 ± 0.038
ours/n=100/USNO 0.0399 ± 0.0022 ms 0.0403 ± 0.0022 ms 0.99 ± 0.078
ours/n=100/Walraven 0.0206 ± 9.2e-05 ms 0.0207 ± 0.00015 ms 0.996 ± 0.0085
ours/n=1000/NOAA 0.412 ± 0.023 ms 0.411 ± 0.023 ms 1 ± 0.078
ours/n=1000/PSA 0.183 ± 0.012 ms 0.183 ± 0.012 ms 0.999 ± 0.092
ours/n=1000/SPA 3 ± 0.021 ms 3.01 ± 0.023 ms 0.995 ± 0.01
ours/n=1000/USNO 0.379 ± 0.011 ms 0.384 ± 0.012 ms 0.986 ± 0.041
ours/n=1000/Walraven 0.215 ± 0.012 ms 0.214 ± 0.011 ms 1 ± 0.077
ours/n=10000/NOAA 3.99 ± 0.0098 ms 3.99 ± 0.021 ms 0.999 ± 0.0058
ours/n=10000/PSA 1.75 ± 0.015 ms 1.76 ± 0.027 ms 0.998 ± 0.018
ours/n=10000/SPA 30.4 ± 0.2 ms 30.6 ± 0.23 ms 0.994 ± 0.0098
ours/n=10000/USNO 3.78 ± 0.023 ms 3.83 ± 0.027 ms 0.986 ± 0.0091
ours/n=10000/Walraven 2.07 ± 0.0067 ms 2.07 ± 0.009 ms 0.999 ± 0.0054
ours/n=100000/NOAA 41 ± 0.13 ms 41.1 ± 0.15 ms 0.999 ± 0.0049
ours/n=100000/PSA 17.8 ± 0.066 ms 17.8 ± 0.11 ms 0.997 ± 0.0073
ours/n=100000/SPA 306 ± 2.5 ms 308 ± 2.3 ms 0.994 ± 0.011
ours/n=100000/USNO 38.6 ± 0.2 ms 39.1 ± 0.11 ms 0.988 ± 0.0057
ours/n=100000/Walraven 20.7 ± 0.051 ms 20.8 ± 0.086 ms 0.996 ± 0.0048
refraction/ARCHER 0.000261 ± 1e-05 ms 0.00026 ± 1e-06 ms 1 ± 0.039
refraction/BENNETT 0.000251 ± 1e-05 ms 0.000251 ± 1e-05 ms 1 ± 0.056
refraction/MICHALSKY 0.00022 ± 1e-06 ms 0.00022 ± 1e-06 ms 1 ± 0.0064
refraction/NoRefraction 0.000211 ± 1e-05 ms 0.00022 ± 1e-05 ms 0.959 ± 0.063
refraction/SG2 0.00027 ± 1e-05 ms 0.00027 ± 1e-05 ms 1 ± 0.052
single/NOAA 0.000451 ± 1e-05 ms 0.000451 ± 1e-06 ms 1 ± 0.022
single/PSA 0.000211 ± 1e-05 ms 0.000211 ± 1e-05 ms 1 ± 0.067
single/SPA 0.00304 ± 1e-05 ms 0.00306 ± 1.1e-05 ms 0.993 ± 0.0048
single/USNO 0.00042 ± 1e-05 ms 0.000411 ± 1e-05 ms 1.02 ± 0.035
single/Walraven 0.000251 ± 1e-05 ms 0.000251 ± 1e-05 ms 1 ± 0.056
solposx/n=100/NOAA 2.86 ± 0.028 ms 2.89 ± 0.028 ms 0.989 ± 0.014
solposx/n=100/PSA 1.99 ± 0.024 ms 2.04 ± 0.026 ms 0.975 ± 0.017
solposx/n=100/SPA 3.06 ± 0.097 ms 3.05 ± 0.097 ms 1 ± 0.045
solposx/n=100/USNO 2.38 ± 0.027 ms 2.41 ± 0.039 ms 0.989 ± 0.02
solposx/n=100/Walraven 0.833 ± 0.016 ms 0.835 ± 0.016 ms 0.997 ± 0.027
solposx/n=1000/NOAA 3.49 ± 0.036 ms 3.52 ± 0.039 ms 0.993 ± 0.015
solposx/n=1000/PSA 2.32 ± 0.028 ms 2.37 ± 0.029 ms 0.979 ± 0.017
solposx/n=1000/SPA 7.61 ± 0.11 ms 7.57 ± 0.12 ms 1.01 ± 0.022
solposx/n=1000/USNO 6.51 ± 0.064 ms 6.48 ± 0.073 ms 1 ± 0.015
solposx/n=1000/Walraven 1.12 ± 0.023 ms 1.13 ± 0.026 ms 0.993 ± 0.03
solposx/n=10000/NOAA 9.46 ± 0.18 ms 9.51 ± 0.22 ms 0.994 ± 0.03
solposx/n=10000/PSA 5.7 ± 0.14 ms 5.74 ± 0.14 ms 0.993 ± 0.035
solposx/n=10000/SPA 49.3 ± 0.3 ms 48.8 ± 0.22 ms 1.01 ± 0.0076
solposx/n=10000/USNO 46.8 ± 0.98 ms 45.6 ± 0.74 ms 1.03 ± 0.027
solposx/n=10000/Walraven 3.74 ± 0.094 ms 3.77 ± 0.078 ms 0.991 ± 0.032
solposx/n=100000/NOAA 68.1 ± 0.49 ms 68.1 ± 0.5 ms 0.999 ± 0.01
solposx/n=100000/PSA 39 ± 1 ms 39.3 ± 1 ms 0.992 ± 0.036
solposx/n=100000/SPA 457 ± 3.6 ms 460 ± 2.6 ms 0.994 ± 0.0096
solposx/n=100000/USNO 452 ± 46 ms 450 ± 42 ms 1 ± 0.14
solposx/n=100000/Walraven 29.3 ± 0.8 ms 29.4 ± 0.85 ms 0.997 ± 0.04
time_to_load 0.172 ± 0.0064 s 0.167 ± 0.0023 s 1.03 ± 0.041
Memory benchmarks
main e5eb838... main / e5eb838...
ours/n=100/NOAA 5 allocs: 4.38 kB 5 allocs: 4.38 kB 1
ours/n=100/PSA 3 allocs: 2.62 kB 3 allocs: 2.62 kB 1
ours/n=100/SPA 5 allocs: 4.38 kB 5 allocs: 4.38 kB 1
ours/n=100/USNO 3 allocs: 2.62 kB 3 allocs: 2.62 kB 1
ours/n=100/Walraven 3 allocs: 2.62 kB 3 allocs: 2.62 kB 1
ours/n=1000/NOAA 5 allocs: 0.0388 MB 5 allocs: 0.0388 MB 1
ours/n=1000/PSA 3 allocs: 23.8 kB 3 allocs: 23.8 kB 1
ours/n=1000/SPA 5 allocs: 0.0388 MB 5 allocs: 0.0388 MB 1
ours/n=1000/USNO 3 allocs: 23.8 kB 3 allocs: 23.8 kB 1
ours/n=1000/Walraven 3 allocs: 23.8 kB 3 allocs: 23.8 kB 1
ours/n=10000/NOAA 10 allocs: 0.382 MB 10 allocs: 0.382 MB 1
ours/n=10000/PSA 6 allocs: 0.229 MB 6 allocs: 0.229 MB 1
ours/n=10000/SPA 10 allocs: 0.382 MB 10 allocs: 0.382 MB 1
ours/n=10000/USNO 6 allocs: 0.229 MB 6 allocs: 0.229 MB 1
ours/n=10000/Walraven 6 allocs: 0.229 MB 6 allocs: 0.229 MB 1
ours/n=100000/NOAA 10 allocs: 3.81 MB 10 allocs: 3.81 MB 1
ours/n=100000/PSA 6 allocs: 2.29 MB 6 allocs: 2.29 MB 1
ours/n=100000/SPA 10 allocs: 3.81 MB 10 allocs: 3.81 MB 1
ours/n=100000/USNO 6 allocs: 2.29 MB 6 allocs: 2.29 MB 1
ours/n=100000/Walraven 6 allocs: 2.29 MB 6 allocs: 2.29 MB 1
refraction/ARCHER 0 allocs: 0 B 0 allocs: 0 B
refraction/BENNETT 0 allocs: 0 B 0 allocs: 0 B
refraction/MICHALSKY 0 allocs: 0 B 0 allocs: 0 B
refraction/NoRefraction 0 allocs: 0 B 0 allocs: 0 B
refraction/SG2 0 allocs: 0 B 0 allocs: 0 B
single/NOAA 0 allocs: 0 B 0 allocs: 0 B
single/PSA 0 allocs: 0 B 0 allocs: 0 B
single/SPA 0 allocs: 0 B 0 allocs: 0 B
single/USNO 0 allocs: 0 B 0 allocs: 0 B
single/Walraven 0 allocs: 0 B 0 allocs: 0 B
solposx/n=100/NOAA 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=100/PSA 0.06 k allocs: 1.66 kB 0.06 k allocs: 1.66 kB 1
solposx/n=100/SPA 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=100/USNO 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=100/Walraven 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=1000/NOAA 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=1000/PSA 0.06 k allocs: 1.66 kB 0.06 k allocs: 1.66 kB 1
solposx/n=1000/SPA 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=1000/USNO 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=1000/Walraven 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=10000/NOAA 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=10000/PSA 0.06 k allocs: 1.66 kB 0.06 k allocs: 1.66 kB 1
solposx/n=10000/SPA 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=10000/USNO 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=10000/Walraven 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=100000/NOAA 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=100000/PSA 0.06 k allocs: 1.66 kB 0.06 k allocs: 1.66 kB 1
solposx/n=100000/SPA 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=100000/USNO 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
solposx/n=100000/Walraven 22 allocs: 0.781 kB 22 allocs: 0.781 kB 1
time_to_load 0.153 k allocs: 14.5 kB 0.153 k allocs: 14.5 kB 1

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results (Julia vpre)

Time benchmarks
main e5eb838... main / e5eb838...
ours/n=100/NOAA 0.0424 ± 0.00023 ms 0.0423 ± 0.00025 ms 1 ± 0.008
ours/n=100/PSA 0.0166 ± 0.00015 ms 0.0167 ± 0.00015 ms 0.995 ± 0.013
ours/n=100/SPA 0.425 ± 0.0093 ms 0.432 ± 0.0088 ms 0.983 ± 0.029
ours/n=100/USNO 0.0404 ± 0.00023 ms 0.0404 ± 0.00023 ms 1 ± 0.0081
ours/n=100/Walraven 0.0196 ± 0.00036 ms 0.0198 ± 0.00046 ms 0.988 ± 0.029
ours/n=1000/NOAA 0.417 ± 0.009 ms 0.415 ± 0.0088 ms 1 ± 0.031
ours/n=1000/PSA 0.167 ± 0.0012 ms 0.166 ± 0.0015 ms 1 ± 0.011
ours/n=1000/SPA 4.22 ± 0.087 ms 4.42 ± 0.029 ms 0.956 ± 0.021
ours/n=1000/USNO 0.394 ± 0.0086 ms 0.399 ± 0.0092 ms 0.989 ± 0.031
ours/n=1000/Walraven 0.197 ± 0.0069 ms 0.195 ± 0.0051 ms 1.01 ± 0.044
ours/n=10000/NOAA 4.19 ± 0.02 ms 4.18 ± 0.025 ms 1 ± 0.0076
ours/n=10000/PSA 1.68 ± 0.0081 ms 1.68 ± 0.0089 ms 1 ± 0.0072
ours/n=10000/SPA 42.8 ± 0.91 ms 43.9 ± 0.67 ms 0.976 ± 0.026
ours/n=10000/USNO 3.99 ± 0.013 ms 3.99 ± 0.039 ms 1 ± 0.01
ours/n=10000/Walraven 1.98 ± 0.0089 ms 1.97 ± 0.014 ms 1.01 ± 0.0084
ours/n=100000/NOAA 42.7 ± 1 ms 42.6 ± 1.6 ms 1 ± 0.045
ours/n=100000/PSA 17 ± 0.52 ms 16.9 ± 0.63 ms 1 ± 0.048
ours/n=100000/SPA 438 ± 9.2 ms 449 ± 8 ms 0.976 ± 0.027
ours/n=100000/USNO 40.3 ± 0.9 ms 40.4 ± 0.98 ms 0.999 ± 0.033
ours/n=100000/Walraven 19.8 ± 0.95 ms 19.7 ± 0.48 ms 1.01 ± 0.054
refraction/ARCHER 0.00024 ± 1.1e-05 ms 0.00024 ± 1e-05 ms 1 ± 0.062
refraction/BENNETT 0.00024 ± 1e-05 ms 0.000231 ± 1e-05 ms 1.04 ± 0.062
refraction/MICHALSKY 0.0002 ± 1e-06 ms 0.0002 ± 1e-06 ms 1 ± 0.0071
refraction/NoRefraction 0.0002 ± 1e-05 ms 0.0002 ± 1e-05 ms 1 ± 0.071
refraction/SG2 0.000251 ± 1e-06 ms 0.00025 ± 1e-06 ms 1 ± 0.0057
single/NOAA 0.000451 ± 0 ms 0.000451 ± 0 ms 1 ± 0
single/PSA 0.0002 ± 1e-05 ms 0.000191 ± 1e-05 ms 1.05 ± 0.076
single/SPA 0.00391 ± 8e-05 ms 0.0039 ± 6e-05 ms 1 ± 0.026
single/USNO 0.000411 ± 1e-06 ms 0.000411 ± 1e-06 ms 1 ± 0.0034
single/Walraven 0.000231 ± 1e-05 ms 0.000231 ± 1e-06 ms 1 ± 0.044
solposx/n=100/NOAA 4.14 ± 0.071 ms 4.08 ± 0.079 ms 1.02 ± 0.026
solposx/n=100/PSA 2.9 ± 0.047 ms 2.91 ± 0.044 ms 0.998 ± 0.022
solposx/n=100/SPA 3.16 ± 0.032 ms 3.19 ± 0.039 ms 0.99 ± 0.016
solposx/n=100/USNO 3.16 ± 0.041 ms 3.15 ± 0.059 ms 1 ± 0.023
solposx/n=100/Walraven 1.16 ± 0.023 ms 1.17 ± 0.027 ms 0.993 ± 0.03
solposx/n=1000/NOAA 4.73 ± 0.13 ms 4.77 ± 0.091 ms 0.991 ± 0.033
solposx/n=1000/PSA 3.3 ± 0.049 ms 3.33 ± 0.052 ms 0.991 ± 0.021
solposx/n=1000/SPA 7.77 ± 0.05 ms 7.76 ± 0.15 ms 1 ± 0.02
solposx/n=1000/USNO 7.39 ± 0.096 ms 7.5 ± 0.19 ms 0.986 ± 0.028
solposx/n=1000/Walraven 1.45 ± 0.033 ms 1.45 ± 0.034 ms 1 ± 0.032
solposx/n=10000/NOAA 10.7 ± 0.15 ms 11 ± 0.25 ms 0.976 ± 0.026
solposx/n=10000/PSA 6.68 ± 0.085 ms 6.85 ± 0.15 ms 0.974 ± 0.024
solposx/n=10000/SPA 50.9 ± 0.43 ms 51.5 ± 0.43 ms 0.988 ± 0.012
solposx/n=10000/USNO 50 ± 0.82 ms 50.8 ± 0.71 ms 0.983 ± 0.021
solposx/n=10000/Walraven 3.98 ± 0.042 ms 4 ± 0.064 ms 0.995 ± 0.019
solposx/n=100000/NOAA 67.5 ± 1.5 ms 67.7 ± 0.78 ms 0.997 ± 0.024
solposx/n=100000/PSA 39.4 ± 0.52 ms 39.7 ± 0.42 ms 0.993 ± 0.017
solposx/n=100000/SPA 510 ± 4.7 ms 504 ± 9.5 ms 1.01 ± 0.021
solposx/n=100000/USNO 479 ± 38 ms 483 ± 25 ms 0.99 ± 0.094
solposx/n=100000/Walraven 29.2 ± 0.44 ms 28.9 ± 0.43 ms 1.01 ± 0.021
time_to_load 0.129 ± 0.0019 s 0.129 ± 0.00057 s 0.994 ± 0.016
Memory benchmarks
main e5eb838... main / e5eb838...
ours/n=100/NOAA 10 allocs: 4.53 kB 10 allocs: 4.53 kB 1
ours/n=100/PSA 6 allocs: 2.72 kB 6 allocs: 2.72 kB 1
ours/n=100/SPA 10 allocs: 4.53 kB 10 allocs: 4.53 kB 1
ours/n=100/USNO 6 allocs: 2.72 kB 6 allocs: 2.72 kB 1
ours/n=100/Walraven 6 allocs: 2.72 kB 6 allocs: 2.72 kB 1
ours/n=1000/NOAA 15 allocs: 0.0385 MB 15 allocs: 0.0385 MB 1
ours/n=1000/PSA 9 allocs: 23.6 kB 9 allocs: 23.6 kB 1
ours/n=1000/SPA 15 allocs: 0.0385 MB 15 allocs: 0.0385 MB 1
ours/n=1000/USNO 9 allocs: 23.6 kB 9 allocs: 23.6 kB 1
ours/n=1000/Walraven 9 allocs: 23.6 kB 9 allocs: 23.6 kB 1
ours/n=10000/NOAA 15 allocs: 0.382 MB 15 allocs: 0.382 MB 1
ours/n=10000/PSA 9 allocs: 0.229 MB 9 allocs: 0.229 MB 1
ours/n=10000/SPA 15 allocs: 0.382 MB 15 allocs: 0.382 MB 1
ours/n=10000/USNO 9 allocs: 0.229 MB 9 allocs: 0.229 MB 1
ours/n=10000/Walraven 9 allocs: 0.229 MB 9 allocs: 0.229 MB 1
ours/n=100000/NOAA 15 allocs: 3.82 MB 15 allocs: 3.82 MB 1
ours/n=100000/PSA 9 allocs: 2.29 MB 9 allocs: 2.29 MB 1
ours/n=100000/SPA 15 allocs: 3.82 MB 15 allocs: 3.82 MB 1
ours/n=100000/USNO 9 allocs: 2.29 MB 9 allocs: 2.29 MB 1
ours/n=100000/Walraven 9 allocs: 2.29 MB 9 allocs: 2.29 MB 1
refraction/ARCHER 0 allocs: 0 B 0 allocs: 0 B
refraction/BENNETT 0 allocs: 0 B 0 allocs: 0 B
refraction/MICHALSKY 0 allocs: 0 B 0 allocs: 0 B
refraction/NoRefraction 0 allocs: 0 B 0 allocs: 0 B
refraction/SG2 0 allocs: 0 B 0 allocs: 0 B
single/NOAA 0 allocs: 0 B 0 allocs: 0 B
single/PSA 0 allocs: 0 B 0 allocs: 0 B
single/SPA 0 allocs: 0 B 0 allocs: 0 B
single/USNO 0 allocs: 0 B 0 allocs: 0 B
single/Walraven 0 allocs: 0 B 0 allocs: 0 B
solposx/n=100/NOAA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100/PSA 0.039 k allocs: 1.2 kB 0.039 k allocs: 1.2 kB 1
solposx/n=100/SPA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100/USNO 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100/Walraven 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=1000/NOAA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=1000/PSA 0.039 k allocs: 1.2 kB 0.039 k allocs: 1.2 kB 1
solposx/n=1000/SPA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=1000/USNO 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=1000/Walraven 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=10000/NOAA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=10000/PSA 0.039 k allocs: 1.2 kB 0.039 k allocs: 1.2 kB 1
solposx/n=10000/SPA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=10000/USNO 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=10000/Walraven 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100000/NOAA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100000/PSA 0.039 k allocs: 1.2 kB 0.039 k allocs: 1.2 kB 1
solposx/n=100000/SPA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100000/USNO 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100000/Walraven 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
time_to_load 0.205 k allocs: 11.9 kB 0.205 k allocs: 11.9 kB 1

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results (Julia v1)

Time benchmarks
main e5eb838... main / e5eb838...
ours/n=100/NOAA 0.0427 ± 0.00024 ms 0.0428 ± 0.00018 ms 0.999 ± 0.007
ours/n=100/PSA 0.0167 ± 0.00014 ms 0.0167 ± 0.00016 ms 0.998 ± 0.013
ours/n=100/SPA 0.303 ± 0.0082 ms 0.305 ± 0.0082 ms 0.995 ± 0.038
ours/n=100/USNO 0.0407 ± 0.0002 ms 0.0407 ± 0.00018 ms 1 ± 0.0066
ours/n=100/Walraven 0.0196 ± 0.0005 ms 0.0201 ± 0.00014 ms 0.978 ± 0.026
ours/n=1000/NOAA 0.419 ± 0.0088 ms 0.419 ± 0.0087 ms 0.999 ± 0.029
ours/n=1000/PSA 0.167 ± 0.0082 ms 0.167 ± 0.0083 ms 0.999 ± 0.07
ours/n=1000/SPA 3.11 ± 0.018 ms 3.13 ± 0.019 ms 0.996 ± 0.0085
ours/n=1000/USNO 0.396 ± 0.0085 ms 0.396 ± 0.0083 ms 1 ± 0.03
ours/n=1000/Walraven 0.196 ± 0.0085 ms 0.197 ± 0.0086 ms 0.997 ± 0.061
ours/n=10000/NOAA 4.22 ± 0.014 ms 4.22 ± 0.016 ms 1 ± 0.0051
ours/n=10000/PSA 1.7 ± 0.0073 ms 1.7 ± 0.0082 ms 1 ± 0.0065
ours/n=10000/SPA 31.3 ± 0.073 ms 31.4 ± 0.081 ms 0.995 ± 0.0035
ours/n=10000/USNO 4.01 ± 0.0099 ms 4.01 ± 0.0095 ms 1 ± 0.0034
ours/n=10000/Walraven 1.99 ± 0.02 ms 1.99 ± 0.0087 ms 1 ± 0.011
ours/n=100000/NOAA 43 ± 0.57 ms 43 ± 0.57 ms 0.999 ± 0.019
ours/n=100000/PSA 17.1 ± 0.93 ms 17.1 ± 0.31 ms 1 ± 0.057
ours/n=100000/SPA 314 ± 1.3 ms 316 ± 0.35 ms 0.995 ± 0.0044
ours/n=100000/USNO 40.5 ± 0.23 ms 40.5 ± 0.15 ms 1 ± 0.0068
ours/n=100000/Walraven 20 ± 0.49 ms 20 ± 0.34 ms 1 ± 0.03
refraction/ARCHER 0.00024 ± 1e-06 ms 0.000231 ± 1e-05 ms 1.04 ± 0.045
refraction/BENNETT 0.00024 ± 1e-05 ms 0.000231 ± 1e-05 ms 1.04 ± 0.062
refraction/MICHALSKY 0.0002 ± 1e-06 ms 0.0002 ± 1e-06 ms 1 ± 0.0071
refraction/NoRefraction 0.0002 ± 1e-06 ms 0.0002 ± 1e-05 ms 1 ± 0.05
refraction/SG2 0.00025 ± 1e-06 ms 0.00025 ± 1e-06 ms 1 ± 0.0057
single/NOAA 0.000451 ± 1e-05 ms 0.00046 ± 1e-05 ms 0.98 ± 0.03
single/PSA 0.000191 ± 1e-05 ms 0.0002 ± 9e-06 ms 0.955 ± 0.066
single/SPA 0.00312 ± 1e-05 ms 0.00313 ± 1e-05 ms 0.997 ± 0.0045
single/USNO 0.000411 ± 1e-05 ms 0.00042 ± 1e-05 ms 0.979 ± 0.033
single/Walraven 0.00024 ± 1e-05 ms 0.000231 ± 1e-05 ms 1.04 ± 0.062
solposx/n=100/NOAA 3.95 ± 0.059 ms 4.08 ± 0.054 ms 0.969 ± 0.019
solposx/n=100/PSA 2.84 ± 0.037 ms 2.94 ± 0.043 ms 0.965 ± 0.019
solposx/n=100/SPA 3.06 ± 0.026 ms 3.1 ± 0.035 ms 0.987 ± 0.014
solposx/n=100/USNO 3.05 ± 0.042 ms 3.12 ± 0.046 ms 0.979 ± 0.02
solposx/n=100/Walraven 1.12 ± 0.023 ms 1.13 ± 0.027 ms 0.988 ± 0.031
solposx/n=1000/NOAA 4.68 ± 0.06 ms 4.77 ± 0.079 ms 0.98 ± 0.021
solposx/n=1000/PSA 3.25 ± 0.043 ms 3.32 ± 0.052 ms 0.978 ± 0.02
solposx/n=1000/SPA 7.57 ± 0.098 ms 7.67 ± 0.063 ms 0.987 ± 0.015
solposx/n=1000/USNO 7.31 ± 0.066 ms 7.35 ± 0.069 ms 0.994 ± 0.013
solposx/n=1000/Walraven 1.43 ± 0.032 ms 1.43 ± 0.035 ms 1 ± 0.033
solposx/n=10000/NOAA 10.6 ± 0.14 ms 10.8 ± 0.17 ms 0.984 ± 0.02
solposx/n=10000/PSA 6.69 ± 0.091 ms 6.72 ± 0.093 ms 0.996 ± 0.019
solposx/n=10000/SPA 50.5 ± 0.36 ms 50.9 ± 0.35 ms 0.993 ± 0.0099
solposx/n=10000/USNO 48 ± 0.65 ms 48.1 ± 0.51 ms 0.997 ± 0.017
solposx/n=10000/Walraven 3.97 ± 0.055 ms 3.97 ± 0.057 ms 1 ± 0.02
solposx/n=100000/NOAA 67.3 ± 0.64 ms 67.4 ± 0.61 ms 0.998 ± 0.013
solposx/n=100000/PSA 39.6 ± 0.76 ms 39.4 ± 0.32 ms 1 ± 0.021
solposx/n=100000/SPA 500 ± 2.6 ms 511 ± 6.5 ms 0.978 ± 0.013
solposx/n=100000/USNO 464 ± 27 ms 458 ± 34 ms 1.01 ± 0.096
solposx/n=100000/Walraven 28.5 ± 0.23 ms 28.9 ± 0.52 ms 0.986 ± 0.019
time_to_load 0.169 ± 0.0012 s 0.171 ± 0.0012 s 0.99 ± 0.01
Memory benchmarks
main e5eb838... main / e5eb838...
ours/n=100/NOAA 10 allocs: 4.53 kB 10 allocs: 4.53 kB 1
ours/n=100/PSA 6 allocs: 2.72 kB 6 allocs: 2.72 kB 1
ours/n=100/SPA 10 allocs: 4.53 kB 10 allocs: 4.53 kB 1
ours/n=100/USNO 6 allocs: 2.72 kB 6 allocs: 2.72 kB 1
ours/n=100/Walraven 6 allocs: 2.72 kB 6 allocs: 2.72 kB 1
ours/n=1000/NOAA 15 allocs: 0.0385 MB 15 allocs: 0.0385 MB 1
ours/n=1000/PSA 9 allocs: 23.6 kB 9 allocs: 23.6 kB 1
ours/n=1000/SPA 15 allocs: 0.0385 MB 15 allocs: 0.0385 MB 1
ours/n=1000/USNO 9 allocs: 23.6 kB 9 allocs: 23.6 kB 1
ours/n=1000/Walraven 9 allocs: 23.6 kB 9 allocs: 23.6 kB 1
ours/n=10000/NOAA 15 allocs: 0.382 MB 15 allocs: 0.382 MB 1
ours/n=10000/PSA 9 allocs: 0.229 MB 9 allocs: 0.229 MB 1
ours/n=10000/SPA 15 allocs: 0.382 MB 15 allocs: 0.382 MB 1
ours/n=10000/USNO 9 allocs: 0.229 MB 9 allocs: 0.229 MB 1
ours/n=10000/Walraven 9 allocs: 0.229 MB 9 allocs: 0.229 MB 1
ours/n=100000/NOAA 15 allocs: 3.82 MB 15 allocs: 3.82 MB 1
ours/n=100000/PSA 9 allocs: 2.29 MB 9 allocs: 2.29 MB 1
ours/n=100000/SPA 15 allocs: 3.82 MB 15 allocs: 3.82 MB 1
ours/n=100000/USNO 9 allocs: 2.29 MB 9 allocs: 2.29 MB 1
ours/n=100000/Walraven 9 allocs: 2.29 MB 9 allocs: 2.29 MB 1
refraction/ARCHER 0 allocs: 0 B 0 allocs: 0 B
refraction/BENNETT 0 allocs: 0 B 0 allocs: 0 B
refraction/MICHALSKY 0 allocs: 0 B 0 allocs: 0 B
refraction/NoRefraction 0 allocs: 0 B 0 allocs: 0 B
refraction/SG2 0 allocs: 0 B 0 allocs: 0 B
single/NOAA 0 allocs: 0 B 0 allocs: 0 B
single/PSA 0 allocs: 0 B 0 allocs: 0 B
single/SPA 0 allocs: 0 B 0 allocs: 0 B
single/USNO 0 allocs: 0 B 0 allocs: 0 B
single/Walraven 0 allocs: 0 B 0 allocs: 0 B
solposx/n=100/NOAA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100/PSA 0.039 k allocs: 1.2 kB 0.039 k allocs: 1.2 kB 1
solposx/n=100/SPA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100/USNO 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100/Walraven 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=1000/NOAA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=1000/PSA 0.039 k allocs: 1.2 kB 0.039 k allocs: 1.2 kB 1
solposx/n=1000/SPA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=1000/USNO 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=1000/Walraven 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=10000/NOAA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=10000/PSA 0.039 k allocs: 1.2 kB 0.039 k allocs: 1.2 kB 1
solposx/n=10000/SPA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=10000/USNO 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=10000/Walraven 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100000/NOAA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100000/PSA 0.039 k allocs: 1.2 kB 0.039 k allocs: 1.2 kB 1
solposx/n=100000/SPA 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100000/USNO 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
solposx/n=100000/Walraven 10 allocs: 0.531 kB 10 allocs: 0.531 kB 1
time_to_load 0.149 k allocs: 11.1 kB 0.145 k allocs: 11 kB 1.02

The block test asserts the interpolant is a drop in replacement for the
wrapped SPA with both NoRefraction and DefaultRefraction, and the guide
gains a section on using Interpolated as a high accuracy forcing,
including span sizing and the :fallback recommendation inside solvers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wg3j4XXUooMvDgUpRajxTq
@langestefan

Copy link
Copy Markdown
Member Author

Added ModelingToolkit coverage in 7a0dccb: Interpolated drops into SolarPositionBlock unchanged (it is just another SolarAlgorithm parameter value), so the new testset asserts the block matches direct SPA to 1e-8 on all three outputs under both NoRefraction and DefaultRefraction, and the MTK guide gains a "High Accuracy Forcing with Interpolated" section with an executed example. Full MTK suite passes (307/307) and the docs build is clean.

The block default stays PSA(): the block cannot know the solve window at construction time (t0 is a runtime parameter), defaulting would couple the MTK extension to Interpolations.jl, and PSA is still the cheaper call. Interpolated(SPA()) is the documented opt-in for SPA accuracy at near PSA cost.

Measured against direct SPA the interpolation error crosses SPA's own
3e-4 degree accuracy between 3 and 5 day steps, so steps above 3 days
now warn at construction. The docstring lists the measured error at
several steps and the 30 day hard cap stays as the unwrap safety limit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wg3j4XXUooMvDgUpRajxTq
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (9173bd4) to head (e5eb838).

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #117   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           18        19    +1     
  Lines          683       735   +52     
=========================================
+ Hits           683       735   +52     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

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

langestefan and others added 5 commits July 28, 2026 13:06
The step now prints as 1 hour instead of 3600000 milliseconds. New
tests hit the extension missing stub through a non SPA algorithm and
the ApparentSolPos result type through the default refraction batch
path, which were the three uncovered lines.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wg3j4XXUooMvDgUpRajxTq
Adds cross references at the first prose mention of Observer, the five
algorithms, DefaultRefraction, and PSA and SPA in the new MTK section.
The README Quadmath footnote becomes a one line pointer to the
precision guide, which keeps the full explanation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wg3j4XXUooMvDgUpRajxTq
Explains that saveat controls recording rather than stepping, shows the
exact post hoc query of observed sun angles through the solution
object, and covers the two error controller failure modes with a
runnable example: sunrise and sunset from transit_sunrise_sunset as
d_discontinuities, and an insolation quadrature state that puts the
forcing in the error budget. Closes with the reference solve check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wg3j4XXUooMvDgUpRajxTq
The guide is not in a stable release yet, so the stable URL 404s in the
link checker. The dev URL resolves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wg3j4XXUooMvDgUpRajxTq
A small autodiff guide section runs the same gradient through the
ForwardDiff and finite difference backends and prints their agreement,
demonstrating that backend agnostic tooling works without any AD hooks
in the package.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wg3j4XXUooMvDgUpRajxTq
@langestefan
langestefan merged commit 00d8142 into main Jul 28, 2026
18 checks passed
@langestefan
langestefan deleted the feature/interpolated-position branch July 28, 2026 12:44
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.

1 participant