Metadata-Version: 2.4
Name: howzat
Version: 0.2.0.post1
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Rust
Classifier: Operating System :: OS Independent
Requires-Dist: numpy>=1.23
License-File: LICENSE
Summary: High-performance polytope backends via Rust FFI bindings to howzat
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# howzat

User-friendly Python bindings for the Rust crate [`howzat`](https://crates.io/crates/howzat) via PyO3.

## Usage

```python
import numpy as np
import howzat

verts = np.asarray([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0]], dtype=np.float64)

res = howzat.solve(verts)  # cached default backend: "snap@howzat-dd:f64"
# res = howzat.Backend().solve(verts)  # same as above
# res = howzat.Backend("howzat-lrs:rug").solve(verts)  # explicit backend

print(res.facets, res.ridges)
print(res.facet_adjacency)
```

Input vertices must be a contiguous (C-order) `numpy.ndarray` of `float64` with shape `(n, d)`.

### Backends

The class `howzat.Backend(spec)` accepts backend spec strings, which specify the algorithm and
parameters of the computation pipeline.

At a high level, the syntax is: `[PURIFIER@]KIND[:SPEC]`. Some examples:
- `snap@howzat-dd:f64` (default)
- `howzat-dd:f64`
- `howzat-dd:f64[eps[1e-12],max]-resolve[rugrat]`
- `cddlib:gmprational`
- `cddlib+hlbl:f64`
- `lrslib+hlbl` (defaults to `lrslib+hlbl:gmpint`)

FIXME: give a complete enumeration of the options and modes.

### API

- `howzat.solve(vertices) -> SolveResult`
  Convenience function which uses the default backend (`snap@howzat-dd:f64`).
- `howzat.Backend(spec: str | None = None)`
  Loads the specified backend; `None` selects the default.
- `Backend.solve(vertices) -> SolveResult`
  Runs the backend synchronously, single-threaded on the provided vertex set, returning a `SolveResult`.

#### SolveResult

A `SolveResult` has the fields:
- `spec: str` backend spec actually used
- `dimension: int` ambient dimension `d`
- `vertices: int` number of vertices `n`
- `facets: int` number of facets
- `ridges: int` number of ridges (edges in the facet adjacency / FR graph)
- `total_seconds: float` time spent inside the backend (seconds)
- `vertex_positions: list[list[float]] | None` vertex coordinates if the backend returned baseline geometry
- `vertex_adjacency: list[list[int]]` vertex adjacency lists (length `vertices`)
- `facets_to_vertices: list[list[int]]` for each facet, the incident vertex indices
- `facet_adjacency: list[list[int]]` facet adjacency lists (FR graph)
- `fails: int` backend-specific failure count (pipeline dependent)
- `fallbacks: int` backend-specific fallback count (pipeline dependent)

## Install

From PyPI:

```bash
python -m pip install howzat
```

Force a local source build, and enabling CPU-native codegen:

```bash
RUSTFLAGS="-C target-cpu=native" python -m pip install --no-binary howzat howzat
```

Prebuilt wheels are compiled for a portable baseline CPU (not `target-cpu=native`).

