saturday work session
mostly focused on data formatting and some data viz. minor refactors on some of the social systems logic in preparation for this weeks workshop
This commit is contained in:
parent
484db212f5
commit
51955e4246
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 142 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -13,7 +13,7 @@ from .partial_state_update_block import partial_state_update_blocks
|
|||
|
||||
sim_config = config_sim({
|
||||
'N': 1,
|
||||
'T': range(100), #day
|
||||
'T': range(183), #day
|
||||
})
|
||||
|
||||
seeds = {
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -95,7 +95,7 @@ def gen_new_participant(network, new_participant_holdings):
|
|||
|
||||
|
||||
|
||||
def gen_new_proposal(network, funds, supply, scale_factor = 1.0/100):
|
||||
def gen_new_proposal(network, funds, supply, scale_factor = 1.0/1000):
|
||||
'''
|
||||
Definition:
|
||||
Driving processes for the arrival of proposals.
|
||||
|
|
@ -163,14 +163,16 @@ def get_nodes_by_type(g, node_type_selection):
|
|||
'''
|
||||
return [node for node in g.nodes if g.nodes[node]['type']== node_type_selection ]
|
||||
|
||||
def get_sentimental(sentiment, force, decay=0):
|
||||
def get_sentimental(sentiment, force, decay=.1):
|
||||
'''
|
||||
'''
|
||||
mu = decay
|
||||
sentiment = sentiment*(1-mu) + force
|
||||
sentiment = sentiment*(1-mu) + force*mu
|
||||
|
||||
if sentiment > 1:
|
||||
sentiment = 1
|
||||
elif sentiment < 0:
|
||||
sentiment = 0
|
||||
|
||||
return sentiment
|
||||
|
||||
|
|
@ -424,7 +426,7 @@ def quantile_plot(xkey, ykey, dataframe, dq=.1, logy=False, return_df = False):
|
|||
if return_df:
|
||||
return data
|
||||
|
||||
def affinities_plot(df):
|
||||
def affinities_plot(df, dims = (8.5, 11) ):
|
||||
'''
|
||||
'''
|
||||
last_net= df.network.values[-1]
|
||||
|
|
@ -440,7 +442,6 @@ def affinities_plot(df):
|
|||
j = last_props[j_ind]
|
||||
affinities[i_ind][j_ind] = last_net.edges[(i,j)]['affinity']
|
||||
|
||||
dims = (20, 5)
|
||||
fig, ax = plt.subplots(figsize=dims)
|
||||
|
||||
sns.heatmap(affinities.T,
|
||||
|
|
@ -448,6 +449,7 @@ def affinities_plot(df):
|
|||
yticklabels=last_props,
|
||||
square=True,
|
||||
cbar=True,
|
||||
cmap = plt.cm.RdYlGn,
|
||||
ax=ax)
|
||||
|
||||
plt.title('affinities between participants and proposals')
|
||||
|
|
@ -457,12 +459,14 @@ def affinities_plot(df):
|
|||
|
||||
|
||||
|
||||
def trigger_sweep(field, trigger_func,beta,rho,alpha,xmax=.2):
|
||||
def trigger_sweep(field, trigger_func,beta,rho,alpha,supply=10**9):
|
||||
'''
|
||||
'''
|
||||
xmax= beta
|
||||
|
||||
if field == 'effective_supply':
|
||||
share_of_funds = np.arange(.001,xmax,.001)
|
||||
total_supply = np.arange(0,10**9, 10**6)
|
||||
total_supply = np.arange(0,supply*10, supply/100)
|
||||
demo_data_XY = np.outer(share_of_funds,total_supply)
|
||||
|
||||
demo_data_Z0=np.empty(demo_data_XY.shape)
|
||||
|
|
@ -484,11 +488,12 @@ def trigger_sweep(field, trigger_func,beta,rho,alpha,xmax=.2):
|
|||
'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}
|
||||
'share_of_funds':share_of_funds,
|
||||
'alpha':alpha}
|
||||
elif field == 'alpha':
|
||||
alpha = np.arange(0,1,.001)
|
||||
#note if alpha >.01 then this will give weird results max alpha will be >1
|
||||
alpha = np.arange(0,.5,.001)
|
||||
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)
|
||||
|
|
@ -498,7 +503,7 @@ def trigger_sweep(field, trigger_func,beta,rho,alpha,xmax=.2):
|
|||
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
|
||||
ts = supply
|
||||
a = alpha[a_ind]
|
||||
tc = ts /(1-a)
|
||||
trigger = trigger_func(sof, 1, ts, beta, rho, a)
|
||||
|
|
@ -512,7 +517,8 @@ def trigger_sweep(field, trigger_func,beta,rho,alpha,xmax=.2):
|
|||
'share_of_max_conv': demo_data_Z6,
|
||||
'log10_share_of_max_conv':demo_data_Z7,
|
||||
'alpha':alpha,
|
||||
'share_of_funds':share_of_funds}
|
||||
'share_of_funds':share_of_funds,
|
||||
'supply':supply}
|
||||
|
||||
else:
|
||||
return "invalid field"
|
||||
|
|
@ -535,53 +541,125 @@ def trigger_plotter(share_of_funds,Z, color_label,y, ylabel,cmap='jet'):
|
|||
|
||||
def trigger_grid(supply_sweep, alpha_sweep):
|
||||
|
||||
fig, axs = plt.subplots(nrows=2, ncols=2,figsize=(20,20))
|
||||
fig, axs = plt.subplots(nrows=2, ncols=1,figsize=(20,20))
|
||||
axs = axs.flatten()
|
||||
|
||||
share_of_funds = alpha_sweep['share_of_funds']
|
||||
Z = alpha_sweep['log10_share_of_max_conv']
|
||||
y = alpha_sweep['alpha']
|
||||
ylabel = 'alpha'
|
||||
# cut out the plots that didn't require the heatmap
|
||||
# and switch to (2,1) subplots
|
||||
|
||||
axs[0].contourf(share_of_funds, y, Z.T,100, cmap='jet', )
|
||||
#axs[0].colorbar(cf)
|
||||
axs[0].axis([share_of_funds[0], share_of_funds[-1], y[0], y[-1]])
|
||||
axs[0].set_ylabel(ylabel)
|
||||
axs[0].set_xlabel('Share of Funds Requested')
|
||||
axs[0].set_title('Trigger Function Map - Alpha sweep')
|
||||
# share_of_funds = alpha_sweep['share_of_funds']
|
||||
# Z = alpha_sweep['log10_share_of_max_conv']
|
||||
# y = alpha_sweep['alpha']
|
||||
# ylabel = 'alpha'
|
||||
|
||||
# axs[0].contourf(share_of_funds, y, Z.T,100, cmap='jet', )
|
||||
# #axs[0].colorbar(cf)
|
||||
# axs[0].axis([share_of_funds[0], share_of_funds[-1], y[0], y[-1]])
|
||||
# axs[0].set_ylabel(ylabel)
|
||||
# axs[0].set_xlabel('Share of Funds Requested')
|
||||
# axs[0].set_title('Trigger Function Map - Alpha sweep')
|
||||
|
||||
share_of_funds = alpha_sweep['share_of_funds']
|
||||
Z = alpha_sweep['log10_trigger']
|
||||
y = alpha_sweep['alpha']
|
||||
ylabel = 'alpha'
|
||||
supply = alpha_sweep['supply']
|
||||
|
||||
axs[1].contourf(share_of_funds, y, Z.T,100, cmap='jet', )
|
||||
axs[1].axis([share_of_funds[0], share_of_funds[-1], y[0], y[-1]])
|
||||
axs[1].set_ylabel(ylabel)
|
||||
axs[1].set_xlabel('Share of Funds Requested')
|
||||
axs[1].set_title('Trigger Function Map - Alpha sweep - Z: log10_trigger')
|
||||
cp0=axs[0].contourf(share_of_funds, y, Z.T,100, cmap='jet', )
|
||||
axs[0].axis([share_of_funds[0], share_of_funds[-1], y[0], y[-1]])
|
||||
axs[0].set_ylabel(ylabel)
|
||||
axs[0].set_xlabel('Share of Funds Requested')
|
||||
axs[0].set_title('Trigger Function Map - Alpha sweep; Supply ='+str(supply))
|
||||
cb0=plt.colorbar(cp0, ax=axs[0])
|
||||
cb0.set_label('log10 of conviction to trigger')
|
||||
|
||||
share_of_funds = supply_sweep['share_of_funds']
|
||||
Z = supply_sweep['log10_share_of_max_conv']
|
||||
y = supply_sweep['total_supply']
|
||||
ylabel = 'Effective Supply'
|
||||
|
||||
axs[2].contourf(share_of_funds, y, Z.T,100, cmap='jet', )
|
||||
axs[2].axis([share_of_funds[0], share_of_funds[-1], y[0], y[-1]])
|
||||
axs[2].set_ylabel(ylabel)
|
||||
axs[2].set_xlabel('Share of Funds Requested')
|
||||
axs[2].set_title('Trigger Function Map - Supply sweep - Z: share_of_max_conv')
|
||||
# share_of_funds = supply_sweep['share_of_funds']
|
||||
# Z = supply_sweep['log10_share_of_max_conv']
|
||||
# y = supply_sweep['total_supply']
|
||||
# ylabel = 'Effective Supply'
|
||||
|
||||
# axs[2].contourf(share_of_funds, y, Z.T,100, cmap='jet', )
|
||||
# axs[2].axis([share_of_funds[0], share_of_funds[-1], y[0], y[-1]])
|
||||
# axs[2].set_ylabel(ylabel)
|
||||
# axs[2].set_xlabel('Share of Funds Requested')
|
||||
# axs[2].set_title('Trigger Function Map - Supply sweep - Z: share_of_max_conv')
|
||||
|
||||
share_of_funds = supply_sweep['share_of_funds']
|
||||
Z = supply_sweep['log10_trigger']
|
||||
y = supply_sweep['total_supply']
|
||||
ylabel = 'Effective Supply'
|
||||
alpha = supply_sweep['alpha']
|
||||
|
||||
axs[3].contourf(share_of_funds, y, Z.T,100, cmap='jet', )
|
||||
axs[3].axis([share_of_funds[0], share_of_funds[-1], y[0], y[-1]])
|
||||
axs[3].set_ylabel(ylabel)
|
||||
axs[3].set_xlabel('Share of Funds Requested')
|
||||
axs[3].set_title('Trigger Function Map - Supply sweep')
|
||||
max_conv = y/(1-alpha)
|
||||
|
||||
cp1=axs[1].contourf(share_of_funds, y, Z.T,100, cmap='jet', )
|
||||
axs[1].axis([share_of_funds[0], share_of_funds[-1], y[0], y[-1]])
|
||||
axs[1].set_ylabel(ylabel)
|
||||
axs[1].set_xlabel('Share of Funds Requested')
|
||||
axs[1].set_title('Trigger Function Map - Supply sweep; alpha='+str(alpha))
|
||||
axs[1].set_label('log10 of conviction to trigger')
|
||||
cb1=plt.colorbar(cp1, ax=axs[1])
|
||||
cb1.set_label('log10 of conviction to trigger')
|
||||
|
||||
|
||||
def initialize_network(n,m, initial_funds, supply):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
'''
|
||||
# initilize network x graph
|
||||
network = nx.DiGraph()
|
||||
# create participant nodes with type and token holding
|
||||
for i in range(n):
|
||||
network.add_node(i)
|
||||
network.nodes[i]['type']= "participant"
|
||||
|
||||
h_rv = expon.rvs(loc=0.0, scale= supply/n)
|
||||
network.nodes[i]['holdings'] = h_rv # SOL check
|
||||
|
||||
s_rv = np.random.rand()
|
||||
network.nodes[i]['sentiment'] = s_rv
|
||||
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
initial_supply = np.sum([ network.nodes[i]['holdings'] for i in participants])
|
||||
|
||||
|
||||
# Generate initial proposals
|
||||
for ind in range(m):
|
||||
j = n+ind
|
||||
network.add_node(j)
|
||||
network.nodes[j]['type']="proposal"
|
||||
network.nodes[j]['conviction'] = 0
|
||||
network.nodes[j]['status'] = 'candidate'
|
||||
network.nodes[j]['age'] = 0
|
||||
|
||||
r_rv = gamma.rvs(3,loc=0.001, scale=100)
|
||||
network.nodes[j]['funds_requested'] = r_rv
|
||||
|
||||
network.nodes[j]['trigger']= trigger_threshold(r_rv, initial_funds, initial_supply,beta,rho,alpha)
|
||||
|
||||
for i in range(n):
|
||||
network.add_edge(i, j)
|
||||
|
||||
rv = np.random.rand()
|
||||
a_rv = np.random.uniform(-1,1,1)[0]
|
||||
network.edges[(i, j)]['affinity'] = a_rv
|
||||
network.edges[(i, j)]['tokens'] = 0
|
||||
network.edges[(i, j)]['conviction'] = 0
|
||||
network.edges[(i, j)]['type'] = 'support'
|
||||
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
total_requested = np.sum([ network.nodes[i]['funds_requested'] for i in proposals])
|
||||
|
||||
network = initial_conflict_network(network, rate = .25)
|
||||
network = initial_social_network(network, scale = 1)
|
||||
|
||||
return network
|
||||
|
|
@ -10,7 +10,8 @@ from .conviction_helper_functions import *
|
|||
beta = .2 #later we should set this to be param so we can sweep it
|
||||
# tuning param for the trigger function
|
||||
rho = .001
|
||||
alpha = 1 - 0.9999599
|
||||
#alpha = 1 - 0.9999599 #native timescale for app as in contract code
|
||||
alpha = .5**3 #timescale set in days with 3 day halflife (from comments in contract comments)
|
||||
supply = 21706 # Honey supply balance as of 7-17-2020
|
||||
initial_sentiment = .6
|
||||
|
||||
|
|
@ -28,65 +29,4 @@ base_failure_rate = 200
|
|||
|
||||
initial_funds = 48000 # in xDai
|
||||
|
||||
def initialize_network(n,m, inital_funds, supply):
|
||||
'''
|
||||
Definition:
|
||||
Function to initialize network x object
|
||||
|
||||
Parameters:
|
||||
|
||||
Assumptions:
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
'''
|
||||
# initilize network x graph
|
||||
network = nx.DiGraph()
|
||||
# create participant nodes with type and token holding
|
||||
for i in range(n):
|
||||
network.add_node(i)
|
||||
network.nodes[i]['type']= "participant"
|
||||
|
||||
h_rv = expon.rvs(loc=0.0, scale= supply/n)
|
||||
network.nodes[i]['holdings'] = h_rv # SOL check
|
||||
|
||||
s_rv = np.random.rand()
|
||||
network.nodes[i]['sentiment'] = s_rv
|
||||
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
initial_supply = np.sum([ network.nodes[i]['holdings'] for i in participants])
|
||||
|
||||
|
||||
# Generate initial proposals
|
||||
for ind in range(m):
|
||||
j = n+ind
|
||||
network.add_node(j)
|
||||
network.nodes[j]['type']="proposal"
|
||||
network.nodes[j]['conviction'] = 0
|
||||
network.nodes[j]['status'] = 'candidate'
|
||||
network.nodes[j]['age'] = 0
|
||||
|
||||
r_rv = gamma.rvs(3,loc=0.001, scale=100)
|
||||
network.nodes[j]['funds_requested'] = r_rv
|
||||
|
||||
network.nodes[j]['trigger']= trigger_threshold(r_rv, initial_funds, initial_supply,beta,rho,alpha)
|
||||
|
||||
for i in range(n):
|
||||
network.add_edge(i, j)
|
||||
|
||||
a_rv = np.random.uniform(-1,1,1)[0]
|
||||
network.edges[(i, j)]['affinity'] = a_rv
|
||||
network.edges[(i, j)]['tokens'] = 0
|
||||
network.edges[(i, j)]['conviction'] = 0
|
||||
network.edges[(i, j)]['type'] = 'support'
|
||||
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
total_requested = np.sum([ network.nodes[i]['funds_requested'] for i in proposals])
|
||||
|
||||
network = initial_conflict_network(network, rate = .25)
|
||||
network = initial_social_network(network, scale = 1)
|
||||
|
||||
return network, initial_funds
|
||||
#initializers
|
||||
network, initial_funds = initialize_network(n,m,initial_funds,supply)
|
||||
network = initialize_network(n,m,initial_funds,supply)
|
||||
|
|
|
|||
|
|
@ -76,27 +76,19 @@ def complete_proposal(params, step, sL, s, _input):
|
|||
return (key, value)
|
||||
|
||||
def update_sentiment_on_completion(params, step, sL, s, _input):
|
||||
|
||||
network = s['network']
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
completed = _input['completed']
|
||||
failed = _input['failed']
|
||||
|
||||
grants_outstanding = np.sum([network.nodes[j]['funds_requested'] for j in proposals if network.nodes[j]['status']=='active'])
|
||||
|
||||
grants_completed = np.sum([network.nodes[j]['funds_requested'] for j in completed])
|
||||
grants_failed = np.sum([network.nodes[j]['funds_requested'] for j in failed])
|
||||
|
||||
sentiment = s['sentiment']
|
||||
|
||||
if grants_outstanding>0:
|
||||
force = (grants_completed-grants_failed)/grants_outstanding
|
||||
else:
|
||||
force=1
|
||||
if (force >=0) and (force <=1):
|
||||
sentiment = get_sentimental(sentiment, force, mu)
|
||||
else:
|
||||
sentiment = get_sentimental(sentiment, 0, mu)
|
||||
completed_count = len(completed)
|
||||
failed_count = len(failed)
|
||||
|
||||
if completed_count+failed_count>0:
|
||||
sentiment = get_sentimental(sentiment,completed_count-failed_count, .25)
|
||||
else:
|
||||
sentiment = get_sentimental(sentiment, 0, 0)
|
||||
|
||||
key = 'sentiment'
|
||||
value = sentiment
|
||||
|
|
@ -134,8 +126,10 @@ def participants_decisions(params, step, sL, s):
|
|||
booster = social_affinity_booster(network, j, i)
|
||||
affinity = network.edges[(i, j)]['affinity']+booster
|
||||
cutoff = sensitivity*np.max([network.edges[(i,p)]['affinity'] for p in candidates])
|
||||
if cutoff <.5:
|
||||
cutoff = .5
|
||||
# range is [-1,1], where 0 is indifference, this determines min affinity supported
|
||||
# if no proposal meets this threshold participants may support a null proposal
|
||||
if cutoff <.3:
|
||||
cutoff = .3
|
||||
|
||||
if affinity > cutoff:
|
||||
support.append(j)
|
||||
|
|
|
|||
|
|
@ -76,11 +76,11 @@ def update_sentiment_on_release(params, step, sL, s, _input):
|
|||
proposals_accepted = np.sum([network.nodes[j]['funds_requested'] for j in accepted])
|
||||
|
||||
sentiment = s['sentiment']
|
||||
force = proposals_accepted/proposals_outstanding
|
||||
if (force >=0) and (force <=1):
|
||||
sentiment = get_sentimental(sentiment, force, False)
|
||||
force = len(accepted)
|
||||
if force>0:
|
||||
sentiment = get_sentimental(sentiment, force, .25)
|
||||
else:
|
||||
sentiment = get_sentimental(sentiment, 0, False)
|
||||
sentiment = get_sentimental(sentiment, 0, 0)
|
||||
|
||||
key = 'sentiment'
|
||||
value = sentiment
|
||||
|
|
|
|||
|
|
@ -16,11 +16,21 @@ def driving_process(params, step, sL, s):
|
|||
arrival_rate = 10/(1+s['sentiment'])
|
||||
rv1 = np.random.rand()
|
||||
new_participant = bool(rv1<1/arrival_rate)
|
||||
supporters = get_edges_by_type(s['network'], 'support')
|
||||
|
||||
len_parts = len(get_nodes_by_type(s['network'], 'participant'))
|
||||
network = s['network']
|
||||
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
|
||||
cadidate_proposals = [j for j in proposals if network.nodes[j]['status']=='candidate']
|
||||
subgraph_nodes = cadidate_proposals+participants
|
||||
|
||||
candidate_subgraph = s['network'].subgraph(subgraph_nodes)
|
||||
supporters = get_edges_by_type(candidate_subgraph, 'support')
|
||||
|
||||
len_parts = len(participants)
|
||||
#supply = s['supply']
|
||||
expected_holdings = .1*supply/len_parts
|
||||
expected_holdings = .01*supply/len_parts
|
||||
if new_participant:
|
||||
h_rv = expon.rvs(loc=0.0, scale=expected_holdings)
|
||||
new_participant_holdings = h_rv
|
||||
|
|
@ -28,16 +38,15 @@ def driving_process(params, step, sL, s):
|
|||
new_participant_holdings = 0
|
||||
|
||||
network = s['network']
|
||||
affinities = [network.edges[e]['affinity'] for e in supporters ]
|
||||
affinities = [network.edges[e]['affinity'] for e in supporters]
|
||||
median_affinity = np.median(affinities)
|
||||
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
fund_requests = [network.nodes[j]['funds_requested'] for j in proposals if network.nodes[j]['status']=='candidate']
|
||||
fund_requests = [network.nodes[j]['funds_requested'] for j in cadidate_proposals]
|
||||
|
||||
funds = s['funds']
|
||||
total_funds_requested = np.sum(fund_requests)
|
||||
|
||||
proposal_rate = 1/median_affinity * (1+total_funds_requested/funds)
|
||||
proposal_rate = 1/(1+median_affinity) * (1+total_funds_requested/funds)
|
||||
rv2 = np.random.rand()
|
||||
new_proposal = bool(rv2<1/proposal_rate)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue