Files
rustytorch/crates/specialized/rtx-cfd/tests/polyline_index_exact.rs
T
Omar SobhandClaude Fable 5.1 01830e5c8d
CI / Test (ubuntu-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (macos-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (ubuntu-latest) (push) Blocked by required conditions
CI / WASM Build + Size Check (push) Blocked by required conditions
CI / Distributed Training Tests (push) Blocked by required conditions
CI / CI Success (push) Blocked by required conditions
CI / Build (macos-latest) (push) Waiting to run
CI / Test (macos-latest) (push) Blocked by required conditions
CI / Build CPU-Only (Explicit) (push) Failing after 5s
Documentation / Build API Documentation (push) Failing after 5s
Documentation / Build User Guide (push) Successful in 6s
CI / Format Check (push) Failing after 22s
CI / Build (ubuntu-latest) (push) Failing after 2m34s
CI / Clippy Check (push) Failing after 3m6s
Performance Benchmarks / Run Benchmarks (push) Successful in 3m47s
PERF-2 P1: exact chunked polyline index for the O-grid's sliding outer ring — PolylineIndex::nearest returns nearest_on_polyline's point bit for bit (same segments, same order, same strict minimum; chunks skipped only when their box is farther than the best by more than 1e-12 relative), used by the Winslow sweep and the two ring projections; pin: 0 mismatches over 39,864 queries on a 3,166-point rounded outline including vertices, mid-points and ties
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01YJPeT6WA2e7YvAnS875AHL
2026-09-15 23:08:09 -05:00

90 lines
3.3 KiB
Rust

//! PERF-2 P1 (`docs/perf2_campaign.md`): the chunked polyline index used
//! by the O-grid's sliding outer ring must return the brute-force scan's
//! point BIT FOR BIT — the recorded marches are gated on digit identity.
//! The polygon is the shape the ring sees: a convex hull offset sampled
//! 24 points per corner (a rounded cylinder + flag outline, ~3,000
//! points); the queries sit inside, on and outside it, and on a lattice
//! whose points fall exactly on vertices and segment mid-points (ties).
use rtx_cfd::mesh::patch_gen::{PolylineIndex, nearest_on_polyline};
use std::f64::consts::PI;
/// A rounded "cylinder + flag" convex outline: a circle of radius 0.05 at
/// the origin joined to a rectangle to x = 0.4, corners rounded with
/// radius 0.06 sampled 24 per corner, plus fine sampling on the arcs.
fn outline() -> Vec<[f64; 2]> {
let mut pts = Vec::new();
// Left semicircle (the cylinder side), 256 points.
for m in 0..256 {
let th = PI / 2.0 + PI * m as f64 / 255.0;
pts.push([0.11 * th.cos(), 0.11 * th.sin()]);
}
// Bottom edge to the tip, 1,200 points.
for m in 1..1200 {
pts.push([-0.0 + 0.46 * m as f64 / 1200.0, -0.11]);
}
// Right rounded end, 512 points.
for m in 0..512 {
let th = -PI / 2.0 + PI * m as f64 / 511.0;
pts.push([0.46 + 0.11 * th.cos(), 0.11 * th.sin()]);
}
// Top edge back, 1,200 points.
for m in 1..1200 {
pts.push([0.46 - 0.46 * m as f64 / 1200.0, 0.11]);
}
pts
}
#[test]
fn indexed_nearest_point_is_the_brute_force_point_bit_for_bit() {
let pts = outline();
let index = PolylineIndex::new(&pts);
let mut queries: Vec<[f64; 2]> = Vec::new();
// A lattice through the whole region (inside, on, outside).
for i in 0..120 {
for j in 0..60 {
queries.push([-0.2 + 0.8 * i as f64 / 119.0, -0.25 + 0.5 * j as f64 / 59.0]);
}
}
// Every vertex, every segment mid-point, and points pushed off them.
let n = pts.len();
for i in 0..n {
let (a, b) = (pts[i], pts[(i + 1) % n]);
queries.push(a);
queries.push([0.5 * (a[0] + b[0]), 0.5 * (a[1] + b[1])]);
queries.push([a[0] * 1.3, a[1] * 1.3]);
queries.push([a[0] * 0.7 + 0.01, a[1] * 0.7]);
}
// A deterministic pseudo-random cloud.
let mut state = 0x9e37_79b9_7f4a_7c15_u64;
for _ in 0..20_000 {
state ^= state << 13;
state ^= state >> 7;
state ^= state << 17;
let u = (state >> 11) as f64 / (1u64 << 53) as f64;
state ^= state << 13;
state ^= state >> 7;
state ^= state << 17;
let v = (state >> 11) as f64 / (1u64 << 53) as f64;
queries.push([-0.3 + 1.0 * u, -0.3 + 0.6 * v]);
}
let mut mismatches = 0;
for &q in &queries {
let a = nearest_on_polyline(&pts, q);
let b = index.nearest(q);
if a[0].to_bits() != b[0].to_bits() || a[1].to_bits() != b[1].to_bits() {
mismatches += 1;
if mismatches < 5 {
eprintln!("mismatch at q = {q:?}: brute {a:?} vs index {b:?}");
}
}
}
println!(
" polyline index: {} points, {} chunks tested over {} queries, {mismatches} mismatches",
pts.len(),
pts.len().div_ceil(32),
queries.len()
);
assert_eq!(mismatches, 0);
}