{"id":50443500,"url":"https://github.com/ericrihm/conformal-toolkit","last_synced_at":"2026-05-31T20:00:47.037Z","repository":{"id":357418069,"uuid":"1236049121","full_name":"ericrihm/conformal-toolkit","owner":"ericrihm","description":"Symbolic conformal geometry toolkit (SageMath) + discrete conformal invariants as GNN features (PyTorch)","archived":false,"fork":false,"pushed_at":"2026-05-12T17:38:50.000Z","size":158,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-12T18:38:33.753Z","etag":null,"topics":["conformal-geometry","differential-geometry","geometric-deep-learning","gjms-operators","mesh-features","pytorch","q-curvature","sagemath","tractor-calculus","willmore"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ericrihm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-11T22:48:25.000Z","updated_at":"2026-05-12T17:38:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ericrihm/conformal-toolkit","commit_stats":null,"previous_names":["ericrihm/conformal-toolkit"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ericrihm/conformal-toolkit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericrihm%2Fconformal-toolkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericrihm%2Fconformal-toolkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericrihm%2Fconformal-toolkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericrihm%2Fconformal-toolkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ericrihm","download_url":"https://codeload.github.com/ericrihm/conformal-toolkit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericrihm%2Fconformal-toolkit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33746513,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["conformal-geometry","differential-geometry","geometric-deep-learning","gjms-operators","mesh-features","pytorch","q-curvature","sagemath","tractor-calculus","willmore"],"created_at":"2026-05-31T20:00:44.526Z","updated_at":"2026-05-31T20:00:47.012Z","avatar_url":"https://github.com/ericrihm.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Conformal Toolkit\n\n[![Tests](https://github.com/ericrihm/conformal-toolkit/actions/workflows/test.yml/badge.svg)](https://github.com/ericrihm/conformal-toolkit/actions/workflows/test.yml)\n[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://python.org)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n[![SageMath 10.x](https://img.shields.io/badge/SageMath-10.x-orange.svg)](https://sagemath.org)\n\n**Symbolic and discrete conformal geometry for SageMath and PyTorch.**\n\nTwo Python packages for computing conformal invariants — geometric quantities unchanged by local stretching — both symbolically (exact formulas via SageMath) and numerically on triangle meshes (GPU-ready via PyTorch). Implements tractor calculus, GJMS operators, Q-curvature, Blitz's conformal fundamental forms, Carroll geometry, and Fefferman-Graham holographic data.\n\n\u003e **This library was independently re-audited for mathematical correctness in May 2026.** Every confirmed error — and exactly how we caught it — is documented in **[ERRATA.md](ERRATA.md)**. We publish the full record on purpose: a teaching tool earns trust by showing its work, mistakes included. See **[\"Verify it yourself\"](#verify-it-yourself)** and **[\"Contributing corrections\"](#contributing-corrections)**.\n\n---\n\n## Quick Start\n\nCompute the Branson Q-curvature exactly on the round 4-sphere, then extract a discrete Willmore feature on a mesh:\n\n```python\n# Symbolic: exact Q₄ on S⁴ via SageMath\nfrom conformal_toolkit import ConformalStructure\ncs = ConformalStructure(g_sphere4)\ncs.q_curvature(order=4)  # → 6   (exact; Branson's Q_n(Sⁿ) = (n-1)! = 3! = 6)\n\n# Discrete: a 4th-order surface feature on an icosphere mesh via PyTorch.\n# NOTE: this returns the Willmore integrand H² − K, NOT the 4D GJMS Q₄\n# (a 2-surface quantity cannot reproduce the 4-manifold value 6 — see ERRATA M15/M16).\nfrom conformal_features.discrete.q_curvature import discrete_q_curvature\nQ4 = discrete_q_curvature(vertices, faces, order=4)\nQ4.mean()  # → 0   (H² − K vanishes on a round sphere of any radius; → 0 under refinement)\n```\n\nThe symbolic formulas ground-truth the geometry; the discrete features are\nmesh-domain analogues — *not* always the same number, and the docs now say which\nis which.\n\n---\n\n## Installation\n\n```bash\n# PyTorch discrete features only (no SageMath needed)\npip install -e \".[ml]\"\n\n# Full development environment\npip install -e \".[dev,ml]\"\n\n# SageMath symbolic package — requires SageMath 10.x\n# Option A: Native (fastest, especially on Apple Silicon)\nmicromamba create -n sage -c conda-forge sage python=3.11 -y\nmicromamba run -n sage sage -python -m pytest tests/test_core/ -v\n\n# Option B: Docker\ndocker compose run sage\n```\n\n---\n\n## What is conformal geometry?\n\nImagine stretching a rubber sheet. Distances change, areas change, but **angles are preserved**. Conformal geometry studies exactly this: properties of shapes that survive arbitrary local stretching.\n\nThis matters because:\n\n- **Physics**: The AdS/CFT correspondence, which connects gravity to quantum field theory, is built on conformal symmetry. The Weyl tensor, Q-curvature, and tractor bundles are the mathematical language.\n- **Computer vision**: Two 3D scans of the same face under different expressions have different metrics but the same conformal structure — conformal features can recognize the face regardless of expression.\n- **Geometry**: The Willmore energy measures how far a surface is from being a round sphere, conformally speaking. Its minimizers (Willmore surfaces) appear in biology (cell membranes), materials science, and geometric analysis.\n\nThis toolkit makes these abstract invariants **computable**.\n\n---\n\n## Examples\n\n### Compute curvature invariants on any Riemannian manifold\n\n```python\nfrom sage.all import Manifold, sin\nfrom conformal_toolkit import ConformalStructure\n\n# The round 2-sphere: ds² = dθ² + sin²θ dφ²\nS = Manifold(2, 'S2', structure='Riemannian')\nchart = S.chart(r'theta:(0,pi) phi:(0,2*pi)')\ntheta, phi = chart[:]\ng = S.metric('g')\ng[0,0] = 1\ng[1,1] = sin(theta)**2\n\ncs = ConformalStructure(g)\n\ncs.ricci_scalar()       # → 2\ncs.schouten()           # → P = (1/2)g  (Schouten tensor)\ncs.q_curvature(order=2) # → 2  (Q₂ = scalar curvature)\ncs.bach()               # → 0  (Bach vanishes — S² is conformally flat)\n```\n\n### Detect if a surface is conformally round (Blitz's theory)\n\nA surface is **umbilical** (conformally equivalent to a sphere) iff L₁ = 0. The conformal fundamental forms ([Blitz–Gover–Waldron, *Indiana Univ. Math. J.* 2023](https://arxiv.org/abs/2107.10381)) are a hierarchy of extrinsic conformal invariants measuring successive orders of non-roundness:\n\n```python\nfrom conformal_toolkit.hypersurface import (\n    conformal_fundamental_form_L1, willmore_density_W2, willmore_density_W4\n)\n\n# Unit sphere S² ⊂ R³: all principal curvatures equal\nL1 = conformal_fundamental_form_L1(h_sphere, L_sphere)\nL1.display()  # → 0  (sphere IS umbilical — conformally round)\n\n# Cylinder S¹×R ⊂ R³: principal curvatures (1, 0)\nL1 = conformal_fundamental_form_L1(h_cyl, L_cyl)\nL1.display()  # → (1/2)dθ⊗dθ + (-1/2)dz⊗dz  (NOT umbilical)\n\nwillmore_density_W2(h_cyl, L_cyl)  # → |L₁|² = 1/2  (Willmore integrand)\n```\n\n### Classify conformal hypersurface invariants\n\nHow many independent conformal invariants does a hypersurface have? Blitz's classification theorem ([arXiv:2212.11711](https://arxiv.org/abs/2212.11711)) gives the answer:\n\n```python\nfrom conformal_toolkit.hypersurface import list_invariants, count_invariants\n\n# Weight-2: always exactly 1 (the Willmore integrand |L₁|²)\ncount_invariants(order=2, ambient_dim=4)  # → 1\n\n# Weight-4: grows with dimension\ncount_invariants(order=4, ambient_dim=3)  # → 1  (just |L₂|²)\ncount_invariants(order=4, ambient_dim=5)  # → 4\n\nfor inv in list_invariants(order=4, ambient_dim=5):\n    print(f\"  {inv['name']}: {inv['formula']}\")\n# → |L₂|², tr(L₁⁴), W·L₁, |W|²\n```\n\n### Extract conformal features for machine learning\n\nNo SageMath required — just PyTorch:\n\n```python\nimport torch\nfrom conformal_features import mesh_conformal_features\n\nvertices = torch.randn(1000, 3)  # your mesh vertices\nfaces = torch.randint(0, 1000, (2000, 3))  # triangle connectivity\n\n# 10D per-vertex features: 7 conformal + 3 isometric invariants\nfeatures = mesh_conformal_features(vertices, faces)  # → (1000, 10)\n\n# Conformal-only (for Möbius-invariant tasks)\nfeatures = mesh_conformal_features(vertices, faces, include_isometry=False)  # → (1000, 7)\n```\n\nThe 10 features per vertex:\n\n| Index | Feature | Invariance | Description |\n|-------|---------|-----------|-------------|\n| 0 | Conformal factor | Conformal | From discrete Yamabe flow |\n| 1 | Willmore density | Conformal | H² (distance from minimality) |\n| 2 | Q₂ | Conformal | Discrete scalar curvature 2K |\n| 3 | Willmore density H²−K | Conformal (integral) | 4th-order surface feature — the Willmore integrand, *not* the 4D GJMS Q₄ ([ERRATA M15](ERRATA.md)) |\n| 4 | Bach norm | Conformal | Bi-Laplacian proxy for non-conformal-flatness |\n| 5–6 | Cross-ratio stats | Möbius | Edge cross-ratio mean and variance |\n| 7 | Gaussian curvature | Isometric | Intrinsic curvature K |\n| 8 | Mean curvature | Isometric | Extrinsic curvature H |\n| 9 | H² − K | Isometric | Alternative Willmore density |\n\n**Conformal features are Möbius-invariant** — they survive inversions and other conformal deformations that destroy standard geometric features like HKS and Gaussian curvature. A shape classifier using conformal features recognizes a Möbius-deformed face; one using HKS does not.\n\n### Work with tractor calculus\n\nTractors are conformal geometry's fundamental algebraic objects — like spinors for conformal symmetry. The standard tractor bundle carries a rank-(n+2) vector bundle with a canonical connection:\n\n```python\nfrom conformal_toolkit.tractor import StandardTractor, thomas_d, tractor_inner\n\n# Thomas D-operator: maps conformal densities to tractors\nT = thomas_d(cs, f, weight=1)\n# → T.sigma = (n + 2w - 2) · w · f      (top slot)\n# → T.mu    = (n + 2w - 2) · ∇f         (middle slot, a 1-form)\n# → T.rho   = −Δf − w · J · f           (bottom slot)\n\n# Tractor inner product: h(I,J) = σρ' + ρσ' + g^{ab}μ_a μ'_b\nh = tractor_inner(cs, T1, T2)\n```\n\n### Compute holographic data from boundary geometry\n\nGiven a boundary metric, compute the bulk Poincaré-Einstein expansion:\n\n```python\nfrom conformal_toolkit.poincare_einstein import fg_expansion, holographic_weyl_anomaly\n\n# Fefferman-Graham: g_bulk = ρ⁻²(dρ² + g₀ + ρ²g₂ + ρ⁴g₄ + ...)\ncoeffs = fg_expansion(g_boundary, order=4)\n# → coeffs[2] = -P(g₀)  (Schouten tensor determines the first correction)\n\n# Holographic Weyl anomaly (the \"a-anomaly\")\nanomaly = holographic_weyl_anomaly(g_boundary)\n# → R/2 for 2D boundary, Q₄ for 4D boundary\n```\n\n### Verify conformal covariance symbolically\n\nThe toolkit can serve as a proof machine — verify that conformal identities hold exactly:\n\n```python\ncs = ConformalStructure(g)\ncs_hat = cs.under_rescaling(omega)\n\n# The Weyl tensor is conformally invariant\n(cs_hat.weyl() - cs.weyl()).display()  # → 0  (for any omega)\n\n# The Bach tensor is conformally invariant in dimension 4\n(cs_hat.bach() - cs.bach()).display()  # → 0\n```\n\n---\n\n## Example Notebooks\n\n| # | Notebook | What it demonstrates |\n|---|---------|---------------------|\n| 01 | [Curvature Invariants](examples/01_willmore_and_curvature.ipynb) | Schouten, Bach, Q-curvature, GJMS on S², S⁴, and flat space |\n| 02 | [Conformal Hypersurface Invariants](examples/02_conformal_fundamental_forms.ipynb) | L₁, L₂, Willmore densities on sphere vs cylinder (Blitz classification) |\n| 03 | [Tractor Calculus](examples/03_tractor_calculus.ipynb) | Standard tractors, tractor connection, Thomas D-operator |\n| 04 | [Poincaré-Einstein](examples/04_poincare_einstein.ipynb) | Fefferman-Graham expansion, holographic anomaly |\n| 05 | [Symbolic → ML Bridge](examples/05_bridge_symbolic_to_ml.ipynb) | Export symbolic invariants, compare to discrete approximations |\n| 06 | [ML Shape Classification](examples/06_ml_shape_classification.ipynb) | Conformal features on meshes, rotation invariance verification |\n\n---\n\n## Architecture\n\n```\nconformal-toolkit/\n├── conformal_toolkit/          # SageMath symbolic package\n│   ├── core/                   # ConformalStructure, Schouten, Bach, Q, GJMS, CKV\n│   ├── tractor/                # Standard tractor bundle, connection, Thomas-D\n│   ├── hypersurface/           # L₁, L₂, Willmore, extrinsic Q, invariant enumeration\n│   ├── carroll/                # Carroll geometry, BMS symmetries\n│   ├── poincare_einstein/      # Fefferman-Graham, holographic data\n│   └── export/                 # tensor_to_numpy, tensor_to_torch\n├── conformal_features/         # PyTorch discrete package (no SageMath needed)\n│   ├── discrete/               # Curvature, Q, Bach, Willmore, cross-ratios, Yamabe, spectral\n│   ├── features/               # mesh_conformal_features() pipeline\n│   └── benchmarks/             # ShapeNet, SHREC, FAUST evaluation (WIP)\n├── tests/                      # 167 tests across both packages\n├── examples/                   # 6 Jupyter notebooks\n└── paper.md                    # JOSS paper draft\n```\n\n---\n\n## Module Reference\n\n### conformal_toolkit (SageMath)\n\n| Module | Key Functions | What it computes |\n|--------|-------------|-----------------|\n| `core` | `ConformalStructure(g)` | Central class wrapping a metric |\n| | `.schouten()` | Schouten tensor P_ab |\n| | `.bach()` | Bach tensor B_ab |\n| | `.q_curvature(order)` | Q-curvature (Q₂ or Q₄) |\n| | `.gjms_operator(f, order)` | GJMS operator (P₂, P₄, or P₆†) |\n| | `.obstruction_tensor()` | Fefferman-Graham obstruction (n=4, 6†) |\n| | `.under_rescaling(omega)` | New structure for e^{2ω}g |\n| `tractor` | `StandardTractor(cs, σ, μ, ρ)` | Section of the rank-(n+2) tractor bundle |\n| | `thomas_d(cs, f, weight)` | Thomas D-operator: density → tractor |\n| | `tractor_connection(cs, I)` | Normal tractor connection ∇^T |\n| `hypersurface` | `conformal_fundamental_form_L1(h, L)` | Trace-free 2nd fundamental form |\n| | `willmore_density_W2(h, L)` | Willmore integrand \\|L₁\\|² |\n| | `list_invariants(order, dim)` | Catalogue of independent invariants |\n| `carroll` | `CarrollStructure(M, v, h)` | Degenerate geometry for c → 0 limit |\n| | `is_bms_symmetry(cs, ξ)` | Check BMS symmetry of a vector field |\n| `poincare_einstein` | `fg_expansion(g₀, order)` | Fefferman-Graham coefficients |\n| | `holographic_weyl_anomaly(g₀)` | Conformal anomaly density |\n| `export` | `conformal_feature_vector(cs)` | Dict of all invariants at a point |\n| | `tensor_to_numpy(T)` | SageMath tensor → NumPy array |\n\n†P₆ computes the leading term (+Δ³) only; exact on conformally flat metrics. Obstruction at n=6 is a leading-order approximation (the Graham–Hirachi normalization constant is not applied — see [ERRATA m3](ERRATA.md)).\n\n### conformal_features (PyTorch)\n\n| Function | Input | Output |\n|----------|-------|--------|\n| `mesh_conformal_features(V, F)` | Vertices (V,3), faces (F,3) | Per-vertex features (V, 7 or 10) |\n| `discrete_gaussian_curvature(V, F)` | Mesh | K per vertex via angle defect |\n| `discrete_mean_curvature(V, F)` | Mesh | H per vertex via cotangent Laplacian |\n| `discrete_q_curvature(V, F, order)` | Mesh | Q₂ or Q₄ per vertex |\n| `discrete_conformal_factor(V, F)` | Mesh | Conformal factor via Yamabe flow |\n| `discrete_cross_ratios(V, F)` | Mesh | Möbius-invariant edge cross-ratios |\n| `cotangent_laplacian(V, F)` | Mesh | Sparse (V,V) cotangent weight matrix |\n| `lbo_eigenvectors(V, F, k)` | Mesh | First k LBO eigenvalues + eigenvectors |\n| `heat_kernel_signature(V, F, k)` | Mesh | HKS descriptors (V, T) |\n| `wave_kernel_signature(V, F, k)` | Mesh | WKS descriptors (V, E) |\n\n---\n\n## Why this toolkit?\n\nExisting tools cover parts of this space, but none bridges symbolic conformal differential geometry with discrete ML features:\n\n| Existing tool | What it does well | What it doesn't cover |\n|--------------|-------------------|----------------------|\n| [SageManifolds](https://sagemanifolds.obspm.fr/) | General differential geometry: Riemann, Ricci, Weyl, Schouten, Cotton | No Q-curvature, GJMS operators, tractor calculus, conformal hypersurface invariants, or ML export |\n| [xAct](https://xact.es/) (Mathematica) | Abstract-index tensor algebra for GR; Weyl tensor | No Schouten, Q-curvature, tractor calculus, or GJMS. Requires Mathematica |\n| [DiffusionNet](https://github.com/nmwsharp/diffusion-net) | Deep learning on meshes via learned diffusion; HKS features | HKS is isometry-invariant, not conformally invariant. No symbolic geometry |\n| [geometry-central](https://geometry-central.net/) / [libigl](https://libigl.github.io/) | Discrete conformal parameterization (BFF, LSCM) | C++/mesh-processing \"conformal\" (angle-preserving maps), not smooth conformal DG |\n| [geomstats](https://geomstats.github.io/) | Riemannian geometry for ML on specific manifolds | Riemannian, not conformal. No Weyl, Q-curvature, tractors |\n\nTo the best of our knowledge, `conformal-toolkit` is the first reusable, Python-accessible implementation of:\n\n1. **Tractor calculus** — standard tractors, tractor connection, Thomas D-operator, tractor curvature\n2. **GJMS operators and Q-curvature** — Paneitz operator P₄, Q₂, Q₄ as general-purpose functions\n3. **Blitz's conformal fundamental forms** — L₁, L₂, Willmore densities, invariant enumeration ([arXiv:2107.10381](https://arxiv.org/abs/2107.10381), [arXiv:2212.11711](https://arxiv.org/abs/2212.11711))\n4. **Symbolic-to-discrete bridge** — the same conformal invariants computed exactly via SageMath and approximately on meshes via PyTorch\n\nPrior computational work exists in FORM scripts (ancillary files of [arXiv:2107.10381](https://arxiv.org/abs/2107.10381)) and narrow Mathematica packages ([Peterson, UND Commons](https://commons.und.edu/data/13/)), but not as a standalone, pip-installable toolkit.\n\n---\n\n## Benchmarks (Work in Progress)\n\nThree CLI tools for evaluating conformal features on standard shape analysis tasks are scaffolded:\n\n```bash\nconformal-shapenet --data-dir ./data/shapenet --feature-set conformal\nconformal-shrec --data-dir ./data/shrec\nconformal-faust --data-dir ./data/faust\n```\n\nFeature extraction and model architectures are implemented; dataset integration and training loops are in progress.\n\n---\n\n## Development\n\n```bash\n# Run all SageMath tests (auto-detects micromamba or Docker)\n./sage-run.sh test\n\n# Run specific symbolic tests\n./sage-run.sh pytest tests/test_core/ -v\n\n# Run discrete tests (PyTorch only, no SageMath needed)\npytest tests/test_discrete/ tests/test_features/ -v\n```\n\n---\n\n## How it's tested — and a SageMath-on-CI recipe you can borrow\n\nThis project has an unusual split that makes a nice teaching example. **SageMath**\nis a large open-source mathematics system (a Python-based computer-algebra system\nbundling [SageManifolds](https://sagemanifolds.obspm.fr/) for exact tensor\ncalculus) — it is *not* a `pip install`, it is a whole math environment. PyTorch,\nby contrast, is an ordinary pip package. So the test suite runs on **two tracks**:\n\n| Track | Needs | Runs | What it checks |\n|-------|-------|------|----------------|\n| **A — symbolic** | SageMath 10.x | `tests/test_core, test_tractor, test_hypersurface, test_carroll, test_pe` | exact conformal-geometry formulas |\n| **B — discrete** | PyTorch (pip) | `tests/test_discrete, test_features` | mesh features on triangle meshes |\n\nEvery push and pull request runs **both** automatically on GitHub Actions\n([`.github/workflows/test.yml`](.github/workflows/test.yml)) — so the symbolic\nformulas in this README are re-verified by a real SageMath install in the cloud,\nnot just asserted. (You can watch it: the green check on a commit means Track A\nrecomputed things like `Q₄(S⁴)=6` from scratch.) In particular,\n`tests/test_pe/test_critical_anchors.py` re-proves the audit's *critical* fixes\non geometries chosen to expose them — the round S³ (where the corrected\nFefferman–Graham `g₄=1/16 g₀` and renormalized volume `v₂=−J/2` differ from the\nold buggy formulas, which only agreed at n=4) and the **non-Einstein** product\nS²(1)×S²(2) (where Bach≠0 and the conformal Laplacian's curvature term is\nnonzero, unlike the Ricci-flat/Einstein metrics that would mask those bugs).\n\nThe part worth stealing if you're learning SageMath: **how to get Sage into CI.**\nSage has no usable pip wheel, but it *is* on conda-forge, so the trick is to\nprovision it with [micromamba](https://github.com/mamba-org/setup-micromamba) and\nrun `pytest` *inside* the Sage Python:\n\n```yaml\n# .github/workflows/test.yml — Track A (SageMath)\n- uses: mamba-org/setup-micromamba@v2\n  with:\n    environment-name: sage\n    create-args: sage python=3.11 pytest   # Sage from conda-forge, ~one cached step\n    channels: conda-forge\n- run: micromamba run -n sage sage -python -m pytest tests/test_core/ -v\n#        └ run pytest with Sage's OWN python, so `from sage.all import …` works\n```\n\nThat `sage -python -m pytest` is the key idea: Sage ships its own Python\ninterpreter, and your tests must run under it. Locally, `./sage-run.sh test`\ndoes the same thing — auto-detecting a native [micromamba](https://github.com/mamba-org/micromamba-releases)\nenv (fastest on Apple Silicon) or falling back to the SageMath Docker image.\n\n---\n\n## Verify it yourself\n\nDon't take our word for any formula — the whole point of a symbolic toolkit is\nthat you can check it. Every correction in [ERRATA.md](ERRATA.md) was caught by\nevaluating a claim on a geometry where the answer is known in closed form. Here\nare the anchors we use; copy them into a Sage session and confirm:\n\n```python\nfrom sage.all import Manifold, sin\nfrom conformal_toolkit import ConformalStructure\n\n# --- Anchor 1: the round 4-sphere, where Branson's Q_n(Sⁿ) = (n-1)! ---\n# On Sⁿ (sectional curvature 1):  Ric = (n-1)g,  R = n(n-1),\n#   Schouten P = ½g,  J = tr P = n/2,  so  Q₄ = -ΔJ - 2|P|² + (n/2)J² = 6.\ncs = ConformalStructure(g_sphere4)\nassert cs.q_curvature(order=4) == 6          # = (4-1)! = 3!  (ERRATA M1)\n\n# --- Anchor 2: the conformal Laplacian carries a curvature term ---\n# P₂ f = Δf - (n-2)/(4(n-1)) R f.  The R-term is NOT optional for n \u003e 2.\n# On S⁴ its coefficient is n(n-2)/4 = 2, never zero.  (ERRATA M2)\n\n# --- Anchor 3: Fefferman-Graham on the hyperbolic filling of Sⁿ ---\n# g_ρ = (1 - ρ²/4)² g₀  ⟹  g₂ = -½ g₀  and  g₄ = 1/16 g₀ exactly.  (ERRATA C1/M11)\n\n# --- Anchor 4 (discrete, PyTorch only): validate on a NON-constant field ---\n# The cotangent Laplacian L is a *stiffness* matrix; for f = x² on a flat mesh,\n# (L f)_i = -2·A_i  while  (M⁻¹ L f)_i = -2  recovers the pointwise Laplacian.\n# \"It vanishes on a sphere\" is a false positive — constants are annihilated by\n# any linear operator.  (ERRATA M17)\n```\n\nThe method generalizes: **reduce a tensor claim to a scalar on a known geometry,\nand check conformal weights as a free checksum.** That single discipline caught\nmost of the errata.\n\n---\n\n## Contributing corrections\n\nWe would rather be corrected than be wrong, and this repository is built to make\nthat easy. **Finding an error we missed is the system working — please send it.**\n\n1. Open an issue titled `Errata: \u003cone-line claim\u003e`.\n2. Give the counter-evidence the way we give ours: a *concrete geometry* (a\n   sphere radius, a flat patch, an explicit metric) on which the claim returns\n   the wrong number, or a *conformal-weight* argument that the terms can't match.\n   A failing check on a named anchor metric is the gold standard.\n3. Propose the corrected formula, stating your normalization convention (Branson\n   vs. analyst signs differ — half of conformal geometry's \"errors\" are\n   convention clashes), with a reference if you have one.\n4. If you can, add a regression test under `tests/` pinning the right value on\n   the anchor. *Verified-on-an-anchor beats argued-in-prose.*\n\nOpen problems where we explicitly want help are listed at the end of\n[ERRATA.md](ERRATA.md) — the complete weight-4 hypersurface invariant basis\n(`M5`), the Fialkow/Weyl terms in `L₂` (`M7`), the full extrinsic `Q₄` (`M8`),\nand the FG `g₄` Bach differential terms (`C1`).\n\n---\n\n## Citation\n\n```bibtex\n@software{conformal_toolkit,\n  author = {Rihm, Eric and Blitz, Samuel},\n  title  = {conformal-toolkit: Symbolic and Discrete Conformal Geometry\n            for SageMath and PyTorch},\n  year   = {2026},\n  url    = {https://github.com/ericrihm/conformal-toolkit}\n}\n```\n\nThe conformal hypersurface module implements theory from:\n\n```bibtex\n@article{blitz2023conformal,\n  author  = {Blitz, Samuel and Gover, A. Rod and Waldron, Andrew},\n  title   = {Conformal Fundamental Forms and the Asymptotically\n             {Poincar\\'{e}--Einstein} Condition},\n  journal = {Indiana University Mathematics Journal},\n  volume  = {72},\n  number  = {6},\n  pages   = {2215--2284},\n  year    = {2023},\n  doi     = {10.1512/iumj.2023.72.9578}\n}\n\n@article{blitz2022classification,\n  author  = {Blitz, Samuel},\n  title   = {Toward a Classification of Conformal Hypersurface Invariants},\n  journal = {Journal of Mathematical Physics},\n  volume  = {64},\n  year    = {2023},\n  doi     = {10.1063/5.0147870}\n}\n\n@article{blitz2024willmore,\n  author  = {Blitz, Samuel and Gover, A. Rod and Waldron, Andrew},\n  title   = {Generalized {W}illmore Energies, {Q}-Curvatures, Extrinsic\n             {P}aneitz Operators, and Extrinsic {L}aplacian Powers},\n  journal = {Communications in Contemporary Mathematics},\n  year    = {2024},\n  doi     = {10.1142/S0219199723500530}\n}\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fericrihm%2Fconformal-toolkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fericrihm%2Fconformal-toolkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fericrihm%2Fconformal-toolkit/lists"}