Metadata-Version: 2.5
Name: akriti
Version: 0.1.0
Summary: The statistically grounded entry point to topological data analysis in Python
Project-URL: Homepage, https://akriti.io
Project-URL: Source, https://github.com/akritihq/akriti
Project-URL: Issues, https://github.com/akritihq/akriti/issues
Project-URL: RFCs, https://github.com/akritihq/akriti/tree/main/rfcs
Author: Pramita Bagchi, Atish Mitra, Žiga Virk
Author-email: Sushovan Majhi <s.majhi@email.gwu.edu>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: hypothesis testing,persistence diagram,persistent homology,statistics,topological data analysis,topology
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Typing :: Typed
Requires-Python: >=3.10
Provides-Extra: alpha
Requires-Dist: gudhi>=3.9; extra == 'alpha'
Provides-Extra: bio
Requires-Dist: anndata>=0.10; extra == 'bio'
Provides-Extra: dev
Requires-Dist: array-api-strict>=2.6.1; extra == 'dev'
Requires-Dist: gudhi>=3.9; extra == 'dev'
Requires-Dist: hypothesis>=6.165.10; extra == 'dev'
Requires-Dist: mypy>=2.3.1; extra == 'dev'
Requires-Dist: numpy>=2.0; extra == 'dev'
Requires-Dist: packaging>=22; extra == 'dev'
Requires-Dist: persim>=0.3.1; extra == 'dev'
Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
Requires-Dist: pytest>=9.1.1; extra == 'dev'
Requires-Dist: ripser>=0.6.4; extra == 'dev'
Requires-Dist: ruff>=0.16.3; extra == 'dev'
Provides-Extra: distances
Requires-Dist: persim>=0.3.1; extra == 'distances'
Provides-Extra: io
Requires-Dist: numpy>=2.0; extra == 'io'
Provides-Extra: lint
Requires-Dist: mypy>=2.3.1; extra == 'lint'
Requires-Dist: ruff>=0.16.3; extra == 'lint'
Provides-Extra: numpy
Requires-Dist: numpy>=2.0; extra == 'numpy'
Provides-Extra: parquet
Requires-Dist: pyarrow>=25.0.0; extra == 'parquet'
Provides-Extra: rips
Requires-Dist: ripser>=0.6.4; extra == 'rips'
Provides-Extra: test
Requires-Dist: array-api-strict>=2.6.1; extra == 'test'
Requires-Dist: hypothesis>=6.165.10; extra == 'test'
Requires-Dist: numpy>=2.0; extra == 'test'
Requires-Dist: packaging>=22; extra == 'test'
Requires-Dist: pytest-cov>=7.1.0; extra == 'test'
Requires-Dist: pytest>=9.1.1; extra == 'test'
Provides-Extra: torch
Requires-Dist: array-api-compat>=1.15.0; extra == 'torch'
Requires-Dist: torch>=2.0; extra == 'torch'
Description-Content-Type: text/markdown

<p align="center">
  <img src="branding/akriti-logo.svg#gh-light-mode-only" alt="Akriti" width="360">
  <img src="branding/akriti-logo-dark.svg#gh-dark-mode-only" alt="Akriti" width="360">
</p>

<p align="center">
  <strong>Statistically grounded topological data analysis for Python.</strong><br>
  <a href="https://akriti.io">akriti.io</a> ·
  <a href="LICENSE">Apache-2.0</a> ·
  built on <a href="https://gudhi.inria.fr/">GUDHI</a> and <a href="https://ripser.scikit-tda.org/">Ripser</a>
</p>

---

Persistence diagrams tell you what shape your data has. Akriti tells you whether
the answer is **significant**.

It provides the statistical layer that Python's TDA stack lacks — hypothesis
tests, effect sizes, per-region significance, and sample-size calculation for
persistence diagrams — while delegating persistence computation to the
established engines rather than reimplementing them.

## Status

> **Early development.** The API is unstable and much of what is described below
> is not written yet. `akriti` on PyPI is currently a `0.0.0` placeholder holding
> the name. Star the repository to follow progress, or watch
> [akriti.io](https://akriti.io).

We would rather be accurate than impressive, so:

| Module | What it is | State |
|---|---|---|
| `akriti.diagrams` | One persistence-diagram type, with adapters for GUDHI, Ripser, giotto-tda, persim and plain arrays — specified by [RFC-0001](rfcs/0001-persistence-diagram-interchange.md) | **building** |
| `akriti.castle` | Two-sample test, sample-size calculator, per-region significance map, robustness certificate, reporting card | **building** |
| `akriti.core` | Landmark embeddings (PLACE / PALACE), closed-form selectors, certificate radii | **building** |
| `akriti.compute` | Diagrams from point clouds, images, time series and graphs — delegated, with defended defaults | planned |
| `akriti.vectorise` | Persistence images, landscapes, Betti curves, landmark embeddings, plus a maintained benchmark | planned |
| `akriti.compat` | Compatibility layer for giotto-tda pipelines | planned |

## Why

Three gaps, stated as precisely as we can:

1. **Statistical inference for diagrams lives in R, not Python.** The `TDA`,
   `TDAstats` and `tdaverse` packages have offered permutation tests and
   bootstrap confidence sets for years. Python users have had essentially
   nothing.
2. **No library, in any language, calculates sample size for a topological
   effect.** *"How many samples do I need to detect a bottleneck-distance
   difference of size δ?"* is a question applied statistics answers routinely,
   and topology has never answered at all.
3. **Python's general-purpose TDA layer has gone quiet.** giotto-tda has had no
   commits since 2024 while still being installed thousands of times a month.
   Its users deserve somewhere maintained to land.

## Design commitments

- **We delegate computation.** Persistence, bottleneck and Wasserstein distances
  go to GUDHI, Ripser and Hera. We do not reimplement them, and we will not.
- **Backend-agnostic input.** Bring diagrams from any library, or none.
- **Honest defaults.** Where our theory supports a principled choice of
  filtration, scale or descriptor, the library makes it and explains why. Where
  it provably does not — the landmark budget, placement, bandwidth, and the
  concatenation rules — the library says so and points you at cross-validation
  instead of pretending.
- **Permissive by default.** Apache-2.0, and the default install closure is
  permissive-only — verified in CI, not asserted. Every backend has a copyleft
  dependency somewhere in its closure, so every backend is an opt-in extra.

## Specifications

Before the code, the contract. **[RFC-0001 — Persistence Diagram
Interchange](rfcs/0001-persistence-diagram-interchange.md)** pins down what a
persistence diagram *is* across Python's backends: infinite bars, ordering,
precision, equality, metadata and serialization. It is open for comment, and it
is useful whether or not you ever install this library — the R ecosystem solved
interchange first, and Python has not.

Every convention in it was measured against GUDHI, Ripser, persim and giotto-tda
rather than recalled. `rfcs/evidence/probe_backends.py` reproduces every number.
Three findings you may want regardless of Akriti:

- **giotto-tda silently drops the essential H0 bar** — under every
  `infinity_values` setting. 40 points, 40 components, 39 reported.
- **giotto-tda's batch padding is indistinguishable from real bars.** The same
  point cloud yields 2 one-dimensional bars alone and 11 when batched with
  another; the padding is written with a genuine birth value.
- **`persim.bottleneck` returns a finite distance between diagrams that are
  infinitely far apart** — 0.5 where the answer is ∞. It does warn that it is
  dropping the infinite bars, but the warning describes the mechanism rather
  than the consequence, and it fires more often on the case it gets *right*
  than on the case it gets wrong.

## Install

```bash
pip install akriti              # interchange layer — zero dependencies
pip install akriti[rips]        # + Ripser    (MIT, GPLv3 transitively)
pip install akriti[alpha]       # + GUDHI     (GPLv3)
pip install akriti[distances]   # + persim    (MIT, GPLv3 transitively)
pip install akriti[numpy]       # + NumPy namespace / Python-row fallback
pip install akriti[parquet]     # + PyArrow   (Apache-2.0)
pip install akriti[torch]       # + torch and array-api-compat
pip install akriti[bio]         # + anndata   (BSD-3)
```

> Currently a placeholder release; real functionality is coming.

**Nothing is a required dependency** — no persistence backend, and no NumPy
either. Native array inputs retain their Python array API namespace. Accepted
Python-row adapter inputs lazily use `akriti[numpy]`; torch tensors use the
compatibility resolver supplied by `akriti[torch]`; and Parquet imports
PyArrow only when requested through `akriti[parquet]`. "Bring your own
diagrams" remains the primary path by design. The licence consequences above
are stated here rather than in a footnote because they are real: `persim`
depends on `hopcroftkarp`, which is GPLv3 and has had no release since 2019,
and the `gudhi` wheel bundles CGAL-dependent modules and ships no licence
metadata at all. See **[DEPENDENCIES.md](DEPENDENCIES.md)** for the verified
closure, and `tools/check_license_closure.py` for the CI gate that keeps it
honest.

## The research behind it

| | |
|---|---|
| **CASTLE** (Paper IV) | A practitioner's toolkit for topological two-sample testing, sample-size calculation and robustness certification · *in preparation* |
| **Paper III** | A statistical-inference pipeline for persistence-landmark kernels: CLT, Berry–Esseen and functional limits · *in preparation* |
| **PLACE** (Paper I) | A closed-form persistence-landmark pipeline for certified point-cloud and graph classification · *TMLR, under review* |
| **PALACE** (Paper II) | Adaptive landmark embeddings for persistence diagrams · *JMLR, under review* |

CASTLE is the practitioner-facing product; the others are the machinery that
makes its guarantees possible.

## Contributing

Contributions are welcome, including — especially — from maintainers of the
projects we build on. If you maintain a TDA library and something here does not
interoperate cleanly with yours, that is a bug and we would like to hear about
it.

Please read [CONTRIBUTING.md](CONTRIBUTING.md) and
[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md). Security reports go to
[SECURITY.md](SECURITY.md).

## Team

- **Sushovan Majhi** — Data Science, GW · lead, library architecture
- **Pramita Bagchi** — biostatistics · practitioner statistics
- **Atish Mitra** — Mathematics, Montana Tech · theoretical foundations
- **Žiga Virk** — Mathematics, Ljubljana · theory advisor
- **Alexander Silberman** — GW · library development
- **Edward Bae** — GW · library development

Built on [GUDHI](https://gudhi.inria.fr/) (INRIA),
[Ripser](https://ripser.scikit-tda.org/), [Hera](https://github.com/anigmetov/hera)
and [persim](https://persim.scikit-tda.org/), and on the landmark embedding of
[Mitra & Virk (2024)](https://arxiv.org/abs/2402.04860). With thanks to the
wider TDA community, including [scikit-tda](https://scikit-tda.org/),
[giotto-tda](https://giotto-ai.github.io/gtda-docs/) and the R
[tdaverse](https://github.com/tdaverse).

## Licence

Apache-2.0 — see [LICENSE](LICENSE). The explicit patent grant is deliberate: it
is what makes the library usable inside institutions whose legal review would
otherwise block adoption.

## Contact

[hello@akriti.io](mailto:hello@akriti.io) · [@akritihq](https://x.com/akritihq) ·
[github.com/akritihq](https://github.com/akritihq)
