Note (August 2026): the research line has moved home. New development of the factor-correlated race machinery — forward shares, scalable probit calibration, Jacobian-vector products, the methods arena, and the benchmark database — now lives in the
winningpackage, where this line of work began (SIAM J. Financial Mathematics, 2021).thurstoneremains maintained as a compatibility layer, and its documentation below stays current for the existing API; new work should import fromwinning.
thurstone
Convert winning probabilities to relative abilities using the fast ability transform.
What it does
Given market odds or winning probabilities, infer the relative abilities of competitors.
Input: Market odds [3.2, 4.8, 12.0, 7.5, 20.0]
Output: Relative abilities [1.15, 0.73, -0.88, 0.21, -1.21]
The model assumes each competitor's performance = true ability + random noise, and the best performance wins.
Usage
pip install thurstone
from thurstone import UniformLattice, Density, AbilityCalibrator, STD_L, STD_UNIT
# Setup
lattice = UniformLattice(L=STD_L, unit=STD_UNIT)
base = Density.skew_normal(lattice, loc=0.0, scale=1.0, a=0.0)
calibrator = AbilityCalibrator(base)
# Convert odds to abilities
odds = [3.2, 4.8, 12.0, 7.5, 20.0]
abilities = calibrator.solve_from_dividends(odds)
probabilities = calibrator.state_prices_from_ability(abilities)
Exact joint inversion (Laplacian Newton–CG)
The Jacobian of the map from abilities to win probabilities is minus a weighted
graph Laplacian, and it can be applied to a vector in O(nM) without ever being
formed. invert_outright_probabilities exploits this for exact joint Newton–CG
inversion — all runners move together, no per-runner curve approximation:
from thurstone import Density, UniformLattice, invert_outright_probabilities
lattice = UniformLattice(L=400, unit=0.05)
bases = [Density.skew_normal(lattice, loc=0.0, scale=s, a=0.0) for s in (0.8, 1.0, 1.2)]
result = invert_outright_probabilities(bases, [0.5, 0.3, 0.2]) # normalized prices
result.abilities # mean-zero abilities reproducing the price ratios
result.converged # honest flag; result.message explains any failure
Targets are matched in ratio (a single multiplicative renormalization absorbs
the lattice tie mass, so longshot probabilities keep their meaning), per-runner
distributions may be heterogeneous, and non-convergence is diagnosed — e.g. a
target requiring more ability spread than the lattice represents. The building
blocks laplacian_weights, laplacian_matvec, and LaplacianOperator are
exported for direct use.
Applications
- E-commerce product ranking
- Search result relevance scoring
- Financial instrument comparison
- Sports betting analysis
- Any competitive scenario with market-implied rankings
Examples
python examples/global_calibration_demo.py # 500 competitors
python examples/dynamic_calibration_demo.py # Time-varying abilities
python examples/diffeomorphism_demo.py # Advanced mappings
python examples/laplacian_newton_demo.py # Laplacian Jacobian + Newton-CG inversion
Documentation
📖 Full Documentation & Interactive Demos
Citation
Cotton, Peter. "Inferring Relative Ability from Winning Probability in Multientrant Contests." SIAM Journal on Financial Mathematics 12.1 (2021): 295-317.
Development
pip install -e ".[test,viz]"
python scripts/format-code.py
pytest
Metadata
Release files for thurstone 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| thurstone-0.2.0.tar.gz | 77.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| thurstone-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 170.8 kB
Release files / thurstone-0.2.0.tar.gz
| Download URL | thurstone-0.2.0.tar.gz |
|---|---|
| Size | 77.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c6279edf4125ffb81b5c5b2b4c90f552de30023a79e2810e371d496ec526eef2
|
|
BLAKE2b-256 checksum How to use checksums |
12988e8534620f738c75f723349a82bbb45f4cda10e92651835643c66ffc6867
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|
Release files / thurstone-0.2.0-py3-none-any.whl
| Download URL | thurstone-0.2.0-py3-none-any.whl |
|---|---|
| Size | 93.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
138b4122d55149a3e24fd5e523171c9015752c803ce03d7673305f86e46d6650
|
|
BLAKE2b-256 checksum How to use checksums |
ec3a89731a27ab62eaf4c76bf68a5c33363c7f4ac60573bf370a08bf10f9a3cd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|