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
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
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
Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01YJPeT6WA2e7YvAnS875AHL
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
11f71b832c
commit
01830e5c8d
@@ -0,0 +1,89 @@
|
||||
//! 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);
|
||||
}
|
||||
Reference in New Issue
Block a user