anyakrakusuma 0.0.1__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sandy H. S. Herho, Iwan P. Anwar, Faruq Khadami, Rusmawan Suwarman, Dasapta E. Irawan
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,304 @@
1
+ Metadata-Version: 2.3
2
+ Name: anyakrakusuma
3
+ Version: 0.0.1
4
+ Summary: 2D Schrödinger Bridge Solver via Entropic Optimal Transport with Log-Domain Sinkhorn
5
+ License: MIT
6
+ Keywords: optimal-transport,schrodinger-bridge,sinkhorn,entropic-regularization,computational-physics
7
+ Author: Sandy H. S. Herho
8
+ Requires-Python: >=3.8,<4.0
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
20
+ Classifier: Topic :: Scientific/Engineering :: Physics
21
+ Requires-Dist: matplotlib (>=3.3.0)
22
+ Requires-Dist: netCDF4 (>=1.5.0)
23
+ Requires-Dist: numba (>=0.53.0)
24
+ Requires-Dist: numpy (>=1.20.0)
25
+ Requires-Dist: pandas (>=1.3.0)
26
+ Requires-Dist: scipy (>=1.7.0)
27
+ Requires-Dist: tqdm (>=4.60.0)
28
+ Description-Content-Type: text/markdown
29
+
30
+ # `anyakrakusuma`: 2D Schrödinger Bridge Solver via Entropic Optimal Transport
31
+
32
+ [![DOI](https://zenodo.org/badge/1136688443.svg)](https://doi.org/10.5281/zenodo.18287395)
33
+ [![Python](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/downloads/)
34
+ [![PyPI](https://img.shields.io/pypi/v/anyakrakusuma-eot-solver.svg)](https://pypi.org/project/anyakrakusuma-eot-solver/)
35
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
36
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
37
+ [![NumPy](https://img.shields.io/badge/NumPy-%23013243.svg?logo=numpy&logoColor=white)](https://numpy.org/)
38
+ [![SciPy](https://img.shields.io/badge/SciPy-%230C55A5.svg?logo=scipy&logoColor=white)](https://scipy.org/)
39
+ [![Matplotlib](https://img.shields.io/badge/Matplotlib-%23ffffff.svg?logo=Matplotlib&logoColor=black)](https://matplotlib.org/)
40
+ [![Pandas](https://img.shields.io/badge/pandas-%23150458.svg?logo=pandas&logoColor=white)](https://pandas.pydata.org/)
41
+ [![netCDF4](https://img.shields.io/badge/netCDF4-%23004B87.svg)](https://unidata.github.io/netcdf4-python/)
42
+ [![Numba](https://img.shields.io/badge/Numba-%2300A3E0.svg?logo=numba&logoColor=white)](https://numba.pydata.org/)
43
+ [![Pillow](https://img.shields.io/badge/Pillow-%23000000.svg)](https://python-pillow.org/)
44
+ [![tqdm](https://img.shields.io/badge/tqdm-%23FFC107.svg)](https://tqdm.github.io/)
45
+
46
+
47
+ > The nomenclature `anyakrakusuma` is directly derived from the regnal titulature of **Sultan Agung of Mataram** (r. 1613–1645), the third and most formidable ruler of the Mataram Sultanate in Java. Born as **Raden Mas Jatmika** (also known as *Raden Mas Rangsang*), he initially adopted the title **Susuhunan Anyakrakusuma** (or *Prabu Pandita Anyakrakusuma*) upon his accession in 1613, a period marked by his aggressive consolidation of power across Central and East Java. His reign is historically distinguished by his staunch military campaigns against the Dutch East India Company (VOC) in Batavia (1628–1629) and his cultural synthesis of Javanese and Islamic traditions, most notably the creation of the Javanese calendar. In 1641, following an investiture by the envoy of Sharif Zaid ibnu Muhsin Al Hasyimi of Mecca, he consecrated his authority with the supreme title **Sultan Abdullah Muhammad Maulana Matarani al-Jawi**, yet he remains immortalized in Javanese historiography by his syncretic honorific: **Sultan Agung Adi Prabu Anyakrakusuma Senapati ing Ngalaga Abdurrahman Sayyidin Panatagama Khalifatullah Tanah Jawi**, identifying him as the "Great Sultan," the supreme ruler, and the commander of the faithful in the land of Java.
48
+
49
+
50
+ ## Overview
51
+
52
+ `anyakrakusuma` is a high-performance Python solver for the **Schrödinger Bridge Problem (SBP)** via **Entropic Optimal Transport (EOT)**. The Schrödinger Bridge computes the most likely stochastic evolution between two probability distributions, combining the geometric structure of optimal transport with the diffusive dynamics of Brownian motion.
53
+
54
+ This solver implements the **log-domain Sinkhorn-Knopp algorithm** for numerical stability, achieving robust convergence even with small regularization parameters. The implementation leverages **Numba JIT compilation** with parallel processing for significant performance gains (10-100× speedup) on large-scale particle systems.
55
+
56
+ **Key Applications:**
57
+ - Generative modeling and distribution morphing
58
+ - Stochastic process interpolation
59
+ - Computational biology (cell trajectory inference)
60
+ - Machine learning (diffusion models, score matching)
61
+ - Statistical physics (entropy-regularized transport)
62
+
63
+ **Note:** This package provides **2D visualization** of particle transport dynamics.
64
+
65
+ ## Physics
66
+
67
+ ### The Schrödinger Bridge Problem
68
+
69
+ The Schrödinger Bridge Problem seeks the most likely evolution of a diffusion process $X_t$ constrained to have marginals $\rho_0$ at $t=0$ and $\rho_1$ at $t=T$.
70
+
71
+ The solution satisfies the **Schrödinger system** (coupled via Feynman-Kac):
72
+
73
+ $$\partial_t \varphi(x,t) = \frac{\varepsilon}{2} \Delta \varphi(x,t) \quad \text{(forward heat equation)}$$
74
+
75
+ $$\partial_t \psi(x,t) = -\frac{\varepsilon}{2} \Delta \psi(x,t) \quad \text{(backward heat equation)}$$
76
+
77
+ with boundary conditions:
78
+ - $\varphi(x,0)\psi(x,0) = \rho_0(x)$
79
+ - $\varphi(x,T)\psi(x,T) = \rho_1(x)$
80
+
81
+ The marginal at time $t$ is: $\rho_t(x) = \varphi(x,t)\psi(x,t)$
82
+
83
+ ### Entropic Optimal Transport Formulation
84
+
85
+ For discrete measures $\mu = \sum_i a_i \delta_{x_i}$ and $\nu = \sum_j b_j \delta_{y_j}$, the entropic optimal transport problem is:
86
+
87
+ $$\min_{\pi \in \Pi(\mu,\nu)} \langle C, \pi \rangle + \varepsilon H(\pi | \mu \otimes \nu)$$
88
+
89
+ where:
90
+ - $C_{ij} = \|x_i - y_j\|^2$ is the squared Euclidean cost
91
+ - $H(\pi | \mu \otimes \nu)$ is the Kullback-Leibler divergence
92
+ - $\varepsilon > 0$ is the entropic regularization (diffusivity)
93
+ - $\Pi(\mu,\nu)$ is the set of couplings with marginals $\mu$ and $\nu$
94
+
95
+ The optimal coupling has the form $\pi^*_{ij} = u_i K_{ij} v_j$ where:
96
+ - $K = \exp(-C/\varepsilon)$ is the **Gibbs kernel** (heat kernel for squared distance)
97
+ - $u, v$ are the **Sinkhorn potentials** found by iterative scaling
98
+
99
+ ### Schrödinger Bridge Displacement Interpolation
100
+
101
+ The Schrödinger bridge displacement interpolation at time $t \in [0,1]$:
102
+
103
+ $$X_t = (1-t)X_0 + t X_1 + \sqrt{\varepsilon \cdot t(1-t)} \cdot Z, \quad Z \sim \mathcal{N}(0, I)$$
104
+
105
+ where $(X_0, X_1)$ are coupled via the optimal entropic plan $\pi^*$.
106
+
107
+ **Physical Interpretation:**
108
+ - **Deterministic drift**: $(1-t)X_0 + tX_1$ — linear interpolation (McCann geodesic)
109
+ - **Stochastic diffusion**: $\sqrt{\varepsilon \cdot t(1-t)} \cdot Z$ — Brownian bridge correction
110
+ - The diffusion term vanishes at $t=0$ and $t=1$, ensuring exact boundary conditions
111
+
112
+ ### Key Theoretical Properties
113
+
114
+ 1. **Entropy Production**: The entropy of $\rho_t$ follows a parabolic profile
115
+ 2. **Cost Decomposition**: Transport cost = Wasserstein cost + Entropic regularization
116
+ 3. **Marginal Constraints**: $\sum_j \pi_{ij} = a_i$ and $\sum_i \pi_{ij} = b_j$
117
+ 4. **Plan Positivity**: $\pi_{ij} > 0$ for all $i,j$ (full support)
118
+
119
+ ## Numerical Methods
120
+
121
+ ### Log-Domain Sinkhorn Algorithm
122
+
123
+ The Sinkhorn iterations in log-domain for numerical stability:
124
+
125
+ $$f^{n+1} = \varepsilon \log(a) - \varepsilon \cdot \text{LSE}_j\left(\frac{g^n - C}{\varepsilon}\right)$$
126
+
127
+ $$g^{n+1} = \varepsilon \log(b) - \varepsilon \cdot \text{LSE}_i\left(\frac{f^{n+1} - C^\top}{\varepsilon}\right)$$
128
+
129
+ where $\text{LSE}$ is the log-sum-exp operator with max-trick for stability:
130
+
131
+ $$\text{LSE}(x) = \max(x) + \log\left(\sum_i \exp(x_i - \max(x))\right)$$
132
+
133
+ ### Convergence Criterion
134
+
135
+ Marginal constraint violation:
136
+
137
+ $$\text{error} = \left\|\pi \mathbf{1} - a\right\|_1$$
138
+
139
+ ### Novel Diagnostic Metrics
140
+
141
+ | Metric | Formula | Physical Meaning |
142
+ |--------|---------|------------------|
143
+ | **Wasserstein Cost** | $W = \langle C, \pi^* \rangle$ | Total transport work |
144
+ | **Plan Entropy** | $H = -\sum_{ij} \pi_{ij} \log(\pi_{ij})$ | Coupling uncertainty |
145
+ | **Effective Sparsity** | $S_{\text{eff}} = \exp(H) / nm$ | Normalized plan support |
146
+ | **Bridge Diffusivity** | $D_{\text{bridge}} = \varepsilon \cdot \mathbb{E}[t(1-t)]$ | Average stochastic spread |
147
+ | **Marginal Fidelity** | $1 - \|\pi\mathbf{1} - a\|_1$ | Constraint satisfaction |
148
+ | **Iteration Efficiency** | $\eta = -\log(\text{tol})/n_{\text{iter}}$ | Convergence rate per iteration |
149
+
150
+ ## Features
151
+
152
+ - **Log-domain stability**: Robust convergence for small $\varepsilon$
153
+ - **Adaptive convergence**: Automatic iteration based on marginal error
154
+ - **High-performance computing**: Numba JIT compilation (10-100× speedup)
155
+ - **Parallel processing**: Multi-core CPU utilization via `prange`
156
+ - **Professional 2D visualization**: Animated particle transport
157
+ - **Comprehensive diagnostics**: Static PNG with convergence curves
158
+ - **Scientific data formats**: NetCDF4 (CF-1.8) and CSV output
159
+ - **Comparable test cases**: Four scenarios with increasing complexity
160
+
161
+ ## Directory Structure
162
+
163
+ ```
164
+ anyakrakusuma/
165
+ ├── configs/ # Simulation configuration files
166
+ │ ├── case1_circle_to_circle.txt # Baseline: concentric circles
167
+ │ ├── case2_spiral_to_gaussian.txt # Topology change
168
+ │ ├── case3_moons_to_moons.txt # Symmetric rotation
169
+ │ └── case4_lissajous_to_trefoil.txt # Complex curves
170
+
171
+ ├── src/anyakrakusuma_eot/ # Main package source
172
+ │ ├── __init__.py # Package initialization
173
+ │ ├── cli.py # Command-line interface
174
+ │ │
175
+ │ ├── core/ # Core numerical algorithms
176
+ │ │ ├── __init__.py
177
+ │ │ ├── solver.py # Sinkhorn solver (log-domain)
178
+ │ │ └── distributions.py # Point cloud generators
179
+ │ │
180
+ │ ├── io/ # Input/output handlers
181
+ │ │ ├── __init__.py
182
+ │ │ ├── config_manager.py # Configuration file parser
183
+ │ │ └── data_handler.py # NetCDF/CSV writer
184
+ │ │
185
+ │ ├── visualization/ # Animation and plotting
186
+ │ │ ├── __init__.py
187
+ │ │ └── animator.py # 2D GIF generator + diagnostics
188
+ │ │
189
+ │ └── utils/ # Utilities
190
+ │ ├── __init__.py
191
+ │ ├── logger.py # Simulation logging
192
+ │ └── timer.py # Performance profiling
193
+
194
+ ├── tests/ # Unit tests
195
+ │ ├── __init__.py
196
+ │ ├── test_solver.py # Solver correctness tests
197
+ │ └── test_distributions.py # Distribution generator tests
198
+
199
+ ├── outputs/ # Generated results (created at runtime)
200
+ │ ├── *.nc # NetCDF data files
201
+ │ ├── *.csv # CSV metric summaries
202
+ │ ├── *_diagnostics.png # Static convergence plots
203
+ │ └── *.gif # Animation files
204
+
205
+ ├── logs/ # Simulation logs (created at runtime)
206
+ │ └── *.log
207
+
208
+ ├── pyproject.toml # Poetry build configuration
209
+ ├── README.md # This file
210
+ ├── LICENSE # MIT license
211
+ └── .gitignore # Git ignore patterns
212
+ ```
213
+
214
+ ## Installation
215
+
216
+ **From PyPI:**
217
+ ```bash
218
+ pip install anyakrakusuma
219
+ ```
220
+
221
+ **From source:**
222
+ ```bash
223
+ git clone https://github.com/sandyherho/anyakrakusuma.git
224
+ cd anyakrakusuma
225
+ pip install -e .
226
+ ```
227
+
228
+ ## Quick Start
229
+
230
+ **Command line:**
231
+ ```bash
232
+ anyakrakusuma case1 # Circle to circle
233
+ anyakrakusuma case4 --cores 8 # Complex case with 8 cores
234
+ anyakrakusuma --all # Run all cases
235
+ ```
236
+
237
+ **Python API:**
238
+ ```python
239
+ from anyakrakusuma_eot import SchrodingerBridgeSolver, generate_circle, generate_spiral
240
+
241
+ # Initialize solver
242
+ solver = SchrodingerBridgeSolver(n_cores=8, verbose=True)
243
+
244
+ # Generate distributions
245
+ X_source = generate_circle(n=1000, radius=1.0)
246
+ X_target = generate_spiral(n=1000, turns=2.0)
247
+
248
+ # Solve Schrödinger Bridge
249
+ result = solver.solve(
250
+ X_source, X_target,
251
+ epsilon=0.05,
252
+ max_iter=2000,
253
+ tol=1e-9
254
+ )
255
+
256
+ # Check convergence
257
+ print(f"Transport cost: {result['cost']:.6f}")
258
+ print(f"Converged: {result['converged']}")
259
+ ```
260
+
261
+ ## Test Cases (Comparable)
262
+
263
+ All test cases use the same number of particles (n=1000) and similar computational settings to enable direct comparison of transport characteristics.
264
+
265
+ | Case | Source → Target | $\varepsilon$ | Key Insight |
266
+ |------|-----------------|---------------|-------------|
267
+ | 1 | Circle (r=1) → Circle (r=2) | 0.02 | Baseline radial scaling |
268
+ | 2 | Spiral → Gaussian mixture | 0.05 | Topology dissolution |
269
+ | 3 | Two moons → Two moons (rotated) | 0.03 | Symmetric interchange |
270
+ | 4 | Lissajous (3:2) → Trefoil knot | 0.04 | Complex curve morphing |
271
+
272
+ **Comparison Metrics (per case):**
273
+ - Wasserstein cost (transport effort)
274
+ - Sinkhorn iterations (convergence difficulty)
275
+ - Plan entropy (coupling complexity)
276
+ - Effective sparsity (plan structure)
277
+
278
+
279
+ ## Citation
280
+
281
+ If you use this software in your study, please cite:
282
+
283
+ ```bibtex
284
+ @software{herho2026anyakrakusuma,
285
+ title = {{anyakrakusuma: 2D Schrödinger Bridge Solver via Entropic Optimal Transport}},
286
+ author = {Herho, Sandy H. S. and Anwar, Iwan P. and Khadami, Faruq and Suwarman, Rusmawan and Irawan, Dasapta E.},
287
+ year = {2026},
288
+ version = {0.0.1},
289
+ url = {https://github.com/sandyherho/anyakrakusuma}
290
+ }
291
+ ```
292
+
293
+ ## Authors
294
+
295
+ - Sandy H. S. Herho (sandy.herho@ronininstitute.org)
296
+ - Iwan P. Anwar
297
+ - Faruq Khadami
298
+ - Rusmawan Suwarman
299
+ - Dasapta E. Irawan
300
+
301
+ ## License
302
+
303
+ MIT License - See [LICENSE](LICENSE) for details.
304
+
@@ -0,0 +1,274 @@
1
+ # `anyakrakusuma`: 2D Schrödinger Bridge Solver via Entropic Optimal Transport
2
+
3
+ [![DOI](https://zenodo.org/badge/1136688443.svg)](https://doi.org/10.5281/zenodo.18287395)
4
+ [![Python](https://img.shields.io/badge/python-3.8%2B-blue.svg)](https://www.python.org/downloads/)
5
+ [![PyPI](https://img.shields.io/pypi/v/anyakrakusuma-eot-solver.svg)](https://pypi.org/project/anyakrakusuma-eot-solver/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
8
+ [![NumPy](https://img.shields.io/badge/NumPy-%23013243.svg?logo=numpy&logoColor=white)](https://numpy.org/)
9
+ [![SciPy](https://img.shields.io/badge/SciPy-%230C55A5.svg?logo=scipy&logoColor=white)](https://scipy.org/)
10
+ [![Matplotlib](https://img.shields.io/badge/Matplotlib-%23ffffff.svg?logo=Matplotlib&logoColor=black)](https://matplotlib.org/)
11
+ [![Pandas](https://img.shields.io/badge/pandas-%23150458.svg?logo=pandas&logoColor=white)](https://pandas.pydata.org/)
12
+ [![netCDF4](https://img.shields.io/badge/netCDF4-%23004B87.svg)](https://unidata.github.io/netcdf4-python/)
13
+ [![Numba](https://img.shields.io/badge/Numba-%2300A3E0.svg?logo=numba&logoColor=white)](https://numba.pydata.org/)
14
+ [![Pillow](https://img.shields.io/badge/Pillow-%23000000.svg)](https://python-pillow.org/)
15
+ [![tqdm](https://img.shields.io/badge/tqdm-%23FFC107.svg)](https://tqdm.github.io/)
16
+
17
+
18
+ > The nomenclature `anyakrakusuma` is directly derived from the regnal titulature of **Sultan Agung of Mataram** (r. 1613–1645), the third and most formidable ruler of the Mataram Sultanate in Java. Born as **Raden Mas Jatmika** (also known as *Raden Mas Rangsang*), he initially adopted the title **Susuhunan Anyakrakusuma** (or *Prabu Pandita Anyakrakusuma*) upon his accession in 1613, a period marked by his aggressive consolidation of power across Central and East Java. His reign is historically distinguished by his staunch military campaigns against the Dutch East India Company (VOC) in Batavia (1628–1629) and his cultural synthesis of Javanese and Islamic traditions, most notably the creation of the Javanese calendar. In 1641, following an investiture by the envoy of Sharif Zaid ibnu Muhsin Al Hasyimi of Mecca, he consecrated his authority with the supreme title **Sultan Abdullah Muhammad Maulana Matarani al-Jawi**, yet he remains immortalized in Javanese historiography by his syncretic honorific: **Sultan Agung Adi Prabu Anyakrakusuma Senapati ing Ngalaga Abdurrahman Sayyidin Panatagama Khalifatullah Tanah Jawi**, identifying him as the "Great Sultan," the supreme ruler, and the commander of the faithful in the land of Java.
19
+
20
+
21
+ ## Overview
22
+
23
+ `anyakrakusuma` is a high-performance Python solver for the **Schrödinger Bridge Problem (SBP)** via **Entropic Optimal Transport (EOT)**. The Schrödinger Bridge computes the most likely stochastic evolution between two probability distributions, combining the geometric structure of optimal transport with the diffusive dynamics of Brownian motion.
24
+
25
+ This solver implements the **log-domain Sinkhorn-Knopp algorithm** for numerical stability, achieving robust convergence even with small regularization parameters. The implementation leverages **Numba JIT compilation** with parallel processing for significant performance gains (10-100× speedup) on large-scale particle systems.
26
+
27
+ **Key Applications:**
28
+ - Generative modeling and distribution morphing
29
+ - Stochastic process interpolation
30
+ - Computational biology (cell trajectory inference)
31
+ - Machine learning (diffusion models, score matching)
32
+ - Statistical physics (entropy-regularized transport)
33
+
34
+ **Note:** This package provides **2D visualization** of particle transport dynamics.
35
+
36
+ ## Physics
37
+
38
+ ### The Schrödinger Bridge Problem
39
+
40
+ The Schrödinger Bridge Problem seeks the most likely evolution of a diffusion process $X_t$ constrained to have marginals $\rho_0$ at $t=0$ and $\rho_1$ at $t=T$.
41
+
42
+ The solution satisfies the **Schrödinger system** (coupled via Feynman-Kac):
43
+
44
+ $$\partial_t \varphi(x,t) = \frac{\varepsilon}{2} \Delta \varphi(x,t) \quad \text{(forward heat equation)}$$
45
+
46
+ $$\partial_t \psi(x,t) = -\frac{\varepsilon}{2} \Delta \psi(x,t) \quad \text{(backward heat equation)}$$
47
+
48
+ with boundary conditions:
49
+ - $\varphi(x,0)\psi(x,0) = \rho_0(x)$
50
+ - $\varphi(x,T)\psi(x,T) = \rho_1(x)$
51
+
52
+ The marginal at time $t$ is: $\rho_t(x) = \varphi(x,t)\psi(x,t)$
53
+
54
+ ### Entropic Optimal Transport Formulation
55
+
56
+ For discrete measures $\mu = \sum_i a_i \delta_{x_i}$ and $\nu = \sum_j b_j \delta_{y_j}$, the entropic optimal transport problem is:
57
+
58
+ $$\min_{\pi \in \Pi(\mu,\nu)} \langle C, \pi \rangle + \varepsilon H(\pi | \mu \otimes \nu)$$
59
+
60
+ where:
61
+ - $C_{ij} = \|x_i - y_j\|^2$ is the squared Euclidean cost
62
+ - $H(\pi | \mu \otimes \nu)$ is the Kullback-Leibler divergence
63
+ - $\varepsilon > 0$ is the entropic regularization (diffusivity)
64
+ - $\Pi(\mu,\nu)$ is the set of couplings with marginals $\mu$ and $\nu$
65
+
66
+ The optimal coupling has the form $\pi^*_{ij} = u_i K_{ij} v_j$ where:
67
+ - $K = \exp(-C/\varepsilon)$ is the **Gibbs kernel** (heat kernel for squared distance)
68
+ - $u, v$ are the **Sinkhorn potentials** found by iterative scaling
69
+
70
+ ### Schrödinger Bridge Displacement Interpolation
71
+
72
+ The Schrödinger bridge displacement interpolation at time $t \in [0,1]$:
73
+
74
+ $$X_t = (1-t)X_0 + t X_1 + \sqrt{\varepsilon \cdot t(1-t)} \cdot Z, \quad Z \sim \mathcal{N}(0, I)$$
75
+
76
+ where $(X_0, X_1)$ are coupled via the optimal entropic plan $\pi^*$.
77
+
78
+ **Physical Interpretation:**
79
+ - **Deterministic drift**: $(1-t)X_0 + tX_1$ — linear interpolation (McCann geodesic)
80
+ - **Stochastic diffusion**: $\sqrt{\varepsilon \cdot t(1-t)} \cdot Z$ — Brownian bridge correction
81
+ - The diffusion term vanishes at $t=0$ and $t=1$, ensuring exact boundary conditions
82
+
83
+ ### Key Theoretical Properties
84
+
85
+ 1. **Entropy Production**: The entropy of $\rho_t$ follows a parabolic profile
86
+ 2. **Cost Decomposition**: Transport cost = Wasserstein cost + Entropic regularization
87
+ 3. **Marginal Constraints**: $\sum_j \pi_{ij} = a_i$ and $\sum_i \pi_{ij} = b_j$
88
+ 4. **Plan Positivity**: $\pi_{ij} > 0$ for all $i,j$ (full support)
89
+
90
+ ## Numerical Methods
91
+
92
+ ### Log-Domain Sinkhorn Algorithm
93
+
94
+ The Sinkhorn iterations in log-domain for numerical stability:
95
+
96
+ $$f^{n+1} = \varepsilon \log(a) - \varepsilon \cdot \text{LSE}_j\left(\frac{g^n - C}{\varepsilon}\right)$$
97
+
98
+ $$g^{n+1} = \varepsilon \log(b) - \varepsilon \cdot \text{LSE}_i\left(\frac{f^{n+1} - C^\top}{\varepsilon}\right)$$
99
+
100
+ where $\text{LSE}$ is the log-sum-exp operator with max-trick for stability:
101
+
102
+ $$\text{LSE}(x) = \max(x) + \log\left(\sum_i \exp(x_i - \max(x))\right)$$
103
+
104
+ ### Convergence Criterion
105
+
106
+ Marginal constraint violation:
107
+
108
+ $$\text{error} = \left\|\pi \mathbf{1} - a\right\|_1$$
109
+
110
+ ### Novel Diagnostic Metrics
111
+
112
+ | Metric | Formula | Physical Meaning |
113
+ |--------|---------|------------------|
114
+ | **Wasserstein Cost** | $W = \langle C, \pi^* \rangle$ | Total transport work |
115
+ | **Plan Entropy** | $H = -\sum_{ij} \pi_{ij} \log(\pi_{ij})$ | Coupling uncertainty |
116
+ | **Effective Sparsity** | $S_{\text{eff}} = \exp(H) / nm$ | Normalized plan support |
117
+ | **Bridge Diffusivity** | $D_{\text{bridge}} = \varepsilon \cdot \mathbb{E}[t(1-t)]$ | Average stochastic spread |
118
+ | **Marginal Fidelity** | $1 - \|\pi\mathbf{1} - a\|_1$ | Constraint satisfaction |
119
+ | **Iteration Efficiency** | $\eta = -\log(\text{tol})/n_{\text{iter}}$ | Convergence rate per iteration |
120
+
121
+ ## Features
122
+
123
+ - **Log-domain stability**: Robust convergence for small $\varepsilon$
124
+ - **Adaptive convergence**: Automatic iteration based on marginal error
125
+ - **High-performance computing**: Numba JIT compilation (10-100× speedup)
126
+ - **Parallel processing**: Multi-core CPU utilization via `prange`
127
+ - **Professional 2D visualization**: Animated particle transport
128
+ - **Comprehensive diagnostics**: Static PNG with convergence curves
129
+ - **Scientific data formats**: NetCDF4 (CF-1.8) and CSV output
130
+ - **Comparable test cases**: Four scenarios with increasing complexity
131
+
132
+ ## Directory Structure
133
+
134
+ ```
135
+ anyakrakusuma/
136
+ ├── configs/ # Simulation configuration files
137
+ │ ├── case1_circle_to_circle.txt # Baseline: concentric circles
138
+ │ ├── case2_spiral_to_gaussian.txt # Topology change
139
+ │ ├── case3_moons_to_moons.txt # Symmetric rotation
140
+ │ └── case4_lissajous_to_trefoil.txt # Complex curves
141
+
142
+ ├── src/anyakrakusuma_eot/ # Main package source
143
+ │ ├── __init__.py # Package initialization
144
+ │ ├── cli.py # Command-line interface
145
+ │ │
146
+ │ ├── core/ # Core numerical algorithms
147
+ │ │ ├── __init__.py
148
+ │ │ ├── solver.py # Sinkhorn solver (log-domain)
149
+ │ │ └── distributions.py # Point cloud generators
150
+ │ │
151
+ │ ├── io/ # Input/output handlers
152
+ │ │ ├── __init__.py
153
+ │ │ ├── config_manager.py # Configuration file parser
154
+ │ │ └── data_handler.py # NetCDF/CSV writer
155
+ │ │
156
+ │ ├── visualization/ # Animation and plotting
157
+ │ │ ├── __init__.py
158
+ │ │ └── animator.py # 2D GIF generator + diagnostics
159
+ │ │
160
+ │ └── utils/ # Utilities
161
+ │ ├── __init__.py
162
+ │ ├── logger.py # Simulation logging
163
+ │ └── timer.py # Performance profiling
164
+
165
+ ├── tests/ # Unit tests
166
+ │ ├── __init__.py
167
+ │ ├── test_solver.py # Solver correctness tests
168
+ │ └── test_distributions.py # Distribution generator tests
169
+
170
+ ├── outputs/ # Generated results (created at runtime)
171
+ │ ├── *.nc # NetCDF data files
172
+ │ ├── *.csv # CSV metric summaries
173
+ │ ├── *_diagnostics.png # Static convergence plots
174
+ │ └── *.gif # Animation files
175
+
176
+ ├── logs/ # Simulation logs (created at runtime)
177
+ │ └── *.log
178
+
179
+ ├── pyproject.toml # Poetry build configuration
180
+ ├── README.md # This file
181
+ ├── LICENSE # MIT license
182
+ └── .gitignore # Git ignore patterns
183
+ ```
184
+
185
+ ## Installation
186
+
187
+ **From PyPI:**
188
+ ```bash
189
+ pip install anyakrakusuma
190
+ ```
191
+
192
+ **From source:**
193
+ ```bash
194
+ git clone https://github.com/sandyherho/anyakrakusuma.git
195
+ cd anyakrakusuma
196
+ pip install -e .
197
+ ```
198
+
199
+ ## Quick Start
200
+
201
+ **Command line:**
202
+ ```bash
203
+ anyakrakusuma case1 # Circle to circle
204
+ anyakrakusuma case4 --cores 8 # Complex case with 8 cores
205
+ anyakrakusuma --all # Run all cases
206
+ ```
207
+
208
+ **Python API:**
209
+ ```python
210
+ from anyakrakusuma_eot import SchrodingerBridgeSolver, generate_circle, generate_spiral
211
+
212
+ # Initialize solver
213
+ solver = SchrodingerBridgeSolver(n_cores=8, verbose=True)
214
+
215
+ # Generate distributions
216
+ X_source = generate_circle(n=1000, radius=1.0)
217
+ X_target = generate_spiral(n=1000, turns=2.0)
218
+
219
+ # Solve Schrödinger Bridge
220
+ result = solver.solve(
221
+ X_source, X_target,
222
+ epsilon=0.05,
223
+ max_iter=2000,
224
+ tol=1e-9
225
+ )
226
+
227
+ # Check convergence
228
+ print(f"Transport cost: {result['cost']:.6f}")
229
+ print(f"Converged: {result['converged']}")
230
+ ```
231
+
232
+ ## Test Cases (Comparable)
233
+
234
+ All test cases use the same number of particles (n=1000) and similar computational settings to enable direct comparison of transport characteristics.
235
+
236
+ | Case | Source → Target | $\varepsilon$ | Key Insight |
237
+ |------|-----------------|---------------|-------------|
238
+ | 1 | Circle (r=1) → Circle (r=2) | 0.02 | Baseline radial scaling |
239
+ | 2 | Spiral → Gaussian mixture | 0.05 | Topology dissolution |
240
+ | 3 | Two moons → Two moons (rotated) | 0.03 | Symmetric interchange |
241
+ | 4 | Lissajous (3:2) → Trefoil knot | 0.04 | Complex curve morphing |
242
+
243
+ **Comparison Metrics (per case):**
244
+ - Wasserstein cost (transport effort)
245
+ - Sinkhorn iterations (convergence difficulty)
246
+ - Plan entropy (coupling complexity)
247
+ - Effective sparsity (plan structure)
248
+
249
+
250
+ ## Citation
251
+
252
+ If you use this software in your study, please cite:
253
+
254
+ ```bibtex
255
+ @software{herho2026anyakrakusuma,
256
+ title = {{anyakrakusuma: 2D Schrödinger Bridge Solver via Entropic Optimal Transport}},
257
+ author = {Herho, Sandy H. S. and Anwar, Iwan P. and Khadami, Faruq and Suwarman, Rusmawan and Irawan, Dasapta E.},
258
+ year = {2026},
259
+ version = {0.0.1},
260
+ url = {https://github.com/sandyherho/anyakrakusuma}
261
+ }
262
+ ```
263
+
264
+ ## Authors
265
+
266
+ - Sandy H. S. Herho (sandy.herho@ronininstitute.org)
267
+ - Iwan P. Anwar
268
+ - Faruq Khadami
269
+ - Rusmawan Suwarman
270
+ - Dasapta E. Irawan
271
+
272
+ ## License
273
+
274
+ MIT License - See [LICENSE](LICENSE) for details.
@@ -0,0 +1,54 @@
1
+ [tool.poetry]
2
+ name = "anyakrakusuma"
3
+ version = "0.0.1"
4
+ description = "2D Schrödinger Bridge Solver via Entropic Optimal Transport with Log-Domain Sinkhorn"
5
+ authors = [
6
+ "Sandy H. S. Herho",
7
+ "Iwan P. Anwar",
8
+ "Faruq Khadami",
9
+ "Rusmawan Suwarman",
10
+ "Dasapta E. Irawan"
11
+ ]
12
+ license = "MIT"
13
+ readme = "README.md"
14
+ packages = [{include = "anyakrakusuma_eot", from = "src"}]
15
+ keywords = ["optimal-transport", "schrodinger-bridge", "sinkhorn", "entropic-regularization", "computational-physics"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Science/Research",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.8",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Topic :: Scientific/Engineering :: Physics",
26
+ "Topic :: Scientific/Engineering :: Mathematics"
27
+ ]
28
+
29
+ [tool.poetry.dependencies]
30
+ python = "^3.8"
31
+ numpy = ">=1.20.0"
32
+ scipy = ">=1.7.0"
33
+ matplotlib = ">=3.3.0"
34
+ netCDF4 = ">=1.5.0"
35
+ tqdm = ">=4.60.0"
36
+ numba = ">=0.53.0"
37
+ pandas = ">=1.3.0"
38
+
39
+ [tool.poetry.group.dev.dependencies]
40
+ pytest = ">=7.0.0"
41
+ pytest-cov = ">=3.0.0"
42
+ black = ">=22.0.0"
43
+
44
+ [tool.poetry.scripts]
45
+ anyakrakusuma = "anyakrakusuma_eot.cli:main"
46
+
47
+ [tool.pytest.ini_options]
48
+ testpaths = ["tests"]
49
+ python_files = ["test_*.py"]
50
+ addopts = "-v --tb=short"
51
+
52
+ [build-system]
53
+ requires = ["poetry-core>=1.0.0"]
54
+ build-backend = "poetry.core.masonry.api"