geomflow 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. geomflow-0.1.0/.DS_Store +0 -0
  2. geomflow-0.1.0/.github/workflows/ci.yml +88 -0
  3. geomflow-0.1.0/.gitignore +90 -0
  4. geomflow-0.1.0/CMakeLists.txt +47 -0
  5. geomflow-0.1.0/LICENSE +21 -0
  6. geomflow-0.1.0/PKG-INFO +264 -0
  7. geomflow-0.1.0/README.md +248 -0
  8. geomflow-0.1.0/examples/cpp/CMakeLists.txt +17 -0
  9. geomflow-0.1.0/examples/cpp/infer_cnf.cpp +299 -0
  10. geomflow-0.1.0/examples/cpp/manifolds/sphere.h +112 -0
  11. geomflow-0.1.0/examples/cpp/manifolds/torus.h +117 -0
  12. geomflow-0.1.0/examples/cpp/train_cnf.cpp +348 -0
  13. geomflow-0.1.0/examples/python/.DS_Store +0 -0
  14. geomflow-0.1.0/examples/python/infer.py +661 -0
  15. geomflow-0.1.0/examples/python/manifolds/sphere.py +57 -0
  16. geomflow-0.1.0/examples/python/manifolds/torus.py +59 -0
  17. geomflow-0.1.0/examples/python/model.py +23 -0
  18. geomflow-0.1.0/examples/python/pv_cpp_vis.py +401 -0
  19. geomflow-0.1.0/examples/python/requirements.txt +5 -0
  20. geomflow-0.1.0/examples/python/scripts/run_sphere.sh +46 -0
  21. geomflow-0.1.0/examples/python/scripts/run_torus.sh +47 -0
  22. geomflow-0.1.0/examples/python/test_smoke.py +46 -0
  23. geomflow-0.1.0/examples/python/train.py +279 -0
  24. geomflow-0.1.0/include/geomflow/adjoint.h +161 -0
  25. geomflow-0.1.0/include/geomflow/connection.h +88 -0
  26. geomflow-0.1.0/include/geomflow/covariant.h +63 -0
  27. geomflow-0.1.0/include/geomflow/divergence.h +53 -0
  28. geomflow-0.1.0/include/geomflow/gradient.h +52 -0
  29. geomflow-0.1.0/include/geomflow/integrator.h +98 -0
  30. geomflow-0.1.0/include/geomflow/manifold.h +40 -0
  31. geomflow-0.1.0/include/geomflow/metric.h +76 -0
  32. geomflow-0.1.0/include/geomflow/objects.h +18 -0
  33. geomflow-0.1.0/include/geomflow/tangent.h +114 -0
  34. geomflow-0.1.0/include/geomflow/vector_field.h +40 -0
  35. geomflow-0.1.0/include/geomflow.h +13 -0
  36. geomflow-0.1.0/pyproject.toml +32 -0
  37. geomflow-0.1.0/python/bindings.cpp +167 -0
  38. geomflow-0.1.0/python/geomflow/__init__.py +133 -0
  39. geomflow-0.1.0/python/geomflow/_preprocess.py +54 -0
  40. geomflow-0.1.0/python/geomflow/_vector_field.py +62 -0
  41. geomflow-0.1.0/python/geomflow/torch/__init__.py +64 -0
  42. geomflow-0.1.0/python/geomflow/torch/_utils.py +30 -0
  43. geomflow-0.1.0/python/geomflow/torch/adjoint.py +132 -0
  44. geomflow-0.1.0/python/geomflow/torch/analytic_metric.py +112 -0
  45. geomflow-0.1.0/python/geomflow/torch/atlas.py +155 -0
  46. geomflow-0.1.0/python/geomflow/torch/fitter.py +259 -0
  47. geomflow-0.1.0/python/geomflow/torch/integrator.py +140 -0
  48. geomflow-0.1.0/python/geomflow/torch/manifolds.py +169 -0
  49. geomflow-0.1.0/python/geomflow/torch/multichart.py +97 -0
  50. geomflow-0.1.0/python/geomflow/torch/multichart_integrator.py +197 -0
  51. geomflow-0.1.0/python/geomflow/torch/operators.py +152 -0
  52. geomflow-0.1.0/python/geomflow/torch/transforms.py +82 -0
  53. geomflow-0.1.0/python/geomflow/torch/vector_field.py +97 -0
  54. geomflow-0.1.0/scripts/compile_cpp.sh +16 -0
  55. geomflow-0.1.0/scripts/visualize.py +263 -0
  56. geomflow-0.1.0/tests/CMakeLists.txt +26 -0
  57. geomflow-0.1.0/tests/test_adjoint.cpp +130 -0
  58. geomflow-0.1.0/tests/test_adjoint.py +50 -0
  59. geomflow-0.1.0/tests/test_cnf.cpp +159 -0
  60. geomflow-0.1.0/tests/test_fitter.py +105 -0
  61. geomflow-0.1.0/tests/test_flow.py +274 -0
  62. geomflow-0.1.0/tests/test_geometry.cpp +148 -0
  63. geomflow-0.1.0/tests/test_multichart_sphere.py +201 -0
  64. geomflow-0.1.0/tests/test_torch.py +176 -0
Binary file
@@ -0,0 +1,88 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+
9
+ jobs:
10
+ build-test:
11
+ name: ${{ matrix.os }} / ${{ matrix.compiler }}
12
+ runs-on: ${{ matrix.os }}
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ os: [ubuntu-24.04, macos-14]
17
+ compiler: [gcc, clang]
18
+ include:
19
+ - os: ubuntu-24.04
20
+ compiler: gcc
21
+ cc: gcc
22
+ cxx: g++
23
+ - os: ubuntu-24.04
24
+ compiler: clang
25
+ cc: clang
26
+ cxx: clang++
27
+ - os: macos-14
28
+ compiler: gcc
29
+ cc: gcc-14
30
+ cxx: g++-14
31
+ - os: macos-14
32
+ compiler: clang
33
+ cc: clang
34
+ cxx: clang++
35
+
36
+ steps:
37
+ - uses: actions/checkout@v4
38
+
39
+ - name: Install dependencies (Linux)
40
+ if: runner.os == 'Linux'
41
+ run: |
42
+ sudo apt-get update
43
+ sudo apt-get install -y cmake build-essential
44
+
45
+ - name: Install dependencies (macOS)
46
+ if: runner.os == 'macOS'
47
+ run: brew install cmake clang-format
48
+
49
+ - name: Configure
50
+ run: |
51
+ CC=${{ matrix.cc }} CXX=${{ matrix.cxx }} \
52
+ cmake -B build -DBUILD_TESTING=ON
53
+
54
+ - name: Build
55
+ run: cmake --build build --target geomflow_tests -j $(nproc 2>/dev/null || sysctl -n hw.logicalcpu)
56
+
57
+ - name: Run tests
58
+ run: ./build/tests/geomflow_tests
59
+
60
+ python-bindings:
61
+ name: Python bindings
62
+ runs-on: ubuntu-24.04
63
+ steps:
64
+ - uses: actions/checkout@v4
65
+
66
+ - uses: actions/setup-python@v5
67
+ with:
68
+ python-version: '3.12'
69
+
70
+ - name: Install system deps
71
+ run: |
72
+ sudo apt-get update
73
+ sudo apt-get install -y cmake build-essential
74
+
75
+ - name: Install key modules
76
+ run: pip install pybind11 numpy torch
77
+
78
+ - name: Get pybind11 CMake dir
79
+ run: echo "PYBIND11_DIR=$(python -c 'import pybind11; print(pybind11.get_cmake_dir())')" >> $GITHUB_ENV
80
+
81
+ - name: Configure
82
+ run: cmake -B build -DBUILD_PYTHON=ON -Dpybind11_DIR=${{ env.PYBIND11_DIR }}
83
+
84
+ - name: Build
85
+ run: cmake --build build -j $(nproc)
86
+
87
+ - name: Import test
88
+ run: PYTHONPATH=python python -c "import geomflow; print(geomflow.EuclideanMetric3D())"
@@ -0,0 +1,90 @@
1
+ gitignore
2
+
3
+ # Prerequisites
4
+ *.d
5
+
6
+ # Compiled Object files
7
+ *.slo
8
+ *.lo
9
+ *.o
10
+ *.obj
11
+
12
+ # Precompiled Headers
13
+ *.gch
14
+ *.pch
15
+
16
+ # Linker files
17
+ *.ilk
18
+
19
+ # Debugger Files
20
+ *.pdb
21
+
22
+ # Compiled Dynamic libraries
23
+ *.so
24
+ *.dylib
25
+ *.dll
26
+ *.so.*
27
+
28
+
29
+ # Fortran module files
30
+ *.mod
31
+ *.smod
32
+
33
+ # Compiled Static libraries
34
+ *.lai
35
+ *.la
36
+ *.a
37
+ *.lib
38
+
39
+ # Executables
40
+ *.exe
41
+ *.out
42
+ *.app
43
+
44
+ # Build directories
45
+ build/
46
+ Build/
47
+ build-*/
48
+
49
+ # CMake generated files
50
+ CMakeFiles/
51
+ CMakeCache.txt
52
+ cmake_install.cmake
53
+ Makefile
54
+ install_manifest.txt
55
+ compile_commands.json
56
+
57
+ # Temporary files
58
+ *.tmp
59
+ *.log
60
+ *.bak
61
+ *.swp
62
+
63
+ # vcpkg
64
+ vcpkg_installed/
65
+
66
+ # debug information files
67
+ *.dwo
68
+
69
+ # test output & cache
70
+ Testing/
71
+ .cache/
72
+
73
+ # Formatting & linter
74
+ .clangd
75
+ .aider*
76
+
77
+ # misc
78
+ .venv/
79
+ .clang-format
80
+ AGENTS.md
81
+ papers/
82
+ auth
83
+ login
84
+ opencode.json
85
+ uv.lock
86
+ *__pycache__/
87
+ *.pt
88
+ *.gif
89
+ *.pdf
90
+ TODO.md
@@ -0,0 +1,47 @@
1
+ cmake_minimum_required(VERSION 3.18)
2
+ project(geomflow LANGUAGES CXX)
3
+
4
+ set(CMAKE_CXX_STANDARD 20)
5
+ set(CMAKE_CXX_EXTENSIONS OFF)
6
+
7
+ # --- Header-only C++ library ---
8
+ add_library(geomflow_headers INTERFACE)
9
+ target_include_directories(geomflow_headers INTERFACE
10
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
11
+ )
12
+
13
+ # --- C++ tests (Catch2) ---
14
+ option(BUILD_TESTS "Build C++ unit tests" ON)
15
+ if(BUILD_TESTS)
16
+ add_subdirectory(tests)
17
+ endif()
18
+
19
+ # --- C++ examples ---
20
+ option(BUILD_EXAMPLES "Build C++ example applications" ON)
21
+ if(BUILD_EXAMPLES)
22
+ add_subdirectory(examples/cpp)
23
+ endif()
24
+
25
+ # --- Python module (pybind11) ---
26
+ option(BUILD_PYTHON "Build Python pybind11 module" OFF)
27
+ if(BUILD_PYTHON)
28
+ find_package(Python COMPONENTS Interpreter Development REQUIRED)
29
+ find_package(pybind11 REQUIRED)
30
+
31
+ pybind11_add_module(_geomflow
32
+ python/bindings.cpp
33
+ )
34
+
35
+ target_link_libraries(_geomflow PRIVATE
36
+ pybind11::module
37
+ )
38
+
39
+ target_include_directories(_geomflow PRIVATE
40
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
41
+ ${Python_INCLUDE_DIRS}
42
+ )
43
+
44
+ set_target_properties(_geomflow PROPERTIES
45
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/python/geomflow"
46
+ )
47
+ endif()
geomflow-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Liiban Mohamud
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,264 @@
1
+ Metadata-Version: 2.2
2
+ Name: geomflow
3
+ Version: 0.1.0
4
+ Summary: Intrinsic Riemannian Manifold Continuous Normalizing Flow Library
5
+ License: MIT
6
+ Requires-Python: >=3.12
7
+ Requires-Dist: torch>=2.0
8
+ Requires-Dist: numpy>=1.24
9
+ Requires-Dist: scipy>=1.10
10
+ Requires-Dist: matplotlib>=3.7
11
+ Requires-Dist: imageio>=2.31
12
+ Provides-Extra: dev
13
+ Requires-Dist: torchdiffeq>=0.2; extra == "dev"
14
+ Requires-Dist: pytest>=7.0; extra == "dev"
15
+ Description-Content-Type: text/markdown
16
+
17
+ # geomflow
18
+
19
+ **General Manifold-Constraint Continuous Normalizing Flows using Intrinsic Riemannian Geometry**
20
+
21
+ `geomflow` is a high-performance, header-only C++20 library and PyTorch framework for Continuous Normalizing Flows (CNFs) on Riemannian manifolds. Built directly on the purely intrinsic manifold formulation I formulated, `geomflow` requires **no ambient space embedding** (such as Whitney's embedding theorem) to evaluate density, integrate flows, or compute adjoint gradients.
22
+
23
+ ---
24
+
25
+ ## Key Features
26
+
27
+ - **Purely Intrinsic Geometry**: All operations—metric tensor $g_{ij}$, Levi-Civita connection $\Gamma_{ij}^k$, divergence $\text{div}_g$, and adjoint gradients—are computed directly on intrinsic coordinate charts.
28
+ - **The Intrinsic Adjoint ODE (Theorem 3.7)**: Memory-efficient backward adjoint ODE solver derived entirely from intrinsic manifold quantities:
29
+ $$\dot{\lambda}(t) + \langle \lambda(t), \nabla f_\theta \rangle = \nabla (\text{div}_g f_\theta)$$
30
+ - **High-Level PyTorch Fitter (`geomflow.torch.ManifoldCNF`)**: Intuitive, scikit-learn-style API with `.fit(data)`, `.log_prob(x)`, and `.sample(n)`.
31
+ - **Multi-Chart Atlas Support**: Seamless dynamic chart-switching during flow integration across coordinate patches with overlap consistency loss.
32
+ - **Built-in Manifold Presets**:
33
+ - **Sphere $S^d$**: Stereographic multi-chart atlas & single-chart metrics.
34
+ - **Torus $T^2$**: Flat periodic angle coordinate metrics.
35
+ - **Hyperbolic Space $\mathbb{H}^d$**: Poincaré disk model metric.
36
+ - **Euclidean Space $\mathbb{R}^d$**: Standard flat space.
37
+ - **Induced Submanifold Metrics**: Automatic pullback metrics $G(x) = J_\phi(x)^T J_\phi(x)$ for arbitrary immersions $\phi: U \subset \mathbb{R}^d \to \mathbb{R}^N$.
38
+ - **C++20 Header-Only Core**: Zero-dependency C++ template headers for embedding into native C++ graphics, physics, or simulation pipelines.
39
+
40
+ ---
41
+
42
+ ## Installation
43
+
44
+ ### Python (PyTorch)
45
+
46
+ ```bash
47
+ git clone https://github.com/LiibanMo/geomflow.git
48
+ cd geomflow
49
+ pip install -e .
50
+ ```
51
+
52
+ Requirements: `torch >= 2.0`, `numpy`, `scipy`.
53
+
54
+ ### C++20 Header-Only Library
55
+
56
+ Simply add `include/` to your project's include paths, or integrate via CMake:
57
+
58
+ ```cmake
59
+ add_subdirectory(geomflow)
60
+ target_link_libraries(your_target PRIVATE geomflow_headers)
61
+ ```
62
+
63
+ Build C++ tests and examples:
64
+
65
+ ```bash
66
+ cmake -B build -DBUILD_TESTS=ON -DBUILD_EXAMPLES=ON
67
+ cmake --build build
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Python Usage & Examples
73
+
74
+ ### 1. High-Level Manifold CNF Fitting (`ManifoldCNF`)
75
+
76
+ Fit a density model on a manifold using built-in presets in just a few lines:
77
+
78
+ ```python
79
+ import torch
80
+ from geomflow import ManifoldCNF, Sphere2DAtlas, Torus2D, PoincareDisk
81
+
82
+ # 1. Select geometry: 2-chart stereographic sphere atlas
83
+ manifold = Sphere2DAtlas(n_samples=500)
84
+
85
+ # 2. Instantiate high-level ManifoldCNF
86
+ cnf = ManifoldCNF(manifold, hidden_dim=64, dt=0.05)
87
+
88
+ # 3. Create target data on manifold
89
+ data = torch.randn(256, 2) * 0.2 + torch.tensor([1.0, 1.0])
90
+
91
+ # 4. Fit density with Adam optimizer & overlap consistency
92
+ loss_history = cnf.fit(data, epochs=50, batch_size=32, lr=0.01)
93
+
94
+ # 5. Evaluate exact Riemannian log-likelihood log p(x)
95
+ log_p = cnf.log_prob(data[:5])
96
+ print("Sample Log Probabilities:", log_p)
97
+
98
+ # 6. Draw new samples from the fitted CNF on the manifold
99
+ samples, final_chart = cnf.sample(n_samples=100)
100
+ print("Generated Samples Shape:", samples.shape)
101
+ ```
102
+
103
+ ---
104
+
105
+ ### 2. Custom Manifolds via Induced Submanifold Metric
106
+
107
+ Define custom manifolds by providing an explicit embedding map $\phi: U \subset \mathbb{R}^d \to \mathbb{R}^N$:
108
+
109
+ ```python
110
+ import torch
111
+ from geomflow import ManifoldCNF, InducedMetric
112
+
113
+ # Define surface z = x^2 + y^2 embedded in R^3
114
+ def paraboloid_immersion(x: torch.Tensor) -> torch.Tensor:
115
+ z = (x * x).sum(dim=-1, keepdim=True)
116
+ return torch.cat([x, z], dim=-1)
117
+
118
+ # Automatically derives metric G(x) = J_phi(x)^T * J_phi(x)
119
+ metric = InducedMetric(dim=2, immersion_fn=paraboloid_immersion)
120
+
121
+ cnf = ManifoldCNF(metric, hidden_dim=32)
122
+ data = torch.randn(128, 2) * 0.5
123
+ cnf.fit(data, epochs=20)
124
+ ```
125
+
126
+ ---
127
+
128
+ ### 3. Custom Closed-Form Metric & Operators
129
+
130
+ Define custom analytic metrics $g_{ij}(x)$ directly and execute intrinsic operators:
131
+
132
+ ```python
133
+ import torch
134
+ from geomflow import AnalyticMetric, christoffel, divergence, gradient
135
+
136
+ # Custom metric function G(x)
137
+ def custom_metric_fn(x: torch.Tensor) -> torch.Tensor:
138
+ # Example: scaled metric g_ij = (1 + ||x||^2) * delta_ij
139
+ scale = 1.0 + (x * x).sum(dim=-1, keepdim=True)
140
+ eye = torch.eye(2, device=x.device, dtype=x.dtype)
141
+ return scale.unsqueeze(-1) * eye
142
+
143
+ metric = AnalyticMetric(dim=2, metric_fn=custom_metric_fn)
144
+
145
+ x = torch.randn(4, 2, requires_grad=True)
146
+
147
+ # Intrinsic Christoffel symbols Gamma^k_ij
148
+ Gamma = christoffel(metric, x) # (4, 2, 2, 2)
149
+
150
+ # Intrinsic vector field divergence div_g(f)
151
+ vf = lambda x_: 0.5 * x_
152
+ div_val = divergence(vf, x, metric) # (4,)
153
+ ```
154
+
155
+ ---
156
+
157
+ ### 4. The Intrinsic Adjoint ODE (Theorem 3.7)
158
+
159
+ For memory-efficient backpropagation without saving intermediate ODE trajectory states:
160
+
161
+ ```python
162
+ import torch
163
+ from geomflow import EuclideanSpace, ManifoldVectorField, IntrinsicAdjointFunction
164
+
165
+ metric = EuclideanSpace(dim=2)
166
+ vf = ManifoldVectorField(dim=2, hidden_dim=32)
167
+ data = torch.randn(16, 2, requires_grad=True)
168
+
169
+ # Compute loss and gradients using Theorem 3.7 intrinsic adjoint ODE
170
+ loss = IntrinsicAdjointFunction.apply(data, vf, metric, 0.05, 0.0, 1.0)
171
+ loss.backward()
172
+
173
+ print("Gradients w.r.t. input data:", data.grad.shape)
174
+ ```
175
+
176
+ ---
177
+
178
+ ## C++20 Usage & Examples
179
+
180
+ `geomflow` provides a header-only C++20 library under `include/geomflow/`.
181
+
182
+ ```cpp
183
+ #include <iostream>
184
+ #include <geomflow/geomflow.h>
185
+
186
+ int main() {
187
+ using Traits = geomflow::ManifoldTraits<3>;
188
+ using Metric = geomflow::EuclideanMetric<Traits>;
189
+ using Tangent = geomflow::TangentVector<Traits>;
190
+
191
+ Metric metric;
192
+
193
+ // Time-dependent vector field f_theta(t, x)
194
+ auto field_fn = [](double t, const auto &x, const auto &theta) {
195
+ (void)t; (void)x;
196
+ return Tangent({theta[0], theta[1], theta[2]});
197
+ };
198
+
199
+ geomflow::ParametrizedVectorField<Traits, Metric> field(metric, field_fn);
200
+ field.set_params({0.5, -0.2, 1.0});
201
+
202
+ // Integrated flow from t0 = 0 to t1 = 1
203
+ geomflow::FlowIntegrator<Traits, Metric, decltype(field)> integrator(metric, field);
204
+ auto result = integrator.integrate({0.0, 0.0, 0.0}, 0.0, 1.0, 0.01);
205
+
206
+ std::cout << "Final position x(1): ["
207
+ << result.x_final[0] << ", "
208
+ << result.x_final[1] << ", "
209
+ << result.x_final[2] << "]\n";
210
+ std::cout << "Integrated log-det-Jacobian: " << result.log_det << "\n";
211
+
212
+ // Adjoint solver for parameter gradients (Theorem 3.7)
213
+ geomflow::CotangentVector<Traits> initial_adj({result.x_final[0], result.x_final[1], result.x_final[2]});
214
+ geomflow::AdjointSolver<Traits, Metric, decltype(field)> adjoint(metric, field);
215
+ auto grad = adjoint.compute_gradient({0.0, 0.0, 0.0}, 0.0, 1.0, 0.01, initial_adj);
216
+
217
+ std::cout << "Gradient dL/d_theta: ["
218
+ << grad[0] << ", " << grad[1] << ", " << grad[2] << "]\n";
219
+
220
+ return 0;
221
+ }
222
+ ```
223
+
224
+ ---
225
+
226
+ ## Repository Structure
227
+
228
+ ```
229
+ geomflow/
230
+ ├── include/
231
+ │ └── geomflow/ — C++20 header-only core
232
+ │ ├── adjoint.h — Intrinsic adjoint ODE solver (Theorem 3.7)
233
+ │ ├── connection.h — Levi-Civita connection & Christoffel symbols
234
+ │ ├── covariant.h — Covariant derivative tensor
235
+ │ ├── divergence.h — Intrinsic divergence operator
236
+ │ ├── integrator.h — Flow integrator with log-det Jacobian
237
+ │ ├── metric.h — Riemannian metric protocol & Euclidean metric
238
+ │ └── vector_field.h — Parameterized vector fields
239
+ ├── python/
240
+ │ └── geomflow/
241
+ │ └── torch/ — PyTorch framework (geomflow.torch)
242
+ │ ├── analytic_metric.py — Analytic metric protocol
243
+ │ ├── atlas.py — Multi-chart atlas & validity balls
244
+ │ ├── fitter.py — High-level ManifoldCNF fitter API
245
+ │ ├── manifolds.py — Presets (Sphere, Torus, Hyperbolic, Induced)
246
+ │ ├── multichart.py — Multi-chart vector fields & overlap loss
247
+ │ ├── multichart_integrator.py — Dynamic chart-switching RK4 solver
248
+ │ ├── operators.py — Intrinsic geometric differential operators
249
+ │ └── adjoint.py — Mohamud intrinsic adjoint autograd Function
250
+ └── tests/ — Comprehensive test suite
251
+ ```
252
+
253
+ ---
254
+
255
+ ## References
256
+
257
+ 1. **Mohamud, L.** — *The Derivation of the Dynamic Chart Manifold Neural ODE Solver*.
258
+ 2. **Lou, A., Lim, D., Isola, P., & Sra, S.** — *Neural Manifold ODEs*. Advances in Neural Information Processing Systems (NeurIPS 2020), arXiv:2006.10254.
259
+
260
+ ---
261
+
262
+ ## License
263
+
264
+ MIT License.