diff --git a/PyCTBN/PyCTBN/cache.py b/PyCTBN/PyCTBN/cache.py
index 97aa1a1..eea1013 100644
--- a/PyCTBN/PyCTBN/cache.py
+++ b/PyCTBN/PyCTBN/cache.py
@@ -4,7 +4,7 @@ import typing
from .set_of_cims import SetOfCims
-class Cache:
+class Cache(object):
"""This class acts as a cache of ``SetOfCims`` objects for a node.
:_list_of_sets_of_parents: a list of ``Sets`` objects of the parents to which the cim in cache at SAME
@@ -51,4 +51,4 @@ class Cache:
"""Clear the contents both of ``_actual_cache`` and ``_list_of_sets_of_parents``.
"""
del self._list_of_sets_of_parents[:]
- del self._actual_cache[:]
\ No newline at end of file
+ del self._actual_cache[:]
diff --git a/PyCTBN/PyCTBN/conditional_intensity_matrix.py b/PyCTBN/PyCTBN/conditional_intensity_matrix.py
index 96a3ae2..4abfdd0 100644
--- a/PyCTBN/PyCTBN/conditional_intensity_matrix.py
+++ b/PyCTBN/PyCTBN/conditional_intensity_matrix.py
@@ -1,7 +1,7 @@
import numpy as np
-class ConditionalIntensityMatrix:
+class ConditionalIntensityMatrix(object):
"""Abstracts the Conditional Intesity matrix of a node as aggregation of the state residence times vector
and state transition matrix and the actual CIM matrix.
diff --git a/PyCTBN/PyCTBN/network_graph.py b/PyCTBN/PyCTBN/network_graph.py
index 24d01c0..a18658f 100644
--- a/PyCTBN/PyCTBN/network_graph.py
+++ b/PyCTBN/PyCTBN/network_graph.py
@@ -6,7 +6,7 @@ import numpy as np
from .structure import Structure
-class NetworkGraph:
+class NetworkGraph(object):
"""Abstracts the infos contained in the Structure class in the form of a directed graph.
Has the task of creating all the necessary filtering and indexing structures for parameters estimation
@@ -47,14 +47,16 @@ class NetworkGraph:
self._aggregated_info_about_nodes_parents = self.get_ordered_by_indx_set_of_parents(node_id)
p_indxs = self._aggregated_info_about_nodes_parents[1]
p_vals = self._aggregated_info_about_nodes_parents[2]
- self._time_scalar_indexing_structure = self.build_time_scalar_indexing_structure_for_a_node(node_id,
- p_vals)
- self._transition_scalar_indexing_structure = self.build_transition_scalar_indexing_structure_for_a_node(node_id,
- p_vals)
+ node_states = self.get_states_number(node_id)
node_indx = self.get_node_indx(node_id)
- self._time_filtering = self.build_time_columns_filtering_for_a_node(node_indx, p_indxs)
- self._transition_filtering = self.build_transition_filtering_for_a_node(node_indx, p_indxs)
- self._p_combs_structure = self.build_p_comb_structure_for_a_node(p_vals)
+ cols_number = self._graph_struct.total_variables_number
+ self._time_scalar_indexing_structure = NetworkGraph.\
+ build_time_scalar_indexing_structure_for_a_node(node_states, p_vals)
+ self._transition_scalar_indexing_structure = NetworkGraph.\
+ build_transition_scalar_indexing_structure_for_a_node(node_states, p_vals)
+ self._time_filtering = NetworkGraph.build_time_columns_filtering_for_a_node(node_indx, p_indxs)
+ self._transition_filtering = NetworkGraph.build_transition_filtering_for_a_node(node_indx, p_indxs, cols_number)
+ self._p_combs_structure = NetworkGraph.build_p_comb_structure_for_a_node(p_vals)
def add_nodes(self, list_of_nodes: typing.List) -> None:
"""Adds the nodes to the ``_graph`` contained in the list of nodes ``list_of_nodes``.
@@ -112,42 +114,45 @@ class NetworkGraph:
get_node_indx = self.get_node_indx
p_indxes = [get_node_indx(node) for node in sorted_parents]
p_values = [self.get_states_number(node) for node in sorted_parents]
- return (sorted_parents, p_indxes, p_values)
+ return sorted_parents, p_indxes, p_values
- def build_time_scalar_indexing_structure_for_a_node(self, node_id: str, parents_vals: typing.List) -> np.ndarray:
+ @staticmethod
+ def build_time_scalar_indexing_structure_for_a_node(node_states: int,
+ parents_vals: typing.List) -> np.ndarray:
"""Builds an indexing structure for the computation of state residence times values.
- :param node_id: the node label
- :type node_id: string
+ :param node_states: the node cardinality
+ :type node_states: int
:param parents_vals: the caridinalites of the node's parents
:type parents_vals: List
:return: The time indexing structure
:rtype: numpy.ndArray
"""
- T_vector = np.array([self.get_states_number(node_id)])
+ T_vector = np.array([node_states])
T_vector = np.append(T_vector, parents_vals)
T_vector = T_vector.cumprod().astype(np.int)
return T_vector
- def build_transition_scalar_indexing_structure_for_a_node(self, node_id: str, parents_vals: typing.List) \
+ @staticmethod
+ def build_transition_scalar_indexing_structure_for_a_node(node_states_number: int, parents_vals: typing.List) \
-> np.ndarray:
"""Builds an indexing structure for the computation of state transitions values.
- :param node_id: the node label
- :type node_id: string
+ :param node_states_number: the node cardinality
+ :type node_states_number: int
:param parents_vals: the caridinalites of the node's parents
:type parents_vals: List
:return: The transition indexing structure
:rtype: numpy.ndArray
"""
- node_states_number = self.get_states_number(node_id)
M_vector = np.array([node_states_number,
node_states_number])
M_vector = np.append(M_vector, parents_vals)
M_vector = M_vector.cumprod().astype(np.int)
return M_vector
- def build_time_columns_filtering_for_a_node(self, node_indx: int, p_indxs: typing.List) -> np.ndarray:
+ @staticmethod
+ def build_time_columns_filtering_for_a_node(node_indx: int, p_indxs: typing.List) -> np.ndarray:
"""
Builds the necessary structure to filter the desired columns indicated by ``node_indx`` and ``p_indxs``
in the dataset.
@@ -161,7 +166,9 @@ class NetworkGraph:
"""
return np.append(np.array([node_indx], dtype=np.int), p_indxs).astype(np.int)
- def build_transition_filtering_for_a_node(self, node_indx: int, p_indxs: typing.List) -> np.ndarray:
+ @staticmethod
+ def build_transition_filtering_for_a_node(node_indx: int, p_indxs: typing.List, nodes_number: int) \
+ -> np.ndarray:
"""Builds the necessary structure to filter the desired columns indicated by ``node_indx`` and ``p_indxs``
in the dataset.
This structure will be used in the computation of the state transitions values.
@@ -169,13 +176,15 @@ class NetworkGraph:
:type node_indx: int
:param p_indxs: the indexes of the node's parents
:type p_indxs: List
+ :param nodes_number: the total number of nodes in the dataset
+ :type nodes_number: int
:return: The filtering structure for transitions estimation
:rtype: numpy.ndArray
"""
- nodes_number = self._graph_struct.total_variables_number
return np.array([node_indx + nodes_number, node_indx, *p_indxs], dtype=np.int)
- def build_p_comb_structure_for_a_node(self, parents_values: typing.List) -> np.ndarray:
+ @staticmethod
+ def build_p_comb_structure_for_a_node(parents_values: typing.List) -> np.ndarray:
"""
Builds the combinatorial structure that contains the combinations of all the values contained in
``parents_values``.
diff --git a/PyCTBN/PyCTBN/parameters_estimator.py b/PyCTBN/PyCTBN/parameters_estimator.py
index a2d9140..01254e2 100644
--- a/PyCTBN/PyCTBN/parameters_estimator.py
+++ b/PyCTBN/PyCTBN/parameters_estimator.py
@@ -6,7 +6,7 @@ from .set_of_cims import SetOfCims
from .network_graph import NetworkGraph
-class ParametersEstimator:
+class ParametersEstimator(object):
"""Has the task of computing the cims of particular node given the trajectories and the net structure
in the graph ``_net_graph``.
@@ -45,7 +45,7 @@ class ParametersEstimator:
node_indx = self._net_graph.get_node_indx(node_id)
state_res_times = self._single_set_of_cims._state_residence_times
transition_matrices = self._single_set_of_cims._transition_matrices
- ParametersEstimator.compute_state_res_time_for_node(node_indx, self._trajectories.times,
+ ParametersEstimator.compute_state_res_time_for_node(self._trajectories.times,
self._trajectories.trajectory,
self._net_graph.time_filtering,
self._net_graph.time_scalar_indexing_strucure,
@@ -58,7 +58,7 @@ class ParametersEstimator:
return self._single_set_of_cims
@staticmethod
- def compute_state_res_time_for_node(node_indx: int, times: np.ndarray, trajectory: np.ndarray,
+ def compute_state_res_time_for_node(times: np.ndarray, trajectory: np.ndarray,
cols_filter: np.ndarray, scalar_indexes_struct: np.ndarray,
T: np.ndarray) -> None:
"""Compute the state residence times for a node and fill the matrix ``T`` with the results
@@ -100,8 +100,8 @@ class ParametersEstimator:
diag_indices = np.array([x * M.shape[1] + x % M.shape[1] for x in range(M.shape[0] * M.shape[1])],
dtype=np.int64)
trj_tmp = trajectory[trajectory[:, int(trajectory.shape[1] / 2) + node_indx].astype(np.int) >= 0]
- M[:] = np.bincount(np.sum(trj_tmp[:, cols_filter] * scalar_indexing / scalar_indexing[0], axis=1).astype(np.int),
- minlength=scalar_indexing[-1]).reshape(-1, M.shape[1], M.shape[2])
+ M[:] = np.bincount(np.sum(trj_tmp[:, cols_filter] * scalar_indexing / scalar_indexing[0], axis=1).astype(np.int)
+ , minlength=scalar_indexing[-1]).reshape(-1, M.shape[1], M.shape[2])
M_raveled = M.ravel()
M_raveled[diag_indices] = 0
M_raveled[diag_indices] = np.sum(M, axis=2).ravel()
diff --git a/PyCTBN/PyCTBN/sample_path.py b/PyCTBN/PyCTBN/sample_path.py
index 6f32cf8..2fc8c1f 100644
--- a/PyCTBN/PyCTBN/sample_path.py
+++ b/PyCTBN/PyCTBN/sample_path.py
@@ -4,7 +4,7 @@ from .structure import Structure
from .trajectory import Trajectory
-class SamplePath:
+class SamplePath(object):
"""Aggregates all the informations about the trajectories, the real structure of the sampled net and variables
cardinalites. Has the task of creating the objects ``Trajectory`` and ``Structure`` that will
contain the mentioned data.
diff --git a/PyCTBN/PyCTBN/set_of_cims.py b/PyCTBN/PyCTBN/set_of_cims.py
index bbab975..7bb89f9 100644
--- a/PyCTBN/PyCTBN/set_of_cims.py
+++ b/PyCTBN/PyCTBN/set_of_cims.py
@@ -4,7 +4,7 @@ import numpy as np
from .conditional_intensity_matrix import ConditionalIntensityMatrix
-class SetOfCims:
+class SetOfCims(object):
"""Aggregates all the CIMS of the node identified by the label _node_id.
:param node_id: the node label
diff --git a/PyCTBN/PyCTBN/structure.py b/PyCTBN/PyCTBN/structure.py
index 4d31f19..7e39277 100644
--- a/PyCTBN/PyCTBN/structure.py
+++ b/PyCTBN/PyCTBN/structure.py
@@ -2,7 +2,7 @@ import typing as ty
import numpy as np
-class Structure:
+class Structure(object):
"""Contains all the infos about the network structure(nodes labels, nodes caridinalites, edges, indexes)
:param nodes_labels_list: the symbolic names of the variables
@@ -105,5 +105,5 @@ class Structure:
np.array_equal(self._nodes_indexes_arr, other._nodes_indexes_arr) and \
self._edges_list == other._edges_list
- return NotImplemented
+ return False
diff --git a/PyCTBN/PyCTBN/structure_estimator.py b/PyCTBN/PyCTBN/structure_estimator.py
index ffa030b..5203f08 100644
--- a/PyCTBN/PyCTBN/structure_estimator.py
+++ b/PyCTBN/PyCTBN/structure_estimator.py
@@ -17,7 +17,7 @@ from .sample_path import SamplePath
from .structure import Structure
-class StructureEstimator:
+class StructureEstimator(object):
"""Has the task of estimating the network structure given the trajectories in ``samplepath``.
:param sample_path: the _sample_path object containing the trajectories and the real structure
@@ -40,12 +40,13 @@ class StructureEstimator:
self._nodes = np.array(self._sample_path.structure.nodes_labels)
self._nodes_vals = self._sample_path.structure.nodes_values
self._nodes_indxs = self._sample_path.structure.nodes_indexes
- self._complete_graph = self.build_complete_graph(self._sample_path.structure.nodes_labels)
+ self._complete_graph = StructureEstimator.build_complete_graph(self._sample_path.structure.nodes_labels)
self._exp_test_sign = exp_test_alfa
self._chi_test_alfa = chi_test_alfa
self._cache = Cache()
- def build_complete_graph(self, node_ids: typing.List) -> nx.DiGraph:
+ @staticmethod
+ def build_complete_graph(node_ids: typing.List) -> nx.DiGraph:
"""Builds a complete directed graph (no self loops) given the nodes labels in the list ``node_ids``:
:param node_ids: the list of nodes labels
@@ -176,7 +177,7 @@ class StructureEstimator:
parent_indx = 0
while parent_indx < len(u):
removed = False
- S = self.generate_possible_sub_sets_of_size(u, b, u[parent_indx])
+ S = StructureEstimator.generate_possible_sub_sets_of_size(u, b, u[parent_indx])
test_parent = u[parent_indx]
for parents_set in S:
if self.complete_test(test_parent, var_id, parents_set, child_states_numb, tot_vars_count):
@@ -189,7 +190,8 @@ class StructureEstimator:
b += 1
self._cache.clear()
- def generate_possible_sub_sets_of_size(self, u: typing.List, size: int, parent_label: str) -> \
+ @staticmethod
+ def generate_possible_sub_sets_of_size(u: typing.List, size: int, parent_label: str) -> \
typing.Iterator:
"""Creates a list containing all possible subsets of the list ``u`` of size ``size``,
that do not contains a the node identified by ``parent_label``.
@@ -219,9 +221,12 @@ class StructureEstimator:
The file is named as the input dataset but the `results_` word is appended to the results file.
"""
res = json_graph.node_link_data(self._complete_graph)
- name = self._sample_path._importer.file_path.rsplit('/', 1)[-1] + str(self._sample_path._importer.dataset_id())
- name = 'results_' + name
- with open(name, 'w') as f:
+ name = self._sample_path._importer.file_path.rsplit('/', 1)[-1]
+ name = name.split('.', 1)[0]
+ name += '_' + str(self._sample_path._importer.dataset_id())
+ name += '.json'
+ file_name = 'results_' + name
+ with open(file_name, 'w') as f:
json.dump(res, f)
def adjacency_matrix(self) -> np.ndarray:
diff --git a/PyCTBN/PyCTBN/trajectory.py b/PyCTBN/PyCTBN/trajectory.py
index ae3ff93..1254016 100644
--- a/PyCTBN/PyCTBN/trajectory.py
+++ b/PyCTBN/PyCTBN/trajectory.py
@@ -3,9 +3,9 @@ import numpy as np
import typing
-class Trajectory:
- """ Abstracts the infos about a complete set of trajectories, represented as a numpy array of doubles (the time deltas)
- and a numpy matrix of ints (the changes of states).
+class Trajectory(object):
+ """ Abstracts the infos about a complete set of trajectories, represented as a numpy array of doubles
+ (the time deltas) and a numpy matrix of ints (the changes of states).
:param list_of_columns: the list containing the times array and values matrix
:type list_of_columns: List
diff --git a/PyCTBN/tests/coverage.xml b/PyCTBN/tests/coverage.xml
deleted file mode 100644
index cef006f..0000000
--- a/PyCTBN/tests/coverage.xml
+++ /dev/null
@@ -1,963 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/PyCTBN/tests/performance_comparisons.py b/PyCTBN/tests/performance_comparisons.py
index 8185644..622ca20 100644
--- a/PyCTBN/tests/performance_comparisons.py
+++ b/PyCTBN/tests/performance_comparisons.py
@@ -4,6 +4,7 @@ import glob
import numpy as np
import pandas as pd
import timeit
+import psutil
from ..PyCTBN.sample_path import SamplePath
from ..PyCTBN.structure_estimator import StructureEstimator
@@ -23,6 +24,7 @@ class PerformanceComparisons(unittest.TestCase):
cls.original_times = []
cls.optimized_times = []
cls.results = []
+ cls.memory_usages = []
def test_time_comparisons(self):
for file_path in self.read_files:
@@ -48,6 +50,17 @@ class PerformanceComparisons(unittest.TestCase):
self.original_times[:] = []
self.optimized_times[:] = []
+ def test_memory_usage(self):
+ for file_path in self.read_files:
+ self.importer = JsonImporter(file_path, 'samples', 'dyn.str', 'variables', 'Time', 'Name')
+ self.aux_build_importer(0)
+ se1 = StructureEstimator(self.s1, 0.1, 0.1)
+ se1.ctpc_algorithm()
+ current_process = psutil.Process(os.getpid())
+ mem = current_process.memory_info().rss
+ self.memory_usages.append((mem / 10 ** 6))
+ self.save_memory_usage_data(self.memory_usages)
+
def aux_build_importer(self, indx):
self.importer.import_data(indx)
self.s1 = SamplePath(self.importer)
@@ -66,7 +79,17 @@ class PerformanceComparisons(unittest.TestCase):
name = name.split('.', 1)[0]
name = 'execution_times_' + name + '.csv'
path = os.path.abspath('./results/')
- print(path)
+ file_dest = path + '/' + name
+ df_results.to_csv(file_dest, index=False)
+
+ def save_memory_usage_data(self, data):
+ if not os.path.exists('memory_results'):
+ os.makedirs('memory_results')
+ df_results = pd.DataFrame({'memory_usage': data})
+ name = self.importer.file_path.rsplit('/', 1)[-1]
+ name = name.split('.', 1)[0]
+ name = 'memory_usage_' + name + '.csv'
+ path = os.path.abspath('./memory_results/')
file_dest = path + '/' + name
df_results.to_csv(file_dest, index=False)
diff --git a/PyCTBN/tests/test_json_importer.py b/PyCTBN/tests/test_json_importer.py
index 4bbbe6d..2ac1baa 100644
--- a/PyCTBN/tests/test_json_importer.py
+++ b/PyCTBN/tests/test_json_importer.py
@@ -39,20 +39,22 @@ class TestJsonImporter(unittest.TestCase):
path = os.getcwd()
path = path + '/data.json'
j1 = JsonImporter(path, '', '', '', '', '')
- #imported_data = j1.read_json_file()
self.assertTrue(self.ordered(data_set) == self.ordered(j1._raw_data))
os.remove('data.json')
def test_read_json_file_not_found(self):
path = os.getcwd()
path = path + '/data.json'
- #j1 = JsonImporter(path, '', '', '', '', '')
self.assertRaises(FileNotFoundError, JsonImporter, path, '', '', '', '', '')
+ def test_build_sorter(self):
+ j1 = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
+ df_samples_list = j1.normalize_trajectories(j1._raw_data, 0, j1._samples_label)
+ sorter = j1.build_sorter(df_samples_list[0])
+ self.assertListEqual(sorter, list(df_samples_list[0].columns.values)[1:])
+
def test_normalize_trajectories(self):
j1 = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
- #raw_data = j1.read_json_file()
- #print(raw_data)
df_samples_list = j1.normalize_trajectories(j1._raw_data, 0, j1._samples_label)
self.assertEqual(len(df_samples_list), len(j1._raw_data[0][j1._samples_label]))
@@ -66,7 +68,6 @@ class TestJsonImporter(unittest.TestCase):
def test_compute_row_delta_single_samples_frame(self):
j1 = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
- #raw_data = j1.read_json_file()
j1._array_indx = 0
j1._df_samples_list = j1.import_trajectories(j1._raw_data)
sample_frame = j1._df_samples_list[0]
@@ -89,7 +90,6 @@ class TestJsonImporter(unittest.TestCase):
def test_compute_row_delta_in_all_frames(self):
j1 = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
- #raw_data = j1.read_json_file()
j1._array_indx = 0
j1._df_samples_list = j1.import_trajectories(j1._raw_data)
j1._sorter = j1.build_sorter(j1._df_samples_list[0])
@@ -98,9 +98,14 @@ class TestJsonImporter(unittest.TestCase):
list(j1.concatenated_samples.columns.values)[:len(list(j1._df_samples_list[0].columns.values))])
self.assertEqual(list(j1.concatenated_samples.columns.values)[0], j1._time_key)
+ def test_compute_row_delta_in_all_frames_not_init_sorter(self):
+ j1 = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
+ j1._array_indx = 0
+ j1._df_samples_list = j1.import_trajectories(j1._raw_data)
+ self.assertRaises(RuntimeError, j1.compute_row_delta_in_all_samples_frames, j1._df_samples_list)
+
def test_clear_data_frame_list(self):
j1 = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
- #raw_data = j1.read_json_file()
j1._array_indx = 0
j1._df_samples_list = j1.import_trajectories(j1._raw_data)
j1._sorter = j1.build_sorter(j1._df_samples_list[0])
@@ -145,7 +150,6 @@ class TestJsonImporter(unittest.TestCase):
raw_data = [{"dyn.str":[{"From":"X","To":"Z"},{"From":"Y","To":"Z"},{"From":"Z","To":"Y"}]}]
j1._array_indx = 0
df_struct = j1.import_structure(raw_data)
- #print(raw_data[0]['dyn.str'][0].items())
self.assertIsInstance(df_struct, pd.DataFrame)
def test_import_sampled_cims(self):
@@ -155,9 +159,18 @@ class TestJsonImporter(unittest.TestCase):
j1._df_samples_list = j1.import_trajectories(raw_data)
j1._sorter = j1.build_sorter(j1._df_samples_list[0])
cims = j1.import_sampled_cims(raw_data, 0, 'dyn.cims')
- #j1.import_variables(raw_data, j1.sorter)
self.assertEqual(list(cims.keys()), j1.sorter)
+ def test_dataset_id(self):
+ j1 = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
+ array_indx = 0
+ j1.import_data(array_indx)
+ self.assertEqual(array_indx, j1.dataset_id())
+
+ def test_file_path(self):
+ j1 = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
+ self.assertEqual(j1.file_path, self.read_files[0])
+
def test_import_data(self):
j1 = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
j1.import_data(0)
diff --git a/PyCTBN/tests/test_networkgraph.py b/PyCTBN/tests/test_networkgraph.py
index db1f727..f9794a4 100644
--- a/PyCTBN/tests/test_networkgraph.py
+++ b/PyCTBN/tests/test_networkgraph.py
@@ -78,7 +78,8 @@ class TestNetworkGraph(unittest.TestCase):
aggr_info[0], aggr_info[2])
def aux_build_time_scalar_indexing_structure_for_a_node(self, graph, node_id, parents_indxs, parents_labels, parents_vals):
- time_scalar_indexing = graph.build_time_scalar_indexing_structure_for_a_node(node_id, parents_vals)
+ node_states = graph.get_states_number(node_id)
+ time_scalar_indexing = NetworkGraph.build_time_scalar_indexing_structure_for_a_node(node_states, parents_vals)
self.assertEqual(len(time_scalar_indexing), len(parents_indxs) + 1)
merged_list = parents_labels[:]
merged_list.insert(0, node_id)
@@ -100,7 +101,8 @@ class TestNetworkGraph(unittest.TestCase):
def aux_build_transition_scalar_indexing_structure_for_a_node(self, graph, node_id, parents_indxs, parents_labels,
parents_values):
- transition_scalar_indexing = graph.build_transition_scalar_indexing_structure_for_a_node(node_id,
+ node_states = graph.get_states_number(node_id)
+ transition_scalar_indexing = graph.build_transition_scalar_indexing_structure_for_a_node(node_states,
parents_values)
self.assertEqual(len(transition_scalar_indexing), len(parents_indxs) + 2)
merged_list = parents_labels[:]
diff --git a/PyCTBN/tests/test_parameters_estimator.py b/PyCTBN/tests/test_parameters_estimator.py
index 44a9059..38994b9 100644
--- a/PyCTBN/tests/test_parameters_estimator.py
+++ b/PyCTBN/tests/test_parameters_estimator.py
@@ -55,7 +55,7 @@ class TestParametersEstimatior(unittest.TestCase):
def cim_equality_test(self, cim1, cim2):
for r1, r2 in zip(cim1, cim2):
- self.assertTrue(np.all(np.isclose(r1, r2, 1e-01, 1e-01) == True))
+ self.assertTrue(np.all(np.isclose(r1, r2, 1e-01, 1e-01) is True))
def aux_import_sampled_cims(self, cims_label):
i1 = JsonImporter(self.read_files[0], '', '', '', '', '')
diff --git a/PyCTBN/tests/test_sample_path.py b/PyCTBN/tests/test_sample_path.py
index c372781..4286bac 100644
--- a/PyCTBN/tests/test_sample_path.py
+++ b/PyCTBN/tests/test_sample_path.py
@@ -2,6 +2,7 @@
import unittest
import glob
import os
+import random
from ..PyCTBN.json_importer import JsonImporter
from ..PyCTBN.sample_path import SamplePath
@@ -19,6 +20,12 @@ class TestSamplePath(unittest.TestCase):
importer = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
self.assertRaises(RuntimeError, SamplePath, importer)
+ def test_init_not_filled_dataframse(self):
+ importer = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
+ importer.import_data(0)
+ importer.clear_concatenated_frame()
+ self.assertRaises(RuntimeError, SamplePath, importer)
+
def test_init(self):
importer = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
importer.import_data(0)
@@ -43,6 +50,13 @@ class TestSamplePath(unittest.TestCase):
self.assertIsInstance(s1.structure, Structure)
self.assertEqual(s1._total_variables_count, len(s1._importer.sorter))
+ def test_build_structure_bad_sorter(self):
+ importer = JsonImporter(self.read_files[0], 'samples', 'dyn.str', 'variables', 'Time', 'Name')
+ importer.import_data(0)
+ s1 = SamplePath(importer)
+ random.shuffle(importer._sorter)
+ self.assertRaises(RuntimeError, s1.build_structure)
+
if __name__ == '__main__':
unittest.main()
diff --git a/PyCTBN/tests/test_structure_estimator.py b/PyCTBN/tests/test_structure_estimator.py
index fe2e140..e3d63d7 100644
--- a/PyCTBN/tests/test_structure_estimator.py
+++ b/PyCTBN/tests/test_structure_estimator.py
@@ -3,11 +3,9 @@ import glob
import math
import os
import unittest
-
+import json
import networkx as nx
import numpy as np
-import psutil
-from line_profiler import LineProfiler
import timeit
from ..PyCTBN.cache import Cache
@@ -61,8 +59,8 @@ class TestStructureEstimator(unittest.TestCase):
for node in self.s1.structure.nodes_labels:
for b in range(nodes_numb):
- sets = se1.generate_possible_sub_sets_of_size(self.s1.structure.nodes_labels, b, node)
- sets2 = se1.generate_possible_sub_sets_of_size(self.s1.structure.nodes_labels, b, node)
+ sets = StructureEstimator.generate_possible_sub_sets_of_size(self.s1.structure.nodes_labels, b, node)
+ sets2 = StructureEstimator.generate_possible_sub_sets_of_size(self.s1.structure.nodes_labels, b, node)
self.assertEqual(len(list(sets)), math.floor(math.factorial(nodes_numb - 1) /
(math.factorial(b)*math.factorial(nodes_numb -1 - b))))
for sset in sets2:
@@ -70,17 +68,8 @@ class TestStructureEstimator(unittest.TestCase):
def test_time(self):
se1 = StructureEstimator(self.s1, 0.1, 0.1)
- lp = LineProfiler()
- #lp.add_function(se1.complete_test)
- #lp.add_function(se1.one_iteration_of_CTPC_algorithm)
- #lp.add_function(se1.independence_test)
- lp_wrapper = lp(se1.ctpc_algorithm)
- lp_wrapper()
- lp.print_stats()
- #print("Last time", lp.dump_stats())
- #print("Exec Time", timeit.timeit(se1.ctpc_algorithm, number=1))
- print(se1._complete_graph.edges)
- print(self.s1.structure.edges)
+ exec_time = timeit.timeit(se1.ctpc_algorithm, number=1)
+ print("Execution Time: ", exec_time)
for ed in self.s1.structure.edges:
self.assertIn(tuple(ed), se1._complete_graph.edges)
tuples_edges = [tuple(rec) for rec in self.s1.structure.edges]
@@ -89,15 +78,27 @@ class TestStructureEstimator(unittest.TestCase):
if not(ed in tuples_edges):
spurious_edges.append(ed)
print("Spurious Edges:",spurious_edges)
- print("Adj Matrix:", nx.adj_matrix(se1._complete_graph).toarray().astype(bool))
- #se1.save_results()
- def test_memory(self):
+ def test_save_results(self):
+ se1 = StructureEstimator(self.s1, 0.1, 0.1)
+ se1.ctpc_algorithm()
+ se1.save_results()
+ name = self.s1._importer.file_path.rsplit('/', 1)[-1]
+ name = name.split('.', 1)[0]
+ name += '_' + str(self.s1._importer.dataset_id())
+ name += '.json'
+ file_name = 'results_' + name
+ with open(file_name) as f:
+ js_graph = json.load(f)
+ result_graph = nx.json_graph.node_link_graph(js_graph)
+ self.assertFalse(nx.difference(se1._complete_graph, result_graph).edges)
+ os.remove(file_name)
+
+ def test_adjacency_matrix(self):
se1 = StructureEstimator(self.s1, 0.1, 0.1)
se1.ctpc_algorithm()
- current_process = psutil.Process(os.getpid())
- mem = current_process.memory_info().rss
- print("Average Memory Usage in MB:", mem / 10**6)
+ adj_matrix = nx.adj_matrix(se1._complete_graph).toarray().astype(bool)
+ self.assertTrue(np.array_equal(adj_matrix, se1.adjacency_matrix()))
if __name__ == '__main__':
diff --git a/coverage.xml b/coverage.xml
new file mode 100644
index 0000000..81c41d6
--- /dev/null
+++ b/coverage.xml
@@ -0,0 +1,660 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+