-
Notifications
You must be signed in to change notification settings - Fork 0
Comparing changes
Open a pull request
base repository: PecaWolf/LoopAlgorithm
base: main
head repository: tidepool-org/LoopAlgorithm
compare: main
- 8 commits
- 16 files changed
- 7 contributors
Commits on Mar 11, 2026
-
Configuration menu - View commit details
-
Copy full SHA for 9e1ff9b - Browse repository at this point
Copy the full SHA 9e1ff9bView commit details -
Configuration menu - View commit details
-
Copy full SHA for 07afc01 - Browse repository at this point
Copy the full SHA 07afc01View commit details
Commits on Mar 25, 2026
-
Configuration menu - View commit details
-
Copy full SHA for 1816673 - Browse repository at this point
Copy the full SHA 1816673View commit details -
Merge pull request tidepool-org#27 from tidepool-org/pd/NEMO-254/meal…
…_bolus_no_isf_test Pd/nemo 254/meal bolus no isf test
Configuration menu - View commit details
-
Copy full SHA for bd1a879 - Browse repository at this point
Copy the full SHA bd1a879View commit details
Commits on May 21, 2026
-
Make decayEffect a continuous function of sample timestamp (tidepool-…
…org#33) * Make decayEffect a continuous function of sample timestamp Reformulates decayEffect using a closed-form quadratic in time-since-sample rather than accumulating step-by-step from the floored simulation boundary. This makes the effect value at any future absolute timestamp independent of which delta-sized simulation bucket the sample's startDate falls into. For samples aligned to delta boundaries the two formulations are mathematically identical. For unaligned samples (the common case with real CGM streams) the new formulation removes a small discontinuity that the old code exhibited at bucket boundaries. Adds LoopMathTests covering continuity across a delta boundary. Existing fixture-calibrated tests are re-pinned to the new values; per-prediction drift is on the order of 0.1 mg/dL. Ports the LoopMath change from LoopKit/LoopKit#556 by Moti Nisenson-Ken to the LoopAlgorithm package, where decayEffect now lives. * Space to kick off tests --------- Co-authored-by: Pete Schwamb <pete@pete-mbp-eth.maplect.net>
Configuration menu - View commit details
-
Copy full SHA for b05f72b - Browse repository at this point
Copy the full SHA b05f72bView commit details -
Add unit tests for StandardRetrospectiveCorrection (tidepool-org#32)
StandardRetrospectiveCorrection (the P-only retrospective correction controller) had no dedicated unit tests — its behavior was only covered transitively via the higher-level LoopAlgorithm tests. Adds 9 tests covering: - Recency gating: stale / nil / empty discrepancy lists clear the correction and return empty. - Total correction effect equals the latest (most-recent) discrepancy magnitude (Standard is P-only on .last). - Positive / negative discrepancies project glucose forward in the expected direction, with the last sample ≈ starting + discrepancy. - The first effect sample equals the starting glucose value at the starting date (correction hasn't yet had time to apply). - Only the latest discrepancy contributes — older entries are ignored (the key behavioral difference vs IntegralRC, which integrates them). - Short discrepancies are clamped to retrospectiveCorrectionGroupingInterval to prevent over-amplified velocity from very short windows. These tests will serve as a backstop while the active-insulin / EGP decomposition work modifies the glucose-effect computation upstream of the RC discrepancy calculation. Co-authored-by: LoopKit Developer <dev@loopkit.org>
Configuration menu - View commit details
-
Copy full SHA for a1d0e57 - Browse repository at this point
Copy the full SHA a1d0e57View commit details -
Faster filterDateRange via binary search (tidepool-org#31)
SampleValue.swift: add a filterDateRange overload for RandomAccessCollection where Element: TimelineValue, Index == Int. Returns the same result as the existing Sequence-based linear-filter implementation but uses two binary searches instead of a linear scan. Picks up automatically for Array-backed callers (which is every caller in this codebase via Swift protocol dispatch). Significant speedup for hot paths that call filterDateRange repeatedly on long schedules — for example, InsulinMath.glucoseEffectsMidAbsorptionISF and DoseMath.insulinCorrection when the sensitivity schedule has many segments. In a LoopEval 60-day per-step prediction sweep with a per-step ISF schedule, total sim wall-clock went from ~30 min to ~1 min (≈30× faster) with bit-identical output to the linear-filter path. Tests: FilterDateRangeTests.swift with 11 cases covering equivalence with the linear-filter reference: boundary cases (empty, both bounds nil, only start, only end), start-before-all, end-after-all, fully- outside, single-sample collections, exact-match-one-segment, and a 100-iteration randomized fuzz over a 200-element contiguous schedule.
Configuration menu - View commit details
-
Copy full SHA for 729e508 - Browse repository at this point
Copy the full SHA 729e508View commit details -
Add PrecomputedInsulinInput for efficient multi-step prediction sweep…
…s + parallelize glucose-effects (tidepool-org#29) * Add PrecomputedInsulinInput for efficient multi-step prediction sweeps Introduces PrecomputedInsulinInput and a new generatePrediction overload that accepts pre-annotated dose data, enabling significant speedups for historical back-testing / evaluation sweeps. The key bottleneck in a dense prediction sweep is doses.annotated(with: basal), which is O(doses × basalSegments) and was called from scratch at every step. Between adjacent 5-min steps the dose list changes only at its edges; the annotation of every dose in the middle is identical. Changes: - Sources/LoopAlgorithm/Insulin/PrecomputedInsulinInput.swift (new) PrecomputedInsulinInput struct holding pre-annotated doses and an optional pre-built insulinEffects timeline. Includes a convenience .build() factory. - Sources/LoopAlgorithm/LoopAlgorithm.swift New generatePrediction(start:glucoseHistory:precomputedInsulin:carbEntries: sensitivity:carbRatio:...) overload. Skips annotated(with:) entirely; optionally skips glucoseEffects() when insulinEffects is pre-supplied. - Sources/LoopAlgorithm/Glucose/GlucoseEffect.swift Add Sendable conformance (struct with value-type fields, safe). - Tests/LoopAlgorithmTests/PrecomputedInsulinInputTests.swift (new) 3 tests verifying the new overload produces output matching the standard path (bit-identical for annotation-only, count-identical + clinically equivalent for pre-built effects). Expected speedup for a 7-day sweep at 5-min step (~2016 calls): annotation bypass alone: ~40-60% wall-clock reduction + effects cache (fixed ISF): additional ~20-30% * Refactor PrecomputedInsulinInput for explicit ISF-sweep pattern Split the API into two explicit steps so ISF sweeps pay annotation cost exactly once across all multipliers: annotate(doses:basal:) → ISF-independent, build once .withEffects(sensitivity:from:to:) → ISF-dependent, once per multiplier Correct ISF sweep pattern: let base = PrecomputedInsulinInput.annotate(doses: doses, basal: basal) for multiplier in isfMultipliers { let input = base.withEffects(sensitivity: scale(sensitivity, by: multiplier)) // run ~2016 steps with input — no annotation, no per-step glucoseEffects } Cost breakdown for 10-multiplier × 7-day sweep (n≈2016 steps each): Before: annotated(with:) + glucoseEffects() called 20160× each After: annotated(with:) called 1×, glucoseEffects() called 10× Also adds testISFSweepPattern verifying bit-identical output across multipliers [0.7, 0.8, ..., 1.3] vs the standard generatePrediction path. * Add sliced(from:to:) for per-step dose window slicing Enables EvalCore to slice pre-annotated doses to the per-step lookback window without re-annotating. Uses binary search on startDate + linear filter on endDate (arrays are ~100-200 entries, linear endDate scan is negligible). Also cleans up the unused private partition helper (now only used by sliced). * Expose dose-recommendation internals as public API Downstream callers (LoopEval bench engine) need to compute dose recommendations from a forecast without going through the full run() API, which re-computes insulin effects. Making insulinCorrection, recommendTempBasal, and recommendAutomaticDose public lets them do that efficiently using already-computed predictions. Enables delivery-based ODR/UDR metrics in LoopEval that compare the actual insulin Loop would deliver across two configurations. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Parallelize glucose-effects accumulation in InsulinMath Replace the sequential reduce loop with DispatchQueue.concurrentPerform over per-step increments, then a final cumsum. Per-step contributions are independent until the final summation, so this scales with available cores. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore: carry forward momentumVelocityMaximum param from eval/precomputed-insulin-effects --------- Co-authored-by: Bot <bot@macmini.maplect.net> Co-authored-by: LoopKit Developer <dev@loopkit.org> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 6e4e315 - Browse repository at this point
Copy the full SHA 6e4e315View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff main...main