humanleague
Introduction
Please note ongoing development is for the python version only. R development is currently maintenance-only due to resource constraints.
humanleague is a python and an R package for microsynthesising populations from marginal and (optionally) seed data. The package is implemented in C++ for performance.
The package contains algorithms that use a number of different microsynthesis techniques:
- Iterative Proportional Fitting (IPF)
- Quasirandom Integer Sampling (QIS) (no seed population)
- Quasirandom Integer Sampling of IPF (QISI): A combination of the two techniques whereby the integral population is sampled (without replacement) from a distribution constructed from a dynamic IPF solution.
The latter provides a bridge between deterministic reweighting and combinatorial optimisation, offering advantages of both techniques:
- generates high-entropy integral populations
- can be used to generate multiple populations for sensitivity analysis
- goes some way to address the 'empty cells' issues that can occur in straight IPF
- relatively fast computation time
The algorithms:
- support arbitrary dimensionality for both the marginals and the seed.
- produce statistical data to ascertain the likelihood/degeneracy of the population (where appropriate).
The package also contains the following utilities:
- a Sobol sequence generator (implemented as a generator class in python)
- a function to construct a closest integer population from a discrete univariate probability distribution.
- an algorithm for sampling an integer population from a discrete multivariate probability distribution, constrained to the marginal sums in every dimension (see below).
- utility functions to convert a population represented as a multidimensional state array into tables of either counts (indexed by state) or individuals.
Version 1.0.1 reflects the work described in the Quasirandom Integer Sampling (QIS) paper.
Installation
Python
Requires Python 3.12 or newer. The package can be installed using pip, e.g.
pip install humanleague
Development
uv is highly recommended for managing environments.
uv sync --dev
uv build
uv run pytest
Nanobind docs suggest a dev workflow where the build happens directly in the dev env - first manually install
the build deps (required after every uv sync)
uv pip install nanobind scikit-build-core[pyproject]
Then build with
uv pip install --no-build-isolation -ve .
R
Official release:
> install.packages("humanleague")
For a development version
> devtools::install_github("virgesmith/humanleague")
Or, for the legacy version
> devtools::install_github("virgesmith/humanleague@1.0.1")
Documentation and Examples
R
Consult the package documentation, e.g.
> library(humanleague)
> ?humanleague
Python
The package now contains type annotations and your IDE should automatically display this, e.g.:
NB type stubs are generated using the pybind11-stubgen package, with some manual corrections.
nanobind now has stubgen functionality (but appears limited as of 2.9.2)
uv run python -m nanobind.stubgen -P -m humanleague.humanleague_ext -o humanleague/__init__.pyi -M humanleague/py.typed
Multidimensional integerisation
Building on the one-dimensionl integerise function - which given a discrete probability distribution and a count, returns the closest integer population to the distribution that sums to the count - a multidimensional equivalent integerise is introduced. In one dimension, for example this:
>>> import humanleague
>>> p = [0.1, 0.2, 0.3, 0.4]
>>> result, stats = humanleague.integerise(p, 11)
>>> result
array([1, 2, 3, 5], dtype=int32)
>>> stats
{'rmse': 0.3535533905932736}
produces the optimal (i.e. closest possible) integer population to the discrete distribution.
The integerise function generalises this problem and applies it to higher dimensions: given an n-dimensional array of real numbers where the 1-d marginal sums in every dimension are integral (and thus the total population is too), it attempts to find an integral array that also satisfies these constraints.
The QISI algorithm is repurposed to this end. As it is a sampling algorithm it cannot guarantee that a solution is found, and if so, whether the solution is optimal. If it fails this does not prove that a solution does not exist for the given input.
>>> import numpy as np
>>> a = np.array([[ 0.3, 1.2, 2. , 1.5],
[ 0.6, 2.4, 4. , 3. ],
[ 1.5, 6. , 10. , 7.5],
[ 0.6, 2.4, 4. , 3. ]])
# marginal sums
>>> a.sum(axis=0)
array([ 3., 12., 20., 15.])
>>> a.sum(axis=1)
array([ 5., 10., 25., 10.])
# perform integerisation
>>> result, stats = humanleague.integerise(a)
>>> stats
{'conv': True, 'rmse': 0.5766281297335398}
>>> result
array([[ 0, 2, 2, 1],
[ 0, 3, 4, 3],
[ 2, 6, 10, 7],
[ 1, 1, 4, 4]])
# check marginals are preserved
>>> (result.sum(axis=0) == a.sum(axis=0)).all()
True
>>> (result.sum(axis=1) == a.sum(axis=1)).all()
True
Release files for humanleague 2.4.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| humanleague-2.4.5.tar.gz | 147.2 kB | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| humanleague-2.4.5-cp312-abi3-win_amd64.whl | CPython 3.12 | abi3 | Windows x86-64 | Details |
| humanleague-2.4.5-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.12 | abi3 | Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| humanleague-2.4.5-cp312-abi3-macosx_11_0_arm64.whl | CPython 3.12 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 991.3 kB
Release files / humanleague-2.4.5.tar.gz
| Download URL | humanleague-2.4.5.tar.gz |
|---|---|
| Size | 147.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
af592afb8fbf5e0f1cf247e96ea9ded2a8f2a5481a66fe989114fcc291eeea58
|
|
BLAKE2b-256 checksum How to use checksums |
26adc8af4f6510670b016d0945ca4bc84a0f081e47930b5961047258f31e8cf1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / humanleague-2.4.5-cp312-abi3-win_amd64.whl
| Download URL | humanleague-2.4.5-cp312-abi3-win_amd64.whl |
|---|---|
| Size | 416.8 kB |
| Tags | CPython 3.12 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
e3a31a53560af2d7b9a51ea3378f09edefea77b46d2950943f942619c3f23218
|
|
BLAKE2b-256 checksum How to use checksums |
ffc93e89668ac293604657aacf6b50bc3828d7db2da16bde8ebd30dd6f0501df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / humanleague-2.4.5-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | humanleague-2.4.5-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 230.1 kB |
| Tags | CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
0bc59adc6224625faf58b097c92cced2be37f6f390a7e7d32713c19a351a6126
|
|
BLAKE2b-256 checksum How to use checksums |
fd8f8f98840bdde0d988752bb5d2ddac8c62d300d30493e1177c8a08e99a1714
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / humanleague-2.4.5-cp312-abi3-macosx_11_0_arm64.whl
| Download URL | humanleague-2.4.5-cp312-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 197.3 kB |
| Tags | CPython 3.12 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
e54eedd13d75654a85c59dc7e36ee82d53f95b2bfadcc59a74023509cfecb2ba
|
|
BLAKE2b-256 checksum How to use checksums |
b536db6250288d109bb7a1304a5e9c81941e833396e44f820c0e7057ac1b7cc4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|