scikit-network 0.33.3__cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of scikit-network might be problematic. Click here for more details.

Files changed (229) hide show
  1. scikit_network-0.33.3.dist-info/METADATA +122 -0
  2. scikit_network-0.33.3.dist-info/RECORD +229 -0
  3. scikit_network-0.33.3.dist-info/WHEEL +6 -0
  4. scikit_network-0.33.3.dist-info/licenses/AUTHORS.rst +43 -0
  5. scikit_network-0.33.3.dist-info/licenses/LICENSE +34 -0
  6. scikit_network-0.33.3.dist-info/top_level.txt +1 -0
  7. scikit_network.libs/libgomp-d22c30c5.so.1.0.0 +0 -0
  8. sknetwork/__init__.py +21 -0
  9. sknetwork/base.py +67 -0
  10. sknetwork/classification/__init__.py +8 -0
  11. sknetwork/classification/base.py +142 -0
  12. sknetwork/classification/base_rank.py +133 -0
  13. sknetwork/classification/diffusion.py +134 -0
  14. sknetwork/classification/knn.py +139 -0
  15. sknetwork/classification/metrics.py +205 -0
  16. sknetwork/classification/pagerank.py +66 -0
  17. sknetwork/classification/propagation.py +152 -0
  18. sknetwork/classification/tests/__init__.py +1 -0
  19. sknetwork/classification/tests/test_API.py +30 -0
  20. sknetwork/classification/tests/test_diffusion.py +77 -0
  21. sknetwork/classification/tests/test_knn.py +23 -0
  22. sknetwork/classification/tests/test_metrics.py +53 -0
  23. sknetwork/classification/tests/test_pagerank.py +20 -0
  24. sknetwork/classification/tests/test_propagation.py +24 -0
  25. sknetwork/classification/vote.cpp +27587 -0
  26. sknetwork/classification/vote.cpython-313-aarch64-linux-gnu.so +0 -0
  27. sknetwork/classification/vote.pyx +56 -0
  28. sknetwork/clustering/__init__.py +8 -0
  29. sknetwork/clustering/base.py +172 -0
  30. sknetwork/clustering/kcenters.py +253 -0
  31. sknetwork/clustering/leiden.py +242 -0
  32. sknetwork/clustering/leiden_core.cpp +31578 -0
  33. sknetwork/clustering/leiden_core.cpython-313-aarch64-linux-gnu.so +0 -0
  34. sknetwork/clustering/leiden_core.pyx +124 -0
  35. sknetwork/clustering/louvain.py +286 -0
  36. sknetwork/clustering/louvain_core.cpp +31223 -0
  37. sknetwork/clustering/louvain_core.cpython-313-aarch64-linux-gnu.so +0 -0
  38. sknetwork/clustering/louvain_core.pyx +124 -0
  39. sknetwork/clustering/metrics.py +91 -0
  40. sknetwork/clustering/postprocess.py +66 -0
  41. sknetwork/clustering/propagation_clustering.py +104 -0
  42. sknetwork/clustering/tests/__init__.py +1 -0
  43. sknetwork/clustering/tests/test_API.py +38 -0
  44. sknetwork/clustering/tests/test_kcenters.py +60 -0
  45. sknetwork/clustering/tests/test_leiden.py +34 -0
  46. sknetwork/clustering/tests/test_louvain.py +135 -0
  47. sknetwork/clustering/tests/test_metrics.py +50 -0
  48. sknetwork/clustering/tests/test_postprocess.py +39 -0
  49. sknetwork/data/__init__.py +6 -0
  50. sknetwork/data/base.py +33 -0
  51. sknetwork/data/load.py +406 -0
  52. sknetwork/data/models.py +459 -0
  53. sknetwork/data/parse.py +644 -0
  54. sknetwork/data/test_graphs.py +84 -0
  55. sknetwork/data/tests/__init__.py +1 -0
  56. sknetwork/data/tests/test_API.py +30 -0
  57. sknetwork/data/tests/test_base.py +14 -0
  58. sknetwork/data/tests/test_load.py +95 -0
  59. sknetwork/data/tests/test_models.py +52 -0
  60. sknetwork/data/tests/test_parse.py +250 -0
  61. sknetwork/data/tests/test_test_graphs.py +29 -0
  62. sknetwork/data/tests/test_toy_graphs.py +68 -0
  63. sknetwork/data/timeout.py +38 -0
  64. sknetwork/data/toy_graphs.py +611 -0
  65. sknetwork/embedding/__init__.py +8 -0
  66. sknetwork/embedding/base.py +94 -0
  67. sknetwork/embedding/force_atlas.py +198 -0
  68. sknetwork/embedding/louvain_embedding.py +148 -0
  69. sknetwork/embedding/random_projection.py +135 -0
  70. sknetwork/embedding/spectral.py +141 -0
  71. sknetwork/embedding/spring.py +198 -0
  72. sknetwork/embedding/svd.py +359 -0
  73. sknetwork/embedding/tests/__init__.py +1 -0
  74. sknetwork/embedding/tests/test_API.py +49 -0
  75. sknetwork/embedding/tests/test_force_atlas.py +35 -0
  76. sknetwork/embedding/tests/test_louvain_embedding.py +33 -0
  77. sknetwork/embedding/tests/test_random_projection.py +28 -0
  78. sknetwork/embedding/tests/test_spectral.py +81 -0
  79. sknetwork/embedding/tests/test_spring.py +50 -0
  80. sknetwork/embedding/tests/test_svd.py +43 -0
  81. sknetwork/gnn/__init__.py +10 -0
  82. sknetwork/gnn/activation.py +117 -0
  83. sknetwork/gnn/base.py +181 -0
  84. sknetwork/gnn/base_activation.py +90 -0
  85. sknetwork/gnn/base_layer.py +109 -0
  86. sknetwork/gnn/gnn_classifier.py +305 -0
  87. sknetwork/gnn/layer.py +153 -0
  88. sknetwork/gnn/loss.py +180 -0
  89. sknetwork/gnn/neighbor_sampler.py +65 -0
  90. sknetwork/gnn/optimizer.py +164 -0
  91. sknetwork/gnn/tests/__init__.py +1 -0
  92. sknetwork/gnn/tests/test_activation.py +56 -0
  93. sknetwork/gnn/tests/test_base.py +75 -0
  94. sknetwork/gnn/tests/test_base_layer.py +37 -0
  95. sknetwork/gnn/tests/test_gnn_classifier.py +130 -0
  96. sknetwork/gnn/tests/test_layers.py +80 -0
  97. sknetwork/gnn/tests/test_loss.py +33 -0
  98. sknetwork/gnn/tests/test_neigh_sampler.py +23 -0
  99. sknetwork/gnn/tests/test_optimizer.py +43 -0
  100. sknetwork/gnn/tests/test_utils.py +41 -0
  101. sknetwork/gnn/utils.py +127 -0
  102. sknetwork/hierarchy/__init__.py +6 -0
  103. sknetwork/hierarchy/base.py +96 -0
  104. sknetwork/hierarchy/louvain_hierarchy.py +272 -0
  105. sknetwork/hierarchy/metrics.py +234 -0
  106. sknetwork/hierarchy/paris.cpp +37871 -0
  107. sknetwork/hierarchy/paris.cpython-313-aarch64-linux-gnu.so +0 -0
  108. sknetwork/hierarchy/paris.pyx +316 -0
  109. sknetwork/hierarchy/postprocess.py +350 -0
  110. sknetwork/hierarchy/tests/__init__.py +1 -0
  111. sknetwork/hierarchy/tests/test_API.py +24 -0
  112. sknetwork/hierarchy/tests/test_algos.py +34 -0
  113. sknetwork/hierarchy/tests/test_metrics.py +62 -0
  114. sknetwork/hierarchy/tests/test_postprocess.py +57 -0
  115. sknetwork/linalg/__init__.py +9 -0
  116. sknetwork/linalg/basics.py +37 -0
  117. sknetwork/linalg/diteration.cpp +27403 -0
  118. sknetwork/linalg/diteration.cpython-313-aarch64-linux-gnu.so +0 -0
  119. sknetwork/linalg/diteration.pyx +47 -0
  120. sknetwork/linalg/eig_solver.py +93 -0
  121. sknetwork/linalg/laplacian.py +15 -0
  122. sknetwork/linalg/normalizer.py +86 -0
  123. sknetwork/linalg/operators.py +225 -0
  124. sknetwork/linalg/polynome.py +76 -0
  125. sknetwork/linalg/ppr_solver.py +170 -0
  126. sknetwork/linalg/push.cpp +31075 -0
  127. sknetwork/linalg/push.cpython-313-aarch64-linux-gnu.so +0 -0
  128. sknetwork/linalg/push.pyx +71 -0
  129. sknetwork/linalg/sparse_lowrank.py +142 -0
  130. sknetwork/linalg/svd_solver.py +91 -0
  131. sknetwork/linalg/tests/__init__.py +1 -0
  132. sknetwork/linalg/tests/test_eig.py +44 -0
  133. sknetwork/linalg/tests/test_laplacian.py +18 -0
  134. sknetwork/linalg/tests/test_normalization.py +34 -0
  135. sknetwork/linalg/tests/test_operators.py +66 -0
  136. sknetwork/linalg/tests/test_polynome.py +38 -0
  137. sknetwork/linalg/tests/test_ppr.py +50 -0
  138. sknetwork/linalg/tests/test_sparse_lowrank.py +61 -0
  139. sknetwork/linalg/tests/test_svd.py +38 -0
  140. sknetwork/linkpred/__init__.py +2 -0
  141. sknetwork/linkpred/base.py +46 -0
  142. sknetwork/linkpred/nn.py +126 -0
  143. sknetwork/linkpred/tests/__init__.py +1 -0
  144. sknetwork/linkpred/tests/test_nn.py +27 -0
  145. sknetwork/log.py +19 -0
  146. sknetwork/path/__init__.py +5 -0
  147. sknetwork/path/dag.py +54 -0
  148. sknetwork/path/distances.py +98 -0
  149. sknetwork/path/search.py +31 -0
  150. sknetwork/path/shortest_path.py +61 -0
  151. sknetwork/path/tests/__init__.py +1 -0
  152. sknetwork/path/tests/test_dag.py +37 -0
  153. sknetwork/path/tests/test_distances.py +62 -0
  154. sknetwork/path/tests/test_search.py +40 -0
  155. sknetwork/path/tests/test_shortest_path.py +40 -0
  156. sknetwork/ranking/__init__.py +8 -0
  157. sknetwork/ranking/base.py +61 -0
  158. sknetwork/ranking/betweenness.cpp +9710 -0
  159. sknetwork/ranking/betweenness.cpython-313-aarch64-linux-gnu.so +0 -0
  160. sknetwork/ranking/betweenness.pyx +97 -0
  161. sknetwork/ranking/closeness.py +92 -0
  162. sknetwork/ranking/hits.py +94 -0
  163. sknetwork/ranking/katz.py +83 -0
  164. sknetwork/ranking/pagerank.py +110 -0
  165. sknetwork/ranking/postprocess.py +37 -0
  166. sknetwork/ranking/tests/__init__.py +1 -0
  167. sknetwork/ranking/tests/test_API.py +32 -0
  168. sknetwork/ranking/tests/test_betweenness.py +38 -0
  169. sknetwork/ranking/tests/test_closeness.py +30 -0
  170. sknetwork/ranking/tests/test_hits.py +20 -0
  171. sknetwork/ranking/tests/test_pagerank.py +62 -0
  172. sknetwork/ranking/tests/test_postprocess.py +26 -0
  173. sknetwork/regression/__init__.py +4 -0
  174. sknetwork/regression/base.py +61 -0
  175. sknetwork/regression/diffusion.py +210 -0
  176. sknetwork/regression/tests/__init__.py +1 -0
  177. sknetwork/regression/tests/test_API.py +32 -0
  178. sknetwork/regression/tests/test_diffusion.py +56 -0
  179. sknetwork/sknetwork.py +3 -0
  180. sknetwork/test_base.py +35 -0
  181. sknetwork/test_log.py +15 -0
  182. sknetwork/topology/__init__.py +8 -0
  183. sknetwork/topology/cliques.cpp +32568 -0
  184. sknetwork/topology/cliques.cpython-313-aarch64-linux-gnu.so +0 -0
  185. sknetwork/topology/cliques.pyx +149 -0
  186. sknetwork/topology/core.cpp +30654 -0
  187. sknetwork/topology/core.cpython-313-aarch64-linux-gnu.so +0 -0
  188. sknetwork/topology/core.pyx +90 -0
  189. sknetwork/topology/cycles.py +243 -0
  190. sknetwork/topology/minheap.cpp +27335 -0
  191. sknetwork/topology/minheap.cpython-313-aarch64-linux-gnu.so +0 -0
  192. sknetwork/topology/minheap.pxd +20 -0
  193. sknetwork/topology/minheap.pyx +109 -0
  194. sknetwork/topology/structure.py +194 -0
  195. sknetwork/topology/tests/__init__.py +1 -0
  196. sknetwork/topology/tests/test_cliques.py +28 -0
  197. sknetwork/topology/tests/test_core.py +19 -0
  198. sknetwork/topology/tests/test_cycles.py +65 -0
  199. sknetwork/topology/tests/test_structure.py +85 -0
  200. sknetwork/topology/tests/test_triangles.py +38 -0
  201. sknetwork/topology/tests/test_wl.py +72 -0
  202. sknetwork/topology/triangles.cpp +8897 -0
  203. sknetwork/topology/triangles.cpython-313-aarch64-linux-gnu.so +0 -0
  204. sknetwork/topology/triangles.pyx +151 -0
  205. sknetwork/topology/weisfeiler_lehman.py +133 -0
  206. sknetwork/topology/weisfeiler_lehman_core.cpp +27638 -0
  207. sknetwork/topology/weisfeiler_lehman_core.cpython-313-aarch64-linux-gnu.so +0 -0
  208. sknetwork/topology/weisfeiler_lehman_core.pyx +114 -0
  209. sknetwork/utils/__init__.py +7 -0
  210. sknetwork/utils/check.py +355 -0
  211. sknetwork/utils/format.py +221 -0
  212. sknetwork/utils/membership.py +82 -0
  213. sknetwork/utils/neighbors.py +115 -0
  214. sknetwork/utils/tests/__init__.py +1 -0
  215. sknetwork/utils/tests/test_check.py +190 -0
  216. sknetwork/utils/tests/test_format.py +63 -0
  217. sknetwork/utils/tests/test_membership.py +24 -0
  218. sknetwork/utils/tests/test_neighbors.py +41 -0
  219. sknetwork/utils/tests/test_tfidf.py +18 -0
  220. sknetwork/utils/tests/test_values.py +66 -0
  221. sknetwork/utils/tfidf.py +37 -0
  222. sknetwork/utils/values.py +76 -0
  223. sknetwork/visualization/__init__.py +4 -0
  224. sknetwork/visualization/colors.py +34 -0
  225. sknetwork/visualization/dendrograms.py +277 -0
  226. sknetwork/visualization/graphs.py +1039 -0
  227. sknetwork/visualization/tests/__init__.py +1 -0
  228. sknetwork/visualization/tests/test_dendrograms.py +53 -0
  229. sknetwork/visualization/tests/test_graphs.py +176 -0
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Created on Nov 29, 2018
5
+ @author: Quentin Lutz <qlutz@enst.fr>
6
+ @author: Nathan de Lara <nathan.delara@polytechnique.org>
7
+ @author: Thomas Bonald <tbonald@enst.fr>
8
+ """
9
+
10
+ import numpy as np
11
+ from scipy import sparse
12
+
13
+ from sknetwork.utils import directed2undirected
14
+
15
+
16
+ def test_digraph():
17
+ """Simple directed graph, used for testing.
18
+ 10 nodes, 12 edges
19
+ """
20
+ row = np.array([0, 1, 1, 3, 4, 6, 6, 6, 6, 7, 8, 8, 9])
21
+ col = np.array([1, 4, 3, 2, 5, 4, 5, 7, 1, 9, 9, 2, 9])
22
+ data = np.array([1, 1, 2.5, 1, 2, 2, 1, 2, 2, 1.5, 2, 1, 2])
23
+ return sparse.csr_matrix((data, (row, col)), shape=(10, 10))
24
+
25
+
26
+ def test_graph():
27
+ """Simple undirected graph, used for testing.
28
+ 10 nodes, 12 edges.
29
+ """
30
+ return directed2undirected(test_digraph(), weighted=True)
31
+
32
+
33
+ def test_bigraph():
34
+ """Simple bipartite graph, used for testing.
35
+ 6 + 8 nodes, 9 edges.
36
+ """
37
+ row = np.array([0, 1, 1, 2, 2, 3, 4, 5, 5])
38
+ col = np.array([1, 2, 3, 1, 0, 4, 7, 5, 6])
39
+ data = np.array([1, 2.5, 1, 2, 2, 1.5, 1, 2, 3])
40
+ return sparse.csr_matrix((data, (row, col)), shape=(6, 8))
41
+
42
+
43
+ def test_disconnected_graph():
44
+ """Simple disconnected undirected graph, used for testing.
45
+ 10 nodes, 10 edges.
46
+ """
47
+ row = np.array([1, 2, 3, 4, 6, 6, 6, 7, 8, 9])
48
+ col = np.array([1, 3, 2, 5, 4, 5, 7, 9, 9, 9])
49
+ data = np.array([1, 2.5, 1, 2, 2, 1, 2, 2, 1.5, 2])
50
+ adjacency = sparse.csr_matrix((data, (row, col)), shape=(10, 10))
51
+ return directed2undirected(adjacency)
52
+
53
+
54
+ def test_bigraph_disconnect():
55
+ """Simple disconnected bipartite graph, used for testing.
56
+ 6 + 8 nodes, 9 edges.
57
+ """
58
+ row = np.array([1, 1, 1, 2, 2, 3, 5, 4, 5])
59
+ col = np.array([1, 2, 3, 1, 3, 4, 7, 7, 6])
60
+ data = np.array([1, 2.5, 1, 2, 2, 1.5, 3, 0, 1])
61
+ return sparse.csr_matrix((data, (row, col)), shape=(6, 8))
62
+
63
+
64
+ def test_graph_bool():
65
+ """Simple undirected graph with boolean entries, used for testing (10 nodes, 10 edges)."""
66
+ adjacency = test_graph()
67
+ adjacency.data = adjacency.data.astype(bool)
68
+ return adjacency
69
+
70
+
71
+ def test_clique():
72
+ """Clique graph, used for testing (10 nodes, 45 edges).
73
+ """
74
+ n = 10
75
+ adjacency = sparse.csr_matrix(np.ones((n, n), dtype=bool))
76
+ adjacency.setdiag(0)
77
+ adjacency.eliminate_zeros()
78
+ return adjacency
79
+
80
+
81
+ def test_graph_empty():
82
+ """Empty graph, used for testing (10 nodes, 0 edges).
83
+ """
84
+ return sparse.csr_matrix((10, 10), dtype=bool)
@@ -0,0 +1 @@
1
+ """tests module"""
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Tests for data API"""
4
+
5
+ import tempfile
6
+ import unittest
7
+ import warnings
8
+
9
+ from sknetwork.data.load import *
10
+ from sknetwork.data.toy_graphs import *
11
+ from sknetwork.data import Dataset
12
+
13
+
14
+ class TestDataAPI(unittest.TestCase):
15
+
16
+ def test_toy_graphs(self):
17
+ toy_graphs = [karate_club, painters, bow_tie, house, miserables]
18
+ for toy_graph in toy_graphs:
19
+ self.assertEqual(type(toy_graph()), sparse.csr_matrix)
20
+ self.assertEqual(type(toy_graph(metadata=True)), Dataset)
21
+
22
+ def test_load(self):
23
+ tmp_data_dir = tempfile.gettempdir() + '/stub'
24
+ clear_data_home(tmp_data_dir)
25
+ try:
26
+ graph = load_netset('stub', tmp_data_dir)
27
+ self.assertEqual(type(graph), Dataset)
28
+ except URLError: # pragma: no cover
29
+ warnings.warn('Could not reach NetSet. Corresponding test has not been performed.', RuntimeWarning)
30
+ return
@@ -0,0 +1,14 @@
1
+ # -*- coding: utf-8 -*-
2
+ """tests for dataset"""
3
+
4
+ import unittest
5
+
6
+ from sknetwork.data.base import Dataset
7
+
8
+
9
+ class TestDataset(unittest.TestCase):
10
+
11
+ def test(self):
12
+ dataset = Dataset(name='dataset')
13
+ self.assertEqual(dataset.name, 'dataset')
14
+ self.assertEqual(dataset['name'], 'dataset')
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """tests for load.py"""
4
+
5
+ import tempfile
6
+ import unittest
7
+ import warnings
8
+
9
+ import numpy as np
10
+
11
+ from sknetwork.data.load import load_netset, load_konect, clear_data_home, save, load
12
+ from sknetwork.data.toy_graphs import house, star_wars
13
+ from sknetwork.data.timeout import TimeOut
14
+
15
+
16
+ class TestLoader(unittest.TestCase):
17
+
18
+ def setUp(self):
19
+ self.data_home = tempfile.gettempdir() + '/data'
20
+
21
+ def test_netset(self):
22
+ clear_data_home(self.data_home)
23
+ try:
24
+ graph = load_netset('stub', self.data_home)
25
+ except: # pragma: no cover
26
+ warnings.warn('Could not reach the NetSet collection. Corresponding test has not been performed.',
27
+ RuntimeWarning)
28
+ return
29
+ n = 2
30
+ self.assertEqual(graph.adjacency.shape, (n, n))
31
+ self.assertEqual(len(graph.names), n)
32
+ clear_data_home(self.data_home)
33
+
34
+ def test_invalid_netset(self):
35
+ try:
36
+ with self.assertRaises(ValueError):
37
+ load_netset('junk', self.data_home)
38
+ except: # pragma: no cover
39
+ warnings.warn('Could not reach the NetSet collection. Corresponding test has not been performed.',
40
+ RuntimeWarning)
41
+ return
42
+ load_netset()
43
+
44
+ def test_konect(self):
45
+ try:
46
+ with TimeOut(2):
47
+ data = load_konect('moreno_crime', self.data_home)
48
+ except (TimeoutError, RuntimeError): # pragma: no cover
49
+ warnings.warn('Could not reach Konect. Corresponding test has not been performed.', RuntimeWarning)
50
+ return
51
+ self.assertEqual(data.biadjacency.shape[0], 829)
52
+ self.assertEqual(data.name.shape[0], 829)
53
+
54
+ # load from bundle
55
+ data = load_konect('moreno_crime', self.data_home)
56
+ self.assertEqual(data.biadjacency.shape[0], 829)
57
+
58
+ try:
59
+ with TimeOut(2):
60
+ data = load_konect('ego-facebook', self.data_home)
61
+ except (TimeoutError, RuntimeError): # pragma: no cover
62
+ warnings.warn('Could not reach Konect. Corresponding test has not been performed.', RuntimeWarning)
63
+ return
64
+ self.assertEqual(data.adjacency.shape[0], 2888)
65
+ clear_data_home(self.data_home)
66
+
67
+ def test_invalid_konect(self):
68
+ try:
69
+ with TimeOut(4):
70
+ with self.assertRaises(ValueError):
71
+ load_konect('junk', self.data_home)
72
+ with self.assertRaises(ValueError):
73
+ load_konect('', self.data_home)
74
+ except (TimeoutError, RuntimeError): # pragma: no cover
75
+ warnings.warn('Could not reach Konect. Corresponding test has not been performed.', RuntimeWarning)
76
+ return
77
+
78
+ def test_save_load(self):
79
+ data = house()
80
+ save(self.data_home + '/house', data)
81
+ loaded_data = load(self.data_home + '/house')
82
+ self.assertTrue(np.allclose(data.data, loaded_data.adjacency.data))
83
+
84
+ data = star_wars()
85
+ save(self.data_home + '/star_wars', data)
86
+ loaded_data = load(self.data_home + '/star_wars')
87
+ self.assertTrue(np.allclose(data.data, loaded_data.biadjacency.data))
88
+
89
+ data = star_wars(metadata=True)
90
+ save(self.data_home + '/star_wars', data)
91
+ loaded_data = load(self.data_home + '/star_wars')
92
+ self.assertTrue(np.allclose(data.biadjacency.data, loaded_data.biadjacency.data))
93
+ self.assertEqual(data.names_col[0], loaded_data.names_col[0])
94
+
95
+
@@ -0,0 +1,52 @@
1
+ # -*- coding: utf-8 -*-
2
+ # tests for toy_graphs.py
3
+ """authors:
4
+ Thomas Bonald <bonald@enst.fr>
5
+ Quentin Lutz <qlutz@enst.fr>"""
6
+ import unittest
7
+
8
+ from sknetwork.data.models import *
9
+
10
+
11
+ class TestModels(unittest.TestCase):
12
+
13
+ def test_shape(self):
14
+ n = 10
15
+ for model in [linear_graph, linear_digraph, cyclic_graph, cyclic_digraph, watts_strogatz]:
16
+ adjacency = model(n)
17
+ graph = model(n, metadata=True)
18
+ self.assertEqual(adjacency.shape, (n, n))
19
+ self.assertEqual(graph.adjacency.shape, (n, n))
20
+ if hasattr(graph, 'position'):
21
+ self.assertEqual(graph.position.shape, (n, 2))
22
+
23
+ adjacency = star(n)
24
+ self.assertEqual(adjacency.shape, (n+1, n+1))
25
+ graph = star(n, metadata=True)
26
+ self.assertTrue(hasattr(graph, 'position'))
27
+
28
+ adjacency = erdos_renyi(n)
29
+ self.assertEqual(adjacency.shape, (n, n))
30
+ adjacency = erdos_renyi(n, directed=True, self_loops=True, seed=4)
31
+ self.assertEqual(adjacency.shape, (n, n))
32
+
33
+ adjacency = albert_barabasi(n, 2)
34
+ self.assertEqual(adjacency.shape, (n, n))
35
+
36
+ n1, n2 = 4, 6
37
+ n = n1 * n2
38
+ adjacency = grid(n1, n2)
39
+ self.assertEqual(adjacency.shape, (n, n))
40
+ graph = grid(n1, n2, metadata=True)
41
+ self.assertEqual(graph.adjacency.shape, (n, n))
42
+ if hasattr(graph, 'position'):
43
+ self.assertEqual(graph.position.shape, (n, 2))
44
+
45
+ def test_block_model(self):
46
+ graph = block_model(np.array([4, 5, 6]), np.array([0.5, 0.3, 0.2]), 0.1, metadata=True)
47
+ adjacency = graph.adjacency
48
+ labels = graph.labels
49
+ self.assertEqual(adjacency.shape, (15, 15))
50
+ self.assertEqual(len(labels), 15)
51
+ adjacency = block_model(np.array([4, 5, 6]), np.array([0.5, 0.3, 0.2]), 0.1, directed=True, self_loops=True)
52
+ self.assertEqual(adjacency.shape, (15, 15))
@@ -0,0 +1,250 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """tests for parse.py"""
4
+
5
+ import unittest
6
+ from os import remove
7
+
8
+ import numpy as np
9
+
10
+ from sknetwork.data import parse
11
+
12
+
13
+ class TestParser(unittest.TestCase):
14
+
15
+ def test_unlabeled_unweighted(self):
16
+ self.stub_data_1 = 'stub_1.txt'
17
+ with open(self.stub_data_1, "w") as text_file:
18
+ text_file.write('%stub\n1 3\n4 5\n0 2')
19
+ adjacency = parse.from_csv(self.stub_data_1)
20
+ self.assertTrue((adjacency.indices == [2, 3, 0, 1, 5, 4]).all())
21
+ self.assertTrue((adjacency.indptr == [0, 1, 2, 3, 4, 5, 6]).all())
22
+ self.assertTrue((adjacency.data == [1, 1, 1, 1, 1, 1]).all())
23
+ adjacency = parse.from_csv(self.stub_data_1, shape=(7, 7))
24
+ self.assertTrue((adjacency.shape == (7, 7)))
25
+ biadjacency = parse.from_csv(self.stub_data_1, bipartite=True, shape=(7, 9))
26
+ self.assertTrue((biadjacency.shape == (7, 9)))
27
+ remove(self.stub_data_1)
28
+
29
+ def test_labeled_weighted(self):
30
+ self.stub_data_2 = 'stub_2.txt'
31
+ with open(self.stub_data_2, "w") as text_file:
32
+ text_file.write('%stub\nf, e, 5\na, d, 6\nc, b, 1')
33
+ graph = parse.from_csv(self.stub_data_2)
34
+ adjacency = graph.adjacency
35
+ names = graph.names
36
+ self.assertTrue((adjacency.indices == [4, 3, 5, 1, 0, 2]).all())
37
+ self.assertTrue((adjacency.indptr == [0, 1, 2, 3, 4, 5, 6]).all())
38
+ self.assertTrue((adjacency.data == [1, 6, 5, 6, 1, 5]).all())
39
+ self.assertTrue((names == [' b', ' d', ' e', 'a', 'c', 'f']).all())
40
+
41
+ remove(self.stub_data_2)
42
+
43
+ def test_auto_reindex(self):
44
+ self.stub_data_4 = 'stub_4.txt'
45
+ with open(self.stub_data_4, "w") as text_file:
46
+ text_file.write('%stub\n14 31\n42 50\n0 12')
47
+ graph = parse.from_csv(self.stub_data_4, reindex=True)
48
+ adjacency = graph.adjacency
49
+ names = graph.names
50
+ self.assertTrue((adjacency.data == [1, 1, 1, 1, 1, 1]).all())
51
+ self.assertTrue((names == [0, 12, 14, 31, 42, 50]).all())
52
+ remove(self.stub_data_4)
53
+
54
+ def test_wrong_format(self):
55
+ self.stub_data_3 = 'stub_3.txt'
56
+ with open(self.stub_data_3, "w") as text_file:
57
+ text_file.write('%stub\n1 3 a\n4 5 b\n0 2 e')
58
+ self.assertRaises(ValueError, parse.from_csv, self.stub_data_3)
59
+ remove(self.stub_data_3)
60
+
61
+ def test_graphml_basic(self):
62
+ self.stub_data_5 = 'stub_5.graphml'
63
+ with open(self.stub_data_5, "w") as graphml_file:
64
+ graphml_file.write("""<?xml version='1.0' encoding='utf-8'?>
65
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
66
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
67
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
68
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
69
+ <key id="d0" for="edge" attr.name="weight" attr.type="int"/>
70
+ <graph edgedefault="directed">
71
+ <node id="node1"/>
72
+ <node id="node2"/>
73
+ <edge source="node1" target="node2">
74
+ <data key="d0">1</data>
75
+ </edge></graph></graphml>""")
76
+ graph = parse.from_graphml(self.stub_data_5)
77
+ adjacency = graph.adjacency
78
+ names = graph.names
79
+ self.assertTrue((adjacency.indices == [1]).all())
80
+ self.assertTrue((adjacency.indptr == [0, 1, 1]).all())
81
+ self.assertTrue((adjacency.data == [1]).all())
82
+ self.assertTrue((names == ['node1', 'node2']).all())
83
+ remove(self.stub_data_5)
84
+
85
+ def test_graphml_refined(self):
86
+ self.stub_data_6 = 'stub_6.graphml'
87
+ with open(self.stub_data_6, "w") as graphml_file:
88
+ graphml_file.write("""<?xml version='1.0' encoding='utf-8'?>
89
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
90
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
91
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
92
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
93
+ <desc>Some file</desc>
94
+ <key id="d0" for="edge" attr.name="weight" attr.type="int"/>
95
+ <key id="d1" for="node" attr.name="color" attr.type="string">
96
+ <desc>Color</desc>
97
+ <default>blue</default>
98
+ </key>
99
+ <key id="d2" for="edge" attr.name="distance" attr.type="double">
100
+ <desc>Distance</desc>
101
+ <default>1.5</default>
102
+ </key>
103
+ <graph edgedefault="undirected" parse.nodeids="canonical"
104
+ parse.nodes="3" parse.edges="4">
105
+ <node id="n0">
106
+ <data key="d1">green</data>
107
+ </node>
108
+ <node id="n1"/>
109
+ <node id="n2"/>
110
+ <edge source="n0" target="n1">
111
+ <data key="d0">1</data>
112
+ <data key="d2">7.2</data>
113
+ </edge>
114
+ <edge source="n1" target="n2" directed='true'>
115
+ <data key="d0">1</data>
116
+ </edge>
117
+ <edge source="n0" target="n2" directed='false'>
118
+ <data key="d0">1</data>
119
+ </edge></graph></graphml>""")
120
+ graph = parse.from_graphml(self.stub_data_6)
121
+ adjacency = graph.adjacency
122
+ colors = graph.node_attribute.color
123
+ distances = graph.edge_attribute.distance
124
+ self.assertTrue((adjacency.indices == [1, 2, 0, 2, 0]).all())
125
+ self.assertTrue((adjacency.indptr == [0, 2, 4, 5]).all())
126
+ self.assertTrue((adjacency.data == [1, 1, 1, 1, 1]).all())
127
+ self.assertTrue((colors == ['green', 'blue', 'blue']).all())
128
+ self.assertTrue((distances == [7.2, 7.2, 1.5, 1.5, 1.5]).all())
129
+ self.assertEqual(graph.meta.description, 'Some file')
130
+ self.assertEqual(graph.meta.attributes.node.color, 'Color')
131
+ self.assertEqual(graph.meta.attributes.edge.distance, 'Distance')
132
+ remove(self.stub_data_6)
133
+
134
+ def test_no_graphml(self):
135
+ self.stub_data_7 = 'stub_7.graphml'
136
+ with open(self.stub_data_7, "w") as graphml_file:
137
+ graphml_file.write("""<?xml version='1.0' encoding='utf-8'?>
138
+ <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
139
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
140
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
141
+ http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
142
+ <key id="d0" for="edge" attr.name="weight" attr.type="int"/>
143
+ </graphml>""")
144
+ self.assertRaises(ValueError, parse.from_graphml, self.stub_data_7)
145
+ remove(self.stub_data_7)
146
+
147
+ def test_csv_adjacency(self):
148
+ self.stub_data_8 = 'stub_8.txt'
149
+ with open(self.stub_data_8, "w") as text_file:
150
+ text_file.write('%stub\n2\n3\n0\n1\n5\n4')
151
+ adjacency = parse.from_csv(self.stub_data_8)
152
+ self.assertTupleEqual(adjacency.shape, (6, 6))
153
+ self.assertTrue((adjacency.indices == [2, 3, 0, 1, 5, 4]).all())
154
+ self.assertTrue((adjacency.indptr == [0, 1, 2, 3, 4, 5, 6]).all())
155
+ self.assertTrue((adjacency.data == [2, 2, 2, 2, 2, 2]).all())
156
+ graph = parse.from_csv(self.stub_data_8, matrix_only=False)
157
+ adjacency = graph.adjacency
158
+ self.assertTupleEqual(adjacency.shape, (6, 6))
159
+ remove(self.stub_data_8)
160
+ # without comment line
161
+ self.stub_data_8 = 'stub_8.txt'
162
+ with open(self.stub_data_8, "w") as text_file:
163
+ text_file.write('2\n3\n0\n1\n5\n4')
164
+ adjacency = parse.from_csv(self.stub_data_8)
165
+ self.assertTupleEqual(adjacency.shape, (6, 6))
166
+ remove(self.stub_data_8)
167
+
168
+ def test_csv_bipartite(self):
169
+ self.stub_data_9 = 'stub_9.txt'
170
+ with open(self.stub_data_9, "w") as text_file:
171
+ text_file.write('#stub\n1 3\n4 5\n0 3')
172
+ graph = parse.from_csv(self.stub_data_9, bipartite=True, reindex=True)
173
+ biadjacency = graph.biadjacency
174
+ self.assertTrue((biadjacency.indices == [0, 0, 1]).all())
175
+ self.assertTrue((biadjacency.indptr == [0, 1, 2, 3]).all())
176
+ self.assertTrue((biadjacency.data == [1, 1, 1]).all())
177
+ biadjacency = parse.from_csv(self.stub_data_9, bipartite=True)
178
+ self.assertTrue(biadjacency.shape == (5, 6))
179
+ remove(self.stub_data_9)
180
+
181
+ def test_edge_list(self):
182
+ edge_list_1 = [('Alice', 'Bob'), ('Carol', 'Alice')]
183
+ graph = parse.from_edge_list(edge_list_1)
184
+ adjacency = graph.adjacency
185
+ names = graph.names
186
+ self.assertTrue((names == ['Alice', 'Bob', 'Carol']).all())
187
+ self.assertTupleEqual(adjacency.shape, (3, 3))
188
+ self.assertTrue((adjacency.indptr == [0, 2, 3, 4]).all())
189
+ self.assertTrue((adjacency.indices == [1, 2, 0, 0]).all())
190
+ self.assertTrue((adjacency.data == [1, 1, 1, 1]).all())
191
+
192
+ edge_list_2 = [('Alice', 'Bob', 4), ('Carol', 'Alice', 6)]
193
+ graph = parse.from_edge_list(edge_list_2)
194
+ adjacency = graph.adjacency
195
+ names = graph.names
196
+ self.assertTrue((names == ['Alice', 'Bob', 'Carol']).all())
197
+ self.assertTupleEqual(adjacency.shape, (3, 3))
198
+ self.assertTrue((adjacency.indptr == [0, 2, 3, 4]).all())
199
+ self.assertTrue((adjacency.indices == [1, 2, 0, 0]).all())
200
+ self.assertTrue((adjacency.data == [4, 6, 4, 6]).all())
201
+
202
+ edge_list_3 = [('Alice', 'Bob'), ('Carol', 'Alice'), ('Alice', 'Bob')]
203
+ graph = parse.from_edge_list(edge_list_3, directed=True)
204
+ adjacency = graph.adjacency
205
+ names = graph.names
206
+ self.assertTrue((names == ['Alice', 'Bob', 'Carol']).all())
207
+ self.assertTupleEqual(adjacency.shape, (3, 3))
208
+ self.assertTrue((adjacency.data == [2, 1]).all())
209
+
210
+ adjacency = parse.from_edge_list(edge_list_3, directed=True, matrix_only=True)
211
+ self.assertTupleEqual(adjacency.shape, (3, 3))
212
+
213
+ graph = parse.from_edge_list(edge_list_3, directed=True, weighted=False)
214
+ adjacency = graph.adjacency
215
+ self.assertTrue((adjacency.data == [1, 1]).all())
216
+
217
+ edge_list = np.array([[0, 1, 1], [1, 2, 2]])
218
+ adjacency = parse.from_edge_list(edge_list, weighted=True, matrix_only=True)
219
+ self.assertTrue((adjacency.data == np.array([1, 1, 2, 2])).all())
220
+
221
+ edge_list = np.array([[0, 1, 2], [0, 1, 1], [1, 2, 1]])
222
+ adjacency = parse.from_edge_list(edge_list, weighted=True, matrix_only=True, sum_duplicates=False)
223
+ self.assertTrue(adjacency.data[0] == 2)
224
+
225
+ def test_adjacency_list(self):
226
+ edge_list_4 = {'Alice': ['Bob', 'Carol'], 'Bob': ['Carol']}
227
+ graph = parse.from_adjacency_list(edge_list_4, directed=True)
228
+ adjacency = graph.adjacency
229
+ names = graph.names
230
+ self.assertTrue((names == ['Alice', 'Bob', 'Carol']).all())
231
+ self.assertTupleEqual(adjacency.shape, (3, 3))
232
+ self.assertTrue((adjacency.data == [1, 1, 1]).all())
233
+
234
+ edge_list_5 = [[0, 1, 2], [2, 3]]
235
+ adjacency = parse.from_adjacency_list(edge_list_5, directed=True)
236
+ self.assertTupleEqual(adjacency.shape, (4, 4))
237
+ self.assertTrue((adjacency.data == [1, 1, 1, 1, 1]).all())
238
+
239
+ self.assertRaises(TypeError, parse.from_adjacency_list, {2, 3})
240
+
241
+ def test_bad_format_edge_list(self):
242
+ edge_list_2 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
243
+ self.assertRaises(ValueError, parse.from_edge_list, edge_list_2)
244
+ edge_list_3 = 'ab cd'
245
+ self.assertRaises(TypeError, parse.from_edge_list, edge_list_3)
246
+
247
+ def test_is_number(self):
248
+ self.assertTrue(parse.is_number(3))
249
+ self.assertFalse(parse.is_number('a'))
250
+
@@ -0,0 +1,29 @@
1
+ # -*- coding: utf-8 -*-
2
+ # tests for test_graphs.py
3
+ """
4
+ @author: Quentin Lutz <qlutz@enst.fr>
5
+ @author: Nathan de Lara <nathan.delara@polytechnique.org>
6
+ @author: Thomas Bonald <tbonald@enst.fr>
7
+ """
8
+ import unittest
9
+
10
+ from sknetwork.data.test_graphs import *
11
+
12
+
13
+ class TestTestGraphs(unittest.TestCase):
14
+
15
+ def test_undirected(self):
16
+ adjacency = test_graph()
17
+ self.assertEqual(adjacency.shape, (10, 10))
18
+ adjacency = test_disconnected_graph()
19
+ self.assertEqual(adjacency.shape, (10, 10))
20
+
21
+ def test_directed(self):
22
+ adjacency = test_digraph()
23
+ self.assertEqual(adjacency.shape, (10, 10))
24
+
25
+ def test_bipartite(self):
26
+ biadjacency = test_bigraph()
27
+ self.assertEqual(biadjacency.shape, (6, 8))
28
+ biadjacency = test_bigraph_disconnect()
29
+ self.assertEqual(biadjacency.shape, (6, 8))
@@ -0,0 +1,68 @@
1
+ # -*- coding: utf-8 -*-
2
+ # tests for toy_graphs.py
3
+ """
4
+ @author: Quentin Lutz <qlutz@enst.fr>
5
+ @author: Nathan de Lara <nathan.delara@polytechnique.org>
6
+ @author: Thomas Bonald <tbonald@enst.fr>
7
+ """
8
+ import unittest
9
+
10
+ from sknetwork.data.toy_graphs import *
11
+
12
+
13
+ class TestToys(unittest.TestCase):
14
+
15
+ def test_undirected(self):
16
+ adjacency = house()
17
+ self.assertEqual(adjacency.shape, (5, 5))
18
+
19
+ dataset = house(metadata=True)
20
+ self.assertEqual(dataset.position.shape, (5, 2))
21
+
22
+ adjacency = bow_tie()
23
+ self.assertEqual(adjacency.shape, (5, 5))
24
+
25
+ dataset = bow_tie(metadata=True)
26
+ self.assertEqual(dataset.position.shape, (5, 2))
27
+
28
+ dataset = karate_club(True)
29
+ self.assertEqual(dataset.adjacency.shape, (34, 34))
30
+ self.assertEqual(len(dataset.labels), 34)
31
+
32
+ dataset = miserables(True)
33
+ self.assertEqual(dataset.adjacency.shape, (77, 77))
34
+ self.assertEqual(len(dataset.names), 77)
35
+
36
+ def test_directed(self):
37
+ adjacency = painters()
38
+ self.assertEqual(adjacency.shape, (14, 14))
39
+
40
+ adjacency = art_philo_science()
41
+ self.assertEqual(adjacency.shape, (30, 30))
42
+
43
+ dataset = painters(True)
44
+ self.assertEqual(dataset.adjacency.shape, (14, 14))
45
+ self.assertEqual(len(dataset.names), 14)
46
+
47
+ dataset = art_philo_science(True)
48
+ self.assertEqual(dataset.adjacency.shape, (30, 30))
49
+ self.assertEqual(len(dataset.names), 30)
50
+
51
+ def test_bipartite(self):
52
+ dataset = star_wars(True)
53
+ self.assertEqual(dataset.biadjacency.shape, (4, 3))
54
+ self.assertEqual(len(dataset.names), 4)
55
+ self.assertEqual(len(dataset.names_col), 3)
56
+
57
+ dataset = movie_actor(True)
58
+ self.assertEqual(dataset.biadjacency.shape, (15, 17))
59
+ self.assertEqual(len(dataset.names), 15)
60
+ self.assertEqual(len(dataset.names_col), 17)
61
+
62
+ dataset = hourglass(True)
63
+ self.assertEqual(dataset.biadjacency.shape, (2, 2))
64
+
65
+ dataset = art_philo_science(True)
66
+ self.assertEqual(dataset.biadjacency.shape, (30, 11))
67
+ self.assertEqual(len(dataset.names), 30)
68
+ self.assertEqual(len(dataset.names_col), 11)
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env python3
2
+ import contextlib
3
+ import signal
4
+ import warnings
5
+
6
+
7
+ class TimeOut(contextlib.ContextDecorator):
8
+ """
9
+ Timeout context manager/decorator.
10
+
11
+ Adapted from https://gist.github.com/TySkby/143190ad1b88c6115597c45f996b030c on 12/10/2020.
12
+
13
+ Examples
14
+ --------
15
+ >>> from time import sleep
16
+ >>> try:
17
+ ... with TimeOut(1):
18
+ ... sleep(10)
19
+ ... except TimeoutError:
20
+ ... print("Function timed out")
21
+ Function timed out
22
+ """
23
+ def __init__(self, seconds: float):
24
+ self.seconds = seconds
25
+
26
+ def _timeout_handler(self, signum, frame):
27
+ raise TimeoutError("Code timed out.")
28
+
29
+ def __enter__(self):
30
+ if hasattr(signal, "SIGALRM"):
31
+ signal.signal(signal.SIGALRM, self._timeout_handler)
32
+ signal.alarm(self.seconds)
33
+ else:
34
+ warnings.warn("SIGALRM is unavailable on Windows. Timeouts are not functional.")
35
+
36
+ def __exit__(self, exc_type, exc_val, exc_tb):
37
+ if hasattr(signal, "SIGALRM"):
38
+ signal.alarm(0)