Python API¶
Input and arithmetic¶
A ChainWindow represents one fixed degree:
A has shape m×n and D has shape n×p, using column vectors. Supply ordered,
unique nonempty basis identifiers for each space and n finite positive weights.
Empty spaces are supported. Invalid dimensions, bases, coordinates, weights, or
AD≠0 raise InvalidInput, a ValueError subclass.
from homology_operator import Matrix
matrix = Matrix.from_rows(((1, 1, 0), (0, 1, 1)))
assert matrix.kernel_basis() == ((1, 1, 1),)
assert matrix.solve((1, 0)) == (1, 0, 0)
assert Matrix.from_rows((), ncols=3) == Matrix.zero(0, 3)
Coordinates must be integer 0/1 values; booleans, floats, truncation, and implicit
reduction modulo 2 are rejected. solve(b) returns a deterministic solution with
free variables set to zero, or None when no solution exists. A valid empty
solution is ().
|
Accepted weights |
Geometry |
|---|---|---|
|
Arbitrary-precision integers |
Exact; objective ratios use |
|
Integers and |
Exact rational arithmetic |
|
Integers, floats, fractions converted to finite positive binary64 |
Numerical |
The caller declares weight_semantics and unit. Positive costs do not imply
that weights are areas or volumes. Original coordinates determine geometry.
Solving and validation¶
Create ProjectionProblem(window) and call solve_projection. The default
FeasibleSolver constructs a deterministic projection without minimizing stretch.
Always check solution.projection before constructing HomologyOperator:
# Continue after the window definition in the quick start.
from homology_operator import HomologyOperator, ProjectionProblem, solve_projection
solution = solve_projection(ProjectionProblem(window))
if solution.projection is None:
raise RuntimeError((solution.status, solution.diagnostics))
op = HomologyOperator(window, solution)
Solver |
Supported scope |
|---|---|
|
General based windows; exact or floating weights; feasibility only |
|
Small exact-weight problems with complete search and certificate replay limits |
|
Exact weights; deterministic cycle enumeration and certified bounds |
|
Exact weights, Betti number 2, explicitly validated structural conditions |
|
Declared CyclicTrace family, m=2/3/4, equal exact positive weights |
The four optimization solvers support explicit native selection through their
Native... names or existing solver classes with native=True. Native selection
preserves each solver’s input and certification domain. Unknown or unsupported
requests return Unavailable.
solve_projection(problem, "NativeFeasibleSolver", fallback=True) can explicitly
fall back to the corresponding reference solver. Requested/selected backend and
fallback reason are recorded in resource_usage.backend_selection. The same
policy applies to supported native optimization solvers. Factorized matrix-free
output has no reference fallback to an explicit matrix.
Before entering an operator, every candidate is independently validated for
P²=P, AP=0, PD=0, and z+Pz∈im(D) on a cycle basis. The first three
equalities alone are insufficient: a zero projection can satisfy them and lose
nonzero homology. Global optimality additionally requires supported independent
certificate replay. See the solver contract.
Single-scale queries¶
Let L=I+P and m_w(x)=sum(w_i*x_i) in the original coordinates.
Method |
Domain and result |
|---|---|
|
Any chain; tuple |
|
Any chain; Boolean |
|
Basis of |
|
Cycle; tuple |
|
Two cycles; Boolean |
|
Cycle; |
|
Two cycles; |
|
Cycle; original coordinate indices of |
|
Two cycles; intersection / union indices |
|
Corresponding query domain; recorded |
|
|
|
Cycle; currently |
|
Immutable |
Class queries reject noncycles. No implicit conversion turns a raw chain into a
homology class. selected_mass is not the true minimum mass of a class.
Feasibility, exact evaluation of the current stretch, and minimum possible
stretch over projections are separate facts.
Finite filtrations¶
OperatorFamily(scales, windows, operators, weight_policy="Inherited", duplicate_policy="OrderedStages", terminal_extension="Constant", cache_limit=64)
accepts a nonempty ordered sequence in one degree. Basis identifiers establish
inclusions in the previous, current, and next spaces; chain-map conditions are
validated. Inherited requires inherited coordinate weights; explicit
Variable allows changed weights with compatible units and semantics.
Repeated scales retain separate ordered stages. Barcodes use half-open stage
intervals with multiplicity; death_stage=None means survival under constant
terminal extension. A cross-stage interval at the same scale remains explicit.
The main result comes from T_ij=P_j J_ij|ker(L_i). barcode() reads adjacent
transport; transport_rank(i,j) reads one interval rank. rank_table() requests
the full s(s+1)/2 table. barcode_basis() requests a historical interval basis
with corrected dying generators, original chain representatives, and identities.
Those larger outputs are explicit requests and can have quadratic cost.
track_class, track_mass, and support tracking accept source cycles and use
the target projection. A dead class yields a zero chain, zero mass, and empty
support. Failed stages remain missing; a failed rank is never an empty barcode.
cache_limit bounds entries in each LRU query cache, not bytes or process RSS.
Default family snapshots use schema 2 with shared boundary/basis storage. Legacy
schema 1 is readable and reissued at its original version; use
to_result(schema_version=1) to request old-format output without the new
historical basis. Single-scale schema remains 1. Recovery independently checks
the family and stored readouts. See filtration guide.
Optional Rust extension¶
The locked build uses Rust 1.98.1, PyO3 0.29.3, and maturin 1.15.0. Native CI covers Windows x64/MSVC with Python 3.10 and Linux x64 with Python 3.12. Other combinations are outside that matrix. Windows also needs MSVC build tools. From the repository root in PowerShell:
uv sync --locked --python 3.10
$pythonPath = uv run --locked python -c "import sys; print(sys.executable)"
$env:RUSTUP_TOOLCHAIN = '1.98.1'
uv tool run --from maturin==1.15.0 maturin build --manifest-path native/Cargo.toml --release --locked --interpreter $pythonPath --out .task-artifacts/native-wheels
$wheel = Get-ChildItem .task-artifacts/native-wheels/*.whl | Sort-Object LastWriteTime -Descending | Select-Object -First 1
uv pip install --python $pythonPath $wheel.FullName
Use uv run --locked --no-sync ... afterward to retain the separately installed
extension; reinstall it after another sync. backend_info() in
homology_operator.native reports actual availability and extension provenance.
Native entry |
Scope |
|---|---|
|
StableBasisOrder/Feasible; each chain space at most 64 dimensions |
|
Same-P Factorized/HC action; |
|
Multiword packed stable decomposition and reusable multi-RHS; not a projection solver |
|
Same-P cyclic geometry for Matrix and Factorized/HC; six-identity binding |
Native geometry does not support CyclicAction. Integer mass uses checked u64
where possible; noninteger rational weights, large integers, and overflow use
explicit exact Python fallback. Floating geometry retains binary64 fsum.
Workspace reuse does not alter saved snapshots or query history and does not
provide a concurrent sharing or RSS limit guarantee.
Missing or incompatible extensions produce Unavailable for supported solver
and batch entries. Direct packed tools and workspace creation require an
extension and raise ImportError when missing. There is no implicit fallback.
Budgets and cancellation¶
ResourceLimits provides state, wall-time, and logical matrix-entry limits.
Checks are cooperative checkpoints, not hard process memory or step preemption.
Independent validation, certificate replay, serialization, and recovery have
their own costs and cannot be omitted from complete timing.
CancellationToken can be supplied to ProjectionProblem and supported native
geometry. Cancellation is reported as ResourceExhausted with a reason, and any
retained candidate must still pass independent validation. Not all algebra or
filtration operations accept a cancellation token; see the API.
See result serialization, solver certificates, and the quickstart.