use geonum::*;
use std::f64::consts::PI;
use std::hint::black_box;
use std::time::Instant;
const EPSILON: f64 = 1e-10;
#[test]
fn it_sweeps_a_screen_with_one_geonum() {
let ex = Angle::new(0.0, 1.0);
let ey = Angle::new(1.0, 2.0);
let angle_steps = 360;
let radial_steps = 20;
let max_radius = 100.0;
let mut pixel_count = 0;
for a in 0..angle_steps {
let pi_frac = 2.0 * a as f64 / angle_steps as f64; let theta = pi_frac * PI;
for r in 1..=radial_steps {
let radius = (r as f64 / radial_steps as f64) * max_radius;
let scanner = Geonum::new_with_angle(radius, Angle::new(pi_frac, 1.0));
let px = scanner.mag * scanner.angle.project(ex);
let py = scanner.mag * scanner.angle.project(ey);
assert!(
(px - radius * theta.cos()).abs() < EPSILON,
"x projection at angle {:.3} radius {:.1}",
theta,
radius
);
assert!(
(py - radius * theta.sin()).abs() < EPSILON,
"y projection at angle {:.3} radius {:.1}",
theta,
radius
);
assert!(
(px * px + py * py - radius * radius).abs() < EPSILON,
"pythagorean identity at angle {:.3} radius {:.1}",
theta,
radius
);
pixel_count += 1;
}
}
assert_eq!(pixel_count, angle_steps * radial_steps);
println!("swept {} pixels with one geonum", pixel_count);
println!(" 360 angles × 20 radii = full polar screen coverage");
println!(" pythagorean identity holds at every pixel");
println!(" zero coordinate arrays allocated");
}
#[test]
fn it_rotates_the_scanner_not_the_scanned() {
let ex = Angle::new(0.0, 1.0);
let ey = Angle::new(1.0, 2.0);
let rotations = [
Angle::new(1.0, 4.0), Angle::new(1.0, 2.0), Angle::new(2.0, 3.0), Angle::new(1.0, 1.0), Angle::new(7.0, 4.0), ];
for rotation in &rotations {
let rot_rad = rotation.grade_angle();
let cos_r = rot_rad.cos();
let sin_r = rot_rad.sin();
for a in 0..36 {
let pi_frac = 2.0 * a as f64 / 36.0;
let theta = pi_frac * PI;
for &radius in &[1.0, 5.0, 10.0, 50.0] {
let scanner = Geonum::new_with_angle(radius, Angle::new(pi_frac, 1.0));
let ox = scanner.mag * scanner.angle.project(ex);
let oy = scanner.mag * scanner.angle.project(ey);
let rotated = scanner.rotate(*rotation);
let rx = rotated.mag * rotated.angle.project(ex);
let ry = rotated.mag * rotated.angle.project(ey);
let trad_x = ox * cos_r - oy * sin_r;
let trad_y = ox * sin_r + oy * cos_r;
assert!(
(rx - trad_x).abs() < EPSILON,
"x mismatch at angle {:.3} radius {:.1} rotation {:.3}",
theta,
radius,
rot_rad
);
assert!(
(ry - trad_y).abs() < EPSILON,
"y mismatch at angle {:.3} radius {:.1} rotation {:.3}",
theta,
radius,
rot_rad
);
assert!(rotated.near_mag(scanner.mag));
}
}
}
}
#[test]
fn it_passes_pixel_values_through_rotation() {
let ex = Angle::new(0.0, 1.0);
let ey = Angle::new(1.0, 2.0);
let rotation = Angle::new(1.0, 3.0); let rot_rad = rotation.grade_angle();
for i in 0..36 {
let pi_frac = 2.0 * i as f64 / 36.0;
let theta = pi_frac * PI;
let intensity = 10.0 + 5.0 * theta.cos();
let scanner = Geonum::new_with_angle(intensity, Angle::new(pi_frac, 1.0));
let rotated = scanner.rotate(rotation);
assert!(
(rotated.mag - intensity).abs() < EPSILON,
"pixel value destroyed at angle {:.3}",
theta
);
let new_x = rotated.mag * rotated.angle.project(ex);
let new_y = rotated.mag * rotated.angle.project(ey);
let original_x = intensity * theta.cos();
let original_y = intensity * theta.sin();
let expected_x = original_x * rot_rad.cos() - original_y * rot_rad.sin();
let expected_y = original_x * rot_rad.sin() + original_y * rot_rad.cos();
assert!(
(new_x - expected_x).abs() < EPSILON,
"pixel x position wrong at angle {:.3}",
theta
);
assert!(
(new_y - expected_y).abs() < EPSILON,
"pixel y position wrong at angle {:.3}",
theta
);
}
}
#[test]
fn it_renders_a_circle_without_coordinates() {
let circle_radius = 5.0;
let mut inside_count = 0;
let mut outside_count = 0;
for a in 0..360 {
let pi_frac = 2.0 * a as f64 / 360.0;
for m in 1..=20 {
let r = m as f64 * 0.5;
let scanner = Geonum::new_with_angle(r, Angle::new(pi_frac, 1.0));
if scanner.mag <= circle_radius {
inside_count += 1;
} else {
outside_count += 1;
}
}
}
assert_eq!(inside_count, 360 * 10);
assert_eq!(outside_count, 360 * 10);
let center = Geonum::new(3.0, 0.0, 1.0);
let pixel_near = Geonum::new(4.0, 0.0, 1.0);
let dist_near = pixel_near.distance_to(¢er);
assert!(dist_near.near_mag(1.0));
let pixel_far = Geonum::new(6.0, 0.0, 1.0);
let dist_far = pixel_far.distance_to(¢er);
assert!(dist_far.near_mag(3.0));
let pixel_perp = Geonum::new(3.0, 1.0, 2.0);
let dist_perp = pixel_perp.distance_to(¢er);
let expected_dist = (9.0_f64 + 9.0).sqrt();
assert!(dist_perp.near_mag(expected_dist));
}
#[test]
fn it_zooms_and_rotates_in_one_operation() {
let ex = Angle::new(0.0, 1.0);
let ey = Angle::new(1.0, 2.0);
let zoom = 3.0;
let rotation = Angle::new(1.0, 6.0); let rot_rad = rotation.grade_angle();
for a in 0..36 {
let pi_frac = 2.0 * a as f64 / 36.0;
let theta = pi_frac * PI;
let radius = 5.0;
let scanner = Geonum::new_with_angle(radius, Angle::new(pi_frac, 1.0));
let transformed = scanner.scale_rotate(zoom, rotation);
let tx = transformed.mag * transformed.angle.project(ex);
let ty = transformed.mag * transformed.angle.project(ey);
let ox = radius * theta.cos();
let oy = radius * theta.sin();
let zx = ox * zoom;
let zy = oy * zoom;
let expected_x = zx * rot_rad.cos() - zy * rot_rad.sin();
let expected_y = zx * rot_rad.sin() + zy * rot_rad.cos();
assert!(
(tx - expected_x).abs() < EPSILON,
"zoom+rotate x mismatch at angle {:.3}",
theta
);
assert!(
(ty - expected_y).abs() < EPSILON,
"zoom+rotate y mismatch at angle {:.3}",
theta
);
assert!(transformed.near_mag(radius * zoom));
}
}
#[test]
fn it_renders_the_same_scene_from_different_camera_angles() {
let ex = Angle::new(0.0, 1.0);
let ey = Angle::new(1.0, 2.0);
let scene: [(f64, Angle, f64); 4] = [
(5.0, Angle::new(0.0, 1.0), 200.0), (3.0, Angle::new(1.0, 2.0), 150.0), (7.0, Angle::new(1.0, 1.0), 100.0), (4.0, Angle::new(3.0, 2.0), 50.0), ];
let camera_rotation = Angle::new(1.0, 2.0);
for &(distance, direction, intensity) in &scene {
let sweep_default = Geonum::new_with_angle(intensity, direction);
let x1 = sweep_default.mag * sweep_default.angle.project(ex);
let y1 = sweep_default.mag * sweep_default.angle.project(ey);
let sweep_rotated = Geonum::new_with_angle(intensity, direction + camera_rotation);
let x2 = sweep_rotated.mag * sweep_rotated.angle.project(ex);
let y2 = sweep_rotated.mag * sweep_rotated.angle.project(ey);
assert!(
(x2 - (-y1)).abs() < EPSILON,
"camera pan x for object at direction {:?}",
direction
);
assert!(
(y2 - x1).abs() < EPSILON,
"camera pan y for object at direction {:?}",
direction
);
assert!(sweep_default.near_mag(intensity));
assert!(sweep_rotated.near_mag(intensity));
let position_default = Geonum::new_with_angle(distance, direction);
let position_rotated = Geonum::new_with_angle(distance, direction + camera_rotation);
assert!(position_default.near_mag(position_rotated.mag));
}
}
#[test]
fn it_proves_dimension_free_rendering() {
let screen_radius = 50.0;
for a in 0..36 {
let pi_frac = 2.0 * a as f64 / 36.0;
let radius = (a as f64 + 1.0) / 36.0 * screen_radius;
let scanner = Geonum::new_with_angle(radius, Angle::new(pi_frac, 1.0));
let axis_small = Angle::new(1.0, 2.0);
let p_small = scanner.mag * scanner.angle.project(axis_small);
let axis_huge = Angle::new(1_000_001.0, 2.0);
let p_huge = scanner.mag * scanner.angle.project(axis_huge);
assert!(
(p_small - p_huge).abs() < 1e-12,
"blade 1 and blade 1_000_001 produce different pixel values at step {}",
a
);
let ex_small = Angle::new(0.0, 1.0);
let ex_huge = Angle::new(1_000_000.0, 2.0);
let px_small = scanner.mag * scanner.angle.project(ex_small);
let px_huge = scanner.mag * scanner.angle.project(ex_huge);
assert!(
(px_small - px_huge).abs() < 1e-12,
"blade 0 and blade 1_000_000 produce different pixel values at step {}",
a
);
}
}
#[test]
fn it_proves_rendering_perf_scales_with_angle_not_dimension() {
let pixel_count: usize = 50_000;
let rotation_angle = PI / 6.0;
let cos_r = rotation_angle.cos();
let sin_r = rotation_angle.sin();
let start = Instant::now();
for i in 0..pixel_count {
let x = black_box((i as f64 * 0.1).cos());
let y = black_box((i as f64 * 0.1).sin());
black_box(x * cos_r - y * sin_r);
black_box(x * sin_r + y * cos_r);
}
let trad_2d = start.elapsed();
let mut mat_10 = [[0.0_f64; 10]; 10];
for (idx, row) in mat_10.iter_mut().enumerate() {
row[idx] = 1.0;
}
mat_10[0][0] = cos_r;
mat_10[0][1] = -sin_r;
mat_10[1][0] = sin_r;
mat_10[1][1] = cos_r;
let start = Instant::now();
for i in 0..pixel_count {
let mut v = [0.0_f64; 10];
v[0] = (i as f64 * 0.1).cos();
v[1] = (i as f64 * 0.1).sin();
let mut result = [0.0_f64; 10];
for r in 0..10 {
let mut sum = 0.0;
for c in 0..10 {
sum += mat_10[r][c] * v[c];
}
result[r] = sum;
}
black_box(result);
}
let trad_10d = start.elapsed();
let mut mat_100 = [[0.0_f64; 100]; 100];
for (idx, row) in mat_100.iter_mut().enumerate() {
row[idx] = 1.0;
}
mat_100[0][0] = cos_r;
mat_100[0][1] = -sin_r;
mat_100[1][0] = sin_r;
mat_100[1][1] = cos_r;
let start = Instant::now();
for i in 0..pixel_count {
let mut v = [0.0_f64; 100];
v[0] = (i as f64 * 0.1).cos();
v[1] = (i as f64 * 0.1).sin();
let mut result = [0.0_f64; 100];
for r in 0..100 {
let mut sum = 0.0;
for c in 0..100 {
sum += mat_100[r][c] * v[c];
}
result[r] = sum;
}
black_box(result);
}
let trad_100d = start.elapsed();
let rotation = Angle::new(1.0, 6.0); let ex = Angle::new(0.0, 1.0);
let ey = Angle::new(1.0, 2.0);
let start = Instant::now();
for i in 0..pixel_count {
let pi_frac = 2.0 * i as f64 / pixel_count as f64;
let scanner = Geonum::new_with_angle(1.0, Angle::new(pi_frac, 1.0) + rotation);
black_box(scanner.mag * scanner.angle.project(ex));
black_box(scanner.mag * scanner.angle.project(ey));
}
let geo_blade_1 = start.elapsed();
let high_blade = Angle::new_with_blade(1_000, 0.0, 1.0);
let start = Instant::now();
for i in 0..pixel_count {
let pi_frac = 2.0 * i as f64 / pixel_count as f64;
let scanner = Geonum::new_with_angle(1.0, Angle::new(pi_frac, 1.0) + high_blade + rotation);
black_box(scanner.mag * scanner.angle.project(ex));
black_box(scanner.mag * scanner.angle.project(ey));
}
let geo_blade_1k = start.elapsed();
let extreme_blade = Angle::new_with_blade(1_000_000, 0.0, 1.0);
let start = Instant::now();
for i in 0..pixel_count {
let pi_frac = 2.0 * i as f64 / pixel_count as f64;
let scanner =
Geonum::new_with_angle(1.0, Angle::new(pi_frac, 1.0) + extreme_blade + rotation);
black_box(scanner.mag * scanner.angle.project(ex));
black_box(scanner.mag * scanner.angle.project(ey));
}
let geo_blade_1m = start.elapsed();
let speedup_100d = trad_100d.as_nanos() as f64 / geo_blade_1.as_nanos().max(1) as f64;
println!("\n traditional 2D per pixel: {:?}", trad_2d);
println!(" traditional 10D per pixel: {:?}", trad_10d);
println!(" traditional 100D per pixel: {:?}", trad_100d);
println!(" geonum per pixel: {:?}", geo_blade_1);
println!(" speedup vs 100D: {:.0}×", speedup_100d);
println!(
"\n traditional 100D storage: {} bytes/object",
100 * std::mem::size_of::<f64>()
);
println!(
" geonum storage: {} bytes/object",
std::mem::size_of::<Geonum>()
);
let geonum_bytes = std::mem::size_of::<Geonum>();
let cache_line = 64; let trad_100d_per_cache_line = cache_line / (100 * std::mem::size_of::<f64>());
let geonum_per_cache_line = cache_line / geonum_bytes;
println!("\n objects per 64-byte cache line:");
println!(" traditional 100D: {}", trad_100d_per_cache_line);
println!(" geonum: {}", geonum_per_cache_line);
let geo_throughput = pixel_count as f64 / geo_blade_1.as_secs_f64();
let trad_100d_throughput = pixel_count as f64 / trad_100d.as_secs_f64();
println!("\n throughput (1 cpu, 0 gpus):");
println!(
" traditional 100D: {:.0} objects/sec",
trad_100d_throughput
);
println!(" geonum: {:.0} objects/sec", geo_throughput);
println!("\n blade 1 time: {:?}", geo_blade_1);
println!(" blade 1,000 time: {:?}", geo_blade_1k);
println!(" blade 1,000,000 time: {:?}", geo_blade_1m);
println!(" dimension doesnt move the needle\n");
let ga_10d_bytes = 2_u64.pow(10) * 8; let ga_20d_bytes = 2_u64.pow(20) * 8; let ga_30d_bytes = 2_u64.pow(30) * 8;
assert_eq!(ga_10d_bytes, 8_192);
assert_eq!(ga_20d_bytes, 8_388_608);
assert_eq!(ga_30d_bytes, 8_589_934_592);
let trad_ops_2d = 6; let trad_ops_10d = 190; let trad_ops_100d = 19_900; let geonum_ops = 6;
assert!(trad_ops_100d > trad_ops_10d * 10);
assert!(trad_ops_10d > trad_ops_2d * 10);
assert_eq!(geonum_ops, 6);
let geonum_bytes = std::mem::size_of::<Geonum>();
assert_eq!(geonum_bytes, 24); assert_eq!(geonum_bytes * 33, 792); assert_eq!(geonum_bytes * 341, 8_184);
assert_eq!(64 / (100 * std::mem::size_of::<f64>()), 0);
assert_eq!(64 / geonum_bytes, 2);
}
#[test]
fn it_enables_a_graphics_rendering_stack_rewrite() {
let ex = Angle::new(0.0, 1.0);
let ey = Angle::new(1.0, 2.0);
let v0 = Geonum::new_from_cartesian(1.0, 0.5); let v1 = Geonum::new_from_cartesian(4.0, 0.0);
let v2 = Geonum::new_from_cartesian(2.0, 3.0);
let model_rotation = Angle::new(1.0, 6.0);
let v0_world = v0.rotate(model_rotation);
let v1_world = v1.rotate(model_rotation);
let v2_world = v2.rotate(model_rotation);
assert!(v0_world.near_mag(v0.mag));
assert!(v1_world.near_mag(v1.mag));
assert!(v2_world.near_mag(v2.mag));
let camera_pan = Angle::new(1.0, 12.0); let v0_view = v0_world.rotate(camera_pan);
let v1_view = v1_world.rotate(camera_pan);
let v2_view = v2_world.rotate(camera_pan);
let focal_length = 10.0;
let v0_proj = Geonum::new_with_angle(focal_length / v0_view.mag, v0_view.angle);
let v1_proj = Geonum::new_with_angle(focal_length / v1_view.mag, v1_view.angle);
let v2_proj = Geonum::new_with_angle(focal_length / v2_view.mag, v2_view.angle);
assert_eq!(v0_proj.angle, v0_view.angle);
assert_eq!(v1_proj.angle, v1_view.angle);
assert_eq!(v2_proj.angle, v2_view.angle);
if v0_view.mag < v1_view.mag {
assert!(v0_proj.mag > v1_proj.mag, "closer projects larger");
}
let s0x = v0_proj.mag * v0_proj.angle.project(ex);
let s0y = v0_proj.mag * v0_proj.angle.project(ey);
let s1x = v1_proj.mag * v1_proj.angle.project(ex);
let s1y = v1_proj.mag * v1_proj.angle.project(ey);
let s2x = v2_proj.mag * v2_proj.angle.project(ex);
let s2y = v2_proj.mag * v2_proj.angle.project(ey);
assert!((s0x * s0x + s0y * s0y - v0_proj.mag * v0_proj.mag).abs() < EPSILON);
assert!((s1x * s1x + s1y * s1y - v1_proj.mag * v1_proj.mag).abs() < EPSILON);
assert!((s2x * s2x + s2y * s2y - v2_proj.mag * v2_proj.mag).abs() < EPSILON);
let edge_mid_angle = (v1_view.angle + v2_view.angle) / 2.0;
let edge_mid_mag = (v1_view.mag + v2_view.mag) / 2.0;
let ray = Geonum::new_with_angle(1.0, edge_mid_angle); let propagated = ray.scale(edge_mid_mag);
assert_eq!(
propagated.angle, ray.angle,
"propagation preserves direction"
);
assert!(
(propagated.mag - edge_mid_mag).abs() < EPSILON,
"ray reaches target distance"
);
let bounding_radius = v1_view.mag.max(v2_view.mag);
let bounding_circle = Geonum::new_with_blade(bounding_radius, 2, 0.0, 1.0);
let ray_bivector = Geonum::new_with_angle(propagated.mag, propagated.angle)
.increment_blade()
.increment_blade();
let hit = bounding_circle.meet(&ray_bivector);
let hit_grade = hit.angle.grade();
assert!(hit_grade == 1 || hit_grade == 3, "meet produces odd grade");
let hit_point = Geonum::new_with_angle(bounding_radius, propagated.angle);
let tangent = hit_point.differentiate(); let normal = tangent.differentiate();
assert_eq!(
tangent.angle.grade(),
(hit_point.angle.grade() + 1) % 4,
"tangent one grade up"
);
assert_eq!(
normal.angle.grade(),
(hit_point.angle.grade() + 2) % 4,
"normal two grades up"
);
assert_eq!(
tangent.mag, hit_point.mag,
"differentiation preserves magnitude"
);
let reflected = propagated.reflect(&hit_point);
assert_eq!(
reflected.mag, propagated.mag,
"reflection preserves intensity"
);
let mut verts_by_depth = [v0_view, v1_view, v2_view];
verts_by_depth.sort_by(|a, b| a.mag.partial_cmp(&b.mag).unwrap());
assert!(verts_by_depth[0].mag <= verts_by_depth[1].mag);
assert!(verts_by_depth[1].mag <= verts_by_depth[2].mag);
let euclidean_part = v1_view.mag; let conformal_part = v1_view.angle;
let reconstructed = Geonum::new_with_angle(euclidean_part, conformal_part);
assert!(
(reconstructed - v1_view).mag < EPSILON,
"split reconstructs"
);
let zoomed = v1_view.scale(2.0);
assert_eq!(zoomed.angle, v1_view.angle, "zoom preserves conformal part");
assert!(
(zoomed.mag - v1_view.mag * 2.0).abs() < EPSILON,
"zoom scales euclidean part"
);
let panned = v1_view.rotate(Angle::new(1.0, 4.0));
assert!(
(panned.mag - v1_view.mag).abs() < EPSILON,
"pan preserves euclidean part"
);
assert_ne!(panned.angle, v1_view.angle, "pan changes conformal part");
}