File: test_random.py

package info (click to toggle)
pybel 0.15.5-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 16,492 kB
  • sloc: python: 29,392; javascript: 246; makefile: 226; sh: 20
file content (138 lines) | stat: -rw-r--r-- 4,764 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# -*- coding: utf-8 -*-

"""Test for functions for inducing random sub-graphs."""

import random
import sys
import unittest
from collections import Counter

import networkx as nx

from pybel.examples import sialic_acid_graph, statin_graph
from pybel.struct.mutation.induction.paths import get_random_path
from pybel.struct.mutation.induction.random_subgraph import (
    _helper,
    get_graph_with_random_edges,
    get_random_node,
    get_random_subgraph,
)
from pybel.testing.generate import generate_random_graph


@unittest.skipIf(sys.version_info < (3,), "Will not support random operations on python2")
class TestRandom(unittest.TestCase):
    """Test random graph induction functions."""

    def setUp(self):
        """Set the random seed before each test."""
        random.seed(125)  # love that number

    def test_random_edges(self):
        """Test getting a graph by random edges."""
        n_nodes, n_edges, n_sample_edges = 15, 80, 40
        graph = generate_random_graph(n_nodes=n_nodes, n_edges=n_edges)

        subgraph = get_graph_with_random_edges(graph, n_edges=n_sample_edges)
        self.assertEqual(n_sample_edges, subgraph.number_of_edges())

    def test_random_nodes(self):
        """Test getting random nodes."""
        graph = nx.MultiDiGraph()

        graph.add_edge(1, 2)
        graph.add_edge(1, 3)
        graph.add_edge(1, 4)
        graph.add_edge(1, 5)

        n = 30000
        r = Counter(get_random_node(graph, set(), invert_degrees=False) for _ in range(n))

        degree_sum = 4 + 1 + 1 + 1 + 1

        self.assertAlmostEqual(4 / degree_sum, r[1] / n, places=2)
        self.assertAlmostEqual(1 / degree_sum, r[2] / n, places=2)
        self.assertAlmostEqual(1 / degree_sum, r[3] / n, places=2)
        self.assertAlmostEqual(1 / degree_sum, r[4] / n, places=2)
        self.assertAlmostEqual(1 / degree_sum, r[5] / n, places=2)

    def test_random_nodes_inverted(self):
        """Test getting random nodes."""
        graph = nx.MultiDiGraph()

        graph.add_edge(1, 2)
        graph.add_edge(1, 3)
        graph.add_edge(1, 4)
        graph.add_edge(1, 5)

        n = 30000
        r = Counter(get_random_node(graph, set(), invert_degrees=True) for _ in range(n))

        degree_sum = (1 / 4) + (1 / 1) + (1 / 1) + (1 / 1) + (1 / 1)

        self.assertAlmostEqual((1 / 4) / degree_sum, r[1] / n, places=2)
        self.assertAlmostEqual((1 / 1) / degree_sum, r[2] / n, places=2)
        self.assertAlmostEqual((1 / 1) / degree_sum, r[3] / n, places=2)
        self.assertAlmostEqual((1 / 1) / degree_sum, r[4] / n, places=2)
        self.assertAlmostEqual((1 / 1) / degree_sum, r[5] / n, places=2)

    def test_random_sample(self):
        """Test randomly sampling a graph."""
        n_nodes, n_edges = 50, 500
        graph = generate_random_graph(n_nodes=n_nodes, n_edges=n_edges)

        self.assertEqual(n_edges, graph.number_of_edges())

        sg_1 = get_random_subgraph(graph, number_edges=250, number_seed_edges=10, invert_degrees=False)
        self.assertEqual(250, sg_1.number_of_edges())

        sg_2 = get_random_subgraph(graph, number_edges=250, number_seed_edges=10, invert_degrees=True)
        self.assertEqual(250, sg_2.number_of_edges())

    def test_random_sample_small(self):
        """Test a graph that is too small to sample."""
        n_nodes, n_edges = 11, 25
        graph = generate_random_graph(n_nodes, n_edges)

        self.assertEqual(n_edges, graph.number_of_edges())

        sg_1 = get_random_subgraph(graph, number_edges=250, number_seed_edges=5, invert_degrees=False)
        self.assertEqual(
            graph.number_of_edges(),
            sg_1.number_of_edges(),
            msg="since graph is too small, the subgraph should contain the whole thing",
        )

        sg_2 = get_random_subgraph(graph, number_edges=250, number_seed_edges=5, invert_degrees=True)
        self.assertEqual(
            graph.number_of_edges(),
            sg_2.number_of_edges(),
            msg="since graph is too small, the subgraph should contain the whole thing",
        )

    def test_helper_failure(self):
        graph = nx.MultiDiGraph()
        graph.add_edge(1, 2)
        graph.add_edge(2, 3)

        result = nx.MultiDiGraph()
        result.add_edge(1, 2)

        _helper(
            result,
            graph,
            number_edges_remaining=5,
            node_blacklist={1, 2, 3},
        )

        self.assertNotIn(3, result)


class TestRandomPath(unittest.TestCase):
    """Test getting random paths."""

    def test_get_random_path(self):
        """Test getting random paths doesn't crash."""
        for graph in (sialic_acid_graph, statin_graph):
            for _ in range(100):
                get_random_path(graph.copy())