election-methods@mailman.electorama.com

Technical discussion of election methods

View all threads

Exact elections -- Proof of concept

DC
Daniel Carrera
Sun, Jan 30, 2022 6:40 PM

Success!

The attached Python script is a minimalist proof of concept that
demonstrates the key features needed to implement Kristofer's exact
election model. I'm using the Polytope library:

https://github.com/tulip-control/polytope

This library isn't as general as QHull, but conversely, it is easier to
use. In the attached script I walk you through the core features and
demonstrate a simple function that computes the Voronoi cell of each
candidate as an object where you can compute volumes and intersections.

Finally, I demonstrate Kristofer's exact spatial model probabilities for a
toy election with 3 candidates in a 2D issue space. Generalizing this
should not be hard, but recursion can be confusing and I wanted to make the
logic as clear as possible for illustration purposes.

Cheers,

Dr. Daniel Carrera
Postdoctoral Research Associate
Iowa State University

Success! The attached Python script is a minimalist proof of concept that demonstrates the key features needed to implement Kristofer's exact election model. I'm using the Polytope library: https://github.com/tulip-control/polytope This library isn't as general as QHull, but conversely, it is easier to use. In the attached script I walk you through the core features and demonstrate a simple function that computes the Voronoi cell of each candidate as an object where you can compute volumes and intersections. Finally, I demonstrate Kristofer's exact spatial model probabilities for a toy election with 3 candidates in a 2D issue space. Generalizing this should not be hard, but recursion can be confusing and I wanted to make the logic as clear as possible for illustration purposes. Cheers, -- Dr. Daniel Carrera Postdoctoral Research Associate Iowa State University
DC
Daniel Carrera
Sun, Jan 30, 2022 11:18 PM

Here is a more complete implementation. The example in the previous email
was more of a tutorial + demonstration. This one is more of an actual code
that you would use. You can have more candidates and higher dimensions. The
usage is very straightforward:

EXAMPLE 2

n_candidates = 4
n_dim = 5

candidates = np.random.rand(n_candidates,n_dim)
unit_bound = [ [0,1] for j in range(n_dim) ]

names = ['A','B','C','D']
tally = compute_tally(candidates,names,unit_bound)

This is an example with 4 candidates in a 5-dimensional space. The
candidates are uniformly randomly distributed and the bounds are the unit
hypercube. To make the results legible, you need to supply a list of names
('A', 'B', 'C', 'D') for the candidates. The compute_tally() function does
all the work and you just get a dictionary that tells you what fraction of
voters choose each ballot.

For example:

In [18]: tally
Out[18]:
{'A>B>C>D': 0.2158439457766137,
'A>B>D>C': 0.058557168066913655,
'A>C>B>D': 0.0872,
'A>C>D>B': 0.0292,
'A>D>B>C': 0.1043845169888461,
'A>D>C>B': 0.09699999999999999,
'B>A>C>D': 0.019399596489520984,
...

and so on.

Cheers,

Dr. Daniel Carrera
Postdoctoral Research Associate
Iowa State University

Here is a more complete implementation. The example in the previous email was more of a tutorial + demonstration. This one is more of an actual code that you would use. You can have more candidates and higher dimensions. The usage is very straightforward: # # EXAMPLE 2 # n_candidates = 4 n_dim = 5 candidates = np.random.rand(n_candidates,n_dim) unit_bound = [ [0,1] for j in range(n_dim) ] names = ['A','B','C','D'] tally = compute_tally(candidates,names,unit_bound) This is an example with 4 candidates in a 5-dimensional space. The candidates are uniformly randomly distributed and the bounds are the unit hypercube. To make the results legible, you need to supply a list of names ('A', 'B', 'C', 'D') for the candidates. The compute_tally() function does all the work and you just get a dictionary that tells you what fraction of voters choose each ballot. For example: In [18]: tally Out[18]: {'A>B>C>D': 0.2158439457766137, 'A>B>D>C': 0.058557168066913655, 'A>C>B>D': 0.0872, 'A>C>D>B': 0.0292, 'A>D>B>C': 0.1043845169888461, 'A>D>C>B': 0.09699999999999999, 'B>A>C>D': 0.019399596489520984, ... and so on. Cheers, -- Dr. Daniel Carrera Postdoctoral Research Associate Iowa State University
FS
Forest Simmons
Sun, Jan 30, 2022 11:30 PM

Wonderful!

El dom., 30 de ene. de 2022 3:18 p. m., Daniel Carrera dcarrera@gmail.com
escribió:

Here is a more complete implementation. The example in the previous email
was more of a tutorial + demonstration. This one is more of an actual code
that you would use. You can have more candidates and higher dimensions. The
usage is very straightforward:

EXAMPLE 2

n_candidates = 4
n_dim = 5

candidates = np.random.rand(n_candidates,n_dim)
unit_bound = [ [0,1] for j in range(n_dim) ]

names = ['A','B','C','D']
tally = compute_tally(candidates,names,unit_bound)

This is an example with 4 candidates in a 5-dimensional space. The
candidates are uniformly randomly distributed and the bounds are the unit
hypercube. To make the results legible, you need to supply a list of names
('A', 'B', 'C', 'D') for the candidates. The compute_tally() function does
all the work and you just get a dictionary that tells you what fraction of
voters choose each ballot.

For example:

In [18]: tally
Out[18]:
{'A>B>C>D': 0.2158439457766137,
'A>B>D>C': 0.058557168066913655,
'A>C>B>D': 0.0872,
'A>C>D>B': 0.0292,
'A>D>B>C': 0.1043845169888461,
'A>D>C>B': 0.09699999999999999,
'B>A>C>D': 0.019399596489520984,
...

and so on.

Cheers,

Dr. Daniel Carrera
Postdoctoral Research Associate
Iowa State University

Election-Methods mailing list - see https://electorama.com/em for list
info

Wonderful! El dom., 30 de ene. de 2022 3:18 p. m., Daniel Carrera <dcarrera@gmail.com> escribió: > Here is a more complete implementation. The example in the previous email > was more of a tutorial + demonstration. This one is more of an actual code > that you would use. You can have more candidates and higher dimensions. The > usage is very straightforward: > > # > # EXAMPLE 2 > # > n_candidates = 4 > n_dim = 5 > > candidates = np.random.rand(n_candidates,n_dim) > unit_bound = [ [0,1] for j in range(n_dim) ] > > names = ['A','B','C','D'] > tally = compute_tally(candidates,names,unit_bound) > > > This is an example with 4 candidates in a 5-dimensional space. The > candidates are uniformly randomly distributed and the bounds are the unit > hypercube. To make the results legible, you need to supply a list of names > ('A', 'B', 'C', 'D') for the candidates. The compute_tally() function does > all the work and you just get a dictionary that tells you what fraction of > voters choose each ballot. > > For example: > > In [18]: tally > Out[18]: > {'A>B>C>D': 0.2158439457766137, > 'A>B>D>C': 0.058557168066913655, > 'A>C>B>D': 0.0872, > 'A>C>D>B': 0.0292, > 'A>D>B>C': 0.1043845169888461, > 'A>D>C>B': 0.09699999999999999, > 'B>A>C>D': 0.019399596489520984, > ... > > and so on. > > Cheers, > -- > Dr. Daniel Carrera > Postdoctoral Research Associate > Iowa State University > ---- > Election-Methods mailing list - see https://electorama.com/em for list > info >