This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
# decorator that validates inputs for the funding mechanisms | |
def funding_mechanism(func): | |
def wrapper(self, contribution_matrix: np.ndarray, *args, **kwargs): | |
# make sure the incoming contribution array is valid | |
if not isinstance(contribution_matrix, np.ndarray): | |
raise TypeError("contribution_matrix must be a numpy array") | |
if len(contribution_matrix.shape) != 2: | |
raise ValueError("contribution_matrix must be a 2D array") | |
return func(self, contribution_matrix, *args, **kwargs) | |
wrapper.__name__ = func.__name__ | |
return wrapper | |
class RoundManager: | |
# TODO: docstring | |
def __init__(self, matching_funds: float): | |
self.matching_funds = matching_funds | |
# useful for comparing all funding mechanisms | |
self.funding_mechanisms = [self.quadratic_funding, self.one_dollar_one_vote, self.one_person_one_vote] | |
def _calculate_matching(self, votes_per_public_good: np.array): | |
assert len(votes_per_public_good.shape) == 1 | |
return np.array(votes_per_public_good) / np.sum(votes_per_public_good) * self.matching_funds | |
@funding_mechanism | |
def quadratic_funding(self, contribution_matrix: np.ndarray): | |
# if not np.all(contribution_matrix[contribution_matrix > 0] >= 1): | |
# raise ValueError("Quadratic funding requires each non-zero donation is >= 1 (because sqrt(x) when x is between 0 and 1 is larger than x).") | |
# quadratic funding requires each donation is >= 1 | |
contribution_matrix[contribution_matrix < 1] = 0 | |
votes = np.power(np.sum(np.sqrt(contribution_matrix), axis=0), 2) | |
return self._calculate_matching(votes) | |
@funding_mechanism | |
def one_dollar_one_vote(self, contribution_matrix: np.ndarray): | |
votes = np.sum(contribution_matrix, axis=0) | |
return self._calculate_matching(votes) | |
@funding_mechanism | |
def one_person_one_vote(self, contribution_matrix: np.ndarray): | |
contribution_matrix = contribution_matrix > 0 | |
votes = np.sum(contribution_matrix, axis=0) | |
return self._calculate_matching(votes) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how the matrix is loaded from a CSV: https://gist.github.com/nollied/a7996277ffa558a854d799d0e936bbb1