Repository navigation
feat: add stable unsigned vector angles - #274
Conversation
- Add allocation-free borrowed-slice and fixed-vector angle APIs with typed shape, zero-vector, and non-finite operand errors. - Preserve extreme scales and tiny separations with power-of-two scaling, compensated exterior products, and full-angle atan2 evaluation. - Add independent numerical regressions and properties, allocation checks, stable benchmark comparisons, and retained measurement provenance. - Document rounded semantics and the quadratic-time, constant-space tradeoff. - Permit Git mutations in agent guidance when explicitly approved by the user. - Validate with full just ci: 955 Rust tests, 502 Python tests, default/exact doctests, lint checks, benchmark compilation, and examples. Refs #249
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
⛔ Files ignored due to path filters (3)
📒 Files selected for processing (16)
🚧 Files skipped from review as they are similar to previous changes (6)
Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour. 📝 WalkthroughWalkthroughThe change adds unsigned-angle calculation for borrowed slices and fixed-size vectors, with typed validation errors and a scaled numerical kernel. It adds correctness tests, benchmark fixtures and comparisons, performance-study records, and API documentation. Repository guidance for version-control operations also changes. ChangesUnsigned vector angles
Version-control guidance
Priority: ➖ Normal Estimated code review effort: 4 (Complex) | ~45 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant Caller
participant VectorAngle
participant Vector
participant angle_kernel
Caller->>VectorAngle: pass borrowed coordinate slices
VectorAngle->>angle_kernel: validate and calculate angle
Caller->>Vector: pass fixed-size vectors
Vector->>angle_kernel: calculate angle from finite vectors
angle_kernel-->>Caller: return angle or error
Merge Risk: ⚪ Minimal · up to No identified issue blocks the unsigned-angle change from merging after normal checks. 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #274 +/- ##
==========================================
- Coverage 98.13% 98.12% -0.01%
==========================================
Files 13 14 +1
Lines 6966 7112 +146
==========================================
+ Hits 6836 6979 +143
- Misses 130 133 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
- Use the direct exterior/dot ratio for sufficiently small positive angles, with a documented arctangent approximation bound, avoiding platform atan2 underflow observed by the Windows CI regression tests. - Test the small-angle transition and normal/subnormal boundary across dimensions 2 through 6, 8, and 64 without relaxing existing tiny-angle tests. - Verify that exact-conversion error formatting propagates writer failures. - Retain the defensive non-finite-result guard without artificial coverage tests, exclusions, or coverage-threshold changes. - Refresh all 80 benchmark records and retain the original measurements by commit for a documented before/after comparison. - Validate with just check, just coverage-ci (876 tests), and isolated just ci (963 Rust tests, 502 Python tests, doctests, lints, benchmarks, and examples). Refs #249
- Replace the unreleased angle_between function with VectorAngle::angle on coordinate slices, retaining Vector::angle and root/prelude exports. - Require validated Vector inputs at the internal finite-angle boundary. - Expand independent rational-reference and typed error-path coverage. - Replace the angle benchmark study with fresh measurements and provenance for the extension API, and update API documentation and examples. - Refresh locked Rust/Python dependencies and the cargo-nextest tool pin. Refs #249
Implements the API and validation work for #249 against the completed Rust 1.99 / LLVM 23 baseline from #251.
angle_between(&[f64], &[f64])andVector::angle(&self, &other)compute allocation-free unsigned angles in radians for arbitrary finite nonzero vectors. Shape, empty/zero input, and non-finite coordinate errors retain typed operand and index context. Both entry points share the numerical kernel; fixed-size vectors reuse their finite-storage invariant.The kernel uses power-of-two scaling, compensated exterior minors, a compensated dot reduction, and
atan2. For positive dot products and exterior/dot ratios at most2^-27, it returns the ratio directly, with the arctangent approximation error bounded below half an ulp. This avoids the subnormalatan2failures observed by Windows CI. This preserves the least positive subnormal angle and nearly proportional directions whose normalized coordinates would become identical. It accepts overflowing input norms and arbitrary ambient lengths. The documented tradeoff is quadratic work with constant storage; results are rounded, without a certified error bound or correct-rounding claim.Independent analytical, integer planar cross/dot, and integer Gram-determinant tests cover lengths 0, 1, 2–6, 8, and 64; identical, parallel, antipodal, nearly parallel/antipodal, mixed-scale, subnormal, signed-zero, invalid, rescaling, and allocation cases are included. A 3–6 dimensional Criterion suite compares a valid stable Kahan control, prepared vectors, borrowed slices, and construction-inclusive calls. All 80 measurements, confidence intervals, and source provenance are retained in
docs/archive/performance/studies/vector-angles.mdand its sidecars.Validation used
just checkduring iteration.just markdown-fix,just markdown-ci, and finaljust cipassed. Final CI ran 963 Rust tests and 502 Python tests, default/exact doctests, all-target Clippy, static/configuration checks, benchmark compilation, and examples. Focused numerical and benchmark-input tests passed before timing. Benchmarks used Rust 1.99.0 / LLVM 23.1.1 on an Apple M4 Max, with 50 samples, 1-second warmup, and 2-second measurement targets.A coverage audit of run 37801925568, generated from
09020aa18a2b233831a8975b343095d2de1670eb, found 96.875% patch coverage against the configured 90% target (2% tolerance). Added tests cover formatter write-failure propagation and the small-angle/normal-subnormal transitions. Localjust coverage-cipassed all 876 tests and estimates 97.92% patch line coverage; only the three defensive non-finite-result lines remain uncovered. No coverage exclusions or thresholds were changed. The XML does not collect branch coverage. Finaljust cipassed in an isolated checkout with the PR's committed dependencies, avoiding concurrent dependency edits in the main checkout.Agent guidance now permits Git mutations with explicit user approval, limited to the approved operations and task.
Package versions remain 0.4.6. Publishing v0.4.7 and downstream Delaunay adoption are separate maintainer steps; this draft does not perform either.
Summary by CodeRabbit