merge integration

This commit is contained in:
jess 2026-03-31 13:22:13 -07:00
commit 59819cf1af
4 changed files with 18 additions and 91 deletions

View File

@ -104,8 +104,6 @@ fn merge_planes_into_boxes(
let d2 = axis.dot(*p2);
let half = (d1 - d2).abs() / 2.0;
if half > 1e-6 {
let center_along_axis = (d1 + d2) / 2.0;
let _ = center_along_axis;
pairs.push((ia, ib, axis, half));
used[ia] = true;
used[ib] = true;
@ -236,18 +234,18 @@ fn align_box_axes(
Vec3::new(0.0, 0.0, 1.0),
];
// Assign each detected axis to the closest canonical axis
let mut assignment = [0usize; 3];
let mut assigned = [false; 3];
let mut src_used = [false; 3];
let mut dst_used = [false; 3];
for pass in 0..3 {
for _ in 0..3 {
let mut best_dot = 0.0f64;
let mut best_src = 0;
let mut best_dst = 0;
for src in 0..3 {
if assignment[src] != 0 && pass > 0 { continue; }
if src_used[src] { continue; }
for dst in 0..3 {
if assigned[dst] { continue; }
if dst_used[dst] { continue; }
let d = axes[src].dot(canonical[dst]).abs();
if d > best_dot {
best_dot = d;
@ -257,8 +255,8 @@ fn align_box_axes(
}
}
assignment[best_src] = best_dst;
assigned[best_dst] = true;
let _ = pass;
src_used[best_src] = true;
dst_used[best_dst] = true;
}
let mut ordered = [0.0; 3];

View File

@ -120,7 +120,8 @@ impl TrigGraph {
TrigOp::Add(_, _) | TrigOp::Sub(_, _) | TrigOp::Neg(_)
| TrigOp::Abs(_) | TrigOp::Min(_, _) | TrigOp::Max(_, _)
| TrigOp::Clamp { .. } => cost.binary += 1,
_ => {}
TrigOp::InputX | TrigOp::InputY | TrigOp::InputZ
| TrigOp::Const(_) => {}
}
}
cost

View File

@ -1,5 +1,5 @@
use crate::ir::{NodeId, TrigGraph, TrigOp};
use std::collections::{HashMap, HashSet};
use std::collections::HashSet;
/// Optimize a TrigGraph in-place.
///
@ -53,7 +53,7 @@ fn constant_fold(graph: &mut TrigGraph) {
_ => None,
}
}
_ => None,
TrigOp::InputX | TrigOp::InputY | TrigOp::InputZ => None,
};
if let Some(c) = val {
@ -96,28 +96,9 @@ fn fold2(values: &[Option<f64>], a: NodeId, b: NodeId, f: fn(f64, f64) -> f64) -
// for the cost model and leave the graph structure intact. The CORDIC
// compiler already recognizes shared-angle patterns.
fn fuse_sincos_pairs(graph: &mut TrigGraph) {
let mut sin_of: HashMap<NodeId, NodeId> = HashMap::new();
let mut cos_of: HashMap<NodeId, NodeId> = HashMap::new();
for (i, op) in graph.nodes.iter().enumerate() {
match op {
TrigOp::Sin(a) => { sin_of.insert(*a, i as NodeId); }
TrigOp::Cos(a) => { cos_of.insert(*a, i as NodeId); }
_ => {}
}
}
// Count fused pairs (both sin and cos of same angle exist)
let _fused: Vec<(NodeId, NodeId)> = sin_of.iter()
.filter_map(|(angle, sin_id)| {
cos_of.get(angle).map(|cos_id| (*sin_id, *cos_id))
})
.collect();
// The CORDIC compiler handles fusion; this pass is a no-op for now
// but validates that pairs exist. Future: rewrite to a fused op.
}
// Sin/cos pair fusion: placeholder for future CORDIC fused-op rewriting.
// The CORDIC compiler already recognizes shared-angle patterns.
fn fuse_sincos_pairs(_graph: &mut TrigGraph) {}
// === Pass 3: Dead node elimination ===

View File

@ -108,15 +108,9 @@ fn traverse_sequential(graph: &TrigGraph, bounds: &EvalBounds) -> EvalResult {
fn traverse_parallel_mesh(
graph: &TrigGraph,
bounds: &EvalBounds,
divisions: usize,
overlap: f64,
_divisions: usize,
_overlap: f64,
) -> EvalResult {
let center = [
(bounds.min[0] + bounds.max[0]) * 0.5,
(bounds.min[1] + bounds.max[1]) * 0.5,
(bounds.min[2] + bounds.max[2]) * 0.5,
];
let res = bounds.resolution;
let step = [
(bounds.max[0] - bounds.min[0]) / (res - 1).max(1) as f64,
@ -124,11 +118,6 @@ fn traverse_parallel_mesh(
(bounds.max[2] - bounds.min[2]) / (res - 1).max(1) as f64,
];
// Sector boundaries in spherical angles
let theta_step = PI / divisions as f64;
let phi_step = 2.0 * PI / divisions as f64;
let _overlap_angle = overlap * theta_step;
let mut values = Vec::with_capacity(res * res * res);
for iz in 0..res {
@ -138,39 +127,8 @@ fn traverse_parallel_mesh(
for ix in 0..res {
let x = bounds.min[0] + ix as f64 * step[0];
let dx = x - center[0];
let dy = y - center[1];
let dz = z - center[2];
let r = (dx * dx + dy * dy + dz * dz).sqrt();
let val = evaluate(graph, x, y, z);
if r < 1e-10 {
values.push(SpatialSample { position: [x, y, z], value: val });
continue;
}
let theta = (dz / r).acos();
let phi = dy.atan2(dx) + PI;
// Determine which sector this point is in
let sector_t = (theta / theta_step).floor() as usize;
let sector_p = (phi / phi_step).floor() as usize;
// Overlap zone blending
let t_frac = theta / theta_step - sector_t as f64;
let p_frac = phi / phi_step - sector_p as f64;
let t_blend = if t_frac < overlap { t_frac / overlap }
else if t_frac > (1.0 - overlap) { (1.0 - t_frac) / overlap }
else { 1.0 };
let p_blend = if p_frac < overlap { p_frac / overlap }
else if p_frac > (1.0 - overlap) { (1.0 - p_frac) / overlap }
else { 1.0 };
let blend = t_blend.min(1.0) * p_blend.min(1.0);
let _ = (sector_t, sector_p, blend); // Sector info for parallel dispatch
// TODO: sector assignment + blend weights for actual parallel dispatch
values.push(SpatialSample { position: [x, y, z], value: val });
}
}
@ -216,8 +174,6 @@ fn traverse_spherical(
continue;
}
// Angular samples scale with r² (surface area of the shell)
let shell_area = 4.0 * PI * r * r;
let angular_samples = (base_angular_samples as f64 * t * t).max(6.0) as usize;
// Fibonacci sphere sampling for uniform angular distribution
@ -237,18 +193,9 @@ fn traverse_spherical(
volume_count += 1;
}
// Convergence check: RMS of volume vs surface area of current shell
let rms = (volume_sum_sq / volume_count as f64).sqrt();
// Normalize both to comparable scales:
// RMS is in distance units, surface area is in distance² units.
// Compare RMS * r (information density scaled by radius)
// against shell_area / (4π) = r² (normalized surface area).
// Convergence when: rms * r >= r² → rms >= r
// Meaning: the average signal strength exceeds the current radius.
// More precisely: the information captured exceeds what the boundary can add.
let volume_metric = rms * r;
let surface_metric = shell_area / (4.0 * PI); // = r²
let surface_metric = r * r;
if volume_metric >= surface_metric && ri > radial_steps / 4 {
convergence_radius = r;