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.
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:
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.
Dr. Daniel Carrera
Postdoctoral Research Associate
Iowa State University
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:
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.
Election-Methods mailing list - see https://electorama.com/em for list
info