def grofman(votes, seats, parties="votes"): r"""Calculate the Grofman index of disproportionality. .. math:: N \sum_{i=1}^n |v_i - s_i| where N is :math:`\sum_{i=1}^n v_i^2` if ``parties == 'votes'`` or :math:`\sum_{i=1}^n s_i^2` if ``parties == 'seats'``. :param list votes: a list of vote counts :param list seats: a list of seat counts :param str parties: ``votes`` or ``seats`` to use to calculate the effective number of parties """ votes = normalize(votes) seats = normalize(seats) if parties == "votes": n = sum([v**2 for v in votes]) elif parties == "seats": n = sum([s**2 for s in seats]) else: raise ValueError("Parties argument must be either votes or seats.") return n * sum([abs(v - s) for v, s in zip(votes, seats)])
def rae(votes, seats): r"""Calculate Rae's index of disproportionality. .. math:: \frac{1}{n} \sum_{i=1}^n |v_i - s_i| :param list votes: a list of vote counts :param list seats: a list of seat counts """ votes = normalize(votes) seats = normalize(seats) return 1.0 / len(votes) * sum([abs(v - s) for v, s in zip(votes, seats)])
def loosemore_hanby(votes, seats): r"""Calculate Loosemore-Hanby index of disproportionality. .. math:: \frac{1}{2} \sum_{i=1}^n |v_i - s_i| :param list votes: a list of vote counts :param list seats: a list of seat counts """ votes = normalize(votes) seats = normalize(seats) return 1.0 / 2 * sum([abs(v - s) for v, s in zip(votes, seats)])
def sainte_lague(votes, seats): r"""Calculate the Sainte-Lague index of disproportionality. .. math:: \sum_{i=1}^n \frac{(v_i - s_i)^2}{v_i} :param list votes: a list of vote counts :param list seats: a list of seat counts """ votes = normalize(votes) seats = normalize(seats) return sum(1.0 / v * (v - s)**2 for v, s in zip(votes, seats))
def dhondt(votes, seats): r"""Calculate the D'Hondt index of disproportionality. .. math:: \max \frac{s_i}{v_i} :param list votes: a list of vote counts :param list seats: a list of seat counts """ votes = normalize(votes) seats = normalize(seats) return max([1.0 * s / v for v, s in zip(votes, seats)])
def gallagher(votes, seats): r"""Calculate the Gallagher index of disproportionality. .. math:: \sqrt{\frac{1}{2} \sum_{i=1}^n (v_i - s_i)^2} :param list votes: a list of vote counts :param list seats: a list of seat counts """ votes = normalize(votes) seats = normalize(seats) return sqrt(1.0 / 2) * least_square(votes, seats)
def least_square(votes, seats): r"""Calculate the least squares index of disproportionality. .. math:: \sqrt{\sum_{i=1}^n (v_i - s_i)^2} :param list votes: a list of vote counts :param list seats: a list of seat counts """ votes = normalize(votes) seats = normalize(seats) return sqrt(sum([(v - s)**2 for v, s in zip(votes, seats)]))
def rose(votes, seats): r"""Calculate the Rose index of proportionality. .. math:: 100 - \frac{1}{2} \sum_{i=1}^n |v_i - s_i| :param list votes: a list of vote counts :param list seats: a list of seat counts """ votes = normalize(votes) seats = normalize(seats) return 100 - loosemore_hanby(votes, seats)
def lijphart(votes, seats): r"""Calculate the Lijphart index of disproportionality. .. math:: \max | v_i - s_i | :param list votes: a list of vote counts :param list seats: a list of seat counts """ votes = normalize(votes) seats = normalize(seats) return max([abs(v - s) for v, s in zip(votes, seats)])
def regression(votes, seats): r"""Calculate the regression index of disproportionality. .. math:: \frac{\sum_{i=1}^n v_i s_i}{\sum_{i=1}^n v_i^2} :param list votes: a list of vote counts :param list seats: a list of seat counts """ votes = normalize(votes) seats = normalize(seats) num = sum([v * s for v, s in zip(votes, seats)]) denom = sum([v**2 for v in votes]) return 1.0 * num / denom
def adjusted_loosemore_hanby(votes, seats, parties="votes"): r"""Calculate the adjusted Loosemore-Hanby index of disproportionality. .. math:: N \sum_{i=1}^n |v_i - s_i| where N is :math:`\sum_{i=1}^n v_i` if ``parties == 'votes'`` or :math:`\sum_{i=1}^n s_i` if ``parties == 'seats'``. :param list votes: a list of vote counts :param list seats: a list of seat counts :param str parties: ``votes`` or ``seats`` to use to calculate the effective number of parties """ votes = normalize(votes) seats = normalize(seats) return grofman(votes, seats, parties)
def shannon(groups): r"""Calculate the Shannon index. .. math:: \sum_{i=1}^n p_i \ln (p_i) :param list groups: a list of integers representing populations of groups """ groups = normalize(groups) return sum([g * log(g) for g in groups])
def berger_parker(groups): r"""Calculate the Berger-Parker index. .. math:: max(p_i) :param list group: a list of integers representing populations of groups """ groups = normalize(groups) return max(groups)
def laakso_taagepera(groups): r"""Calculate the effective number of parties using Laakso-Taagepera. .. math:: \frac{1}{\sum_{i=1}^n p_i^2} :param list group: a list of integers representing populations of groups """ groups = normalize(groups) return 1.0 / sum([g**2 for g in groups])
def simpson(groups): r"""Calculate the Simpson index. .. math:: \sum_{i=1}^n p_i^2 :param list groups: a list of integers representing populations of groups """ groups = normalize(groups) return sum([g**2 for g in groups])
def general(groups, q=1): r"""Calculate the general diversity index. .. math:: \left( \sum_{i=1}^n p_i^q \right) ^ {1/(1-q)} :param list groups: a list of integers representing populations of groups :param float q: weight value """ if q == 1: return exp(shannon(groups)) groups = normalize(groups) return sum([g**q for g in groups])**(1.0 / (1 - q))
def golosov(groups): r"""Calculate the effective number of parties using Golosov. .. math:: \sum_{i=1}^n \frac{p_i}{p_i + p_1^2 - p_i^2} where :math:`p_1` is the largest proportion. :param list group: a list of integers representing populations of a group """ groups = normalize(groups) p1 = max(groups) return sum([g / (g + p1**2 - g**2) for g in groups])
def renyi(groups, q=0): r"""Calculate the Renyi entropy. .. math:: \frac{1}{1-q} \ln \left( \sum_{i=1}^n p_i ^ q \right) :param list groups: a list of integers representing populations of groups :param float q: weight value """ if q == 1: return shannon(groups) groups = normalize(groups) return 1.0 / (1 - q) * log(sum([g**q for g in groups]))