partition-lattice
Partition lattice algebra in exact integer arithmetic: meet, join, and logical
entropy. Python bindings for the Rust crate
partition-lattice.
A partition of a finite universe splits it into disjoint blocks. Partitions form a lattice under refinement, and this package exposes that lattice directly — the two operations, the order, and the measures — without going through probabilities or floats where integers will do.
from partition_lattice import Partition
a = Partition([0, 0, 1, 1]) # {0,1}{2,3}
b = Partition([0, 1, 0, 1]) # {0,2}{1,3}
a.refine(b).block_count() # 4 — every element separated
a.coarsen(b).block_count() # 1 — everything merged
a.logical_entropy() # 0.5
a.dit_count() # 8 — the exact integer numerator
Block labels carry no information, so equal groupings are equal partitions:
Partition([0, 0, 1, 1]) == Partition([7, 7, 3, 3]) # True
Two conventions worth knowing before you start
Order. a.refines(b) means finer, so Partition.discrete(n) is the least
element and Partition.indiscrete(n) the greatest. <= is that refinement order.
The operations are refine and coarsen, not meet and join. Much of the
literature — including Ellerman's papers — calls the common refinement join; other
sources call it meet. Both are standard, and they are opposite conventions on the
same structure, so a name like meet cannot be read without first knowing which
convention is in force. refine and coarsen say what the operation does, so they
read the same either way.
meet, join, &, | and the order comparisons <= < >= > were removed in
0.2.0. They would have kept working while meaning the opposite thing to a reader
coming from the other convention — a silent wrong answer. They now raise, and
refines() covers the order:
a.refines(b) # is a finer than b? (same reading under either convention)
a == b # equality was never convention-dependent, and is unchanged
Exactness
Distinction counts are integers and stay integers. logical_entropy() is the only
place a division happens, and its numerator is available separately as
dit_count(), so entropies can be compared exactly rather than through floats.
weighted_entropy(weights) and cross_entropy(p, q) return exact
(numerator, denominator) pairs. A weight is a multiplicity, not a probability:
the result equals the ordinary logical entropy of the multiset repeating element u
exactly w[u] times. Note that a non-uniform weight breaks relabelling invariance.
API
| Construction | Partition(ids), Partition.discrete(n), Partition.indiscrete(n), Partition.from_blocks(n, blocks) |
| Structure | block_count(), blocks(), ids(), block_of(e), len(p) |
| Operations | refine(o), coarsen(o), refines(o) |
| Measures | logical_entropy(), dit_count(), distance(o), mutual_information(o), divergence(o), rand_agreement(o), jaccard(o) |
| Exact measures | weighted_entropy(w), cross_entropy(p, q) |
| Module | dit_xor_count(a, b), destr(a, b), creat(a, b) |
Unlike the Rust from_blocks, Partition.from_blocks rejects a partial or
overlapping cover instead of silently reassigning elements.
Examples — four algorithms, two operations
Finding functional dependencies, comparing clusterings, minimising a DFA, and finding connected components are four different problems with four different standard algorithms. All four turn out to be the same two lattice operations:
| problem | usually reached for | what it is here |
|---|---|---|
| functional dependencies | TANE and relatives | partition(X).refines(partition(Y)) |
| comparing two clusterings | Rand, ARI, NMI | coarsen for the consensus, destr / creat for the direction |
| DFA minimisation | Hopcroft, Moore | refine until dit_count stops growing |
| connected components | union-find | coarsen folded over the edges |
That is the case for the library. Not that it computes these faster, but that it is the structure those algorithms were reconstructing each time. Once the data is a partition, the parts that normally need care — fixed points, transitive closure, composite keys — come from the lattice rather than from you, and what is left is small: the logic in these examples is 9 lines for components, 21 for dependencies and 29 for DFA minimisation, with the clustering one containing no algorithm at all, only calls. The rest of each file is printing and sample data.
Two properties do the work throughout:
- Counts stay integers.
dit_countis the exact numerator of the entropy, so a fixed point is==rather thanabs(a - b) < eps, and near-misses rank without float ties deciding the winner. - The order is available, not just a number. A similarity index answers how much.
refineandcoarsenanswer what: which distinctions two groupings agree on, which one of them drew and the other erased.
Run them as-is with python examples/<name>.py. Each has a Rust twin in the
crate.
| what it shows | |
|---|---|
functional_dependencies |
X -> Y is the refinement order, so finding dependencies needs no dependency-checking algorithm. Composite determinants are one refine. |
clustering_comparison |
A scalar index says how much two clusterings differ; coarsen / refine / destr / creat say in what way, and keep the direction a single number discards. |
dfa_minimisation |
Moore's algorithm is refine in a loop, and its fixed point is an exact integer comparison — no epsilon. |
graph_components |
Folding edges with coarsen gives connected components. The join is the union-find. |
Install
pip install partition-lattice
Wheels are built against the stable ABI (abi3), so one wheel per platform covers
CPython 3.8 and newer.
License
MIT OR Apache-2.0, at your option.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file partition_lattice-0.3.1.tar.gz.
File metadata
- Download URL: partition_lattice-0.3.1.tar.gz
- Upload date:
- Size: 28.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
33a99c263de4f75d6f3a5d647f197c270eeca5f62ba1d296b7542c215c9e944e
|
|
| MD5 |
d902ed77207ef957b2bd9fa7d87a5fea
|
|
| BLAKE2b-256 |
844eba931658ff1e89977bc97031f10c49d9ff98e3e4348a8af5bbbcc2e8678f
|
File details
Details for the file partition_lattice-0.3.1-cp38-abi3-win_amd64.whl.
File metadata
- Download URL: partition_lattice-0.3.1-cp38-abi3-win_amd64.whl
- Upload date:
- Size: 287.3 kB
- Tags: CPython 3.8+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52017cc031172d5201776c1d7663ca7fff1343c704011564e7901c9b5e20f1f4
|
|
| MD5 |
cdb82b9f1737570c77054b3656ee0a7b
|
|
| BLAKE2b-256 |
39090f09411f6080a5223bf3f0b1772f542721c0f34c976422edfee1fb0b118f
|
File details
Details for the file partition_lattice-0.3.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: partition_lattice-0.3.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 422.3 kB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64a44a2a9113d96818135e906e2e4589dda45bca0f189af669e96235335c65ca
|
|
| MD5 |
e905a5c39c085f216c421c1d6cd89863
|
|
| BLAKE2b-256 |
9ea50a06e63a31044d6f73ee2f11c2a0227318a48ad2504cce3e7c97c6d095c0
|
File details
Details for the file partition_lattice-0.3.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: partition_lattice-0.3.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 395.7 kB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66dd5c9c128a21f0917741a0096d0667100fbdf99300786ca338294a43585c5e
|
|
| MD5 |
712ddab0195b3dc4d35666e213772423
|
|
| BLAKE2b-256 |
849b08815030404828a145a4d53518f549514d0b28138d18167e556a0ea71a6d
|
File details
Details for the file partition_lattice-0.3.1-cp38-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: partition_lattice-0.3.1-cp38-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 342.6 kB
- Tags: CPython 3.8+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02c890d56d63109248286c9b36a55e7367769e3f0d19fc3db0d42e8c47283981
|
|
| MD5 |
5ffd2a734fcec19e8ae75e08a61cb86a
|
|
| BLAKE2b-256 |
0144cee34226822220acca5b6456d583833a1128607d87e4bf0982b3421063ce
|
File details
Details for the file partition_lattice-0.3.1-cp38-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: partition_lattice-0.3.1-cp38-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 358.8 kB
- Tags: CPython 3.8+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a002b4d6503d361972aebfffe0e53d9e21ed3f200b1cba33954a2c2a29580258
|
|
| MD5 |
e0d197cb384bc5e272f3f1ca313ac304
|
|
| BLAKE2b-256 |
8ff96785730deabbd22a5bc891edcbd1c59dd26721c1d8d9e0712d6d989dc089
|