MatrixWeightedMajority

class whalrus.MatrixWeightedMajority(*args, converter: whalrus.converters_ballot.converter_ballot.ConverterBallot = None, higher_vs_lower: Optional[numbers.Number] = 1, lower_vs_higher: Optional[numbers.Number] = 0, indifference: Optional[numbers.Number] = Fraction(1, 2), ordered_vs_unordered: Optional[numbers.Number] = 1, unordered_vs_ordered: Optional[numbers.Number] = 0, unordered_vs_unordered: Optional[numbers.Number] = Fraction(1, 2), ordered_vs_absent: Optional[numbers.Number] = None, absent_vs_ordered: Optional[numbers.Number] = None, unordered_vs_absent: Optional[numbers.Number] = None, absent_vs_unordered: Optional[numbers.Number] = None, absent_vs_absent: Optional[numbers.Number] = None, diagonal_score: numbers.Number = 0, default_score: numbers.Number = 0, antisymmetric: bool = False, **kwargs)[source]

The weighted majority matrix.

Parameters
  • args – Cf. parent class.

  • converter (ConverterBallot) – Default: ConverterBallotToOrder.

  • higher_vs_lower (Number or None) – Number of points for candidate c when it is ordered higher than candidate d.

  • lower_vs_higher (Number or None) – Number of points for candidate c when it is ordered lower than candidate d.

  • indifference (Number or None) – Number of points for candidate c when it is ordered and tied with candidate d.

  • ordered_vs_unordered (Number or None) – Number of points for candidate c when it is ordered and d is unordered.

  • unordered_vs_ordered (Number or None) – Number of points for candidate c when it is unordered and d is ordered.

  • unordered_vs_unordered (Number or None) – Number of points for candidate c when it is unordered and d is unordered.

  • ordered_vs_absent (Number or None) – Number of points for candidate c when it is ordered and d is absent.

  • absent_vs_ordered (Number or None) – Number of points for candidate c when it is absent and d is ordered.

  • unordered_vs_absent (Number or None) – Number of points for candidate c when it is unordered and d is absent.

  • absent_vs_unordered (Number or None) – Number of points for candidate c when it is absent and d is unordered.

  • absent_vs_absent (Number or None) – Number of points for candidate c when it is absent and d is absent.

  • diagonal_score (Number) – Value of the diagonal coefficients.

  • default_score (Number) – Default score in the matrix in case of division by 0 (except for the diagonal coefficients).

  • antisymmetric (bool) – If True, then an antisymmetric version of the matrix is computed (by subtracting the transposed matrix at the end of the computation).

  • kwargs – Cf. parent class.

Examples

In the most general syntax, firstly, you define the matrix computation algorithm:

>>> matrix = MatrixWeightedMajority(diagonal_score=.5)

Secondly, you use it as a callable to load a particular election (profile, candidates):

>>> matrix(ballots=['a > b', 'b > a'], weights=[3, 1], voters=['v', 'w'], candidates={'a', 'b'})  
<... object at ...>

Finally, you can access the computed variables:

>>> matrix.as_array_
array([[Fraction(1, 2), Fraction(3, 4)],
       [Fraction(1, 4), Fraction(1, 2)]], dtype=object)

Later, if you wish, you can load another profile with the same matrix computation algorithm, and so on.

Optionally, you can specify an election (profile and candidates) as soon as the Matrix object is initialized. This allows for “one-liners” such as:

>>> MatrixWeightedMajority(ballots=['a > b', 'b > a'], weights=[3, 1], voters=['x', 'y'],
...                        candidates={'a', 'b'}, diagonal_score=.5).as_array_
array([[Fraction(1, 2), Fraction(3, 4)],
       [Fraction(1, 4), Fraction(1, 2)]], dtype=object)

Antisymmetric version:

>>> MatrixWeightedMajority(ballots=['a > b', 'b > a'], weights=[3, 1], voters=['x', 'y'],
...                        candidates={'a', 'b'}, antisymmetric=True).as_array_
array([[0, Fraction(1, 2)],
       [Fraction(-1, 2), 0]], dtype=object)

An “unordered” candidate is a candidate that the voter has seen but not included in her ranking; i.e. it is in the attribute BallotOrder.candidates_not_in_b of the ballot. An “absent” candidate is a candidate that the voter has not even seen; i.e. it is in self.candidates_, but not the attribute Ballot.candidates of the ballot. For all the “scoring” parameters (from higher_vs_lower to absent_vs_absent), the value None can be used. In that case, the corresponding occurrences are not taken into account in the average (neither the numerator, not the denominator). Consider this example:

>>> ballots = ['a > b', 'a ~ b']

With indifference=Fraction(1, 2) (default), the ratio of voters who prefer a to b is (1 + 1 / 2) / 2 = 3 / 4 (the indifferent voter gives 1 / 2 point and is counted in the denominator):

>>> MatrixWeightedMajority(ballots).as_array_
array([[0, Fraction(3, 4)],
       [Fraction(1, 4), 0]], dtype=object)

With indifference=0, the ratio of voters who prefer a to b is 1 / 2 (the indifferent voter gives no point, but is counted in the denominator):

>>> MatrixWeightedMajority(ballots, indifference=0).as_array_
array([[0, Fraction(1, 2)],
       [0, 0]], dtype=object)

With indifference=None, the ratio of voters who prefer a to b is 1 / 1 = 1 (the indifferent voter is not counted in the average at all):

>>> MatrixWeightedMajority(ballots, indifference=None).as_array_
array([[0, 1],
       [0, 0]])
property as_array_

The matrix, as a numpy array. Each row and each column corresponds to a candidate (in the order of candidates_as_list_).

Type

Array

property as_array_of_floats_

The matrix, as a numpy array. It is the same as as_array_, but converted to floats.

Type

Array

property candidates_as_list_

The list of candidates. Candidates are sorted if possible.

Type

list

property candidates_indexes_

The candidates as a dictionary. To each candidate, it associates its index in candidates_as_list_.

Type

NiceDict

property gross_

The “gross” matrix. Keys are pairs of candidates. Each coefficient is the weighted number of points (used as numerator in the average).

Examples

>>> from whalrus import MatrixWeightedMajority
>>> MatrixWeightedMajority(ballots=['a > b', 'a ~ b'], weights=[2, 1]).gross_
{('a', 'a'): 0, ('a', 'b'): Fraction(5, 2), ('b', 'a'): Fraction(1, 2), ('b', 'b'): 0}
Type

NiceDict

property weights_

The matrix of weights. Keys are pairs of candidates. Each coefficient is the total weight (used as denominator in the average).

Examples

In most usual cases, all non-diagonal coefficients are equal, and are equal to the total weight of all voters:

>>> from whalrus import MatrixWeightedMajority
>>> MatrixWeightedMajority(ballots=['a > b', 'a ~ b'], weights=[2, 1]).weights_
{('a', 'a'): 0, ('a', 'b'): 3, ('b', 'a'): 3, ('b', 'b'): 0}

However, if some scoring parameters are None, some weights can be lower than the total weight of all voters:

>>> from whalrus import MatrixWeightedMajority
>>> MatrixWeightedMajority(ballots=['a > b', 'a ~ b'], weights=[2, 1],
...                        indifference=None).weights_
{('a', 'a'): 0, ('a', 'b'): 2, ('b', 'a'): 2, ('b', 'b'): 0}
Type

NiceDict