Beispiel #1
0
def test_PathCollection_add_path():
    """Add path to the path collection."""
    a = Node('a')
    b = Node('b')
    c = Node('c')
    e = Edge(a, b, uid='e')
    f = Edge(b, c, uid='f')

    p1 = Path(e, f, uid='p1')
    p2 = Path(e, uid='p2')
    p3 = Path(a, uid='p3')

    paths = PathCollection()
    paths.add(p1)

    paths.add(p1)
    assert paths.counter['p1'] == 2

    assert len(paths.nodes) == 2
    # assert len(paths.edges) == 2
    assert len(paths) == 1
    assert p1 in paths

    paths = PathCollection()
    paths.add(p1, p2)

    assert p1 in paths
    assert p2 in paths
Beispiel #2
0
def test_PathCollection_add_edges():
    """Add edge path to the path collection."""
    a = Node('a')
    b = Node('b')
    c = Node('c')
    e = Edge(a, b, uid='e')
    f = Edge(b, c, uid='f')

    paths = PathCollection()
    paths.add(e, f, uid='p1')

    assert len(paths.nodes) == 2
    #     assert len(paths.edges) == 2
    assert len(paths) == 1
    assert 'p1' in paths

    paths.add(e, f, uid='p1')
    assert paths.counter['p1'] == 2

    paths.add(e, f)
    assert paths.counter['p1'] == 3

    with pytest.raises(Exception):
        paths.add(e, f, uid='p2')

    assert paths.counter['p1'] == 3
def test_possible_paths():
    """Test to generate all possible paths."""
    paths = PathCollection()
    paths.add('a', 'a', 'b', 'b', 'a')

    null = NullModel()
    assert len(null.possible_relations(paths, length=3)) == 16
def test_fit_path_collection():
    """Fit PathCollection to a HON"""
    paths = PathCollection()
    paths.add('a', 'c', 'd', uid='acd', frequency=10)
    paths.add('b', 'c', 'e', uid='bce', frequency=10)

    hon = HigherOrderNetwork()
    hon.fit(paths, order=0)

    assert hon.order == 0
    assert hon.number_of_nodes() == 5
    assert hon.number_of_edges() == 0

    hon = HigherOrderNetwork()
    hon.fit(paths, order=1)

    assert hon.order == 1
    assert hon.number_of_nodes() == 5
    assert hon.number_of_edges() == 4

    hon = HigherOrderNetwork()
    hon.fit(paths, order=2)

    assert hon.order == 2
    assert hon.number_of_nodes() == 4
    assert hon.number_of_edges() == 2

    hon = HigherOrderNetwork.from_paths(paths, order=2)

    assert hon.order == 2
    assert hon.number_of_nodes() == 4
    assert hon.number_of_edges() == 2
def test_outdegrees():
    """Fit PathCollection to a HON"""
    paths = PathCollection()
    paths.add('a', 'c', 'd', uid='acd', frequency=10)
    paths.add('b', 'c', 'e', uid='bce', frequency=10)

    hon = HigherOrderNetwork()
    hon.fit(paths, order=2)

    assert sum(hon.outdegrees().values()) == 2
Beispiel #6
0
    def _(self,
          data: Network,
          order: Optional[int] = None,
          subpaths: bool = True) -> None:
        paths = PathCollection(directed=data.directed,
                               multipaths=data.multiedges)
        for edge in data.edges:
            paths.add(*edge, count=data.edges.counter[edge.uid])

        self.fit(paths, order=order)
    def routes_from(self, v, node_mapping=None) -> PathCollection:
        """
        Constructs all paths from node v to any leaf nodes

        Parameters
        ----------
        v:  str
            uid of node from which to start
        node_mapping: dict
            an optional mapping from node to a different set.

        Returns
        -------
        list
            a list of lists, where each list contains one path from the source
            node v until a leaf node is reached
        """

        if node_mapping is None:
            node_mapping = {w.uid: w.uid for w in self.nodes}

        paths = PathCollection()

        # Collect temporary paths, indexed by the target node
        temp_paths = defaultdict(list)
        temp_paths[v] = [[v]]

        # set of unprocessed nodes
        queue = {v}
        # print('Queue = ', queue)

        while queue:
            # take one unprocessed node
            x = queue.pop()
            # print('Dequeued ', x)
            # successors of x expand all temporary
            # paths, currently ending in x
            if len(self.successors[x]) > 0:
                for w in self.successors[x]:
                    for p in temp_paths[x]:
                        temp_paths[w.uid].append(p + [w.uid])
                    # print('Adding ', w.uid)
                    queue.add(w.uid)
                del temp_paths[x]
            #print('Queue = ', queue)

        # flatten list
        for possible_paths in temp_paths.values():
            for path in possible_paths:
                if node_mapping:
                    path = [node_mapping[k] for k in path]
                paths.add(path, count=1, uid='-'.join(path))

        return paths
def test_degrees_of_reedom():
    """Tets degrees of freedom"""
    paths = PathCollection()
    paths.add('a', 'c', 'd', frequency=2)
    paths.add('b', 'c', 'e', frequency=2)

    null = NullModel.from_paths(paths, order=0)
    assert null.degrees_of_freedom() == 4

    null = NullModel.from_paths(paths, order=1)
    assert null.degrees_of_freedom() == 1

    null = NullModel.from_paths(paths, order=2)
    assert null.degrees_of_freedom() == 2

    null = NullModel.from_paths(paths, order=3)
    assert null.degrees_of_freedom() == 0
def test_basic():
    """Test basic functions"""

    paths = PathCollection()
    paths.add('a', 'c', 'd', uid='a-c-d', count=10)
    paths.add('b', 'c', 'e', uid='b-c-e', count=10)

    null = NullModel()
    null.fit(paths, order=2)

    # null = NullModel.from_paths(paths, order=2)

    assert null.number_of_edges() == 4
    assert null.number_of_nodes() == 4

    for e in null.edges.uids:
        assert null.edges.counter[e] == 5.0
Beispiel #10
0
    def _(self,
          data: PathCollection,
          order: Optional[int] = None,
          subpaths: bool = True) -> None:

        # update
        if order is not None:
            self._order = order

        # iterate over all paths
        for uid, path in tqdm(data.items(), desc='convert paths to hon'):

            # generate subpaths of order-1 for higher-order nodes
            nodes = path.subpaths(min_length=self.order - 1,
                                  max_length=self.order - 1,
                                  include_self=True,
                                  paths=False)
            # add higher-order nodes to the network
            for node in nodes:
                if node not in self.nodes:
                    self.add_node(*node, uid='-'.join(node), count=0)
                self.nodes.counter[self.nodes[node].uid] += data.counter[uid]

            # do not create edges if order is 0
            nodes = nodes if self.order > 0 else []

            # generat higher-order edges
            for _v, _w in zip(nodes[:-1], nodes[1:]):
                _v, _w = self.nodes[_v], self.nodes[_w]

                # check if edge exist otherwise add new edge
                if (_v, _w) not in self.edges:
                    self.add_edge(_v, _w, count=0)

                # get edge and update counters
                edge = self.edges[_v, _w]
                self.edges.counter[edge.uid] += data.counter[uid]

                if order == len(path):
                    self._observed[
                        edge.first_order_relations] += data.counter[uid]
                else:
                    self._subpaths[
                        edge.first_order_relations] += data.counter[uid]

        # calculate frequencies for a zero-order network
        if self.order == 0:
            total = sum(self.nodes.counter.values())
            for key, value in self.nodes.counter.items():
                self.nodes.counter[key] = value / total

        # create all possible higher-order nodes
        if subpaths and self.order > 1:
            for node in self.possible_relations(data, self.order - 1):
                if node not in self.nodes:
                    self.add_node(*node, count=0)
Beispiel #11
0
    def __init__(self, paths: Optional[PathCollection] = None) -> None:
        """Initialize sub-paths object."""

        # check if inital paths are given
        if isinstance(paths, PathCollection):
            self._paths = paths
        else:
            self._paths = PathCollection()

        # initialize the base class
        super().__init__(directed=self._paths.directed,
                         multiedges=self._paths.multiedges,
                         multipaths=self._paths.multipaths,
                         nodes=self._paths.nodes,
                         edges=self._paths.edges)

        # initialize counters
        self._counter: Counter = Counter()
        self._observed: defaultdict = defaultdict(Counter)
        self._possible: defaultdict = defaultdict(Counter)
Beispiel #12
0
    def _(self, data: Network, order: Optional[int] = None) -> None:

        # Check order
        if order is not None:
            self._order = order

        if 0 <= self.order <= 1:
            super().fit(data, order=self.order)

        elif self.order > 1:

            # TODO: create function to transfer base data from PathCollection object
            # --- START ---
            nc = NodeCollection()
            for node in data.nodes.values():
                nc.add(node)

            ec = EdgeCollection(nodes=nc)
            for edge in data.edges.values():
                ec.add(edge)

            self._nodes = HigherOrderNodeCollection(nodes=nc, edges=ec)
            # --- END ---

            # get network data
            network = data

            # generate a path representation of the data
            paths = PathCollection(directed=network.directed,
                                   nodes=network.nodes,
                                   edges=network.edges)
            for edge in data.edges:
                paths.add(edge, frequency=edge.attributes.get('frequency', 1))

            self.calculate(network, paths)

        else:
            LOG.error('A Null Model with order %s is not supported',
                      self.order)
            raise AttributeError
Beispiel #13
0
def _temp(self, **kwargs):
    """Convert a temproal netwok to paths."""
    from pathpy.models.directed_acyclic_graph import DirectedAcyclicGraph

    #paths = PathCollection(edges=self.edges.copy())
    paths = PathCollection()

    delta = kwargs.get('delta', 1)
    # generate a single time-unfolded DAG
    dag = DirectedAcyclicGraph.from_temporal_network(self, delta=delta)

    for root in dag.roots:
        causal_tree = _causal_tree(dag, root)

        _paths = causal_tree.to_paths()

        for path in _paths:
            edges = [e['original'] for e in path.edges]
            if edges not in paths:
                paths.add(*edges, frequency=1)
            else:
                paths[edges]['frequency'] += 1
    return paths
Beispiel #14
0
def test_PathCollection_add_str():
    """Add string path to the path collection."""

    paths = PathCollection()
    paths.add('a', 'b', 'c', uid='p1')

    assert len(paths.nodes) == 3
    # assert len(paths.edges) == 2
    assert len(paths) == 1
    assert 'p1' in paths

    paths.add('a', 'b', 'c', uid='p1')
    assert paths.counter['p1'] == 2

    paths.add('a', 'b', 'c')
    assert paths.counter['p1'] == 3
Beispiel #15
0
def _dag(self, **kwargs):
    """Convert a DAG to paths."""

    # check if dag is acyclic
    if self.acyclic is None:
        self.topological_sorting()

    if not self.acyclic:
        LOG.error('Cannot extract statistics from a cyclic graph')
        raise ValueError

    paths = PathCollection(edges=self.edges.copy())

    for root in self.roots:
        paths = self.routes_from(root, paths)

    return paths
Beispiel #16
0
def test_PathCollection_add_tuple():
    """Add path tuple to the path collection."""

    paths = PathCollection()
    paths.add(('a', 'b'), ('a', 'b', 'c'))

    assert len(paths.nodes) == 3
    # assert len(paths.edges) == 2
    assert len(paths) == 2

    paths.add('a', 'b', 'c')
    assert paths.counter[paths['a', 'b', 'c'].uid] == 2
Beispiel #17
0
def test_PathCollection_add_nodes():
    """Add node path to the path collection."""
    a = Node('a')
    b = Node('b')
    c = Node('c')

    paths = PathCollection()
    paths.add(a, b, c, uid='p1')

    assert len(paths.nodes) == 3
    # assert len(paths.edges) == 2
    assert len(paths) == 1
    assert 'p1' in paths

    paths.add(a, b, c, uid='p1')
    assert paths.counter['p1'] == 2

    paths.add(a, b, c)
    assert paths.counter['p1'] == 3
Beispiel #18
0
    def likelihood(self, data: PathCollection, log: bool = False) -> float:
        """Returns the likelihood given some observation data."""

        # some information for debugging
        LOG.debug('I\'m a likelihood of a HigherOrderNetwork')

        # get a list of nodes for the matrix indices
        idx = self.nodes.index

        # get the transition matrix
        matrix = transition_matrix(self, count=True, transposed=True)

        # initialize likelihood
        likelihood, _path_likelihood = (0, 0)

        # iterate over observed hon paths
        for uid, path in data.items():

            # get frequency of the observed path
            frequency = data.counter[uid]

            # initial path likelihood
            path_likelihood = _path_likelihood

            # generate subpaths of order-1 for higher-order nodes
            nodes = path.subpaths(min_length=self.order - 1,
                                  max_length=self.order - 1,
                                  include_self=True,
                                  paths=False)

            for _v, _w in zip(nodes[:-1], nodes[1:]):
                path_likelihood += np.log(matrix[idx[self.nodes[_w].uid],
                                                 idx[self.nodes[_v].uid]])

            likelihood += path_likelihood * frequency

        return likelihood if log else np.exp(likelihood)
Beispiel #19
0
def test_PathCollection_remove_path():
    """Remove path from the path collection."""
    a = Node('a')
    b = Node('b')
    c = Node('c')
    e = Edge(a, b, uid='e')
    f = Edge(b, c, uid='f')

    p1 = Path(e, f, uid='p1')
    p2 = Path(e, uid='p2')
    p3 = Path(a, uid='p3')

    paths = PathCollection()
    paths.add(p1)

    paths.remove(p1)

    assert len(paths.nodes) == 0
    # assert len(paths.edges) == 2
    assert len(paths) == 0
    assert p1 not in paths
Beispiel #20
0
class SubPathCollection(PathCollection):
    """Class for sub-path statistics."""
    def __init__(self, paths: Optional[PathCollection] = None) -> None:
        """Initialize sub-paths object."""

        # check if inital paths are given
        if isinstance(paths, PathCollection):
            self._paths = paths
        else:
            self._paths = PathCollection()

        # initialize the base class
        super().__init__(directed=self._paths.directed,
                         multiedges=self._paths.multiedges,
                         multipaths=self._paths.multipaths,
                         nodes=self._paths.nodes,
                         edges=self._paths.edges)

        # initialize counters
        self._counter: Counter = Counter()
        self._observed: defaultdict = defaultdict(Counter)
        self._possible: defaultdict = defaultdict(Counter)

    def __call__(self,
                 min_length: int = 0,
                 max_length: int = sys.maxsize,
                 include_path: bool = False,
                 recalculate: bool = False) -> SubPathCollection:
        """Returns a sub-pahts"""
        if len(self) == 0 or recalculate:
            self.calculate(min_length=min_length,
                           max_length=max_length,
                           include_path=include_path)
        return self

    def __str__(self) -> str:
        """Print a summary of the sub-paths."""
        return self.summary()

    @property
    def observed(self) -> defaultdict:
        """Returns observed paths as a dict of counters."""
        return self._observed

    @property
    def possible(self) -> defaultdict:
        """Returns possible paths as a dict of counters."""
        return self._possible

    @property
    def counter(self) -> Counter:
        """Returns a subpath counter"""
        return self._counter

    def calculate(self,
                  min_length: int = 0,
                  max_length: int = sys.maxsize,
                  include_path: bool = False) -> None:
        """Helper function to calculate subpaths."""

        if len(self) > 0:
            LOG.warning('Recalculating sub-paths!')
        # get the default max and min path lengths
        _min_length: int = min_length
        _max_length: int = max_length

        # iterrate over all paths
        for path in tqdm(self._paths.values(), desc='sub-path calculation'):

            # number of counted paths
            frequency = path.attributes.get('frequency', 1)

            # if min_length is zero, account also for nodes
            if _min_length <= 0:
                for node in path.nodes:
                    if (node, ) not in self:
                        self._add(Path(node, possible=frequency, frequency=0))
                    else:
                        self[(node, )]['possible'] += frequency

            # get min and max length
            min_length = max(_min_length, 1)
            max_length = min(len(path) - 1, _max_length)

            # get subpaths
            for i in range(min_length - 1, max_length):
                for j in range(len(path) - i):
                    edges = tuple(path.edges[j:j + i + 1])
                    if edges not in self:
                        self._add(Path(*edges, possible=frequency,
                                       frequency=0))
                    else:
                        # TODO: fix the frequency assignment
                        if self[edges]['possible'] is None:
                            self[edges]['possible'] = 0
                        self[edges]['possible'] += frequency

            # include the path
            if include_path:
                if path not in self and _min_length <= len(
                        path) <= _max_length:
                    path['possible'] = 0
                    self._add(path)

        for path in self:
            self._observed[len(path)][path] += path['frequency'] or 0
            self._possible[len(path)][path] += path['possible'] or 0
            self._counter[path] += path['frequency'] or 0
            self._counter[path] += path['possible'] or 0

    def summary(self) -> str:
        """Returns a summary of the sub path statistic.

        Returns
        -------
        str
            Retruns a summary of the sub path statistics.

        """

        # check if sub path statistic is already calculated
        if len(self) == 0:
            return super().__str__()

        # initialize a data storage
        counter: Counter = Counter()

        # get max order
        max_order_obs = max(self.observed.keys())
        max_order_pos = max(self.possible.keys())
        max_order = max(max_order_obs, max_order_pos)

        # get data of observed paths
        for order in range(max_order_obs + 1):
            counter[order] = int(sum(self.observed[order].values()))

        data: list = list(counter.elements())

        # TODO: Find better solution for printing
        # TODO: Move to util
        line_length = 54
        row = {}
        row['==='] = '=' * line_length
        row['sf'] = '{:<25s}{:>15.3f}'
        row['s|sss|ss'] = '{:^6s} | {:^9s} {:^9s} {:^9s} | {:^6s} {:^6s}'
        row['-|---|--'] = '{:->6s} | {:->9s} {:->9s} {:->9s} | {:->6s} {:->6s}'
        row['d|ddd|dd'] = '{:>6d} | {:>9d} {:>9d} {:>9d} | {:>6d} {:>6d}'
        row['f|fff|ff'] = '{:>6.0f} | {:>9.0f} {:>9.0f} {:>9.0f} | {:>6.0f} {:>6.0f}'
        row['s| s | s'] = '{:^6s} | {:^29s} | {:^13s}'

        # initialize summary text
        summary: list = [
            row['==='],
            'Sub path statistics',
        ]

        if data:
            # add general statistics
            lines: list = [['- General '],
                           ['Number of unique nodes:',
                            len(self.nodes)],
                           ['Number of unique edges:',
                            len(self.edges)],
                           ['Number of unique paths:',
                            len(self._paths)], ['- Path statistics '],
                           ['Mean path length:',
                            np.mean(data)],
                           ['Standard derivation:',
                            np.std(data)], ['Min. path length:',
                                            np.min(data)],
                           ['25% quantile:',
                            np.quantile(data, 0.25)],
                           ['50% quantile:',
                            np.quantile(data, 0.50)],
                           ['75% quantile:',
                            np.quantile(data, 0.75)],
                           ['Max. path length:',
                            np.max(data)], ['- Sub path statistics ']]

            for line in lines:
                if len(line) == 1:
                    summary.append('{}'.format(line[0]).ljust(
                        line_length, '-'))
                else:
                    summary.append(row['sf'].format(line[0], line[1]))

        # add sub path statistics
        # add headings
        summary.append(row['s| s | s'].format('path', 'frequencies', 'unique'))
        summary.append(row['s|sss|ss'].format('length', 'obs', 'pos', 'tot',
                                              'obs', 'pos'))

        # add line
        summary.append(row['-|---|--'].format('', '', '', '', '', ''))

        # add row for each order
        data: list = [[], [], [], [], []]
        for order in range(max_order + 1):

            data[0].append(sum(self.observed[order].values()))
            data[1].append(sum(self.possible[order].values()))
            data[2].append(data[0][-1] + data[1][-1])
            data[3].append(
                np.count_nonzero(list(self.observed[order].values())))
            data[4].append(
                np.count_nonzero(list(self.possible[order].values())))

            summary.append(row['f|fff|ff'].format(order,
                                                  *[v[-1] for v in data]))

        # add line
        summary.append(row['-|---|--'].format('', '', '', '', '', ''))

        # add column sums
        summary.append(row['f|fff|ff'].format(order, *[sum(v) for v in data]))

        # add legend
        summary.append('obs ... observed paths (in the network)')
        summary.append('pos ... possible paths (but not observed)')
        summary.append('tot ... total number of paths')

        # add double line
        summary.append('=' * line_length, )

        # # if logging is enabled print summary as INFO log
        # # TODO: Move this code to a helper function
        return '\n'.join(summary)

    @classmethod
    def from_paths(cls,
                   paths: PathCollection,
                   min_length: int = 0,
                   max_length: int = sys.maxsize,
                   include_path: bool = False) -> SubPathCollection:
        """Create sub-paths statistic from a path collection object."""
        subpaths = cls(paths)
        subpaths.calculate(min_length=min_length,
                           max_length=max_length,
                           include_path=include_path)
        return subpaths
Beispiel #21
0
def read_pathcollection(filename: str,
                        separator: str = ',',
                        frequency: bool = False,
                        directed: bool = True,
                        maxlines: int = None) -> PathCollection:
    """Read path in edgelist format

    Reads data from a file containing multiple lines of *edges* of the form
    "v,w,frequency,X" (where frequency is optional and X are arbitrary
    additional columns). The default separating character ',' can be changed.

    Parameters
    ----------
    filename : str
        path to edgelist file
    separator : str
        character separating the nodes
    frequency : bool
        is a frequency given? if ``True`` it is the last element in the
        edge (i.e. ``a,b,2``)
    directed : bool
        are the edges directed or undirected
    maxlines : int
        number of lines to read (useful to test large files).
        None means the entire file is read

    """

    from pathpy.core.path import Path, PathCollection

    nodes: dict = {}
    edges: dict = {}
    paths: dict = {}

    with open(filename, 'r') as csv:
        for n, line in enumerate(csv):
            fields = line.rstrip().split(separator)
            assert len(fields) >= 1, 'Error: empty line: {0}'.format(line)

            if frequency:
                path = tuple(fields[:-1])
                freq = float(fields[-1])
            else:
                path = tuple(fields)
                freq = 1.0

            for node in path:
                if node not in nodes:
                    nodes[node] = Node(node)

            if len(path) == 1 and path not in paths:
                paths[path] = Path(nodes[path[0]], frequency=freq)

            else:
                edge_list = []
                for u, v in zip(path[:-1], path[1:]):
                    if (u, v) not in edges:
                        edges[(u, v)] = Edge(nodes[u], nodes[v])
                    edge_list.append(edges[(u, v)])

                if path not in paths:
                    paths[path] = Path(*edge_list, frequency=freq)

            if maxlines is not None and n >= maxlines:
                break

    ncoll = NodeCollection()
    for node in nodes.values():
        ncoll.add(node)

    ecoll = EdgeCollection(nodes=ncoll)
    for edge in edges.values():
        ecoll._add(edge)

    _paths = PathCollection(directed=directed, nodes=ncoll, edges=ecoll)

    for _path in paths.values():
        _paths._add(_path)

    return _paths
Beispiel #22
0
def test_fit_path_collection():
    """Fit PathCollection to a HON"""
    paths = PathCollection()
    a = Node('a')
    b = Node('b')
    c = Node('c')
    d = Node('d')
    e = Node('e')
    # paths.add(a, c, d, uid='acd', frequency=10)
    # paths.add(b, c, e, uid='bce', frequency=10)
    paths.add('a', c, 'd', 'f', uid='acd', count=10)
    paths.add('b', c, 'e', 'g', uid='bce', count=10)

    # paths.add('a', 'c', 'd', uid='acd', frequency=10)
    # paths.add('b', 'c', 'e', uid='bce', frequency=10)

    # print(paths.counter)
    # hon = HigherOrderNetwork()
    # hon.fit(paths, order=3)

    # print(hon.nodes['xxx'].objects)
    # print(hon.nodes.counter)
    # for e in hon.edges:
    #     print(e.first_order_relations)
    #     print()
    #     break

    paths = PathCollection()
    paths.add('a', 'c', 'b', uid='acb', count=10)
    paths.add('c', 'b', 'a', 'c', uid='cba', count=20)
    paths.add('a', 'b', 'a', 'c', uid='abac', count=30)
    # paths.add(a, 'b', 'c', 'd', 'e', 'f', uid='p1')
    # paths.add(a, 'b', 'c', 'd', 'e', 'x')
    hon = HigherOrderNetwork(uid='hon')
    hon.fit(paths, order=1)

    print(hon)

    # for n in hon.nodes:
    #     print((n, hon.indegrees()[n.uid], hon.outdegrees()[n.uid]))
    ##p = paths['p1'].subpaths(min_length=0, max_length=None, paths=True)
    # # print(paths)
    # print(hon.observed)
    # print(hon.subpaths)
    # print(hon.edges.counter)

    print('no log', hon.likelihood(paths, log=False))
    print('log', hon.likelihood(paths, log=True))
    import numpy as np
    print(np.exp(hon.likelihood(paths, log=True)))
Beispiel #23
0
def test_PathCollection():
    """Test the paths object"""
    a = Node('a')
    b = Node('b')
    c = Node('c')
    e = Edge(a, b, uid='e')
    f = Edge(b, c, uid='f')

    p1 = Path(e, f, uid='p1')
    p2 = Path(e, uid='p2')
    p3 = Path(a, uid='p3')

    paths = PathCollection()
    paths.add(p1)
    paths.add(p2)
    paths.add(p3)

    with pytest.raises(Exception):
        paths.add(p1)

    assert len(paths.nodes) == 3
    assert len(paths.edges) == 2
    assert len(paths) == 3
    assert p1 in paths
    assert p2 in paths
    assert p3 in paths

    assert 'p1' in paths
    assert 'p2' in paths
    assert 'p3' in paths

    assert (e, f) in paths
    assert ('e', 'f') in paths
    assert [e] in paths
    assert ['e'] in paths

    assert (a, b, c) in paths
    assert ('a', 'b', 'c') in paths
    assert (a, b) in paths
    assert ('a', 'b') in paths

    assert (a, ) in paths
    assert ('a', ) in paths
    assert [a] in paths
    assert ['a'] in paths

    # print(paths['p1'] == p1)
    #print(paths[p1] == p1)

    assert paths['a', 'b', 'c'] == p1
    assert paths['e', 'f'] == p1

    with pytest.raises(Exception):
        p = paths['x', 'y']

    g = Edge(b, c, uid='a')
    p4 = Path(g, uid='p4')
    paths.add(p4)

    # issue warning
    assert ['a'] in paths

    paths = PathCollection()
    paths.add(a, b)

    with pytest.raises(Exception):
        paths.add(a, b)

    paths = PathCollection()
    paths.add('a', 'b', 'c', uid='a-b-c')

    assert len(paths) == 1
    assert 'a-b-c' in paths
    assert 'a' and 'b' and 'c' in paths.nodes
    assert ('a', 'b') and ('b', 'c') in paths.edges

    paths = PathCollection()
    paths.add(p1, p2)

    assert len(paths) == 2

    paths = PathCollection()
    paths.add(('a', 'b', 'c'), ('a', 'b'))

    assert len(paths.nodes) == 3
    assert len(paths.edges) == 2
    assert len(paths) == 2

    paths = PathCollection()
    paths.add(e, f, uid='p1')

    assert len(paths) == 1
    assert len(paths.edges) == 2
    assert len(paths.nodes) == 3

    assert (e, f) in paths
    assert ('a', 'b', 'c') in paths

    with pytest.raises(Exception):
        paths.add(f, e, uid='p2')

    paths = PathCollection()
    paths.add('e1', uid='p1', nodes=False)

    assert len(paths) == 1
    assert len(paths.edges) == 1
    assert len(paths.nodes) == 2
    assert 'p1' in paths
    assert 'e1' in paths.edges

    paths = PathCollection()
    paths.add('e1', 'e2', uid='p1', nodes=False)

    assert len(paths) == 1
    assert len(paths.edges) == 2
    assert len(paths.nodes) == 3
    assert 'p1' in paths
    assert 'e1' and 'e2' in paths.edges

    assert paths.edges['e1'].w == paths.edges['e2'].v

    paths = PathCollection()
    paths.add(('e1', 'e2'), ('e3', 'e4'), nodes=False)

    assert len(paths.nodes) == 6
    assert len(paths.edges) == 4
    assert len(paths) == 2

    paths = PathCollection()
    paths.add(p1, p2, p3)

    assert len(paths.nodes) == 3
    assert len(paths.edges) == 2
    assert len(paths) == 3

    paths.remove(p3)
    assert len(paths.nodes) == 3
    assert len(paths.edges) == 2
    assert len(paths) == 2
    assert p3 not in paths

    paths.remove('p1')
    assert len(paths.nodes) == 3
    assert len(paths.edges) == 2
    assert len(paths) == 1
    assert p1 not in paths

    paths = PathCollection()
    paths.add(('a', 'b', 'c'), ('a', 'b'))

    assert len(paths) == 2

    paths.remove('a', 'b')

    assert len(paths) == 1

    paths = PathCollection()
    paths.add(('a', 'b'), ('b', 'c'), ('c', 'd'))
    paths.remove(('a', 'b'), ('b', 'c'))

    assert len(paths) == 1
    assert ('a', 'b') not in paths
    assert ('b', 'c') not in paths
    assert ('c', 'd') in paths

    paths = PathCollection()
    paths.add(('e1', 'e2'), ('e2', 'e3'), ('e3', 'e4'), nodes=False)

    assert len(paths) == 3
    assert len(paths.edges) == 4

    paths.remove('e1', 'e2')
    assert len(paths) == 2

    paths.remove(('e2', 'e3'), ('e3', 'e4'))
    assert len(paths) == 0

    paths = PathCollection()
    paths.add('a', 'b', uid='p1')
    paths.add('b', 'c', uid='p2')
    paths.add('c', 'd', uid='p3')
    paths.add('d', 'e', uid='p4')

    assert len(paths) == 4

    paths.remove('p1')

    assert len(paths) == 3

    paths.remove('p2', 'p3')

    assert len(paths) == 1
Beispiel #24
0
def test_PathCollection_counter():
    """Test the counter of the path collection"""
    paths = PathCollection()
    paths.add('a', 'b', count=5)
    paths.add('a', 'b', count=7)
    assert paths.counter[paths['a', 'b'].uid] == 12

    p1 = Path('a', 'x', 'c', uid='a-x-c')
    p2 = Path('b', 'x', 'd', uid='b-x-d')
    pc = PathCollection(multipaths=True)
    pc.add(p1)
    pc.add(p2)
    pc.add(p2)

    assert 'a-x-c' and 'b-x-d' in pc.counter

    p3 = Path('b', 'x', 'd', uid='b-x-d-2')
    pc.add(p3)

    assert 'a-x-c' and 'b-x-d' and 'b-x-d-2' in pc.counter
Beispiel #25
0
def test_PathCollection():
    """Test the paths object"""
    a = Node('a')
    b = Node('b')
    c = Node('c')
    e = Edge(a, b, uid='e')
    f = Edge(b, c, uid='f')

    p1 = Path(e, f, uid='p1')
    p2 = Path(e, uid='p2')
    p3 = Path(a, uid='p3')

    paths = PathCollection()
    paths.add(p1)
    paths.add(p2)
    paths.add(p3)

    paths.add(p1)
    assert paths.counter['p1'] == 2

    assert len(paths.nodes) == 3
    # assert len(paths.edges) == 2
    assert len(paths) == 3
    assert p1 in paths
    assert p2 in paths
    assert p3 in paths

    assert 'p1' in paths
    assert 'p2' in paths
    assert 'p3' in paths

    assert (e, f) in paths
    assert ('e', 'f') in paths
    assert (e, ) in paths
    assert ('e', ) in paths
    assert (a, ) in paths
    assert ('a', ) in paths

    a = Node('a')
    b = Node('b')
    c = Node('c')

    p1 = Path(a, b, c, uid='p1')
    p2 = Path(a, b, uid='p2')
    p3 = Path(a, uid='p3')

    paths = PathCollection()
    paths.add(p1)
    paths.add(p2)
    paths.add(p3)

    assert (a, b, c) in paths
    assert ('a', 'b', 'c') in paths
    assert (a, b) in paths
    assert ('a', 'b') in paths

    assert (a, ) in paths
    assert ('a', ) in paths
    # assert [a] in paths
    # assert ['a'] in paths

    assert paths['a', 'b', 'c'] == p1
    assert paths['a', 'b'] == p2

    with pytest.raises(Exception):
        p = paths['x', 'y']

    p4 = Path(b, c, uid='p4')
    # with pytest.raises(Exception):
    paths.add(p4)
    assert paths.counter['p4'] == 1

    paths = PathCollection()
    paths.add(a, b)

    # with pytest.raises(Exception):
    paths.add(a, b)
    assert paths.counter[paths['a', 'b'].uid] == 2

    paths = PathCollection()
    paths.add('a', 'b', 'c', uid='a-b-c')

    assert len(paths) == 1
    assert 'a-b-c' in paths
    assert 'a' and 'b' and 'c' in paths.nodes

    paths = PathCollection()
    paths.add(p1, p2)

    assert len(paths) == 2

    paths = PathCollection()
    paths.add(('a', 'b', 'c'), ('a', 'b'))

    assert len(paths.nodes) == 3
    #assert len(paths.edges) == 2
    assert len(paths) == 2

    paths = PathCollection()
    paths.add(e, f, uid='p1')

    assert len(paths) == 1
    #assert len(paths.edges) == 2
    assert len(paths.nodes) == 2

    assert (e, f) in paths
    #assert ('a', 'b', 'c') in paths

    # with pytest.raises(Exception):
    paths.add(f, e, uid='p2')

    #     paths = PathCollection()
    #     paths.add('e1', uid='p1', nodes=False)

    #     assert len(paths) == 1
    #     assert len(paths.edges) == 1
    #     assert len(paths.nodes) == 2
    #     assert 'p1' in paths
    #     assert 'e1' in paths.edges

    #     paths = PathCollection()
    #     paths.add('e1', 'e2', uid='p1', nodes=False)

    #     assert len(paths) == 1
    #     assert len(paths.edges) == 2
    #     assert len(paths.nodes) == 3
    #     assert 'p1' in paths
    #     assert 'e1' and 'e2' in paths.edges

    #     assert paths.edges['e1'].w == paths.edges['e2'].v

    #     paths = PathCollection()
    #     paths.add(('e1', 'e2'), ('e3', 'e4'), nodes=False)

    #     assert len(paths.nodes) == 6
    #     assert len(paths.edges) == 4
    #     assert len(paths) == 2

    paths = PathCollection()
    paths.add(p1, p2, p3)

    assert len(paths.nodes) == 3
    assert len(paths) == 3

    paths.remove(p3)
    assert len(paths.nodes) == 3
    #assert len(paths.edges) == 2
    assert len(paths) == 2
    assert p3 not in paths

    paths.remove('p1')
    assert len(paths.nodes) == 2
    #assert len(paths.edges) == 2
    assert len(paths) == 1
    assert p1 not in paths

    paths = PathCollection()
    paths.add(('a', 'b', 'c'), ('a', 'b'))

    assert len(paths) == 2

    paths.remove('a', 'b')

    assert len(paths) == 1

    paths = PathCollection()
    paths.add(('a', 'b'), ('b', 'c'), ('c', 'd'))
    paths.remove(('a', 'b'), ('b', 'c'))

    assert len(paths) == 1
    assert ('a', 'b') not in paths
    assert ('b', 'c') not in paths
    assert ('c', 'd') in paths

    #     paths = PathCollection()
    #     paths.add(('e1', 'e2'), ('e2', 'e3'), ('e3', 'e4'), nodes=False)

    #     assert len(paths) == 3
    #     assert len(paths.edges) == 4

    #     paths.remove('e1', 'e2')
    #     assert len(paths) == 2

    #     paths.remove(('e2', 'e3'), ('e3', 'e4'))
    #     assert len(paths) == 0

    paths = PathCollection()
    paths.add('a', 'b', uid='p1')
    paths.add('b', 'c', uid='p2')
    paths.add('c', 'd', uid='p3')
    paths.add('d', 'e', uid='p4')

    assert len(paths) == 4

    paths.remove('p1')

    assert len(paths) == 3

    paths.remove(('p2', 'p3'))
Beispiel #26
0
def test_PathCollection_remove_edges():
    """Remove edge path from the path collection."""
    a = Node('a')
    b = Node('b')
    c = Node('c')
    e = Edge(a, b, uid='e')
    f = Edge(b, c, uid='f')

    paths = PathCollection()
    paths.add(e, f, uid='p1')

    paths.remove(e, f)
    assert len(paths) == 0
    assert 'p1' not in paths

    paths.add(e, f, uid='p1')
    paths.remove('p1')
    assert len(paths) == 0

    paths.add(e, f, uid='p1')
    paths.remove(e, f)
    assert len(paths) == 0

    paths.add(e, f, uid='p1')
    paths.remove('e', 'f')
    assert len(paths) == 0
Beispiel #27
0
def test_possible_paths():
    """Test to generate all possible paths."""
    paths = PathCollection()
    paths.add('a', 'a', 'b', 'b', 'a')

    assert len(NullModel.possible_paths(paths.edges, order=3)) == 16