def create_attractors(attractors_dict_list={}): if len(attractors_dict_list) == 0: attrctr1 = utilities.bool2int(1 for _ in range(number_of_bits)) attrctr2 = utilities.bool2int(0 for _ in range(number_of_bits)) attrctrs = [attrctr1, attrctr2] for index, val in enumerate(attrctrs): attractor_state = attrctrs[index] attractor_depth = random.randint( attrctr_min_depth, attrctr_max_depth ) # depth for each attractors is picked randomly attractor_radius = random.randint(attrctr_min_radius, attrctr_max_radius) attractors[attractor_state] = { 'depth': attractor_depth, 'radius': attractor_radius } #TODO: Fix this with dynamic rather than static attractor depth and radius attrctrs_1 = [[k, 100, 1] for k, v in attractors.items()] else: attrctrs_1 = [[att['state'], att['depth'], att['radius']] for att in attractors_dict_list] attrctr, coherence_mat = analysis.init_coherence_matrix( number_of_bits, attrctrs_1, 3) return coherence_mat
def run_simulation(end_time, agents, states): static_obj = ray.put(shrd_static) sim_result_lst = [] ncores = os.cpu_count() for t in range(end_time): dynamic_obj = ray.put(states) chunked = chunks(agents, ncores) sim_result = defaultdict(list) for agt_index, agt_state in enumerate(states): sim_result['Agent_Number'].append(agt_index) sim_result['Time'].append(t) sim_result['Current_Knowledge_State'].append( utilities.bool2int(agt_state)) results = [ agent_update.remote(chunk, static_obj, dynamic_obj) for chunk in chunked ] states = [item for sublist in ray.get(results) for item in sublist] for agt_nxt_state in states: sim_result['Next_Knowledge_State'].append( utilities.bool2int(agt_nxt_state)) sim_result_lst.append(sim_result) del dynamic_obj return sim_result_lst
def run_simulation(alpha, coherence, bit_mat, list_agents, end_time, exp): d = [] generations = 0 for t in range(end_time): # compute next state for all agents for agt in list_agents: agt.update_knowledge(alpha, coherence, bit_mat) # keep record of current record and all other values for agt in list_agents: row = {'Agent_Number': int(agt.name.split('t')[1]), 'Time':t, # at any time step we will need normalized how many neighbors disagree on bits 'bits_disagreement':np.mean(agt.state_disagreements), #'Current_Knowledge_State':agt.knowledge_state, 'Current': utilities.bool2int(agt.knowledge_state), 'alpha':alpha, 'Next': utilities.bool2int(agt.next_state), #'Next_Knowledge_State':agt.next_state, "Experiment":exp} d.append(row) # now update all agents next state with computed next state for agt in list_agents: agt.knowledge_state = agt.next_state agt.next_state = None agt.dissonance_lst = None generations+=1 return pd.DataFrame(d)
def doit(): attrctr1 = utilities.bool2int([1, 1, 1, 1, 1, 1]) attrctr2 = utilities.bool2int([0, 0, 0, 0, 0, 0]) attrctrs = [attrctr1, attrctr2] attractors = {} number_attractors = 0 while number_attractors < 2: attractor_state = attrctrs.pop() attractor_depth = random.randint( 1, 4) # depth for each attractors is picked randomly attractor_radius = random.randint(1, 2) attractors[attractor_state] = { 'depth': attractor_depth, 'radius': attractor_radius } number_attractors += 1 attrctrs_1 = [[k, 100, 1] for k, v in attractors.items()] attrctr, coh = analysis.init_coherence_matrix(number_of_bits, attrctrs_1, 3) ### This cell is for generating the dataset # constants intialization network_parameters = [0.7] #np.arange(0, 1, 0.1).round(2) proportion_parameters = [0.7] #np.arange(0, 1, 0.1).round(2) end_simulation_time = 10 #alphas = np.arange(0, 1, 0.1).round(2) alphas = [0.1] exp_times = 1 constants = const.Constants() bit_mat = constants.get_bit_matrix() record_df_list = [] start = time.time() for exp in range(1): for alpha in alphas: for j in proportion_parameters: # first create environment for i in network_parameters: run_simulation(alpha, coh, bit_mat, end_simulation_time, i, j) # tmp_record_df = tmp_record_df[tmp_record_df['Time']==49] # tmp_record_df['exp'] = exp # record_df_list.append(tmp_record_df) end = time.time() print((end - start) / 60.0)
def update_knowledge(self, alpha, txn, bit_matrix): """Takes alpha and transition matrix (expects a 2d array)""" # first convert state binary to int to get the row in coherence matrix row_ptr = utilities.bool2int(self.knowledge_state) # get the corresponding probabilites from the matrix coh_prob_tx = txn[row_ptr] ones_list = np.zeros(number_of_bits) dissonance_list = [] disagreements = [] for index, curr_bit_state in enumerate(self.knowledge_state): # now look for neighbors who disagree in this bit value neigh_disagreement_count = self.count_dissimilar_neighbors(index) # compute d as (# of neighbors disagree on bit/# of neighbors) if len(self.neighbors) > 0: d = neigh_disagreement_count / len(self.neighbors) else: d = 0 #TODO: Handle the viral parameter - in general, if d = 0 and viral is set, #TODO: it should not be possible to make that transition if d > 0: dissonance = utilities.sigmoid(d, self.tau) else: dissonance = 0 dissonance_list.append(dissonance) # keeping track of disagreement of bits/total neighbors disagreements.append(d) # transition probabilities given social pressure for moving to a state # with a '1' at this bit ones_list[index] = (1 - dissonance if curr_bit_state else dissonance) zeros_list = 1 - ones_list tmp_soc_mat = ones_list * bit_matrix + zeros_list * (1 - bit_matrix) # Probabilities for each state given social pressure soc_prob_tx = np.prod(tmp_soc_mat, 1) #TODO logs soc_prob_tx for each agent at each time step probs = alpha * soc_prob_tx + (1 - alpha) * coh_prob_tx self.next_state_probs = probs self.soc_probs = soc_prob_tx self.next_state = utilities.int2bool( np.random.choice(range(2**number_of_bits), 1, p=probs)[0], number_of_bits) self.dissonance_lst = dissonance_list self.state_disagreements = disagreements return soc_prob_tx
def update(self, static, dynamic): """Takes environment with common values to compute""" # first convert state binary to int to get the row in coherence matrix txn = static["coherence_matrix"] bit_matrix = static["bit_matrix"] alpha = static["alpha"] kstate = dynamic[self.idx] # for agt in population: row_ptr = utilities.bool2int(kstate) # get the corresponding probabilites from the matrix coh_prob_tx = txn[row_ptr] ones_list = np.zeros(number_of_bits) for kbit, curr_bit_state in enumerate(kstate): # now look for neighbors who disagree in this bit value count = 0 for alter in self.neighbors: alter_state = dynamic[alter] if curr_bit_state != alter_state[kbit]: count += 1 dissonance = 0 if len( self.neighbors) == 0 else count / len(self.neighbors) #TODO: Handle the viral parameter - in general, if d = 0 and viral is set, #TODO: it should not be possible to make that transition if dissonance > 0: dissonance = utilities.sigmoid(dissonance, self.tau) # transition probabilities given social pressure for moving to a state # with a '1' at this bit ones_list[kbit] = (1 - dissonance if curr_bit_state else dissonance) zeros_list = 1 - ones_list tmp_soc_mat = ones_list * bit_matrix + zeros_list * (1 - bit_matrix) # Probabilities for each state given social pressure soc_prob_tx = np.prod(tmp_soc_mat, 1) #TODO logs soc_prob_tx for each agent at each time step probs = alpha * soc_prob_tx + (1 - alpha) * coh_prob_tx return utilities.int2bool( np.random.choice(range(2**number_of_bits), 1, p=probs)[0], number_of_bits)