class svvamp.Profile(preferences_ut=None, preferences_rk=None, preferences_borda_rk=None, log_creation=None, labels_candidates=None, sort_voters=False)[source]

Create a profile of voters with preferences over some candidates.

Parameters:
  • preferences_ut (list of list (or 2d ndarray)) – 2d array of floats. preferences_ut[v, c] is the utility of candidate c as seen by voter v.

  • preferences_rk (list of list (or 2d ndarray)) – 2d array of integers. preferences_rk[v, k] is the candidate at rank k for voter v.

  • preferences_borda_rk (list of list (or 2d ndarray)) – 2d array of integers. preferences_borda_rk[v, c] gains 1 point for each candidate d such that voter v ranks c before d. So, these Borda scores are between 0 and C - 1.

  • log_creation (object) – Any type (string, list…). Some comments.

  • labels_candidates (list of str) – Names of the candidates.

  • sort_voters (bool) – If True, then when the profile is created, voters are immediately sorted, first by their strict order of preference (their row in preferences_rk), then by their weak order of preference (their row in preferences_borda_ut). Note that two voters having the same strict order may have different weak orders, and vice versa. The objective of this sorting is to accelerate some algorithms (typically Individual Manipulation). It can also be convenient to visualize the profile.

Notes

You may enter preferences_ut, preferences_rk or both to define the preferences of the population. In all cases, instead of preferences_rk, you may enter preferences_borda_rk.

If you provide preferences_rk only, then preferences_ut is set to the corresponding Borda scores (preferences_borda_rk).

If you provide preferences_ut only, then preferences_rk is naturally derived from utilities. If voter v has a greater utility for candidate c than for candidate d, then she ranks c before d. If voter v attributes the same utility to several candidates, then the first time the attribute preferences_rk is called, a random ranking will be decided for these tied candidates (once and for all).

If you provide both, then SVVAMP DOES NOT CHECK that they are consistent. You should ensure that they are, in the sense that if v ranks c before d, then she her utility for c must be at least equal to her utility for d. Similarly, you can provide both preferences_rk and preferences_borda_rk, but SVVAMP DOES NOT CHECK that they are consistent.

preferences_rk will be used for sincere voting when a voting system accepts only strict orders.

In contrast, for manipulation purposes, preferences_ut is always used , which means that indifference is taken into account as such to determine the interest in manipulation. If voter v attributes the same utility to candidates w and c, and if w is the sincere winner in an election, then v is not interested in a manipulation for c.

If all voters have a strict order of preference (in the sense of ut), then for functions below having variants with suffix _ut or _rk, the two variants are equivalent.

In some voting systems and in some of the attributes below, we use a process referred as candidate tie-breaking or CTB in SVVAMP. It means that lowest-index candidates are favored. When using CTB, if candidates c and d are tied (for example, in an election using Plurality), then c is favored over d iff c < d.

Implications between majority favorite and Condorcet criteria (cf. corresponding attributes below).

majority_favorite_ut          ==>         majority_favorite_ut_ctb
||              ||                                ||            ||
V               ||                                ||            ||
Resistant Cond. V                                 V             ||
||       majority_favorite_rk ==> majority_favorite_rk_ctb      ||
||                     ||                ||                     ||
V                      ||                ||                     V
Condorcet_ut_abs              ==>             Condorcet_ut_abs_ctb
||      ||             ||                ||            ||       ||
||      V              V                 V             V        ||
V         Condorcet_rk        ==>        Condorcet_rk_ctb       V
Condorcet_ut_rel              ==>             Condorcet_ut_rel_ctb
||
V
Weak Condorcet
||
V
Condorcet-admissible

If all voters have strict orders of preference (in the sense of ut) and if there is an odd number of voters, then:

  • majority_favorite_ut, majority_favorite_rk, majority_favorite_ut_ctb and majority_favorite_rk_ctb are equivalent,

  • Condorcet_ut_abs, Condorcet_ut_abs_ctb, Condorcet_rk, Condorcet_rk_ctb, Condorcet_ut_rel, Condorcet_ut_rel_ctb, Weak Condorcet and Condorcet-admissible are equivalent.

Examples

>>> profile = Profile(preferences_borda_rk=[[2, 1, 0], [1, 0, 2]])
>>> profile.preferences_rk
array([[0, 1, 2],
       [2, 0, 1]])
>>> profile = Profile(preferences_ut=[[1, .3, 0], [.7, 0, 1]])
>>> profile.preferences_rk
array([[0, 1, 2],
       [2, 0, 1]])
>>> profile = Profile()
>>> profile.preferences_rk
Traceback (most recent call last):
ValueError: Please provide at least preferences_rk, preferences_borda_rk or preferences_ut.
property borda_score_c_rk

1d array of integers. borda_score_c_rk[c] is the total Borda score of candidate c (using preferences_borda_rk, i.e. strict preferences).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.borda_score_c_rk
array([4, 2, 0])
property borda_score_c_ut

1d array of floats. borda_score_c_ut[c] is the total Borda score of candidate c (using preferences_borda_ut, i.e. weak preferences).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.borda_score_c_ut
array([4., 2., 0.])
property c_might_be_there_when_cw_is_eliminated_irv_style

Whether a candidate c might be present in a round where the Condorcet winner is eliminated, IRV-style.

Returns:

If there is no condorcet_winner_rk_ctb, then return None. If there is a condorcet_winner_rk_ctb, denote her w. c_might_be_there_when_cw_rk_is_eliminated_irv_style[c] is True iff there exists a subset of candidates including c and w such that, in a Plurality election over this subset of candidates, w has at most n_v / card(subset) votes. What is interesting is the negation: if it is False, then it is impossible for c to manipulate in several IRV-related rules, because c cannot be there when w is eliminated.

Return type:

ndarray or None

Examples

When there is no Condorcet winner (rk ctb), then the output is None:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.condorcet_winner_rk_ctb
nan
>>> print(profile.c_might_be_there_when_cw_is_eliminated_irv_style)
None
property candidates_by_decreasing_borda_score_rk

1d array of integers. candidates_by_decreasing_borda_score_rk[k] is the candidate ranked k th by decreasing Borda score (using borda_score_c_rk, i.e. strict preferences).

For example, candidates_by_decreasing_borda_score_rk[0] is the candidate with highest Borda score (rk).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.candidates_by_decreasing_borda_score_rk
array([0, 1, 2])
property candidates_by_decreasing_borda_score_ut

1d array of integers. candidates_by_decreasing_borda_score_ut[k] is the candidate ranked k th by decreasing Borda score (using borda_score_c_ut, i.e. weak preferences).

For example, candidates_by_decreasing_borda_score_ut[0] is the candidate with highest Borda score (ut).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.candidates_by_decreasing_borda_score_ut
array([0, 1, 2])
property condorcet_admissible_candidates

1d array of booleans. condorcet_admissible_candidates[c] is True iff candidate c is Condorcet-admissible, i.e. iff no candidate d has an absolute victory against c (in the sense of matrix_victories_ut_abs).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.condorcet_admissible_candidates
array([ True, False, False])

See also

nb_condorcet_admissible, exists_condorcet_admissible, not_exists_condorcet_admissible

property condorcet_winner_rk

Integer or NaN. Candidate who has only victories in matrix_victories_rk. If there is no such candidate, then NaN.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.condorcet_winner_rk
0

No Condorcet winner:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.condorcet_winner_rk
nan

See also

exists_condorcet_winner_rk, not_exists_condorcet_winner_rk

property condorcet_winner_rk_ctb

Integer or NaN. Candidate who has only victories in matrix_victories_rk_ctb. If there is no such candidate, then NaN.

Examples

>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.condorcet_winner_rk_ctb
0

No Condorcet winner:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.condorcet_winner_rk_ctb
nan

See also

exists_condorcet_winner_rk_ctb, not_exists_condorcet_winner_rk_ctb

property condorcet_winner_ut_abs

Integer or NaN. Candidate who has only victories in matrix_victories_ut_abs. If there is no such candidate, then NaN.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.condorcet_winner_ut_abs
0

No Condorcet winner:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.condorcet_winner_ut_abs
nan

See also

exists_condorcet_winner_ut_abs, not_exists_condorcet_winner_ut_abs

property condorcet_winner_ut_abs_ctb

Integer or NaN. Candidate who has only victories in matrix_victories_ut_abs_ctb. If there is no such candidate, then NaN.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.condorcet_winner_ut_abs_ctb
0

No Condorcet winner:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.condorcet_winner_ut_abs_ctb
nan

See also

exists_condorcet_winner_ut_abs_ctb, not_exists_condorcet_winner_ut_abs_ctb

property condorcet_winner_ut_rel

Integer or NaN. Candidate who has only victories in matrix_victories_ut_rel. If there is no such candidate, then NaN.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.condorcet_winner_ut_rel
0

No Condorcet winner:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.condorcet_winner_ut_rel
nan

See also

exists_condorcet_winner_ut_rel, not_exists_condorcet_winner_ut_rel

property condorcet_winner_ut_rel_ctb

Integer or NaN. Candidate who has only victories in matrix_victories_ut_rel_ctb. If there is no such candidate, then NaN.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.condorcet_winner_ut_rel_ctb
0

No Condorcet winner:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.condorcet_winner_ut_rel_ctb
nan

See also

exists_condorcet_winner_ut_rel_ctb, not_exists_condorcet_winner_ut_rel_ctb

property decreasing_borda_scores_rk

1d array of integers. decreasing_borda_scores_rk[k] is the k-th Borda score (using borda_score_c_rk, i.e. strict preferences) by decreasing order.

For example, decreasing_borda_scores_rk[0] is the highest Borda score for a candidate (rk).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.decreasing_borda_scores_rk
array([4, 2, 0])
property decreasing_borda_scores_ut

1d array of integers. decreasing_borda_scores_ut[k] is the k-th Borda score (using borda_score_c_ut, i.e. weak preferences) by decreasing order.

For example, decreasing_borda_scores_ut[0] is the highest Borda score for a candidate (rk).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.decreasing_borda_scores_ut
array([4., 2., 0.])
demo(log_depth=1)[source]

Demonstrate the methods of Population class.

Parameters:

log_depth (int) – Integer from 0 (basic info) to 3 (verbose).

Examples

>>> initialize_random_seeds()
>>> preferences_ut_test = np.random.randint(-5, 5, (10, 5))
>>> profile = Profile(preferences_ut=preferences_ut_test,
...                   labels_candidates=['Alice', 'Bob', 'Catherine', 'Dave', 'Ellen'],
...                   sort_voters=True)
>>> profile.demo(log_depth=0)  

************************
*   Basic properties   *
************************
n_v = 10
n_c = 5
labels_candidates = ['Alice', 'Bob', 'Catherine', 'Dave', 'Ellen']
preferences_ut =
[[ 4 -2  0 -3 -1]
 [ 4  4 -5 -1  2]
 [ 0  4  3  4 -1]
 [-2 -2  2 -5 -4]
 [-2 -3  2 -3 -5]
 [-3 -2  3 -4 -2]
 [ 2  1  3  3 -4]
 [-2 -5 -2  0 -5]
 [ 1  2  2  3 -4]
 [ 0 -5 -2 -2  2]]
preferences_borda_ut =
[[4.  1.  3.  0.  2. ]
 [3.5 3.5 0.  1.  2. ]
 [1.  3.5 2.  3.5 0. ]
 [2.5 2.5 4.  0.  1. ]
 [3.  1.5 4.  1.5 0. ]
 [1.  2.5 4.  0.  2.5]
 [2.  1.  3.5 3.5 0. ]
 [2.5 0.5 2.5 4.  0.5]
 [1.  2.5 2.5 4.  0. ]
 [3.  0.  1.5 1.5 4. ]]
preferences_borda_rk =
[[4 1 3 0 2]
 [3 4 0 1 2]
 [1 4 2 3 0]
 [3 2 4 0 1]
 [3 1 4 2 0]
 [1 3 4 0 2]
 [2 1 3 4 0]
 [2 0 3 4 1]
 [1 2 3 4 0]
 [3 0 2 1 4]]
preferences_rk =
[[0 2 4 1 3]
 [1 0 4 3 2]
 [1 3 2 0 4]
 [2 0 1 4 3]
 [2 0 3 1 4]
 [2 1 4 0 3]
 [3 2 0 1 4]
 [3 2 0 4 1]
 [3 2 1 0 4]
 [4 0 2 3 1]]
v_has_same_ordinal_preferences_as_previous_voter =
[False False False False False False False False False False]

************************
*   Plurality scores   *
************************
preferences_rk (reminder) =
[[0 2 4 1 3]
 [1 0 4 3 2]
 [1 3 2 0 4]
 [2 0 1 4 3]
 [2 0 3 1 4]
 [2 1 4 0 3]
 [3 2 0 1 4]
 [3 2 0 4 1]
 [3 2 1 0 4]
 [4 0 2 3 1]]
plurality_scores_rk = [1 2 3 3 1]
majority_favorite_rk = nan
majority_favorite_rk_ctb = nan

preferences_borda_ut (reminder) =
[[4.  1.  3.  0.  2. ]
 [3.5 3.5 0.  1.  2. ]
 [1.  3.5 2.  3.5 0. ]
 [2.5 2.5 4.  0.  1. ]
 [3.  1.5 4.  1.5 0. ]
 [1.  2.5 4.  0.  2.5]
 [2.  1.  3.5 3.5 0. ]
 [2.5 0.5 2.5 4.  0.5]
 [1.  2.5 2.5 4.  0. ]
 [3.  0.  1.5 1.5 4. ]]
plurality_scores_ut = [1 0 3 2 1]
majority_favorite_ut = nan
majority_favorite_ut_ctb = nan

********************
*   Borda scores   *
********************
preferences_borda_rk (reminder) =
[[4 1 3 0 2]
 [3 4 0 1 2]
 [1 4 2 3 0]
 [3 2 4 0 1]
 [3 1 4 2 0]
 [1 3 4 0 2]
 [2 1 3 4 0]
 [2 0 3 4 1]
 [1 2 3 4 0]
 [3 0 2 1 4]]
borda_score_c_rk =
[23 18 28 19 12]
Remark: Borda scores above are computed with the matrix of duels.
Check: np.sum(self.preferences_borda_rk, 0) =
[23 18 28 19 12]
decreasing_borda_scores_rk =
[28 23 19 18 12]
candidates_by_decreasing_borda_score_rk =
[2 0 3 1 4]

preferences_borda_ut (reminder) =
[[4.  1.  3.  0.  2. ]
 [3.5 3.5 0.  1.  2. ]
 [1.  3.5 2.  3.5 0. ]
 [2.5 2.5 4.  0.  1. ]
 [3.  1.5 4.  1.5 0. ]
 [1.  2.5 4.  0.  2.5]
 [2.  1.  3.5 3.5 0. ]
 [2.5 0.5 2.5 4.  0.5]
 [1.  2.5 2.5 4.  0. ]
 [3.  0.  1.5 1.5 4. ]]
borda_score_c_ut =
[23.5 18.5 27.  19.  12. ]
decreasing_borda_scores_ut =
[27.  23.5 19.  18.5 12. ]
candidates_by_decreasing_borda_score_ut =
[2 0 3 1 4]

*****************
*   Utilities   *
*****************
preferences_ut (reminder) =
[[ 4 -2  0 -3 -1]
 [ 4  4 -5 -1  2]
 [ 0  4  3  4 -1]
 [-2 -2  2 -5 -4]
 [-2 -3  2 -3 -5]
 [-3 -2  3 -4 -2]
 [ 2  1  3  3 -4]
 [-2 -5 -2  0 -5]
 [ 1  2  2  3 -4]
 [ 0 -5 -2 -2  2]]
total_utility_c =
[  2  -8   6  -8 -22]
total_utility_min = -22
total_utility_max = 6
total_utility_mean = -6.0
total_utility_std = 9.715966241192895

*******************************************
*   Condorcet notions based on rankings   *
*******************************************
preferences_rk (reminder) =
[[0 2 4 1 3]
 [1 0 4 3 2]
 [1 3 2 0 4]
 [2 0 1 4 3]
 [2 0 3 1 4]
 [2 1 4 0 3]
 [3 2 0 1 4]
 [3 2 0 4 1]
 [3 2 1 0 4]
 [4 0 2 3 1]]
matrix_duels_rk =
[[0 6 3 6 8]
 [4 0 2 5 7]
 [7 8 0 5 8]
 [4 5 5 0 5]
 [2 3 2 5 0]]
matrix_victories_rk =
[[0.  1.  0.  1.  1. ]
 [0.  0.  0.  0.5 1. ]
 [1.  1.  0.  0.5 1. ]
 [0.  0.5 0.5 0.  0.5]
 [0.  0.  0.  0.5 0. ]]
condorcet_winner_rk = nan
exists_condorcet_order_rk = False
matrix_victories_rk_ctb =
[[0. 1. 0. 1. 1.]
 [0. 0. 0. 1. 1.]
 [1. 1. 0. 1. 1.]
 [0. 0. 0. 0. 1.]
 [0. 0. 0. 0. 0.]]
condorcet_winner_rk_ctb = 2
exists_condorcet_order_rk_ctb = True

***************************************
*   Relative Condorcet notions (ut)   *
***************************************
preferences_borda_ut (reminder) =
[[4.  1.  3.  0.  2. ]
 [3.5 3.5 0.  1.  2. ]
 [1.  3.5 2.  3.5 0. ]
 [2.5 2.5 4.  0.  1. ]
 [3.  1.5 4.  1.5 0. ]
 [1.  2.5 4.  0.  2.5]
 [2.  1.  3.5 3.5 0. ]
 [2.5 0.5 2.5 4.  0.5]
 [1.  2.5 2.5 4.  0. ]
 [3.  0.  1.5 1.5 4. ]]
matrix_duels_ut =
[[0 5 3 6 8]
 [3 0 2 4 6]
 [6 7 0 4 8]
 [4 4 4 0 5]
 [2 2 2 5 0]]
matrix_victories_ut_rel =
[[0.  1.  0.  1.  1. ]
 [0.  0.  0.  0.5 1. ]
 [1.  1.  0.  0.5 1. ]
 [0.  0.5 0.5 0.  0.5]
 [0.  0.  0.  0.5 0. ]]
condorcet_winner_ut_rel = nan
exists_condorcet_order_ut_rel = False
matrix_victories_ut_rel_ctb =
[[0. 1. 0. 1. 1.]
 [0. 0. 0. 1. 1.]
 [1. 1. 0. 1. 1.]
 [0. 0. 0. 0. 1.]
 [0. 0. 0. 0. 0.]]
condorcet_winner_ut_rel_ctb = 2
exists_condorcet_order_ut_rel_ctb = True

***************************************
*   Absolute Condorcet notions (ut)   *
***************************************
matrix_duels_ut (reminder) =
[[0 5 3 6 8]
 [3 0 2 4 6]
 [6 7 0 4 8]
 [4 4 4 0 5]
 [2 2 2 5 0]]
matrix_victories_ut_abs =
[[0.  0.5 0.  1.  1. ]
 [0.  0.  0.  0.  1. ]
 [1.  1.  0.  0.  1. ]
 [0.  0.  0.  0.  0.5]
 [0.  0.  0.  0.5 0. ]]
condorcet_admissible_candidates =
[False False  True False False]
nb_condorcet_admissible = 1
weak_condorcet_winners =
[False False  True False False]
nb_weak_condorcet_winners = 1
condorcet_winner_ut_abs = nan
exists_condorcet_order_ut_abs = False
resistant_condorcet_winner = nan
threshold_c_prevents_w_Condorcet_ut_abs =
[[0 0 0 2 0]
 [0 0 0 0 0]
 [2 0 0 2 0]
 [0 0 2 0 0]
 [0 0 0 1 0]]
matrix_victories_ut_abs_ctb =
[[0. 1. 0. 1. 1.]
 [0. 0. 0. 0. 1.]
 [1. 1. 0. 0. 1.]
 [0. 0. 0. 0. 1.]
 [0. 0. 0. 0. 0.]]
condorcet_winner_ut_abs_ctb = nan
exists_condorcet_order_ut_abs_ctb = False

**********************************************
*   Implications between Condorcet notions   *
**********************************************
maj_fav_ut (False)             ==>            maj_fav_ut_ctb (False)
 ||          ||                                     ||           ||
 ||          V                                      V            ||
 ||         maj_fav_rk (False) ==> maj_fav_rk_ctb (False)        ||
 V                         ||       ||                           ||
Resistant Condorcet (False)                                      ||
 ||                        ||       ||                           ||
 V                         ||       ||                           V
Condorcet_ut_abs (False)       ==>      Condorcet_ut_abs_ctb (False)
 ||          ||            ||       ||              ||           ||
 ||          V             V        V               V            ||
 ||       Condorcet_rk (False) ==> Condorcet_rk_ctb (True)       ||
 V                                                               V
Condorcet_ut_rel (False)       ==>      Condorcet_ut_rel_ctb (True)
 ||
 V
Weak Condorcet (True)
 ||
 V
Condorcet-admissible (True)
property exists_condorcet_admissible

Boolean (True iff there is at least one Condorcet-admissible candidate, condorcet_admissible_candidates).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_admissible
True
property exists_condorcet_order_rk

Boolean. True iff in matrix matrix_victories_rk, there is a candidate with n_c - 1 victories, a candidate with n_c - 2 victories, etc.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_order_rk
True

See also

not_exists_condorcet_order_rk

property exists_condorcet_order_rk_ctb

Boolean. True iff in matrix matrix_victories_rk_ctb, there is a candidate with n_c - 1 victories, a candidate with n_c - 2 victories, etc.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_order_rk_ctb
True

See also

not_exists_condorcet_order_rk_ctb

property exists_condorcet_order_ut_abs

Boolean. True iff in matrix matrix_victories_ut_abs, there is a candidate with n_c - 1 victories, a candidate with n_c - 2 victories, etc.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_order_ut_abs
True

See also

not_exists_condorcet_order_ut_abs

property exists_condorcet_order_ut_abs_ctb

Boolean. True iff in matrix matrix_victories_ut_abs_ctb, there is a candidate with n_c - 1 victories, a candidate with n_c - 2 victories, etc.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_order_ut_abs_ctb
True

See also

not_exists_condorcet_order_ut_abs_ctb

property exists_condorcet_order_ut_rel

Boolean. True iff in matrix matrix_victories_ut_rel, there is a candidate with n_c - 1 victories, a candidate with n_c - 2 victories, etc.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_order_ut_rel
True

See also

not_exists_condorcet_order_ut_rel

property exists_condorcet_order_ut_rel_ctb

Boolean. True iff in matrix matrix_victories_ut_rel_ctb, there is a candidate with n_c - 1 victories, a candidate with n_c - 2 victories, etc.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_order_ut_rel_ctb
True

See also

not_exists_condorcet_order_ut_rel_ctb

property exists_condorcet_winner_rk

Boolean (True iff there is a condorcet_winner_rk).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_winner_rk
True
property exists_condorcet_winner_rk_ctb

Boolean (True iff there is a condorcet_winner_rk_ctb).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_winner_rk_ctb
True
property exists_condorcet_winner_ut_abs

Boolean (True iff there is a condorcet_winner_ut_abs).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_winner_ut_abs
True
property exists_condorcet_winner_ut_abs_ctb

Boolean (True iff there is a condorcet_winner_ut_abs_ctb).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_winner_ut_abs_ctb
True
property exists_condorcet_winner_ut_rel

Boolean (True iff there is a condorcet_winner_ut_rel).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_winner_ut_rel
True
property exists_condorcet_winner_ut_rel_ctb

Boolean (True iff there is a condorcet_winner_ut_rel_ctb).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_condorcet_winner_ut_rel_ctb
True
property exists_irv_immune_candidate

Whether there exists a ‘IRV-immune’ candidate.

A candidate w is IRV-immune iff she is Condorcet winner (rk ctb) and for any other candidate c, we have that c_might_be_there_when_cw_is_eliminated_irv_style[c] ` is False. In other words, there is no subset of candidates containing `w such that w has at most n_v / card(subset) plurality votes.

Examples

>>> profile = Profile(preferences_rk=[[0, 2, 1], [0, 2, 1], [1, 2, 0], [1, 2, 0], [2, 0, 1]])
>>> profile.condorcet_winner_rk_ctb
2
>>> profile.exists_irv_immune_candidate
False
property exists_majority_favorite_rk

Boolean (True iff there is a majority_favorite_rk).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_majority_favorite_rk
True
property exists_majority_favorite_rk_ctb

Boolean (True iff there is a majority_favorite_rk_ctb).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_majority_favorite_rk_ctb
True
property exists_majority_favorite_ut

Boolean (True iff there is a majority_favorite_ut).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_majority_favorite_ut
True
property exists_majority_favorite_ut_ctb

Boolean (True iff there is a majority_favorite_ut_ctb).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_majority_favorite_ut_ctb
True
property exists_resistant_condorcet_winner

Boolean (True iff there is a resistant_condorcet_winner).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_resistant_condorcet_winner
True
property exists_weak_condorcet_winner

Boolean (True iff there is at least one weak Condorcet winner, weak_condorcet_winners).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.exists_weak_condorcet_winner
True
property labels_candidates

List of n_c strings (names of the candidates).

property majority_favorite_rk

Integer or NaN. Candidate who has strictly more than n_v/2 in plurality_scores_rk. If there is no such candidate, then NaN.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.majority_favorite_rk
0

No majority favorite:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.majority_favorite_rk
nan

See also

exists_majority_favorite_rk, not_exists_majority_favorite_rk

property majority_favorite_rk_ctb

Integer or NaN. Candidate who has strictly more than n_v/2 in plurality_scores_rk. Can also be candidate 0 with exactly n_v/2. If there is no such candidate, then NaN.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.majority_favorite_rk_ctb
0

No majority favorite:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.majority_favorite_rk_ctb
nan

See also

exists_majority_favorite_rk_ctb, not_exists_majority_favorite_rk_ctb

property majority_favorite_ut

Integer or NaN. Candidate who has strictly more than n_v/2 in plurality_scores_ut. If there is no such candidate, then NaN.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.majority_favorite_ut
0

No majority favorite:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.majority_favorite_ut
nan

See also

exists_majority_favorite_ut, not_exists_majority_favorite_ut

property majority_favorite_ut_ctb

Integer or NaN. Candidate who has strictly more than n_v/2 in plurality_scores_ut. Can also be candidate 0 with exactly n_v/2. If there is no such candidate, then NaN.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.majority_favorite_ut_ctb
0

No majority favorite:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.majority_favorite_ut_ctb
nan

See also

exists_majority_favorite_ut_ctb, not_exists_majority_favorite_ut_ctb

property matrix_duels_rk

2d array of integers. matrix_duels_rk[c, d] is the number of voters who rank candidate c before d (in the sense of preferences_rk). By convention, diagonal coefficients are set to 0.

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.matrix_duels_rk
array([[0, 2, 2],
       [0, 0, 2],
       [0, 0, 0]])
property matrix_duels_ut

2d array of integers. matrix_duels_ut[c, d] is the number of voters who have a strictly greater utility for c than for d. By convention, diagonal coefficients are set to 0.

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.matrix_duels_ut
array([[0, 2, 2],
       [0, 0, 2],
       [0, 0, 0]])
property matrix_victories_rk

2d array of values in {0, 0.5, 1}. Matrix of victories based on matrix_duels_rk.

matrix_victories_rk[c, d] is:

  • 1 iff matrix_duels_rk[c, d] > matrix_duels_rk[d, c], i.e. iff matrix_duels_rk[c, d] > V / 2.

  • 0.5 iff matrix_duels_rk[c, d] = matrix_duels_rk[d, c], i.e. iff matrix_duels_rk[c, d] = V / 2.

  • 0 iff matrix_duels_rk[c, d] < matrix_duels_rk[d, c], i.e. iff matrix_duels_rk[c, d] < V / 2.

By convention, diagonal coefficients are set to 0.

Examples

A victory:

>>> profile = Profile(preferences_rk=[[0, 1], [0, 1]])
>>> profile.matrix_victories_rk
array([[0., 1.],
       [0., 0.]])

A tie:

>>> profile = Profile(preferences_rk=[[0, 1], [1, 0]])
>>> profile.matrix_victories_rk
array([[0. , 0.5],
       [0.5, 0. ]])
property matrix_victories_rk_ctb

2d array of values in {0, 1}. Matrix of victories based on matrix_duels_rk, with tie-breaks on candidates.

matrix_victories_rk_ctb[c, d] is:

  • 1 iff matrix_duels_rk[c, d] > matrix_duels_rk[d, c], or matrix_duels_rk[c, d] = matrix_duels_rk[d, c] and c < d.

  • 0 iff matrix_duels_rk[c, d] < matrix_duels_rk[d, c], or matrix_duels_rk[c, d] = matrix_duels_rk[d, c] and d < c.

By convention, diagonal coefficients are set to 0.

Examples

A victory (without tie-breaking):

>>> profile = Profile(preferences_rk=[[0, 1], [0, 1]])
>>> profile.matrix_victories_rk_ctb
array([[0., 1.],
       [0., 0.]])

A victory with tie-breaking:

>>> profile = Profile(preferences_rk=[[0, 1], [1, 0]])
>>> profile.matrix_victories_rk_ctb
array([[0., 1.],
       [0., 0.]])
property matrix_victories_ut_abs

2d array of values in {0, 0.5, 1}. Matrix of absolute victories based on matrix_duels_ut.

matrix_victories_ut_abs[c, d] is:

  • 1 iff matrix_duels_ut[c, d] > V / 2.

  • 0.5 iff matrix_duels_ut[c, d] = V / 2.

  • 0 iff matrix_duels_ut[c, d] < V / 2.

By convention, diagonal coefficients are set to 0.

Examples

A victory:

>>> profile = Profile(preferences_ut=[[1, 0], [1, 0]])
>>> profile.matrix_victories_ut_abs
array([[0., 1.],
       [0., 0.]])

A half-victory, but the other candidate has lost:

>>> profile = Profile(preferences_ut=[[1, 0], [42, 42]])
>>> profile.matrix_victories_ut_abs
array([[0. , 0.5],
       [0. , 0. ]])

A half-victory for each candidate:

>>> profile = Profile(preferences_ut=[[1, 0], [0, 1]])
>>> profile.matrix_victories_ut_abs
array([[0. , 0.5],
       [0.5, 0. ]])

A defeat for each candidate:

>>> profile = Profile(preferences_ut=[[0, 0], [0, 0]])
>>> profile.matrix_victories_ut_abs
array([[0., 0.],
       [0., 0.]])
property matrix_victories_ut_abs_ctb

2d array of values in {0, 1}. Matrix of absolute victories based on matrix_duels_ut, with tie-breaks on candidates.

matrix_victories_ut_abs_ctb[c, d] is:

  • 1 iff matrix_duels_ut[c, d] > V / 2, or matrix_duels_ut[c, d] = V / 2 and c < d.

  • 0 iff matrix_duels_ut[c, d] < V / 2, or matrix_duels_ut[c, d] = V / 2 and d < c.

By convention, diagonal coefficients are set to 0.

Examples

A victory (without tie-breaking):

>>> profile = Profile(preferences_ut=[[1, 0], [1, 0]])
>>> profile.matrix_victories_ut_abs_ctb
array([[0., 1.],
       [0., 0.]])

A victory with tie-breaking:

>>> profile = Profile(preferences_ut=[[1, 0], [0, 1]])
>>> profile.matrix_victories_ut_abs_ctb
array([[0., 1.],
       [0., 0.]])

Another case of victory with tie-breaking:

>>> profile = Profile(preferences_ut=[[1, 0], [42, 42]])
>>> profile.matrix_victories_ut_abs_ctb
array([[0., 1.],
       [0., 0.]])

A defeat for each candidate:

>>> profile = Profile(preferences_ut=[[0, 0], [0, 0]])
>>> profile.matrix_victories_ut_abs_ctb
array([[0., 0.],
       [0., 0.]])
property matrix_victories_ut_rel

2d array of values in {0, 0.5, 1}. Matrix of relative victories based on matrix_duels_ut.

matrix_victories_ut_rel[c, d] is:

  • 1 iff matrix_duels_ut[c, d] > matrix_duels_ut[d, c].

  • 0.5 iff matrix_duels_ut[c, d] = matrix_duels_ut[d, c].

  • 0 iff matrix_duels_ut[c, d] < matrix_duels_ut[d, c].

By convention, diagonal coefficients are set to 0.

Examples

A relative victory (which is not an absolute victory):

>>> profile = Profile(preferences_ut=[[1, 0], [0, 0], [0, 0]])
>>> profile.matrix_victories_ut_rel
array([[0., 1.],
       [0., 0.]])

A tie:

>>> profile = Profile(preferences_ut=[[1, 0], [0, 1], [0, 0]])
>>> profile.matrix_victories_ut_rel
array([[0. , 0.5],
       [0.5, 0. ]])
property matrix_victories_ut_rel_ctb

2d array of values in {0, 1}. Matrix of relative victories based on matrix_duels_ut, with tie-breaks on candidates.

matrix_victories_ut_rel_ctb[c, d] is:

  • 1 iff matrix_duels_ut[c, d] > matrix_duels_ut[d, c], or matrix_duels_ut[c, d] = matrix_duels_ut[d, c] and c < d.

  • 0 iff matrix_duels_ut[c, d] < matrix_duels_ut[d, c], or matrix_duels_ut[c, d] = matrix_duels_ut[d, c] and d < c.

By convention, diagonal coefficients are set to 0.

Examples

A relative victory (without tie-breaking):

>>> profile = Profile(preferences_ut=[[1, 0], [0, 0], [0, 0]])
>>> profile.matrix_victories_ut_rel_ctb
array([[0., 1.],
       [0., 0.]])

A relative victory with tie-breaking:

>>> profile = Profile(preferences_ut=[[1, 0], [0, 1], [0, 0]])
>>> profile.matrix_victories_ut_rel_ctb
array([[0., 1.],
       [0., 0.]])
property mean_utility_c

1d array of floats. mean_utility_c[c] is the mean utility for candidate c (i.e. the mean of c’s column in matrix preferences_ut).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[5, 1, 2], [4, 10, 1]])
>>> profile.mean_utility_c
array([4.5, 5.5, 1.5])
property mean_utility_max

Float. mean_utility_max is the maximum of mean_utility_c.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[5, 1, 2], [4, 10, 1]])
>>> profile.mean_utility_max
5.5
property mean_utility_mean

Float. mean_utility_mean is the mean of mean_utility_c.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[5, 1, 2], [4, 10, 1]])
>>> profile.mean_utility_mean == (4.5 + 5.5 + 1.5) / 3
True
property mean_utility_min

Float. mean_utility_min is the minimum of mean_utility_c.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[5, 1, 2], [4, 10, 1]])
>>> profile.mean_utility_min
1.5
property mean_utility_std

Float. mean_utility_std is the standard deviation of mean_utility_c.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[5, 1, 2], [4, 10, 1]])
>>> profile.mean_utility_std == np.std([4.5, 5.5, 1.5])
True
property n_c

Number of candidates.

Type:

int

property n_v

Number of voters.

Type:

int

property nb_condorcet_admissible

Integer (number of Condorcet-admissible candidates, condorcet_admissible_candidates).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.nb_condorcet_admissible
1
property nb_weak_condorcet_winners

Integer (number of weak Condorcet winners, weak_condorcet_winners).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.nb_weak_condorcet_winners
1
property necessary_coalition_size_to_break_irv_immunity

Necessary coalition size to break IRV immunity.

Returns:

If there is no condorcet_winner_rk_ctb, then return None. If there is a condorcet_winner_rk_ctb, denote her w. For a given c, consider the voters who would be sincere in case of manipulation for c, i.e. those who do not prefer c to w. Now, consider a subset of candidates that includes c and w. The sincere voters ensure that w has a certain plurality score s. To eliminate w in this configuration, it is necessary that the total number of voters (sincere + manipulators) is greater than s multiplied by the number of candidates in the subset. Implicitly, this implies a necessary number of manipulators. Taking the minimal value of this necessary number over all possible subsets, this gives necessary_coalition_size_to_break_irv_immunity[c]. In an IRV-style election, it is necessary to have at least this number of manipulators to manipulate in favor of c.

Return type:

ndarray or None

Examples

When there is no Condorcet winner (rk ctb), then the output is None:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.condorcet_winner_rk_ctb
nan
>>> print(profile.necessary_coalition_size_to_break_irv_immunity)
None
property not_exists_condorcet_admissible

Boolean (True iff there is no Condorcet-admissible candidate, condorcet_admissible_candidates).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_admissible
False
property not_exists_condorcet_order_rk

Boolean. Cf. exists_condorcet_order_rk.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_order_rk
False
property not_exists_condorcet_order_rk_ctb

Boolean. Cf. exists_condorcet_order_rk_ctb.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_order_rk_ctb
False
property not_exists_condorcet_order_ut_abs

Boolean. Cf. exists_condorcet_order_ut_abs.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_order_ut_abs
False
property not_exists_condorcet_order_ut_abs_ctb

Boolean. Cf. exists_condorcet_order_ut_abs_ctb.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_order_ut_abs_ctb
False
property not_exists_condorcet_order_ut_rel

Boolean. Cf. exists_condorcet_order_ut_rel.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_order_ut_rel
False
property not_exists_condorcet_order_ut_rel_ctb

Boolean. Cf. exists_condorcet_order_ut_rel_ctb.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_order_ut_rel_ctb
False
property not_exists_condorcet_winner_rk

Boolean (True iff there is no condorcet_winner_rk).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_winner_rk
False
property not_exists_condorcet_winner_rk_ctb

Boolean (True iff there is no condorcet_winner_rk_ctb).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_winner_rk_ctb
False
property not_exists_condorcet_winner_ut_abs

Boolean (True iff there is no condorcet_winner_ut_abs).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_winner_ut_abs
False
property not_exists_condorcet_winner_ut_abs_ctb

Boolean (True iff there is no condorcet_winner_ut_abs_ctb).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_winner_ut_abs_ctb
False
property not_exists_condorcet_winner_ut_rel

Boolean (True iff there is no condorcet_winner_ut_rel).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_winner_ut_rel
False
property not_exists_condorcet_winner_ut_rel_ctb

Boolean (True iff there is no condorcet_winner_ut_rel_ctb).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_condorcet_winner_ut_rel_ctb
False
property not_exists_majority_favorite_rk

Boolean (True iff there is no majority_favorite_rk).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_majority_favorite_rk
False
property not_exists_majority_favorite_rk_ctb

Boolean (True iff there is no majority_favorite_rk_ctb).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_majority_favorite_rk_ctb
False
property not_exists_majority_favorite_ut

Boolean (True iff there is no majority_favorite_ut).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_majority_favorite_ut
False
property not_exists_majority_favorite_ut_ctb

Boolean (True iff there is no majority_favorite_ut_ctb).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_majority_favorite_ut_ctb
False
property not_exists_resistant_condorcet_winner

Boolean (True iff there is no resistant_condorcet_winner).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_resistant_condorcet_winner
False
property not_exists_weak_condorcet_winner

Boolean (True iff there is no weak Condorcet winner, weak_condorcet_winners).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.not_exists_weak_condorcet_winner
False
plot3(indexes=None, normalize=True, use_labels=True)[source]

Plot utilities for 3 candidates (with approval limit).

Parameters:
  • indexes (list) – List of 3 candidates. If None, defaults to [0, 1, 2].

  • normalize (bool) – Cf. below.

  • use_labels (bool) – If True, then labels_candidates is used to label the plot. Otherwise, candidates are simply represented by their index.

Notes

Each red point of the plot represents a voter v. Its position is preferences_ut[v, indexes]. If normalize is True, then each position is normalized before plotting so that its Euclidean norm is equal to 1.

The equator (in blue) is the set of points \(\mathbf{u}\) such that \(\sum {u_i}^2 = 1\) and \(\sum u_i = 0\), i.e. the unit circle of the plan that is orthogonal to the main diagonal [1, 1, 1].

Other blue circles are the frontiers between the 6 different strict total orders on the candidates.

Examples

Typical usage:

>>> initialize_random_seeds()
>>> preferences_ut_test = np.random.randint(-5, 5, (10, 5))
>>> profile = Profile(preferences_ut=preferences_ut_test,
...                   labels_candidates=['Alice', 'Bob', 'Catherine', 'Dave', 'Ellen'])
>>> profile.plot3(indexes=[0, 1, 2])

If indexes is not given, it defaults to [0, 1, 2]:

>>> profile.plot3()

You can ignore the labels of the candidates and simply use their numbers:

>>> profile.plot3(use_labels=False)

References

Durand et al., ‘Geometry on the Utility Space’.

plot4(indexes=None, normalize=True, use_labels=True)[source]

Plot utilities for 4 candidates (without approval limit).

Parameters:
  • indexes (list) – List of 4 candidates. If None, defaults to [0, 1, 2, 3].

  • normalize (bool) – Cf. below.

  • use_labels (bool) – If True, then labels_candidates is used to label the plot. Otherwise, candidates are simply represented by their index.

Notes

Each red point of the plot represents a voter v.

  • preferences_ut[v, indexes] is sent to the hyperplane that is orthogonal to [1, 1, 1, 1] (by orthogonal projection), which discards information related to approval limit and keeps only the relative preferences between candidates.

  • The plot is done in this 3d hyperplane. In practice, we use a mirror symmetry that exchanges [1, 1, 1, 1] and [0, 0, 0, 1]. This way, the image vector is orthogonal to [0, 0, 0, 1] and can be plotted in the first 3 dimensions.

  • If normalize is True, then the image vector is normalized before plotting so that its Euclidean norm is equal to 1.

Blue lines are the frontiers between the 24 different strict total orders on the candidates (‘permutohedron’).

Examples

Typical usage:

>>> initialize_random_seeds()
>>> preferences_ut_test = np.random.randint(-5, 5, (10, 5))
>>> profile = Profile(preferences_ut=preferences_ut_test,
...                   labels_candidates=['Alice', 'Bob', 'Catherine', 'Dave', 'Ellen'])
>>> profile.plot4(indexes=[0, 1, 2, 4])

If indexes is not given, it defaults to [0, 1, 2, 3]:

>>> profile.plot4()

You can ignore the labels of the candidates and simply use their numbers:

>>> profile.plot4(use_labels=False)

It is possible to avoid normalization:

>>> profile.plot4(normalize=False)

References

Durand et al., ‘Geometry on the Utility Space’.

property plurality_scores_rk

1d array of int. plurality_scores_rk[c] is the number of voters for whom c is the top-ranked candidate (with voter tie-breaking).

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.plurality_scores_rk
array([2, 0, 0])
property plurality_scores_ut

1d array of int. plurality_scores_ut[c] is the number of voters who strictly prefer c to all other candidates. If a voter has several candidates with maximal utility, then none of them receives any point.

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[2, 1, 0], [0, 1, 1]])
>>> profile.plurality_scores_ut
array([1, 0, 0])
property preferences_borda_rk

2d array of integers. preferences_borda_rk[v, c] gains 1 point for each candidate d such that voter v ranks c before d. So, these Borda scores are between 0 and C - 1.

property preferences_borda_ut

2d array of floats. preferences_borda_ut[v, c] gains 1 point for each d such that v strictly prefers c to d (in the sense of utilities), and 0.5 point for each d such that v is indifferent between c and d. So, these Borda scores are between 0 and C - 1.

property preferences_rk

2d array of integers. preferences_rk[v, k] is the candidate at rank k for voter v. For example, preferences_rk[v, 0] is v’s preferred candidate.

property preferences_ut

2d array of floats. preferences_ut[v, c] is the utility of candidate c as seen by voter v.

property relative_social_welfare_c

1d array of numbers. relative_social_welfare_c[c] is equal to total_utility_c[c], but renormalized so that the minimum is 0 and the maximum is 1.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[5, 1, 2], [4, 10, 1]])
>>> profile.relative_social_welfare_c
array([0.75, 1.  , 0.  ])

By convention, if all candidates have the same social welfare, then their relative social welfare is 1:

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[2, 1, 1], [1, 2, 2]])
>>> profile.relative_social_welfare_c
array([1, 1, 1])
property resistant_condorcet_winner

Integer or NaN. Resistant Condorcet Winner. If there is no such candidate, then NaN.

A Condorcet winner w (in the sense of condorcet_winner_ut_abs) is resistant iff in any Condorcet voting system (in the same sense), the profile is not manipulable (cf. Durand et al.). This is equivalent to say that for any pair (c, d) of other distinct candidates, there is a strict majority of voters who simultaneously:

  1. Do not prefer c to w,

  2. And prefer w to d.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.resistant_condorcet_winner
0

No resistant Condorcet winner:

>>> profile = Profile(preferences_rk=[[0, 1, 2], [1, 2, 0], [2, 0, 1]])
>>> profile.resistant_condorcet_winner
nan

See also

exists_resistant_condorcet_winner, not_exists_resistant_condorcet_winner

property smith_set_rk

List. Smith set computed from matrix_victories_rk.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2, 3], [1, 2, 0, 3], [2, 0, 1, 3]])
>>> profile.smith_set_rk
[0, 1, 2]
property smith_set_rk_ctb

List. Smith set computed from matrix_victories_rk_ctb.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2, 3], [1, 2, 0, 3], [2, 0, 1, 3]])
>>> profile.smith_set_rk_ctb
[0, 1, 2]
property smith_set_ut_abs

List. Smith set computed from matrix_victories_ut_abs.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2, 3], [1, 2, 0, 3], [2, 0, 1, 3]])
>>> profile.smith_set_ut_abs
[0, 1, 2]
property smith_set_ut_abs_ctb

List. Smith set computed from matrix_victories_ut_abs_ctb.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2, 3], [1, 2, 0, 3], [2, 0, 1, 3]])
>>> profile.smith_set_ut_abs_ctb
[0, 1, 2]
property smith_set_ut_rel

List. Smith set computed from matrix_victories_ut_rel.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2, 3], [1, 2, 0, 3], [2, 0, 1, 3]])
>>> profile.smith_set_ut_rel
[0, 1, 2]
property smith_set_ut_rel_ctb

List. Smith set computed from matrix_victories_ut_rel_ctb.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2, 3], [1, 2, 0, 3], [2, 0, 1, 3]])
>>> profile.smith_set_ut_rel_ctb
[0, 1, 2]
property threshold_c_prevents_w_condorcet_ut_abs

2d array of integers. Threshold for c-manipulators to prevent w from being a Condorcet winner (in the sense of condorcet_winner_ut_abs).

Intuitively, the question is the following: in an election where w is the winner, how many c-manipulators are needed to prevent w from being a Condorcet winner?

We start with the sub-population of \(n_s\) ‘sincere’ voters, i.e. not preferring c to w. The precise question is: how many c-manipulators \(n_m\) must we add in order to create a non-victory for w against some candidate d \(\neq\) w (possibly c herself)?

In the following, \(| c > d |\) denotes the number of voters who strictly prefer candidate c to d. We need:

\[| \text{sincere voters for whom } w > d | \leq \frac{n_s + n_m}{2}.\]

I.e.:

\[| \text{non } c > w \text{ and } w > d | \leq \frac{| \text{non } c > w | + n_m}{2}.\]

I.e.:

\[n_m \geq 2 \cdot | \text{non } c > w \text{ and } w > d | - | \text{non } c > w |.\]

One candidate d is enough, so:

threshold_c_prevents_w_Condorcet_ut_abs[c, w] \(= 2 \cdot \min_{d \neq w} |w \geq c \text{ and } w > d| - |w \geq c|\).

If this result is negative, it means that even without c-manipulators, w is not a Condorcet winner. In that case, threshold is set to 0 instead.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.threshold_c_prevents_w_condorcet_ut_abs
array([[0, 0, 0],
       [2, 0, 0],
       [2, 0, 0]])
to_doctest_string(ut=True, rk=True)[source]

Convert to string, in the doctest format.

Parameters:
  • ut (bool) – Whether to print preferences_ut.

  • rk (bool) – Whether to print preferences_rk.

Returns:

A string that can be copied-pasted to make a doctest.

Return type:

str

Examples

>>> profile = Profile(preferences_rk=[[0, 1], [0, 1]])
>>> print('.' + profile.to_doctest_string())  
    . >>> profile = Profile(preferences_ut=[
    ...     [1, 0],
    ...     [1, 0],
    ... ], preferences_rk=[
    ...     [0, 1],
    ...     [0, 1],
    ... ])
property total_utility_c

1d array of numbers. total_utility_c[c] is the total utility for candidate c (i.e. the sum of c’s column in matrix preferences_ut).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[5, 1, 2], [4, 10, 1]])
>>> profile.total_utility_c
array([ 9, 11,  3])
property total_utility_max

Float. total_utility_max is the maximum of total_utility_c.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[5, 1, 2], [4, 10, 1]])
>>> profile.total_utility_max
11
property total_utility_mean

Float. total_utility_mean is the mean of total_utility_c.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[5, 1, 2], [4, 10, 1]])
>>> profile.total_utility_mean == (9 + 11 + 3) / 3
True
property total_utility_min

Float. total_utility_min is the minimum of total_utility_c.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[5, 1, 2], [4, 10, 1]])
>>> profile.total_utility_min
3
property total_utility_std

Float. total_utility_std is the standard deviation of total_utility_c.

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_ut=[[5, 1, 2], [4, 10, 1]])
>>> profile.total_utility_std == np.std([9, 11, 3])
True
property v_has_same_ordinal_preferences_as_previous_voter

1d array of booleans. v_has_same_ordinal_preferences_as_previous_voter[v] is True iff voter v has the same preference strict order (row in preferences_rk) and the same preference weak order (row in preferences_borda_ut) as voter v-1. By convention, it is False for voter 0.

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.v_has_same_ordinal_preferences_as_previous_voter
array([False,  True])
property weak_condorcet_winners

1d array of booleans. weak_condorcet_winners[c] is True iff candidate c is a weak Condorcet winner, i.e. iff no candidate d has a relative victory against c (in the sense of matrix_victories_ut_rel).

Examples

>>> from svvamp import Profile
>>> profile = Profile(preferences_rk=[[0, 1, 2], [0, 1, 2]])
>>> profile.weak_condorcet_winners
array([ True, False, False])

See also

nb_weak_condorcet_winners, exists_weak_condorcet_winner, not_exists_weak_condorcet_winner