Skip to main content

Election Simulator 3000

Actions Status codecov

This is a library of functions for simulating thousands of elections held using different voting methods (Borda count, Approval voting, etc.) under different voter models (impartial culture, spatial model, etc.) and estimating various metrics from them (Social Utility Efficiency = Voter Satisfaction Efficiency = VSE, Condorcet Efficiency, likelihood of Condorcet cycles, etc.)

For example, it can be used to reproduce Figure 1 from Merrill 1984:

Graph of Condorcet Efficiencies for a Random Society for Plurality, Runoff, Hare, Approval, Borda, Coomsb, Black compared to Merrill's results

Or the table of Effectiveness from Weber 1977:

Standard Vote-for-half Borda
2 81.37 81.71 81.41
3 75.10 75.00 86.53
4 69.90 79.92 89.47
5 65.02 79.09 91.34
6 61.08 81.20 92.61
10 50.78 82.94 95.35
255 12.78 86.37 99.80

See /examples folder for more on what it can do, such as reproductions of previous research.

Goals

  • Fast (~25,000 elections per second on Core i7-9750H)
  • Flexible
  • Well-documented, easily-used and improved upon by other people
  • Well-tested and bug-free
  • Able to reproduce peer-reviewed research

Requirements

See pyproject.toml. As of this README, it includes numpy and scipy for the simulations, tabulate for printing example tables, joblib for parallelizing extreme examples, and pytest, hypothesis, and pytest-cov for running the tests. All should be installable through conda.

Optionally, elsim can use numba for speed. Use the fast extra when possible. If not available, the code will still run, just more slowly. (Numba is optional because it does not support every CPU/OS/python combination, and pulls a large LLVM-based stack.)

Installation

From PyPI (recommended — includes Numba):

pip install elsim[fast]

Core only (no Numba — lighter install, pure Python paths):

pip install elsim

Documentation

Currently just the docstrings of the submodules and functions themselves, in numpydoc format. Now being rendered at https://endolith.github.io/elsim/

Usage

Specify an election with three candidates (0, 1, 2), where two voters rank candidates 0 > 2 > 1, two voters rank candidates 1 > 2 > 0, and one ranks candidates 2 > 0 > 1:

>>> election = [[0, 2, 1],
...             [0, 2, 1],
...             [1, 2, 0],
...             [1, 2, 0],
...             [2, 0, 1]]

Calculate the winner using Black's method:

>>> from elsim.methods import black
>>> black(election)
2

Candidate 2 is the Condorcet winner, and wins under Black's method.

Submodules and chained functions

Originally, the functions in submodules were meant to be chained together in a simple flow:

  1. A function from elsim.elections takes parameters as input (number of candidates, number of voters, dispersion in spatial model, etc.) and produces an array of utilities (each voter's appraisal of each candidate).
  2. Then a function from elsim.strategies converts each voter's utilities into a ballot.
  3. Then a function from elsim.methods counts the collection of ballots and chooses a winner.
flowchart LR
    Parameters -- Election --> Utilities
    Utilities -- Strategy --> Ballots
    Ballots -- Method --> Winner

However, while implementing many different types of simulations, it has become more complicated. Some functions produce intermediate results, while others skip over multiple steps. I'm no longer sure the best way to organize these functions into submodules. Here is a diagram showing the flow of every function currently in the submodules:

%%{ init: { 'flowchart': { 'curve': 'monotoneX' } } }%%
flowchart LR
    %% elections.py
    Parameters -- <code>normal_electorate</code> --> Positions[Spatial positions]
    Positions -- <code>normed_dist_utilities</code> --> Utilities
    Parameters -- <code>random_utilities</code> --> Utilities
    Parameters -- <code>impartial_culture</code> --> ranked_ballots

    %% strategies.py
    Utilities -- <code>approval_optimal</code> --> approval_ballots
    Utilities -- <code>vote_for_k</code> --> approval_ballots
    Utilities -- <code>honest_normed_scores</code> --> score_ballots
    Utilities -- <code>honest_rankings</code> --> ranked_ballots

    subgraph Ballots
        approval_ballots[Approval ballots]
        score_ballots[Score ballots]
        ranked_ballots[Ranked ballots]
    end

    %% approval.py
    approval_ballots -- <code>approval</code> --> Winner
    score_ballots -- <code>combined_approval</code> --> Winner

    %% condorcet.py (moved out of order so it renders with fewer line collisions)
    ranked_ballots -- <code>ranked_election_to_matrix</code> --> Matrix
    Matrix -- <code>condorcet_from_matrix</code> --> Winner
    ranked_ballots -- <code>condorcet</code> --> Winner

    %% black.py
    ranked_ballots -- <code>black</code> --> Winner

    %% borda.py
    ranked_ballots -- <code>borda</code> --> Winner

    %% coombs.py
    ranked_ballots -- <code>coombs</code> --> Winner

    %% fptp.py
    ranked_ballots -- <code>fptp</code> --> Winner
    ranked_ballots -- <code>sntv</code> --> Winner

    %% irv.py
    ranked_ballots -- <code>irv</code> --> Winner

    %% runoff.py
    ranked_ballots -- <code>runoff</code> --> Winner

    %% score.py
    score_ballots -- <code>score</code> --> Winner

    %% star.py
    score_ballots -- <code>star</code> --> Winner
    score_ballots -- <code>matrix_from_scores</code> --> Matrix

    %% utility_winner.py
    Utilities -- <code>utility_winner</code> --> Winner

Tests

Tests can be run by installing the testing dependencies and then running pytest in the project folder.

Bugs / Requests

File issues on the GitHub issue tracker.

Similar projects

Election simulators

Voting system implementations

Metadata

Release files for elsim 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for elsim 0.1.3
File Size Uploaded
elsim-0.1.3.tar.gz 1.7 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for elsim 0.1.3
File Interpreter ABI Platform
elsim-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 1.7 MB

Release files / elsim-0.1.3.tar.gz

Download URL elsim-0.1.3.tar.gz
Size 1.7 MB
Tags Source
SHA-256 checksum
How to use checksums
2c69fab25c487b3f8aabccf600d247b48ed31bd8dde7d7c6fe3b236b22755bcc
BLAKE2b-256 checksum
How to use checksums
f03a12359055eb7f9b8f9e32841a568dd32cfdc1d900fde30e5ab8fe867dc756
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 8, 2026.

Transparency log

Release files / elsim-0.1.3-py3-none-any.whl

Download URL elsim-0.1.3-py3-none-any.whl
Size 32.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
471853054c15d9a03225bfd52ffef68a26c5b59064fa40a14dfdf65c1dd62aec
BLAKE2b-256 checksum
How to use checksums
61a513b5f6172017d733a1d36feae639d22a27befd811707c46c02df1b2b0b7b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page