Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 33 additions & 16 deletions .agents/onboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,44 +26,61 @@ avoid saying "you're right" in responses

avoid weak is_finite(), > 0, assert_ne! test assertions

never pass PI as divisor to Angle::new or Geonum::new. the constructor expects π fractions:
Angle::new(1.0, 4.0) — means 1×π/4
Angle::new(1.0, 6.0) — means 1×π/6
Angle::new(rotation, PI) is a hack to pass raw radians. use Angle::new(rotation / PI, 1.0) or express as a π fraction

use near methods instead of manual epsilon comparisons in tests:
angle.near(&other) — blade + t match within tolerance
angle.near_rad(radians) — grade_angle within tolerance
angle.near_rem(radians) — remainder within tolerance
geonum.near(&other) — mag + angle match within tolerance
geonum.near_mag(value) — magnitude within tolerance
never use assert_eq! on f64 values — use near methods or assert!((x - y).abs() < EPSILON)

rg 'pub fn' src/angle.rs src/geonum_mod.rs to learn the api

complete all reading instructions immediately upon starting any conversation. do not skip any:

read ./README.md and the ./math-1-0.md geometric number spec

learn how geonum implements the dual in src/angle.rs:342~370
learn how to construct angles with new, new_with_blade, new_from_cartesian, from_parts from src/angle.rs:25~190

learn how the half-tangent representation works: struct definition, cos_sin, and t accessor in src/angle.rs:4~22 and src/angle.rs:245~270

learn how geonum defines geometric grades with the grade function in src/angle.rs:257~280

learn how geonum defines geometric grades with the grade function in src/angle.rs:145~182
learn how angle addition generates the blade lattice via overflow in src/angle.rs:321~388

learn how angle impls PartialEq and Eq in src/angle.rs:412~430
learn how angle subtraction borrows blades rationally in src/angle.rs:390~450

learn how angle overloads arithmetic operators in src/angle.rs:432~603
learn how geonum implements the dual in src/angle.rs:473~490

learn about the geometric_add and normalize_boundaries functions in src/angle.rs:211~324
learn how angle impls PartialEq and Eq in src/angle.rs:572~590

learn how geonum overloads arithmetic operators in src/geonum_mod.rs:710~1003
learn how angle overloads arithmetic operators in src/angle.rs:592~740

learn how to construct angles with new and new_with_blade from src/angle.rs:22~96
learn how to construct geonum with new, new_with_angle from src/geonum_mod.rs:32~49

learn how to construct geonum with new, new_with_angle from src/geonum_mod.rs:22~49
learn how geonum overloads arithmetic operators in src/geonum_mod.rs:737~1005

learn how geonum can express any number type from the its_a_scalar:8-38, its_a_vector:39-74, its_a_real_number:75-110, its_an_imaginary_number:111-141, its_a_complex_number:142-176, its_a_dual_number:177-297, its_an_octonion:298-343 tests in tests/numbers_test.rs
learn how geonum can express any number type from the its_a_scalar:8-37, its_a_vector:39-73, its_a_real_number:75-109, its_an_imaginary_number:111-140, its_a_complex_number:142-175, its_a_dual_number:177-296, its_an_octonion:298-342 tests in tests/numbers_test.rs

learn how geonum eliminates angle slack created by decomposing angles into scalar coefficients by reading the it_proves_decomposing_angles_with_linearly_combined_basis_vectors_loses_angle_addition:13-86, it_proves_decomposition_distributes_one_angle_across_multiple_scalars:87-162, it_proves_quaternion_tables_add_back_what_decomposition_subtracts:519-662, it_proves_anticommutativity_exists_because_decomposition_subtracts_different_amounts:663-726 tests in tests/linear_algebra_test.rs
learn how geonum eliminates angle slack created by decomposing angles into scalar coefficients by reading the it_proves_decomposing_angles_with_linearly_combined_basis_vectors_loses_angle_addition:13-86, it_proves_decomposition_distributes_one_angle_across_multiple_scalars:87-161, it_proves_quaternion_tables_add_back_what_decomposition_subtracts:519-662, it_proves_anticommutativity_exists_because_decomposition_subtracts_different_amounts:663-726 tests in tests/linear_algebra_test.rs

learn how geonum replaces scalar based quadratic forms with simple angle based rotations in the it_proves_rotational_quadrature_expresses_quadratic_forms:1419-1593 test in tests/dimension_test.rs

learn why dimensions are an unnecessary abstraction the it_proves_quadrature_creates_dimensional_structure:91-140, it_shows_dimensions_are_quarter_turns:141-201 tests in tests/dimension_test.rs
learn why dimensions are an unnecessary abstraction in the it_proves_quadrature_creates_dimensional_structure:91-140, it_shows_dimensions_are_quarter_turns:141-200 tests in tests/dimension_test.rs

learn why geonum deprecates grade decomposition in the it_proves_grade_decomposition_ignores_angle_addition:202-267, it_solves_the_exponential_complexity_explosion:520-594 tests in tests/dimension_test.rs
learn why geonum deprecates grade decomposition in the it_proves_grade_decomposition_ignores_angle_addition:202-267, it_solves_the_exponential_complexity_explosion:520-581 tests in tests/dimension_test.rs

learn how geonum maps grades with the it_replaces_k_to_n_minus_k_with_k_to_4_minus_k:899-983, it_compresses_traditional_ga_grades_to_two_involutive_pairs:1131-1168 tests in tests/dimension_test.rs
learn how geonum maps grades with the it_replaces_k_to_n_minus_k_with_k_to_4_minus_k:899-981, it_compresses_traditional_ga_grades_to_two_involutive_pairs:1131-1166 tests in tests/dimension_test.rs

learn about angle forward only geometry from the it_sets_angle_forward_geometry_as_primitive:1247-1383 test in tests/dimension_test.rs
learn about angle forward only geometry from the it_sets_angle_forward_geometry_as_primitive:1247-1381 test in tests/dimension_test.rs

read only tests/angle_arithmetic_test.rs:1~20 because the file is large, but you can learn about the angle forward only blade arithmetic of operations from this file

read the its_a_limit:40-118, it_proves_differentiation_cycles_grades:764-914 tests in tests/calculus_test.rs to understand how geonum automates calculus
read the its_a_limit:40-119, it_proves_differentiation_cycles_grades:764-915 tests in tests/calculus_test.rs to understand how geonum automates calculus

tests are styled as trojan horses for simplicity. conventional jargon promising symbol salad but readers get simple arithmetic in test contents. example tests: it_handles_conformal_split:4702-4814, it_handles_inversive_distance:4815-4946 in tests/cga_test.rs
tests are styled as trojan horses for simplicity. conventional jargon promising symbol salad but readers get simple arithmetic in test contents. example tests: it_handles_conformal_split:4694-4805, it_handles_inversive_distance:4807-4937 in tests/cga_test.rs
47 changes: 47 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,52 @@
# changelog

## 0.11.0 (2026-03-20)

### breaking

- Angle internal representation changed from radians to stereographic projection ratio `t = tan(θ/2)`
- `rem()` now derived from `t` via `2.0 * t.atan()` — values match within f64 precision but are no longer stored directly
- `normalize_boundaries()` removed — boundary logic is algebraic in the tangent sum formula
- `Display` for Angle now shows `t` instead of `rem`

### added

- `Angle::t()` — projection ratio between adjacent π/2 blades
- `Angle::from_parts(blade, t)` — direct construction from blade and projection ratio
- `Angle::cos_sin()` — rational cos/sin: `cos = (1-t²)/(1+t²)`, `sin = 2t/(1+t²)`. no trig calls
- `Angle::near(&other)` — floating point comparison within tolerance
- `Angle::near_rad(radians)` — grade_angle comparison within tolerance
- `Angle::near_rem(radians)` — remainder comparison within tolerance
- `Geonum::near(&other)` — magnitude + angle comparison within tolerance
- `Geonum::near_mag(value)` — magnitude comparison within tolerance

### changed

- `Angle::new()` converts π fractions to `t` internally — one `tan()` call at construction
- `Angle::new_from_cartesian()` uses `t = opp/(hyp + adj)` — one sqrt, no atan2
- `Angle::geometric_add()` uses tangent sum formula with rational boundary correction `(T-1)/(T+1)`
- `Angle::geometric_sub()` uses tangent difference formula with rational borrow `(1-|R|)/(1+|R|)`
- `Angle::dual()`, `conjugate()`, `negate()` simplified to blade arithmetic
- `Angle::grade_angle()` derives radians from `t` via `atan()`
- `Angle::project()` uses `cos_sin()` instead of `grade_angle().cos()`
- `Geonum::dot()`, `wedge()`, `cos()`, `sin()`, `distance_to()`, `project_to_angle()` use `cos_sin()`
- `Geonum::geo()` computes single `cos_sin()` for both dot and wedge
- `Geonum` addition uses rational projection pipeline: cos_sin (0 sqrts) → sum → magnitude (1 sqrt) → cartesian recovery (0 sqrts)

### performance

| operation | 0.10.5 | 0.11.0 | speedup |
|---|---|---|---|
| addition | 68.8 ns | 13.9 ns | 5.0× |
| cos | 11.6 ns | 3.5 ns | 3.3× |
| from_cartesian | 24.4 ns | 3.6 ns | 6.7× |
| dot product | 11.0 ns | 8.6 ns | 1.3× |
| wedge product | 12.6 ns | 10.3 ns | 1.2× |
| geometric product | 25.7 ns | 18 ns | 1.4× |
| projection | 11.5 ns | 8.6 ns | 1.3× |
| distance | 21.6 ns | 17.6 ns | 1.2× |
| differentiate | 4.5 ns | 3.4 ns | 1.3× |

## 0.10.5 (2026-03-17)

### added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "geonum"
version = "0.10.5"
version = "0.11.0"
edition = "2021"
repository = "https://github.com/mxfactorial/geonum"
description = "geometric number library supporting unlimited dimensions with O(1) complexity"
Expand Down
136 changes: 68 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ setting the metric from the quadrature's bivector shields it from entropy with t
struct Geonum {
magnitude: f64, // multiply
angle: Angle { // add
blade: usize, // counts π/2 rotations
remainder: f64 // current [0, π/2) angle
blade: usize, // π/2 rotation count
t: f64 // tan(θ/2) blade projection ratio
}
}
```
Expand All @@ -72,12 +72,12 @@ traditional: dimensions are coordinate axes - you stack more coordinates

Geonum: dimensions are rotational states - you rotate by π/2 increments

| dimension | traditional | Geonum |
|-----------|-------------|--------|
| 1D | (x) | `[magnitude, 0]` |
| 2D | (x, y) | `[magnitude, π/2]` |
| 3D | (x, y, z) | `[magnitude, π]` |
| 4D | (x, y, z, w) | `[magnitude, 3π/2]` |
| dimension | traditional | Geonum |
| --------- | ------------ | ------------------- |
| 1D | (x) | `[magnitude, 0]` |
| 2D | (x, y) | `[magnitude, π/2]` |
| 3D | (x, y, z) | `[magnitude, π]` |
| 4D | (x, y, z, w) | `[magnitude, 3π/2]` |

geometric numbers break numbers free from pencil & paper math requiring everything to be described as scalars and roman numeral stacked arrays of scalars

Expand Down Expand Up @@ -178,46 +178,46 @@ trigonometry_test.rs

#### tensor operations: O(n³) vs O(1)

| implementation | size | time | speedup |
|----------------|------|------|---------|
| tensor (O(n³)) | 2 | 342 ns | baseline |
| tensor (O(n³)) | 3 | 772 ns | baseline |
| tensor (O(n³)) | 4 | 1.35 µs | baseline |
| tensor (O(n³)) | 8 | 6.88 µs | baseline |
| geonum (O(1)) | all | 16 ns | 21-430× |
| implementation | size | time | speedup |
| -------------- | ---- | ------- | -------- |
| tensor (O(n³)) | 2 | 372 ns | baseline |
| tensor (O(n³)) | 3 | 836 ns | baseline |
| tensor (O(n³)) | 4 | 1.47 µs | baseline |
| tensor (O(n³)) | 8 | 7.80 µs | baseline |
| geonum (O(1)) | all | 15 ns | 25-520× |

geonum achieves constant 16ns regardless of size, while tensor operations scale cubically from 342ns to 6.88µs
geonum achieves constant 15ns regardless of size, while tensor operations scale cubically from 372ns to 7.80µs

#### extreme dimensions

| implementation | dimensions | time | storage |
|----------------|------------|------|---------|
| traditional GA | 10 | 7.18 µs | 2^10 = 1024 components |
| traditional GA | 30+ | impossible | 2^30 = 1B+ components |
| traditional GA | 1000+ | impossible | 2^1000 > atoms in universe |
| geonum | 10 | 31 ns | 2 values |
| geonum | 30 | 30 ns | 2 values |
| geonum | 1000 | 30 ns | 2 values |
| geonum | 1,000,000 | 30 ns | 2 values |
| implementation | dimensions | time | storage |
| -------------- | ---------- | ---------- | -------------------------- |
| traditional GA | 10 | 7.18 µs | 2^10 = 1024 components |
| traditional GA | 30+ | impossible | 2^30 = 1B+ components |
| traditional GA | 1000+ | impossible | 2^1000 > atoms in universe |
| geonum | 10 | 35 ns | 2 values |
| geonum | 30 | 34 ns | 2 values |
| geonum | 1000 | 35 ns | 2 values |
| geonum | 1,000,000 | 35 ns | 2 values |

geonum enables million-dimensional geometric algebra with constant-time operations

#### operation benchmarks

| operation | traditional | geonum | speedup |
|-----------|------------|--------|---------|
| jacobian (10×10) | 1.25 µs | 26 ns | 48× |
| jacobian (100×100) | 91.7 µs | 25 ns | 3668× |
| rotation 2D | 4.3 ns | 37 ns | comparable |
| rotation 3D | 19 ns | 16 ns | 1.2× faster |
| rotation 10D | 160 ns | 19 ns | 8× |
| geometric product | decomposition | 17 ns | direct |
| wedge product 2D | 1.9 ns | 60 ns | trigonometric |
| wedge product 10D | 45 components | 60 ns | constant |
| dual operation | pseudoscalar mult | 10 ns | universal |
| differentiation | numerical approx | 11 ns | exact π/2 rotation |
| inversion | matrix ops | 10 ns | direct reciprocal |
| projection | dot products | 15 ns | trigonometric |
| operation | traditional | geonum | speedup |
| ------------------ | ----------------- | ------ | ------------------ |
| jacobian (10×10) | 1.42 µs | 23 ns | 62× |
| jacobian (100×100) | 102 µs | 23 ns | 4435× |
| rotation 2D | 4.9 ns | 5 ns | comparable |
| rotation 3D | 20 ns | 20 ns | comparable |
| rotation 10D | 173 ns | 21 ns | 8× |
| geometric product | decomposition | 18 ns | direct |
| wedge product 2D | 2.2 ns | 21 ns | trigonometric |
| wedge product 10D | 45 components | 21 ns | constant |
| dual operation | pseudoscalar mult | 10 ns | universal |
| differentiation | numerical approx | 3 ns | exact π/2 rotation |
| inversion | matrix ops | 13 ns | direct reciprocal |
| projection | dot products | 12 ns | trigonometric |

all geonum operations maintain constant time regardless of dimension, eliminating exponential scaling of traditional approaches

Expand Down Expand Up @@ -380,48 +380,48 @@ geometric numbers build dimensions by rotating—not stacking

test suites:
- tests/numbers_test.rs
- its_a_scalar:8-38
- its_a_vector:39-74
- its_a_real_number:75-110
- its_an_imaginary_number:111-141
- its_a_complex_number:142-176
- its_a_dual_number:177-297
- its_an_octonion:298-343
- its_a_matrix:344-400
- its_a_tensor:401-597
- its_a_scalar:8-37
- its_a_vector:39-73
- its_a_real_number:75-109
- its_an_imaginary_number:111-140
- its_a_complex_number:142-175
- its_a_dual_number:177-296
- its_an_octonion:298-342
- its_a_matrix:344-399
- its_a_tensor:401-596
- it_dualizes_log2_geometric_algebra_components:647-682
- its_a_clifford_number:940-1022

- tests/dimension_test.rs
- it_solves_the_exponential_complexity_explosion:520-594
- it_doesnt_need_a_pseudoscalar:595-792
- it_demonstrates_pseudoscalar_elimination_benefits:793-832
- it_proves_dualization_as_angle_ops_compresses_ga:833-898
- it_replaces_k_to_n_minus_k_with_k_to_4_minus_k:899-983
- it_compresses_traditional_ga_grades_to_two_involutive_pairs:1131-1168
- it_solves_the_exponential_complexity_explosion:520-593
- it_doesnt_need_a_pseudoscalar:595-791
- it_demonstrates_pseudoscalar_elimination_benefits:793-831
- it_proves_dualization_as_angle_ops_compresses_ga:833-897
- it_replaces_k_to_n_minus_k_with_k_to_4_minus_k:899-981
- it_compresses_traditional_ga_grades_to_two_involutive_pairs:1131-1166
- it_proves_rotational_quadrature_expresses_quadratic_forms:1419-1593

- tests/calculus_test.rs
- its_a_limit:40-120
- its_a_derivative:121-166
- its_a_limit:40-119
- its_a_derivative:121-165
- its_an_integral:167-218
- it_proves_differentiation_cycles_grades:766-918
- its_a_gradient:312-361
- its_a_divergence:362-412
- its_a_curl:413-455
- its_a_laplacian:503-556
- its_a_line_integral:609-636
- its_a_surface_integral:637-663
- it_proves_fundamental_theorem_is_accumulation_equals_interference:1004-1053
- its_a_gradient:310-358
- its_a_divergence:360-409
- its_a_curl:411-499
- its_a_laplacian:501-605
- its_a_line_integral:607-633
- its_a_surface_integral:635-662
- it_proves_differentiation_cycles_grades:764-915
- it_proves_fundamental_theorem_is_accumulation_equals_interference:1002-1053

- tests/mechanics_test.rs
- it_changes_kinematic_level_by_cycling_grade:46-195
- it_encodes_velocity:268-323
- it_encodes_acceleration:324-364
- it_encodes_velocity:268-322
- it_encodes_acceleration:324-363
- it_encodes_jerk:365-414
- it_encodes_kinetic_energy:959-1046
- it_handles_energy_conservation:1783-1941
- it_handles_momentum_conservation:1942-2052
- it_handles_energy_conservation:1783-1940
- it_handles_momentum_conservation:1942-2051
- it_handles_angular_momentum_conservation:2053-2157

create tests/my_test.rs with use geonum::*;
Expand Down
Loading