LJdacnMXkr / evidence /code /claim5_jaw.py
DineshAI's picture
Publish cumulative Sinkhorn reproduction evidence
5338e3e verified
Raw
History Blame Contribute Delete
13.3 kB
"""Faithful sparse-jaw diffusion experiment for Claim 5.
The paper does not identify or release the jaw volume shown in Figure 1. This
module therefore uses the independently published OpenMandible cortical-bone
model. The source is commit- and hash-pinned, and the substitution is recorded
as a limitation instead of being presented as the authors' original scan.
"""
from __future__ import annotations
import hashlib
import math
import time
import urllib.request
from collections import deque
from typing import Callable
import numpy as np
from scipy.ndimage import gaussian_filter
from scipy.sparse.linalg import LinearOperator, eigsh
from armadillo import USER_AGENT, _normalize_to_unit_ball, _sample_surface
def _download(spec: dict) -> tuple[bytes, dict]:
request = urllib.request.Request(
spec["url"], headers={"User-Agent": USER_AGENT}
)
with urllib.request.urlopen(request, timeout=180) as response:
payload = response.read()
observed = hashlib.sha256(payload).hexdigest()
if observed != spec["sha256"]:
raise RuntimeError(
"OpenMandible hash mismatch: "
f"expected {spec['sha256']}, got {observed}"
)
return payload, {
"dataset": spec["dataset"],
"dataset_paper_doi": spec["dataset_paper_doi"],
"repository": spec["repository"],
"commit": spec["commit"],
"url": spec["url"],
"sha256": observed,
"bytes": len(payload),
"retrieval_user_agent": USER_AGENT,
}
def _parse_ascii_stl(payload: bytes) -> tuple[np.ndarray, np.ndarray, dict]:
coordinates: list[list[float]] = []
for raw_line in payload.splitlines():
fields = raw_line.split()
if fields and fields[0] == b"vertex":
if len(fields) != 4:
raise RuntimeError("malformed OpenMandible STL vertex")
coordinates.append(
[float(fields[1]), float(fields[2]), float(fields[3])]
)
vertices = np.asarray(coordinates, dtype=np.float64)
if vertices.shape[0] == 0 or vertices.shape[0] % 3:
raise RuntimeError("OpenMandible STL is not an all-triangle mesh")
faces = np.arange(vertices.shape[0], dtype=np.int64).reshape(-1, 3)
triangles = vertices[faces]
doubled_area = np.linalg.norm(
np.cross(
triangles[:, 1] - triangles[:, 0],
triangles[:, 2] - triangles[:, 0],
),
axis=1,
)
if np.any(doubled_area <= 0.0):
raise RuntimeError("OpenMandible STL contains degenerate triangles")
return vertices, faces, {
"format": "ASCII STL",
"triangle_count": int(faces.shape[0]),
"vertex_records": int(vertices.shape[0]),
"all_triangles": True,
"degenerate_triangles": 0,
}
def _sparse_surface_voxels(
vertices: np.ndarray,
faces: np.ndarray,
edge: float,
sample_count: int,
seed: int,
) -> tuple[np.ndarray, np.ndarray, dict]:
samples, sampling = _sample_surface(
vertices, faces, sample_count, seed
)
grid_size = int(round(2.0 / edge))
indices = np.floor((samples + 1.0) / edge).astype(np.int64)
indices = np.clip(indices, 0, grid_size - 1)
indices = np.unique(indices, axis=0)
centers = -1.0 + edge * (indices.astype(np.float64) + 0.5)
return indices, centers, {
**sampling,
"representation": "sparse regular-grid surface voxels",
"grid_shape": [grid_size, grid_size, grid_size],
"voxel_edge": float(edge),
"nonempty_voxels": int(indices.shape[0]),
"occupancy_fraction": float(indices.shape[0] / grid_size**3),
"index_extent": (
indices.max(axis=0) - indices.min(axis=0) + 1
).tolist(),
}
def _largest_component_fraction(indices: np.ndarray) -> float:
lookup = {tuple(int(value) for value in row) for row in indices}
remaining = set(lookup)
largest = 0
offsets = (
(1, 0, 0),
(-1, 0, 0),
(0, 1, 0),
(0, -1, 0),
(0, 0, 1),
(0, 0, -1),
)
while remaining:
root = remaining.pop()
queue: deque[tuple[int, int, int]] = deque([root])
size = 0
while queue:
current = queue.popleft()
size += 1
for offset in offsets:
neighbor = (
current[0] + offset[0],
current[1] + offset[1],
current[2] + offset[2],
)
if neighbor in remaining:
remaining.remove(neighbor)
queue.append(neighbor)
largest = max(largest, size)
return float(largest / max(indices.shape[0], 1))
def _voxel_gaussian_operator(
indices: np.ndarray,
grid_size: int,
sigma_grid: float,
truncate: float,
) -> Callable[[np.ndarray], np.ndarray]:
workspace = np.zeros(
(grid_size, grid_size, grid_size), dtype=np.float64
)
def matvec(vector: np.ndarray) -> np.ndarray:
workspace.fill(0.0)
workspace[indices[:, 0], indices[:, 1], indices[:, 2]] = vector
convolved = gaussian_filter(
workspace,
sigma=sigma_grid,
mode="constant",
cval=0.0,
truncate=truncate,
)
return convolved[
indices[:, 0], indices[:, 1], indices[:, 2]
]
return matvec
def _sinkhorn(
kernel_matvec: Callable[[np.ndarray], np.ndarray],
weights: np.ndarray,
) -> tuple[np.ndarray, list[float], int, float]:
scaling = np.ones(weights.shape[0], dtype=np.float64)
curve: list[float] = []
threshold_iteration = -1
residual_max = math.inf
for iteration in range(1, 301):
kernel_scaled = kernel_matvec(weights * scaling)
row_values = scaling * kernel_scaled
mean_error = float(np.sum(weights * np.abs(row_values - 1.0)))
curve.append(mean_error)
if threshold_iteration < 0 and mean_error < 1e-3:
threshold_iteration = iteration
residual_max = float(np.max(np.abs(row_values - 1.0)))
if residual_max < 1e-12:
return scaling, curve, threshold_iteration, residual_max
scaling = np.sqrt(
scaling / np.maximum(kernel_scaled, 1e-300)
)
raise RuntimeError(
f"OpenMandible Sinkhorn did not converge: {residual_max}"
)
def _record_diffusion(
indices: np.ndarray,
centers: np.ndarray,
weights: np.ndarray,
kernel_matvec: Callable[[np.ndarray], np.ndarray],
scaling: np.ndarray,
steps: list[int],
normalization: str,
) -> dict:
def apply(signal: np.ndarray) -> np.ndarray:
return scaling * kernel_matvec(weights * scaling * signal)
row_values = apply(np.ones(weights.shape[0], dtype=np.float64))
source_index = int(np.argmin(centers[:, 0]))
source = centers[source_index]
signal = np.zeros(weights.shape[0], dtype=np.float64)
signal[source_index] = 1.0 / weights[source_index]
snapshots: list[dict] = []
maximum_step = max(steps)
for step in range(maximum_step + 1):
if step in steps:
next_signal = apply(signal)
constant = float(np.sum(weights * signal))
centered_signal = signal - constant
q_roughness = float(
np.sum(weights * signal * (signal - next_signal))
)
weighted_l2_from_constant = float(
np.sum(weights * centered_signal**2)
)
spatial_second_moment = float(
np.sum(
weights
* np.maximum(signal, 0.0)
* np.sum((centers - source) ** 2, axis=1)
)
)
snapshots.append(
{
"step": step,
"mass": constant,
"minimum": float(signal.min()),
"maximum": float(signal.max()),
"q_roughness": q_roughness,
"weighted_l2_from_constant": (
weighted_l2_from_constant
),
"spatial_second_moment": spatial_second_moment,
"signal": signal.tolist(),
}
)
if step < maximum_step:
signal = apply(signal)
diagonal = np.sqrt(weights) * scaling
symmetric_operator = LinearOperator(
(weights.shape[0], weights.shape[0]),
matvec=lambda vector: diagonal
* kernel_matvec(diagonal * vector),
rmatvec=lambda vector: diagonal
* kernel_matvec(diagonal * vector),
dtype=np.float64,
)
largest = eigsh(
symmetric_operator,
k=6,
which="LA",
return_eigenvectors=False,
tol=2e-9,
maxiter=1_000,
)
smallest = eigsh(
symmetric_operator,
k=3,
which="SA",
return_eigenvectors=False,
tol=2e-9,
maxiter=1_000,
)
return {
"normalization": normalization,
"source_index": source_index,
"source_voxel_index": indices[source_index].tolist(),
"row_residual_max": float(np.max(np.abs(row_values - 1.0))),
"constant_preservation_max_error": float(
np.max(np.abs(row_values - 1.0))
),
"largest_symmetric_eigenvalues": np.sort(largest)[::-1].tolist(),
"smallest_symmetric_eigenvalues": np.sort(smallest).tolist(),
"snapshots": snapshots,
}
def run_claim5_jaw(config: dict, spectral_result: dict) -> tuple[dict, dict]:
spec = config["claim5_jaw"]
start = time.perf_counter()
payload, source = _download(spec)
vertices, faces, mesh = _parse_ascii_stl(payload)
vertices, normalization = _normalize_to_unit_ball(vertices)
indices, centers, voxelization = _sparse_surface_voxels(
vertices,
faces,
float(spec["voxel_edge"]),
int(spec["surface_sample_count"]),
int(spec["seed"]),
)
voxelization["largest_6_connected_component_fraction"] = (
_largest_component_fraction(indices)
)
grid_size = int(round(2.0 / float(spec["voxel_edge"])))
sigma_grid = float(spec["kernel_sigma"]) / float(spec["voxel_edge"])
truncate = float(spec["gaussian_truncate_sigma"])
kernel_matvec = _voxel_gaussian_operator(
indices, grid_size, sigma_grid, truncate
)
weights = np.full(indices.shape[0], 1.0 / indices.shape[0])
scaling, curve, threshold_iteration, residual = _sinkhorn(
kernel_matvec, weights
)
steps = [int(value) for value in spec["diffusion_steps"]]
sinkhorn_record = _record_diffusion(
indices,
centers,
weights,
kernel_matvec,
scaling,
steps,
"symmetric Sinkhorn",
)
sinkhorn_record.update(
{
"sinkhorn_curve": curve,
"sinkhorn_iterations": len(curve),
"sinkhorn_iterations_to_1e-3": threshold_iteration,
"sinkhorn_residual_max": residual,
}
)
raw_record = _record_diffusion(
indices,
centers,
weights,
kernel_matvec,
np.ones_like(weights),
steps,
"raw unnormalized Gaussian",
)
modalities = spectral_result["modalities"]
cross_modalities = {
"point_cloud": modalities["point_5000"],
"covariance_aware_gmm": modalities["gmm_500"],
"sparse_armadillo_voxels": modalities["surface_voxels"],
}
common = {
"claim_id": 5,
"source_statement": (
"The method is demonstrated on point clouds, sparse voxel "
"grids (jaw bone geometry), and Gaussian mixture models with "
"covariance-aware kernels, showing Laplacian-like smoothing."
),
"paper_source_anchor": "Figure 1, Figure 3, Sections 5-6, Eq.6",
"jaw_source": source,
"jaw_source_substitution": (
"OpenMandible cortical bone replaces the paper's unidentified "
"and unreleased jaw scan; it is not claimed to be the same scan."
),
"mesh": mesh,
"normalization": normalization,
"voxelization": voxelization,
"voxel_indices": indices.tolist(),
"weights": weights.tolist(),
"kernel": {
"type": "matrix-free separable Gaussian convolution",
"physical_sigma": float(spec["kernel_sigma"]),
"sigma_grid_cells": sigma_grid,
"truncate_sigma": truncate,
"maximum_omitted_axis_weight": float(
math.exp(-0.5 * truncate**2)
),
},
"cross_modalities": cross_modalities,
"runtime_seconds": time.perf_counter() - start,
"seed": int(spec["seed"]),
}
actual = {
**common,
"scaling": scaling.tolist(),
"diffusion": sinkhorn_record,
}
negative = {
**common,
"scaling": np.ones_like(weights).tolist(),
"diffusion": raw_record,
"negative_control": (
"omit Sinkhorn scaling while retaining the same jaw, voxels, "
"kernel, weights, source signal, and evaluation checks"
),
}
return actual, negative