Metadata-Version: 2.4
Name: pyect
Version: 1.0.1
Summary: Computation of (weighted) Euler characteristic functions and transforms in general settings using PyTorch.
Author: Alex McCleary, Jack Ruder, Jacob Sriraman
Author-email: Eli Quist <eli.quist@student.montana.edu>
License: MIT
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: torch
Requires-Dist: Pillow
Requires-Dist: numpy
Requires-Dist: torchvision
Requires-Dist: trimesh
Provides-Extra: gudhi
Requires-Dist: gudhi; extra == "gudhi"
Dynamic: license-file

 <div align="center">

# pyECT

**Fast, general, GPU-ready Euler Characteristic Functions and Transforms in PyTorch**

[![PyPI version](https://img.shields.io/pypi/v/pyect.svg)](https://pypi.org/project/pyect/)
[![Python versions](https://img.shields.io/pypi/pyversions/pyect.svg)](https://pypi.org/project/pyect/)
[![Tests](https://github.com/compTAG/pyECT/actions/workflows/tests.yml/badge.svg)](https://github.com/compTAG/pyECT/actions/workflows/tests.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![DOI](https://img.shields.io/badge/DOI-10.4230%2FLIPIcs.SoCG.2026.32-blue.svg)](https://doi.org/10.4230/LIPIcs.SoCG.2026.32)

</div>

---

`pyECT` computes the **Euler Characteristic Function (ECF)** and **Euler Characteristic
Transform (ECT),** as well as their **weighted** counterparts (WECF / WECT), for
geometric and topological data. These are compact, expressive descriptors that summarize
the shape of images, meshes, point clouds, and simplicial/cubical complexes, and they are
widely used as features in topological data analysis and machine learning pipelines.

The entire computation is expressed as vectorized (tensor-based) PyTorch operations.
This makes `pyECT` fast on CPU out of the box.
And, because it is built on `torch`, it can be accelerated without custom kernels
or recompilation if GPU hardware (CUDA or MPS) is available in your computation environment.

## Why pyECT?

Most existing ECT tooling handles a narrow slice of the problem — unweighted complexes
only, images only, or only either the (W)ECF or (W)ECT.
`pyECT` is designed to be the most general-purpose implementation that works for all usecases:

- **Weighted *and* unweighted complexes** — compute the ECF/ECT or the *weighted* WECF/WECT from a
  single, unified API. Set weights to `1` to recover the classical (unweighted) transform.
- **Arbitrary lower-star filtrations** — not restricted to height/sublevel filtrations on
  images. Any lower-star filtration on a simplicial or cubical complex is supported.
- **The fully general (non-lower-star) case** — `compute_wecfs_general` handles filtrations
  with a value assigned to *every* simplex, the most general setting possible.
- **Arbitrary Dimensions** — first-class support for simplicial and cubical complexes of arbitrary dimension,
    not just $\R^2$ and $\R^3$.
- **Fast on CPU, effortless on GPU** — vectorized PyTorch throughout; move your inputs to
  `cuda` or `mps` and the same code runs on accelerated hardware.
- **Composable with deep learning** — the transforms are `torch.nn.Module`s, so they drop
  straight into a network as a layer and export cleanly to **TorchScript** for deployment
  outside Python.
- **Convenient ingestion** — helpers to build complexes from grayscale images
  (Freudenthal / cubical), triangle meshes, and — optionally — Gudhi alpha complexes.

## Installation

```bash
pip install pyect
```

Optional [Gudhi](https://gudhi.inria.fr/) alpha-complex support:

```bash
pip install pyect[gudhi]
```

The Gudhi integration lives in `pyect.integrations.gudhi`, so Gudhi is never imported by
the core package. In `alpha_complex_to_filtration_data`, `point_weights` are passed to
Gudhi to construct the alpha filtration; pyECT simplex weights default to `1.0`, and you
can pass a custom `simplex_weight_fn` (for example, the max of a simplex's vertex weights).

## Quick start

Compute both the (unweighted) image ECF and the WECT of a 2D array:

```python
import torch
from pyect import (
    WECT,
    Image_ECF_2D,
    sample_directions_2d,
    weighted_freudenthal,
)

# Pick a device — the same code runs on CPU, CUDA, or Apple MPS.
device = torch.device("cpu")          # or "cuda", or "mps"

# Example input (use image_to_grayscale_tensor to load a real image file).
img = torch.rand((500, 500), device=device)

num_bins = 100        # discretization resolution of the (W)ECF
num_directions = 25   # directions to sample the transform over

# --- Image ECF ---
ecf = Image_ECF_2D(num_bins).eval()
ecf_result = ecf(img)

# --- Weighted ECT ---
directions = sample_directions_2d(num_directions, device=device)
wect = WECT(directions, num_bins).eval()
complex_data = weighted_freudenthal(img, device=device)
wect_result = wect(complex_data)
```

Everything above is a standard PyTorch module: `.eval()`, `.to(device)`, `torch.jit.script`,
and use as a network layer all work as expected.

For the fully general, non-lower-star case, use `compute_wecfs_general`, and see the
[`examples/`](examples) directory for image, mesh (Stanford bunny), and Gudhi alpha-complex
walkthroughs.

## Citation

This package accompanies the paper published at the *42nd International Symposium on
Computational Geometry (SoCG 2026)*. If you use `pyECT` in your work, please cite:

```bibtex
@InProceedings{cisewskikehe_et_al:LIPIcs.SoCG.2026.32,
  author =	{Cisewski-Kehe, Jessi and Fasy, Brittany Terese and McCleary, Alexander and Quist, Eli},
  title =	{{Tensor Computation of Euler Characteristic Functions and Transforms}},
  booktitle =	{42nd International Symposium on Computational Geometry (SoCG 2026)},
  pages =	{32:1--32:17},
  series =	{Leibniz International Proceedings in Informatics (LIPIcs)},
  ISBN =	{978-3-95977-418-5},
  ISSN =	{1868-8969},
  year =	{2026},
  volume =	{367},
  editor =	{Ahn, Hee-Kap and Hoffmann, Michael and Nayyeri, Amir},
  publisher =	{Schloss Dagstuhl -- Leibniz-Zentrum f{\"u}r Informatik},
  address =	{Dagstuhl, Germany},
  URL =		{https://drops.dagstuhl.de/entities/document/10.4230/LIPIcs.SoCG.2026.32},
  URN =		{urn:nbn:de:0030-drops-258380},
  doi =		{10.4230/LIPIcs.SoCG.2026.32},
  annote =	{Keywords: Topological data analysis, weighted Euler characteristic transform, Euler characteristic function, tensor computation, GPU computation}
}
```

An earlier preprint is also available on [arXiv](https://arxiv.org/abs/2511.03909).

## Contributing

Contributions are welcome! Please fork the repository and submit a pull request. For major
changes, open an issue first to discuss what you'd like to change. Pull requests are
automatically checked against the end-to-end test suite.

## License & attribution

`pyECT` is released under the permissive **MIT License** (see [LICENSE](LICENSE)) — you are
free to use, modify, and distribute it, including for commercial purposes.

If you use `pyECT` in academic or published work, we ask that you also **cite the paper**
above as attribution. A machine-readable [`CITATION.cff`](CITATION.cff) is included, so
GitHub's *"Cite this repository"* button and tools like `cffconvert` can generate the
citation for you automatically.
