use scirs2_core::ndarray::{Array1, Array2};
use scirs2_interpolate::voronoi::VoronoiDiagram;
fn simplex_sites_4d() -> Array2<f64> {
#[rustfmt::skip]
let data: Vec<f64> = vec![
0.0, 0.0, 0.0, 0.0,
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
];
Array2::from_shape_vec((5, 4), data).expect("simplex_sites_4d: shape_vec failed")
}
fn hypercube_sites_4d() -> Array2<f64> {
let mut data = Vec::with_capacity(16 * 4);
for i in 0..16_usize {
data.push((i & 1) as f64);
data.push(((i >> 1) & 1) as f64);
data.push(((i >> 2) & 1) as f64);
data.push(((i >> 3) & 1) as f64);
}
Array2::from_shape_vec((16, 4), data).expect("hypercube_sites_4d: shape_vec failed")
}
#[test]
fn test_4d_simplex_voronoi_diagram_creates() {
let sites = simplex_sites_4d();
let values = Array1::from_vec(vec![1.0_f64; 5]);
let diagram = VoronoiDiagram::new(sites.view(), values.view(), None)
.expect("VoronoiDiagram::new should succeed for 4D simplex");
assert_eq!(diagram.cells.len(), 5, "Should have 5 cells");
assert_eq!(diagram.dim, 4, "Dimension should be 4");
}
#[test]
fn test_4d_simplex_cells_have_neighbours() {
let sites = simplex_sites_4d();
let values = Array1::from_vec(vec![1.0_f64; 5]);
let diagram = VoronoiDiagram::new(sites.view(), values.view(), None)
.expect("VoronoiDiagram::new should succeed");
for (i, cell) in diagram.cells.iter().enumerate() {
let neighbours = cell.neighbours_nd().expect("neighbours_nd should succeed");
assert!(
!neighbours.is_empty(),
"Cell {} should have at least one neighbour",
i
);
}
}
#[test]
fn test_4d_simplex_cells_non_negative_volume() {
let sites = simplex_sites_4d();
let values = Array1::from_vec(vec![1.0_f64; 5]);
let diagram = VoronoiDiagram::new(sites.view(), values.view(), None)
.expect("VoronoiDiagram::new should succeed");
for (i, cell) in diagram.cells.iter().enumerate() {
let vol = cell.volume_nd().expect("volume_nd should succeed");
assert!(
vol >= 0.0,
"Cell {} volume should be non-negative, got {}",
i,
vol
);
assert!(
vol.is_finite(),
"Cell {} volume should be finite, got {}",
i,
vol
);
}
}
#[test]
fn test_4d_simplex_vertices_are_4d() {
let sites = simplex_sites_4d();
let values = Array1::from_vec(vec![1.0_f64; 5]);
let diagram = VoronoiDiagram::new(sites.view(), values.view(), None)
.expect("VoronoiDiagram::new should succeed");
for cell in &diagram.cells {
let verts = cell.vertices_nd().expect("vertices_nd should succeed");
for v in &verts {
assert_eq!(v.len(), 4, "Each vertex should be 4-dimensional");
}
}
}
#[test]
#[ignore = "slow: Bowyer-Watson 4D Delaunay for 16 points measured ~83-84s consistently \
across all 6 tests in this file under load (0.6.5 ignore audit); already has a \
dedicated 600s override in .config/nextest.toml, so left ignored by default \
rather than adding ~500s to the routine test-suite run"]
fn test_4d_hypercube_voronoi_diagram_creates() {
let sites = hypercube_sites_4d();
let values = Array1::from_vec(vec![1.0_f64; 16]);
let diagram = VoronoiDiagram::new(sites.view(), values.view(), None)
.expect("VoronoiDiagram::new should succeed for 4D hypercube");
assert_eq!(diagram.cells.len(), 16, "Should have 16 cells");
assert_eq!(diagram.dim, 4, "Dimension should be 4");
}
#[test]
#[ignore = "slow: Bowyer-Watson 4D Delaunay for 16 points measured ~83-84s consistently \
across all 6 tests in this file under load (0.6.5 ignore audit); already has a \
dedicated 600s override in .config/nextest.toml, so left ignored by default \
rather than adding ~500s to the routine test-suite run"]
fn test_4d_hypercube_all_cells_have_vertices() {
let sites = hypercube_sites_4d();
let values = Array1::from_vec(vec![1.0_f64; 16]);
let diagram = VoronoiDiagram::new(sites.view(), values.view(), None)
.expect("VoronoiDiagram::new should succeed");
let mut cells_with_verts = 0;
for cell in &diagram.cells {
let verts = cell.vertices_nd().expect("vertices_nd should succeed");
if !verts.is_empty() {
cells_with_verts += 1;
for v in &verts {
assert_eq!(v.len(), 4, "Each vertex should be 4-dimensional");
}
}
}
assert!(
cells_with_verts >= 8,
"At least 8 of 16 cells should have Voronoi vertices (nD circumcentres), got {}",
cells_with_verts
);
}
#[test]
#[ignore = "slow: Bowyer-Watson 4D Delaunay for 16 points measured ~83-84s consistently \
across all 6 tests in this file under load (0.6.5 ignore audit); already has a \
dedicated 600s override in .config/nextest.toml, so left ignored by default \
rather than adding ~500s to the routine test-suite run"]
fn test_4d_hypercube_all_cells_have_non_negative_volume() {
let sites = hypercube_sites_4d();
let values = Array1::from_vec(vec![1.0_f64; 16]);
let diagram = VoronoiDiagram::new(sites.view(), values.view(), None)
.expect("VoronoiDiagram::new should succeed");
for (i, cell) in diagram.cells.iter().enumerate() {
let vol = cell.volume_nd().expect("volume_nd should succeed");
assert!(
vol >= 0.0,
"Cell {} volume should be non-negative, got {}",
i,
vol
);
assert!(
vol.is_finite(),
"Cell {} volume should be finite, got {}",
i,
vol
);
}
}
#[test]
#[ignore = "slow: Bowyer-Watson 4D Delaunay for 16 points measured ~83-84s consistently \
across all 6 tests in this file under load (0.6.5 ignore audit); already has a \
dedicated 600s override in .config/nextest.toml, so left ignored by default \
rather than adding ~500s to the routine test-suite run"]
fn test_4d_hypercube_cell_volume_within_range() {
let sites = hypercube_sites_4d();
let values = Array1::from_vec(vec![1.0_f64; 16]);
let diagram = VoronoiDiagram::new(sites.view(), values.view(), None)
.expect("VoronoiDiagram::new should succeed");
for (i, cell) in diagram.cells.iter().enumerate() {
let vol = cell.volume_nd().expect("volume_nd should succeed");
assert!(
vol >= 0.0,
"Cell {} volume should be non-negative, got {}",
i,
vol
);
if vol > 0.0 {
assert!(vol < 100.0, "Cell {} volume too large: {}", i, vol);
}
}
}
#[test]
#[ignore = "slow: Bowyer-Watson 4D Delaunay for 16 points measured ~83-84s consistently \
across all 6 tests in this file under load (0.6.5 ignore audit); already has a \
dedicated 600s override in .config/nextest.toml, so left ignored by default \
rather than adding ~500s to the routine test-suite run"]
fn test_4d_hypercube_cells_have_neighbours() {
let sites = hypercube_sites_4d();
let values = Array1::from_vec(vec![1.0_f64; 16]);
let diagram = VoronoiDiagram::new(sites.view(), values.view(), None)
.expect("VoronoiDiagram::new should succeed");
for (i, cell) in diagram.cells.iter().enumerate() {
let neighbours = cell.neighbours_nd().expect("neighbours_nd should succeed");
assert!(!neighbours.is_empty(), "Cell {} should have neighbours", i);
}
}
#[test]
#[ignore = "slow: Bowyer-Watson 4D Delaunay for 16 points measured ~83-84s consistently \
across all 6 tests in this file under load (0.6.5 ignore audit); already has a \
dedicated 600s override in .config/nextest.toml, so left ignored by default \
rather than adding ~500s to the routine test-suite run"]
fn test_4d_hypercube_individual_cell_volume_approx() {
let sites = hypercube_sites_4d();
let values = Array1::from_vec(vec![1.0_f64; 16]);
let diagram = VoronoiDiagram::new(sites.view(), values.view(), None)
.expect("VoronoiDiagram::new should succeed");
let expected_volume = 1.0_f64 / 16.0;
let tolerance = 1e-4_f64;
let mut failed = 0;
for (i, cell) in diagram.cells.iter().enumerate() {
let vol = cell.volume_nd().expect("volume_nd should succeed");
if vol > 0.0 {
let diff = (vol - expected_volume).abs();
if diff > tolerance {
eprintln!(
"Cell {} volume = {:.8}, expected = {:.8}, diff = {:.8e}",
i, vol, expected_volume, diff
);
failed += 1;
}
}
}
let cells_with_vertices = diagram
.cells
.iter()
.filter(|c| c.volume_nd().unwrap_or(0.0) > 0.0)
.count();
if cells_with_vertices > 0 {
assert!(
failed <= cells_with_vertices / 2,
"Too many cells with inaccurate volumes: {} out of {}",
failed,
cells_with_vertices
);
}
}