1
0
Fork 0

Correct number of CIMs per node; Add fancy indexing

parallel_struct_est
philpMartin 4 years ago
parent 6f73412f29
commit b9188c9275
  1. 16
      main_package/classes/amalgamated_cims.py
  2. 48
      main_package/classes/network_graph.py
  3. 24
      main_package/classes/parameters_estimator.py
  4. 37
      main_package/classes/set_of_cims.py
  5. 6
      main_package/classes/structure.py

@ -8,16 +8,16 @@ class AmalgamatedCims:
{X:SetofCimsX, Y:SetOfCimsY.......} {X:SetofCimsX, Y:SetOfCimsY.......}
""" """
# list_of_vars_orders contiene tutte le liste con i parent ordinati secondo il valore indx # list_of_vars_orders contiene tutte le liste con i parent ordinati secondo il valore indx
def __init__(self, states_number, list_of_keys, list_of_vars_order): def __init__(self, states_number_per_node, list_of_keys, list_of_parents_states_number):
self.sets_of_cims = {} self.sets_of_cims = {}
self.init_cims_structure(list_of_keys, states_number, list_of_vars_order) self.init_cims_structure(list_of_keys, states_number_per_node, list_of_parents_states_number)
self.states_per_variable = states_number #self.states_per_variable = states_number
def init_cims_structure(self, keys, nodes_val, list_of_vars_order): def init_cims_structure(self, keys, states_number_per_node, list_of_parents_states_number):
print(keys) print(keys)
print(list_of_vars_order) print(list_of_parents_states_number)
for indx, key in enumerate(keys): for indx, key in enumerate(keys):
self.sets_of_cims[key] = socim.SetOfCims(key, list_of_vars_order[indx], nodes_val) self.sets_of_cims[key] = socim.SetOfCims(key, list_of_parents_states_number[indx], states_number_per_node[indx])
def get_set_of_cims(self, node_id): def get_set_of_cims(self, node_id):
return self.sets_of_cims[node_id] return self.sets_of_cims[node_id]
@ -25,8 +25,8 @@ class AmalgamatedCims:
def get_vars_order(self, node): def get_vars_order(self, node):
return self.actual_cims[node][1] return self.actual_cims[node][1]
def update_state_transition_for_matrix(self, node, dict_of_nodes_values, element_indx): def update_state_transition_for_matrix(self, node, which_matrix, element_indx):
self.sets_of_cims[node].update_state_transition(dict_of_nodes_values, element_indx) self.sets_of_cims[node].update_state_transition(which_matrix, element_indx)
def update_state_residence_time_for_matrix(self, which_node, which_matrix, which_element, time): def update_state_residence_time_for_matrix(self, which_node, which_matrix, which_element, time):
self.sets_of_cims[which_node].update_state_residence_time(which_matrix, which_element, time) self.sets_of_cims[which_node].update_state_residence_time(which_matrix, which_element, time)

@ -1,5 +1,7 @@
import os
import sample_path as sp
import networkx as nx import networkx as nx
import numpy as np
@ -45,14 +47,47 @@ class NetworkGraph():
result.append(self.get_ordered_by_indx_set_of_parents(node)) result.append(self.get_ordered_by_indx_set_of_parents(node))
return result return result
def get_ordered_by_indx_parents_values(self, node):
parents_values = []
parents = self.get_parents_by_id(node)
parents.sort() #Assumo che la structure rifletta l'ordine delle colonne del dataset
for n in parents:
parents_values.append(self.graph_struct.get_states_number(n))
return parents_values
def get_ordered_by_indx_parents_values_for_all_nodes(self):
result = []
for node in self.get_nodes(): #TODO bisogna essere sicuri che l'ordine sia coerente con quello del dataset serve un metodo get_nodes_sort_by_indx
result.append(self.get_ordered_by_indx_parents_values(node))
return result
def get_states_number_of_all_nodes_sorted(self):
states_number_list = []
for node in self.get_nodes(): #TODO SERVE UN get_nodes_ordered!!!!!!
states_number_list.append(self.get_states_number(node))
return states_number_list
def build_fancy_indexing_structure(self, start_indx):
list_of_parents_list = self.get_ord_set_of_par_of_all_nodes()
index_structure = []
for i, list_of_parents in enumerate(list_of_parents_list):
indexes_for_a_node = []
for j, node in enumerate(list_of_parents):
indexes_for_a_node.append(self.get_node_indx(node) + start_indx)
index_structure.append(indexes_for_a_node)
return index_structure
def get_nodes(self): def get_nodes(self):
return list(self.graph.nodes) return list(self.graph.nodes)
def get_nodes_sorted_by_indx(self):
return self.graph_struct.list_of_nodes
def get_parents_by_id(self, node_id): def get_parents_by_id(self, node_id):
return list(self.graph.predecessors(node_id)) return list(self.graph.predecessors(node_id))
def get_states_number(self): def get_states_number(self, node_id):
return self.graph_struct.get_states_number() return self.graph_struct.get_states_number(node_id)
def get_node_by_index(self, node_indx): def get_node_by_index(self, node_indx):
return self.graph_struct.get_node_id(node_indx) return self.graph_struct.get_node_id(node_indx)
@ -80,10 +115,11 @@ print(g1.graph.number_of_edges())
print(nx.get_node_attributes(g1.graph, 'indx')['X']) print(nx.get_node_attributes(g1.graph, 'indx')['X'])
for node in g1.get_parents_by_id('Z'): for node in g1.get_parents_by_id('Z'):
print(g1.get_node_by_index(node)) # print(g1.get_node_by_index(node))
print(node) print(node)
print(g1.get_ordered_by_indx_set_of_parents('Z')) print(g1.get_ordered_by_indx_parents_values_for_all_nodes())
print(g1.get_ord_set_of_par_of_all_nodes())""" print(g1.build_fancy_indexing_structure())
print(g1.get_states_number_of_all_nodes_sorted())"""

@ -11,12 +11,13 @@ class ParametersEstimator:
def __init__(self, sample_path, net_graph): def __init__(self, sample_path, net_graph):
self.sample_path = sample_path self.sample_path = sample_path
self.net_graph = net_graph self.net_graph = net_graph
self.fancy_indexing_structure = self.net_graph.build_fancy_indexing_structure(1)
self.amalgamated_cims_struct = None self.amalgamated_cims_struct = None
def init_amalgamated_cims_struct(self): def init_amalgamated_cims_struct(self):
self.amalgamated_cims_struct = acims.AmalgamatedCims(self.net_graph.get_states_number(), self.amalgamated_cims_struct = acims.AmalgamatedCims(self.net_graph.get_states_number_of_all_nodes_sorted(),
self.net_graph.get_nodes(), self.net_graph.get_nodes(),
self.net_graph.get_ord_set_of_par_of_all_nodes()) self.net_graph.get_ordered_by_indx_parents_values_for_all_nodes())
def parameters_estimation(self): def parameters_estimation(self):
print("Starting computing") print("Starting computing")
@ -36,19 +37,19 @@ class ParametersEstimator:
transition = self.find_transition(trajectory[indx], trajectory[indx + 1]) transition = self.find_transition(trajectory[indx], trajectory[indx + 1])
which_node = self.net_graph.get_node_by_index(transition[0]) which_node = self.net_graph.get_node_by_index(transition[0])
# print(which_node) # print(which_node)
which_matrix = self.which_matrix_to_update(row, which_node) which_matrix = self.which_matrix_to_update(row, transition[0])
which_element = transition[1] which_element = transition[1]
self.amalgamated_cims_struct.update_state_transition_for_matrix(which_node, which_matrix, which_element) self.amalgamated_cims_struct.update_state_transition_for_matrix(which_node, which_matrix, which_element)
#changed_node = which_node #changed_node = which_node
time = self.compute_time_delta(trajectory[indx], trajectory[indx + 1]) time = self.compute_time_delta(trajectory[indx], trajectory[indx + 1])
for node in self.net_graph.get_nodes(): for node_indx, node in enumerate(self.net_graph.get_nodes()):
#if node != changed_node: #if node != changed_node:
# print(node) # print(node)
which_node = node which_node = node
which_matrix = self.which_matrix_to_update(row, which_node) which_matrix = self.which_matrix_to_update(row, node_indx)
which_element = row[self.net_graph.get_node_indx(node) + 1] which_element = row[node_indx + 1]
# print("State res time element " + str(which_element) + node) # print("State res time element " + str(which_element) + node)
# print("State res time matrix indx" + str(which_matrix)) # print("State res time matrix indx" + str(which_matrix))
self.amalgamated_cims_struct.update_state_residence_time_for_matrix(which_node, which_matrix, which_element, time) self.amalgamated_cims_struct.update_state_residence_time_for_matrix(which_node, which_matrix, which_element, time)
@ -63,13 +64,9 @@ class ParametersEstimator:
def compute_time_delta(self, current_row, next_row): def compute_time_delta(self, current_row, next_row):
return next_row[0] - current_row[0] return next_row[0] - current_row[0]
def which_matrix_to_update(self, current_row, node_id): # produce strutture {'X':1, 'Y':2} dove X e Y sono i parent di node_id def which_matrix_to_update(self, current_row, node_indx): # produce strutture {'X':1, 'Y':2} dove X e Y sono i parent di node_id
result = {} return current_row[self.fancy_indexing_structure[node_indx]]
parent_list = self.net_graph.get_parents_by_id(node_id)
for node in parent_list:
result[node] = current_row[self.net_graph.get_node_indx(node) + 1]
# print(result)
return result
@ -90,6 +87,7 @@ pe = ParametersEstimator(s1, g1)
pe.init_amalgamated_cims_struct() pe.init_amalgamated_cims_struct()
print(pe.amalgamated_cims_struct.get_set_of_cims('X').get_cims_number()) print(pe.amalgamated_cims_struct.get_set_of_cims('X').get_cims_number())
print(pe.amalgamated_cims_struct.get_set_of_cims('Y').get_cims_number()) print(pe.amalgamated_cims_struct.get_set_of_cims('Y').get_cims_number())
print(pe.amalgamated_cims_struct.get_set_of_cims('Z').get_cims_number())
#pe.parameters_estimation_single_trajectory(pe.sample_path.trajectories[0].get_trajectory()) #pe.parameters_estimation_single_trajectory(pe.sample_path.trajectories[0].get_trajectory())
pe.parameters_estimation() pe.parameters_estimation()
for matrix in pe.amalgamated_cims_struct.get_set_of_cims('Y').actual_cims: for matrix in pe.amalgamated_cims_struct.get_set_of_cims('Y').actual_cims:

@ -12,21 +12,23 @@ class SetOfCims:
:actual_cims: le CIM della varibile :actual_cims: le CIM della varibile
""" """
def __init__(self, node_id, ordered_parent_set, value_type): def __init__(self, node_id, parents_states_number, node_states_number):
self.node_id = node_id self.node_id = node_id
self.ordered_parent_set = ordered_parent_set self.parents_states_number = parents_states_number
self.value = value_type self.node_states_number = node_states_number
self.actual_cims = None self.actual_cims = None
self.build_actual_cims_structure() self.build_actual_cims_structure()
def build_actual_cims_structure(self): def build_actual_cims_structure(self):
cims_number = self.value**len(self.ordered_parent_set) cims_number = 1
for state_number in self.parents_states_number:
cims_number = cims_number * state_number
self.actual_cims = np.empty(cims_number, dtype=cim.ConditionalIntensityMatrix) self.actual_cims = np.empty(cims_number, dtype=cim.ConditionalIntensityMatrix)
for indx, matrix in enumerate(self.actual_cims): for indx, matrix in enumerate(self.actual_cims):
self.actual_cims[indx] = cim.ConditionalIntensityMatrix(self.value) self.actual_cims[indx] = cim.ConditionalIntensityMatrix(self.node_states_number)
def update_state_transition(self, dict_of_indexes, element_indx_tuple): def update_state_transition(self, indexes, element_indx_tuple):
matrix_indx = self.indexes_converter(dict_of_indexes) matrix_indx = self.indexes_converter(indexes)
self.actual_cims[matrix_indx].update_state_transition_count(element_indx_tuple) self.actual_cims[matrix_indx].update_state_transition_count(element_indx_tuple)
def update_state_residence_time(self, which_matrix, which_element, time): def update_state_residence_time(self, which_matrix, which_element, time):
@ -37,23 +39,22 @@ class SetOfCims:
def get_cims_number(self): def get_cims_number(self):
return len(self.actual_cims) return len(self.actual_cims)
def indexes_converter(self, dict_of_indexes): # Si aspetta oggetti del tipo {X:1, Y:1, Z:0} dove def indexes_converter(self, indexes): # Si aspetta array del tipo [2,2] dove
# le keys sono i parent del nodo e i values sono i valori che assumono #print(type(indexes))
if not dict_of_indexes: if indexes.size == 0:
return 0 return 0
else: else:
literal_index = "" vector_index = 0
for node in self.ordered_parent_set: for indx, value in enumerate(indexes):
literal_index = literal_index + str(dict_of_indexes[node]) vector_index = vector_index*self.parents_states_number[indx] + indexes[indx]
#print(literal_index) return vector_index
return int(literal_index, self.value)
"""
"""sofc = SetOfCims('W', ['X','Y', 'Z'], 2) sofc = SetOfCims('W', [], 2)
sofc.build_actual_cims_structure() sofc.build_actual_cims_structure()
print(sofc.actual_cims) print(sofc.actual_cims)
print(sofc.indexes_converter({'X':1, 'Y':1, 'Z':0}))""" print(sofc.indexes_converter([]))"""

@ -21,7 +21,7 @@ class Structure:
return edges_list return edges_list
def list_of_nodes(self): def list_of_nodes(self):
return self.variables_frame['Name'] #TODO rimuovere dipendenza diretta dalla key 'Name' return self.variables_frame['Name'].values.tolist() #TODO rimuovere dipendenza diretta dalla key 'Name'
def get_node_id(self, node_indx): def get_node_id(self, node_indx):
return self.variables_frame['Name'][node_indx] return self.variables_frame['Name'][node_indx]
@ -29,5 +29,5 @@ class Structure:
def get_node_indx(self, node_id): def get_node_indx(self, node_id):
return list(self.variables_frame['Name']).index(node_id) return list(self.variables_frame['Name']).index(node_id)
def get_states_number(self): def get_states_number(self, node):
return self.variables_frame['Value'][0] return self.variables_frame['Value'][self.get_node_indx(node)]