cleaning up functions
This commit is contained in:
parent
2e85eed486
commit
c6eb046373
File diff suppressed because one or more lines are too long
47
README.md
47
README.md
|
|
@ -1 +1,46 @@
|
|||
# Aragon_Conviction_Voting
|
||||
# Aragon_Conviction_Voting
|
||||
|
||||
[Conviction Voting](https://medium.com/giveth/conviction-voting-a-novel-continuous-decision-making-alternative-to-governance-aa746cfb9475) is a novel decision making process where votes express their preference for which proposals they would like to see approved in a continuous rather than discrete way. The longer the community keeps a preference on an individual proposal, the “stronger” the proposal conviction becomes. In the conviction voting model, a graph structure is used to record the the introduction and removal of participants, candidates, proposals, and their outcomes.
|
||||
|
||||
## What is cadCAD?
|
||||
cadCAD (complex adaptive dynamics Computer-Aided Design) is a python based modeling framework for research, validation, and Computer Aided Design of complex systems. Given a model of a complex system, cadCAD can simulate the impact that a set of actions might have on it. This helps users make informed, rigorously tested decisions on how best to modify or interact with the system in order to achieve their goals. cadCAD supports different system modeling approaches and can be easily integrated with common empirical data science workflows. Monte Carlo methods, A/B testing and parameter sweeping features are natively supported and optimized for.
|
||||
|
||||
|
||||
## Reproducibility
|
||||
In order to reperform this code, we recommend the researcher use the following link to download https://www.anaconda.com/products/individual to download Python 3.7.To install the specific version of cadCAD this repository was built with, run the following code:
|
||||
pip install cadCAD==0.4.17
|
||||
|
||||
Then run cd Aragon_Conviction_Voting to enter the repository. Finally, run jupyter notebook to open a notebook server to run the various notebooks in this repository.
|
||||
|
||||
## Simulations
|
||||
|
||||
|
||||
## Background information & concepts addressed
|
||||
|
||||
|
||||
### Systems Thinking
|
||||
* https://community.cadcad.org/t/introduction-to-systems-thinking/18
|
||||
* https://community.cadcad.org/t/working-glossary-of-systems-concepts/17
|
||||
|
||||
|
||||
### cadCAD
|
||||
|
||||
* https://community.cadcad.org/t/introduction-to-cadcad/15
|
||||
* https://community.cadcad.org/t/putting-cadcad-in-context/19
|
||||
* https://github.com/BlockScience/cadCAD/tree/master/tutorials
|
||||
|
||||
|
||||
### Token Engineering
|
||||
|
||||
* https://blog.oceanprotocol.com/towards-a-practice-of-token-engineering-b02feeeff7ca
|
||||
* https://assets.pubpub.org/sy02t720/31581340240758.pdf
|
||||
|
||||
### Complex systems
|
||||
|
||||
* https://www.frontiersin.org/articles/10.3389/fams.2015.00007/full
|
||||
* https://epub.wu.ac.at/7433/1/zargham_paruch_shorish.pdf
|
||||
|
||||
|
||||
### Systems Engineering
|
||||
|
||||
* http://systems.hitchins.net/systems-engineering/se-monographs/seessence.pdf
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -10,15 +10,10 @@ from cadCAD.configuration.utils import bound_norm_random, ep_time_step, config_s
|
|||
from .genesis_states import genesis_states
|
||||
from .partial_state_update_block import partial_state_update_blocks
|
||||
|
||||
params: Dict[str, List[int]] = {
|
||||
'month': [0,12,36,50,100]
|
||||
}
|
||||
|
||||
|
||||
sim_config = config_sim({
|
||||
'N': 1,
|
||||
'T': range(100), #day
|
||||
# 'M': #params,
|
||||
})
|
||||
|
||||
seeds = {
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -11,15 +11,7 @@ default_rho = 0.02
|
|||
|
||||
def trigger_threshold(requested, funds, supply, beta = default_beta, rho = default_rho):
|
||||
'''
|
||||
Definition:
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
Function that determines threshold for proposals being accepted.
|
||||
'''
|
||||
share = requested/funds
|
||||
if share < beta:
|
||||
|
|
@ -29,16 +21,7 @@ def trigger_threshold(requested, funds, supply, beta = default_beta, rho = defau
|
|||
|
||||
def initial_social_network(network, scale = 1, sigmas=3):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
Function to initialize network x social network edges
|
||||
'''
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
|
||||
|
|
@ -55,15 +38,7 @@ def initial_social_network(network, scale = 1, sigmas=3):
|
|||
def initial_conflict_network(network, rate = .25):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
Function to initialize network x conflict edges
|
||||
'''
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
|
||||
|
|
@ -189,32 +164,14 @@ def get_nodes_by_type(g, node_type_selection):
|
|||
|
||||
def get_edges_by_type(g, edge_type_selection):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
Functions to extract edges based on type
|
||||
'''
|
||||
return [edge for edge in g.edges if g.edges[edge]['type']== edge_type_selection ]
|
||||
|
||||
|
||||
def conviction_order(network, proposals):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
Function to sort conviction order
|
||||
'''
|
||||
ordered = sorted(proposals, key=lambda j:network.nodes[j]['conviction'] , reverse=True)
|
||||
|
||||
|
|
@ -224,16 +181,6 @@ def conviction_order(network, proposals):
|
|||
|
||||
def social_links(network, participant, scale = 1):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
'''
|
||||
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
|
|
@ -251,16 +198,6 @@ def social_links(network, participant, scale = 1):
|
|||
|
||||
def conflict_links(network,proposal ,rate = .25):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
'''
|
||||
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
|
|
@ -277,16 +214,6 @@ def conflict_links(network,proposal ,rate = .25):
|
|||
|
||||
def social_affinity_booster(network, proposal, participant):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
'''
|
||||
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
|
|
@ -313,117 +240,8 @@ def social_affinity_booster(network, proposal, participant):
|
|||
return np.sum(boosts)
|
||||
|
||||
|
||||
def trigger_sweep(field, trigger_func,xmax=.2,default_alpha=.5):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
'''
|
||||
|
||||
if field == 'token_supply':
|
||||
alpha = default_alpha
|
||||
share_of_funds = np.arange(.001,xmax,.001)
|
||||
total_supply = np.arange(0,10**9, 10**6)
|
||||
demo_data_XY = np.outer(share_of_funds,total_supply)
|
||||
|
||||
demo_data_Z0=np.empty(demo_data_XY.shape)
|
||||
demo_data_Z1=np.empty(demo_data_XY.shape)
|
||||
demo_data_Z2=np.empty(demo_data_XY.shape)
|
||||
demo_data_Z3=np.empty(demo_data_XY.shape)
|
||||
for sof_ind in range(len(share_of_funds)):
|
||||
sof = share_of_funds[sof_ind]
|
||||
for ts_ind in range(len(total_supply)):
|
||||
ts = total_supply[ts_ind]
|
||||
tc = ts /(1-alpha)
|
||||
trigger = trigger_func(sof, 1, ts)
|
||||
demo_data_Z0[sof_ind,ts_ind] = np.log10(trigger)
|
||||
demo_data_Z1[sof_ind,ts_ind] = trigger
|
||||
demo_data_Z2[sof_ind,ts_ind] = trigger/tc #share of maximum possible conviction
|
||||
demo_data_Z3[sof_ind,ts_ind] = np.log10(trigger/tc)
|
||||
return {'log10_trigger':demo_data_Z0,
|
||||
'trigger':demo_data_Z1,
|
||||
'share_of_max_conv': demo_data_Z2,
|
||||
'log10_share_of_max_conv':demo_data_Z3,
|
||||
'total_supply':total_supply,
|
||||
'share_of_funds':share_of_funds}
|
||||
elif field == 'alpha':
|
||||
alpha = np.arange(.5,1,.01)
|
||||
share_of_funds = np.arange(.001,xmax,.001)
|
||||
total_supply = 10**9
|
||||
demo_data_XY = np.outer(share_of_funds,alpha)
|
||||
|
||||
demo_data_Z4=np.empty(demo_data_XY.shape)
|
||||
demo_data_Z5=np.empty(demo_data_XY.shape)
|
||||
demo_data_Z6=np.empty(demo_data_XY.shape)
|
||||
demo_data_Z7=np.empty(demo_data_XY.shape)
|
||||
for sof_ind in range(len(share_of_funds)):
|
||||
sof = share_of_funds[sof_ind]
|
||||
for a_ind in range(len(alpha)):
|
||||
ts = total_supply
|
||||
a = alpha[a_ind]
|
||||
tc = ts /(1-a)
|
||||
trigger = trigger_func(sof, 1, ts)
|
||||
demo_data_Z4[sof_ind,a_ind] = np.log10(trigger)
|
||||
demo_data_Z5[sof_ind,a_ind] = trigger
|
||||
demo_data_Z6[sof_ind,a_ind] = trigger/tc #share of maximum possible conviction
|
||||
demo_data_Z7[sof_ind,a_ind] = np.log10(trigger/tc)
|
||||
|
||||
return {'log10_trigger':demo_data_Z4,
|
||||
'trigger':demo_data_Z5,
|
||||
'share_of_max_conv': demo_data_Z6,
|
||||
'log10_share_of_max_conv':demo_data_Z7,
|
||||
'alpha':alpha,
|
||||
'share_of_funds':share_of_funds}
|
||||
|
||||
else:
|
||||
return "invalid field"
|
||||
|
||||
def trigger_plotter(share_of_funds,Z, color_label,y, ylabel,cmap='jet'):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
'''
|
||||
dims = (10, 5)
|
||||
fig, ax = plt.subplots(figsize=dims)
|
||||
|
||||
cf = plt.contourf(share_of_funds, y, Z.T, 100, cmap=cmap)
|
||||
cbar=plt.colorbar(cf)
|
||||
plt.axis([share_of_funds[0], share_of_funds[-1], y[0], y[-1]])
|
||||
#ax.set_xscale('log')
|
||||
plt.ylabel(ylabel)
|
||||
plt.xlabel('Share of Funds Requested')
|
||||
plt.title('Trigger Function Map')
|
||||
|
||||
cbar.ax.set_ylabel(color_label)
|
||||
|
||||
|
||||
def snap_plot(nets, size_scale = 1/500, ani = False, dims = (20,20), savefigs=False):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
'''
|
||||
|
||||
last_net = nets[-1]
|
||||
|
|
@ -556,16 +374,6 @@ def snap_plot(nets, size_scale = 1/500, ani = False, dims = (20,20), savefigs=Fa
|
|||
|
||||
def pad(vec, length,fill=True):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
'''
|
||||
|
||||
if fill:
|
||||
|
|
@ -581,16 +389,6 @@ def pad(vec, length,fill=True):
|
|||
|
||||
def make2D(key, data, fill=False):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
'''
|
||||
maxL = data[key].apply(len).max()
|
||||
newkey = 'padded_'+key
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import numpy as np
|
|||
from .conviction_helper_functions import *
|
||||
|
||||
# Parameters
|
||||
#maximum share of funds a proposal can take
|
||||
# maximum share of funds a proposal can take
|
||||
beta = .2 #later we should set this to be param so we can sweep it
|
||||
# tuning param for the trigger function
|
||||
rho = .001
|
||||
|
|
@ -20,16 +20,13 @@ m= 3 #initial proposals
|
|||
initial_sentiment = .6
|
||||
|
||||
theta =.35
|
||||
kappa = 6 #bonding curve curvature
|
||||
alpha = 0.5
|
||||
sale_price = .1
|
||||
sensitivity = .75
|
||||
tmin = 7 #unit days; minimum periods passed before a proposal can pass
|
||||
min_supp = 50 #number of tokens that must be stake for a proposal to be a candidate
|
||||
sentiment_decay = .01 #termed mu in the state update function
|
||||
base_completion_rate = 100
|
||||
base_failure_rate = 200
|
||||
# trigger_func = trigger_threshold
|
||||
tax_rate = .02
|
||||
|
||||
initial_funds = 40781.42
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import numpy as np
|
|||
from .initialization import *
|
||||
from .conviction_helper_functions import *
|
||||
import networkx as nx
|
||||
# from scipy.stats import expon, gamma
|
||||
|
||||
|
||||
# Phase 2
|
||||
|
|
@ -36,7 +35,7 @@ def check_progress(params, step, sL, s):
|
|||
# Mechanisms
|
||||
def complete_proposal(params, step, sL, s, _input):
|
||||
'''
|
||||
Book-keeping
|
||||
Book-keeping of failed and completed proposals. Update network object
|
||||
'''
|
||||
|
||||
network = s['network']
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ tmin = 7
|
|||
# Behaviors
|
||||
def trigger_function(params, step, sL, s):
|
||||
'''
|
||||
This policy checks to see if each proposal passes or not.
|
||||
'''
|
||||
network = s['network']
|
||||
funds = s['funds']
|
||||
|
|
@ -53,6 +54,7 @@ def trigger_function(params, step, sL, s):
|
|||
# Mechanisms
|
||||
def decrement_funds(params, step, sL, s, _input):
|
||||
'''
|
||||
If a proposal passes, funds are decremented by the amount of the proposal
|
||||
'''
|
||||
|
||||
funds = s['funds']
|
||||
|
|
@ -70,6 +72,7 @@ def decrement_funds(params, step, sL, s, _input):
|
|||
|
||||
def update_proposals(params, step, sL, s, _input):
|
||||
'''
|
||||
If proposal passes, its status is changed in the network object.
|
||||
'''
|
||||
|
||||
network = s['network']
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@ sentiment = 0.6
|
|||
|
||||
|
||||
# Behaviors
|
||||
def driving_process(params, step, sL, s):
|
||||
def driving_process(params, step, sL, s):
|
||||
'''
|
||||
Driving process for adding new participants (their funds) and new proposals.
|
||||
'''
|
||||
arrival_rate = 10/(1+sentiment)
|
||||
rv1 = np.random.rand()
|
||||
new_participant = bool(rv1<1/arrival_rate)
|
||||
|
|
@ -61,6 +64,9 @@ def driving_process(params, step, sL, s):
|
|||
|
||||
# Mechanisms
|
||||
def update_network(params, step, sL, s, _input):
|
||||
'''
|
||||
Add new participants and proposals to network object
|
||||
'''
|
||||
|
||||
network = s['network']
|
||||
funds = s['funds']
|
||||
|
|
@ -93,7 +99,9 @@ def update_network(params, step, sL, s, _input):
|
|||
return (key, value)
|
||||
|
||||
def increment_funds(params, step, sL, s, _input):
|
||||
|
||||
'''
|
||||
Increase funds by the amount of the new particpant's funds.
|
||||
'''
|
||||
funds = s['funds']
|
||||
funds_arrival = _input['funds_arrival']
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ def run(input_config=configs):
|
|||
|
||||
def postprocessing(df):
|
||||
'''
|
||||
Function for postprocessing the simulation results to extract key information from the network object.
|
||||
'''
|
||||
# Extract information from dataframe
|
||||
df['conviction'] = df.network.apply(lambda g: np.array([g.nodes[j]['conviction'] for j in get_nodes_by_type(g, 'proposal') if g.nodes[j]['status']=='candidate']))
|
||||
|
|
@ -55,6 +56,7 @@ def postprocessing(df):
|
|||
|
||||
df['conviction_share_of_trigger_all'] = df.conviction_all/df.triggers_all
|
||||
|
||||
# subset to last substep of each simulation
|
||||
rdf= df[df.substep==df.substep.max()].copy()
|
||||
|
||||
return df,rdf
|
||||
Loading…
Reference in New Issue