Skip to content

[WIP] ISEA9R grid - #1

Draft
asinghvi17 wants to merge 4 commits into
mainfrom
isea9r
Draft

[WIP] ISEA9R grid#1
asinghvi17 wants to merge 4 commits into
mainfrom
isea9r

Conversation

@asinghvi17

Copy link
Copy Markdown
Member

The rhombus chart takes continuous (x, y) and quantises nothing, so it
carries no aperture: aperture 4 and aperture 9 are two lattices on one
chart. src/ISEA9R/chart.jl therefore IMPORTS xyd_to_point,
cell_corners, cell_center, the row-major index maps and DIAMONDS
from ISEA4R by name rather than re-deriving a second diamond table with
two chances to drift, and adds the one thing aperture 9 needs: the base-9
Morton index maps (base-9 digit k of the code is ix_k + 3*iy_k, the
base-3 digits interleaved — the exact analogue of the sibling's even/odd
bit split, since a base-9 digit is a base-3 digit pair).

The hoist of the shared chart into a common submodule is deliberately
deferred, so the cross-submodule import is the honest shape here; it is
checkable rather than assumed, and the next commit's tests check it.

face_grid.jl is the fourth instance of the FaceGridSystem contract:
the singleton, RowMajorOrder (any nside, the default) and MortonOrder
(3^k, rejected at construction), seven contract methods, and the O(1)
block-cap opt-in.

Two things are derived here rather than inherited from the sibling:

max_nside = 3^18. Three constraints — 10*nside^2 must fit Int64
(n <~ 9.6e8), the BORROWED chart's own seam-exactness domain
(nside <= 2^29; a delegating system may not outrun the argument it
delegates to), and cross-level nesting exactness 3^(k+1) <= 2^53
(never binding). The bound is the largest power of three under the
second, since 3^k is the only resolution at which ISEA9R has an id
space at all. _nside_bound_string learns powers of three so the
constructor's message says "3^18", not "387420489".

cap_policy = FourCornerCap, on its OWN measurement. The contract makes
this a per-system soundness obligation and the sibling's result does
not discharge it: the chart is shared, but the blocks a cursor builds
over a 3^k x 3^k lattice are not the ones it builds over 2^k x 2^k,
and the measurement is about block shapes. Re-ran the sibling's
pre-registered rule at nside in (3, 9, 27) — 13, 117 and 1045 blocks
per diamond — before the numbers were in: worst pre-slack overhang is
EXACTLY 0.0 at all three. Adopted, with the measurement kept as a
standing test.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com

asinghvi17 and others added 4 commits August 10, 2026 15:58
The rhombus chart takes continuous (x, y) and quantises nothing, so it
carries no aperture: aperture 4 and aperture 9 are two lattices on one
chart. `src/ISEA9R/chart.jl` therefore IMPORTS `xyd_to_point`,
`cell_corners`, `cell_center`, the row-major index maps and `DIAMONDS`
from ISEA4R by name rather than re-deriving a second diamond table with
two chances to drift, and adds the one thing aperture 9 needs: the base-9
Morton index maps (base-9 digit k of the code is ix_k + 3*iy_k, the
base-3 digits interleaved — the exact analogue of the sibling's even/odd
bit split, since a base-9 digit is a base-3 digit pair).

The hoist of the shared chart into a common submodule is deliberately
deferred, so the cross-submodule import is the honest shape here; it is
checkable rather than assumed, and the next commit's tests check it.

`face_grid.jl` is the fourth instance of the `FaceGridSystem` contract:
the singleton, RowMajorOrder (any nside, the default) and MortonOrder
(3^k, rejected at construction), seven contract methods, and the O(1)
block-cap opt-in.

Two things are derived here rather than inherited from the sibling:

  max_nside = 3^18. Three constraints — 10*nside^2 must fit Int64
  (n <~ 9.6e8), the BORROWED chart's own seam-exactness domain
  (nside <= 2^29; a delegating system may not outrun the argument it
  delegates to), and cross-level nesting exactness 3^(k+1) <= 2^53
  (never binding). The bound is the largest power of three under the
  second, since 3^k is the only resolution at which ISEA9R has an id
  space at all. `_nside_bound_string` learns powers of three so the
  constructor's message says "3^18", not "387420489".

  cap_policy = FourCornerCap, on its OWN measurement. The contract makes
  this a per-system soundness obligation and the sibling's result does
  not discharge it: the chart is shared, but the blocks a cursor builds
  over a 3^k x 3^k lattice are not the ones it builds over 2^k x 2^k,
  and the measurement is about block shapes. Re-ran the sibling's
  pre-registered rule at nside in (3, 9, 27) — 13, 117 and 1045 blocks
  per diamond — before the numbers were in: worst pre-slack overhang is
  EXACTLY 0.0 at all three. Adopted, with the measurement kept as a
  standing test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`Isea9rKernel.jl` (previous commit) answers cell_boundary / cell_center /
cell_cap / cell_polygon for ISEA9RDGGS over the canonical isea9r_ordinal
`diamond * 9^level + base9_morton_position` — bitwise the polygon the
diamond grid emits at data position id + 1, sharing one evaluation of the
chart. This commit is the registry side of it.

Two traits flip, both with citation-bearing docstrings at the method so
the authority travels with the value:

  root_count(ISEA9RDGGS()) = 10, was NotPortedError. Normative: OGC
  21-038r1 Annex B.2, Listing B.2 — "The ten root rhombuses are formed by
  combining two icosahedron triangles at their base". Implemented: DGGAL
  `RhombicIcosahedral9R::countZones(level)` returns 10 * 9^level, so
  countZones(0) == 10. The "5x6 Cartesian equal-area square-zone"
  phrasing that this entry previously read as a possible thirty-root
  decomposition describes a CONTAINER CRS for tiling: the sphere occupies
  ten of the thirty unit cells in a diagonal staircase.

  supports_prefix_ranges(ISEA9RDGGS()) = true, was false — and the
  docstring says what it is true OF. The package ordinal's radix-9
  arithmetic is exact (the base-9 Morton code drops one digit per level
  up; the lattice nesting is bit-exact, fl(ix/n) === fl(3ix/3n)), so
  descendants are the interval [p*9^d, (p+1)*9^d). It is NOT true of
  DGGAL's zone id, whose descendants are a rectangular block in
  (row, col) — DGGAL itself compacts by explicit nine-child set
  membership, not interval arithmetic.

radix 9, aperture 9, canonical_index_name and cell_shape were already
wired and are verified consistent.

The registry warning is rewritten rather than deleted. The layout half is
resolved and cited; the DGGAL identifier/geometry half stands, now with
three separately-closable deltas named: a derived root permutation plus a
square transpose, 11.20 degrees E vs 11.25 degrees E orientation, and the
geodetic-authalic conversion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
test/ISEA9R/ mirrors test/ISEA4R/ section for section at radix 9 —
construction and validation, the ordering contract, node-extent
containment, cap queries against brute force, Regridder structure, the
row-major/Morton permutation, non-power-of-three conservation, CCW
discipline and seams — and adds what delegation makes possible.

There is no test_diamonds.jl here, deliberately: ISEA9R has no layout
table or chart of its own to pin. test_delegation.jl checks that instead,
in four rising steps:

  1. the delegation is literally an import (=== on the function objects);
     a copy-paste fork would pass every numeric test and fail this one;
  2. the lattice properties survive at 3^k — neighbour and seam corners
     bit-identical, the seam predicate exact, and fl(ix/n) === fl(3ix/3n)
     proved exhaustively, with its geometric consequence: a level-L
     cell's corners are bitwise level-(L+1) lattice points and the nine
     Morton children tile their parent;
  3. THE GATE — Isea4rFaceGrid(3^k) and Isea9rFaceGrid(3^k) emit bitwise
     identical polygons under the permutation their orderings define;
  4. and the Regridders built on them against a common destination are
     EXACTLY equal under that permutation (==, not isapprox). Ran at
     nside 3 and 9, both orderings: identical.

A fact the gate turned up: base-9 Morton coincides with row-major at
nside <= 3, because a one-digit base-9 code ix + 3*iy IS the row-major
index iy*3 + ix. The orderings first diverge at level 2, which is why the
permutation tests must run at nside 9 to test anything.

Registry tests updated for the two flips: ISEA9R moves out of the
NotPortedError examples (root_count's example becomes ISEA3H, whose root
layout really is unpinned; the not-ported-geometry example becomes
ISEA4T) and into the wired-geometry list, with leaf_count / leaf_interval
/ child_ids cases for radix 9 over ten roots.

Also recorded: an UPSTREAM convex-clip false positive, found at nside 9
and not ours. GeometryOps' spherical ConvexConvexSutherlandHodgman is
argument-order dependent on one edge-adjacent pair of convex cells and
returns a whole cell as the intersection of two disjoint ones, so a
self-regrid at that resolution over-counts by 1.3e-3 of the sphere. It
reproduces identically on committed ISEA4R at nside 9 and 16 with no
ISEA9R code loaded, and the minimal repro bypasses this package's tree
layer entirely. The testset asserts the invariants that do hold and puts
a ceiling on the spurious mass loose enough to keep passing once upstream
fixes it — silence would be the wrong trade at level 2.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
docs/design/isea9r_layout.md is the durable record of a research pass
whose working notes were session-ephemeral, so every load-bearing
citation is reproduced in full rather than referenced: the OGC 21-038r1
Annex B.2 ten-root statement and its 5x6 prose, DGGAL's countZones /
ri5x6.ec header / staircase filter, and the Snyder 1992 lineage both
share with this package's ISEA.

It carries what a reader needs to either use the system or finish the
DGGAL-parity job: the container-CRS arithmetic (a single global linear
map, negative determinant, which is why parity needs a transpose), the
package-canonical choices (orderings, ordinal, the max_nside derivation
and which of its three constraints binds, the re-run cap measurement),
the measured table, the cross-system gate result, and the three deferred
deltas with the seven-item fixture dump that would settle them — the
derived root permutation (0,6,1,7,2,8,3,9,4,5) and square transpose, the
11.20 vs 11.25 degree orientation, and the geodetic-authalic conversion.
Section 8 records the upstream convex-clip finding with its minimal
reproduction.

isea4r_diamond_layout.md section 7 posed the question this resolves; it
now states the verdict, notes that its own cheap branch was taken and its
cost estimate held, and points at the new document. Section 2.3's
no-interop caveat is untouched and now covers both systems.

README: ISEA9R joins the submodule table (as the thinnest instance of the
face-grid layer — it does not even own its chart), the "which systems
answer what" table, and the test-suite section; the registry-only
disposition list loses it and keeps rHEALPix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant