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,459 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Created in July 2019
5
+ @author: Thomas Bonald <bonald@enst.fr>
6
+ @author: Quentin Lutz <qlutz@enst.fr>
7
+ @author: Nathan de Lara <nathan.delara@polytechnique.org>
8
+ """
9
+ from math import pi
10
+ from typing import Union, Optional, Iterable
11
+
12
+ import numpy as np
13
+ from scipy import sparse
14
+
15
+ from sknetwork.data.base import Dataset
16
+ from sknetwork.data.parse import from_edge_list
17
+ from sknetwork.utils.check import check_random_state
18
+ from sknetwork.utils.format import directed2undirected
19
+
20
+
21
+ def block_model(sizes: Iterable, p_in: Union[float, list, np.ndarray] = .2, p_out: float = .05,
22
+ directed: bool = False, self_loops: bool = False, metadata: bool = False, seed: Optional[int] = None) \
23
+ -> Union[sparse.csr_matrix, Dataset]:
24
+ """Stochastic block model.
25
+
26
+ Parameters
27
+ ----------
28
+ sizes :
29
+ Block sizes.
30
+ p_in :
31
+ Probability of connection within blocks.
32
+ p_out :
33
+ Probability of connection across blocks.
34
+ directed :
35
+ If ``True``, return a directed graph.
36
+ self_loops :
37
+ If ``True``, allow self-loops.
38
+ metadata :
39
+ If ``True``, return a `Dataset` object with labels.
40
+ seed :
41
+ Seed of the random generator (optional).
42
+ Returns
43
+ -------
44
+ adjacency or graph : Union[sparse.csr_matrix, Dataset]
45
+ Adjacency matrix or graph with metadata (labels).
46
+
47
+ Example
48
+ -------
49
+ >>> from sknetwork.data import block_model
50
+ >>> sizes = np.array([4, 5])
51
+ >>> adjacency = block_model(sizes)
52
+ >>> adjacency.shape
53
+ (9, 9)
54
+
55
+ References
56
+ ----------
57
+ Airoldi, E., Blei, D., Feinberg, S., Xing, E. (2007).
58
+ `Mixed membership stochastic blockmodels. <https://arxiv.org/pdf/0705.4485.pdf>`_
59
+ Journal of Machine Learning Research.
60
+ """
61
+ random_state = check_random_state(seed)
62
+
63
+ if isinstance(p_in, (np.floating, float, int)):
64
+ p_in = p_in * np.ones_like(sizes)
65
+ else:
66
+ p_in = np.array(p_in)
67
+
68
+ blocks = []
69
+ for i, a in enumerate(sizes):
70
+ row = []
71
+ for j, b in enumerate(sizes):
72
+ if j == i:
73
+ row.append(sparse.random(a, a, p_in[i], dtype=bool, random_state=random_state))
74
+ else:
75
+ row.append(sparse.random(a, b, p_out, dtype=bool, random_state=random_state))
76
+ blocks.append(row)
77
+ adjacency = sparse.bmat(blocks)
78
+ if not self_loops:
79
+ adjacency = sparse.lil_matrix(adjacency)
80
+ adjacency.setdiag(0)
81
+ if directed:
82
+ adjacency = sparse.csr_matrix(adjacency)
83
+ else:
84
+ adjacency = directed2undirected(sparse.csr_matrix(sparse.triu(adjacency)), weighted=False)
85
+ if metadata:
86
+ graph = Dataset()
87
+ graph.adjacency = adjacency
88
+ labels = np.repeat(np.arange(len(sizes)), sizes)
89
+ graph.labels = labels
90
+ return graph
91
+ else:
92
+ return adjacency
93
+
94
+
95
+ def erdos_renyi(n: int = 20, p: float = .3, directed: bool = False, self_loops: bool = False,
96
+ seed: Optional[int] = None) -> sparse.csr_matrix:
97
+ """Erdos-Renyi graph.
98
+
99
+ Parameters
100
+ ----------
101
+ n :
102
+ Number of nodes.
103
+ p :
104
+ Probability of connection between nodes.
105
+ directed :
106
+ If ``True``, return a directed graph.
107
+ self_loops :
108
+ If ``True``, allow self-loops.
109
+ seed :
110
+ Seed of the random generator (optional).
111
+
112
+ Returns
113
+ -------
114
+ adjacency : sparse.csr_matrix
115
+ Adjacency matrix.
116
+
117
+ Example
118
+ -------
119
+ >>> from sknetwork.data import erdos_renyi
120
+ >>> adjacency = erdos_renyi(7)
121
+ >>> adjacency.shape
122
+ (7, 7)
123
+
124
+ References
125
+ ----------
126
+ Erdős, P., Rényi, A. (1959). `On Random Graphs. <https://www.renyi.hu/~p_erdos/1959-11.pdf>`_
127
+ Publicationes Mathematicae.
128
+ """
129
+ return block_model([n], p, 0., directed=directed, self_loops=self_loops, metadata=False, seed=seed)
130
+
131
+
132
+ def linear_digraph(n: int = 3, metadata: bool = False) -> Union[sparse.csr_matrix, Dataset]:
133
+ """Linear graph (directed).
134
+
135
+ Parameters
136
+ ----------
137
+ n : int
138
+ Number of nodes.
139
+ metadata : bool
140
+ If ``True``, return a `Dataset` object with metadata.
141
+
142
+ Returns
143
+ -------
144
+ adjacency or graph : Union[sparse.csr_matrix, Dataset]
145
+ Adjacency matrix or graph with metadata (positions).
146
+
147
+ Example
148
+ -------
149
+ >>> from sknetwork.data import linear_digraph
150
+ >>> adjacency = linear_digraph(5)
151
+ >>> adjacency.shape
152
+ (5, 5)
153
+ """
154
+ row = np.arange(n - 1)
155
+ col = np.arange(1, n)
156
+ adjacency = sparse.csr_matrix((np.ones(len(row), dtype=int), (row, col)), shape=(n, n))
157
+
158
+ if metadata:
159
+ x = np.arange(n)
160
+ y = np.zeros(n)
161
+ graph = Dataset()
162
+ graph.adjacency = adjacency
163
+ graph.position = np.array((x, y)).T
164
+ return graph
165
+ else:
166
+ return adjacency
167
+
168
+
169
+ def linear_graph(n: int = 3, metadata: bool = False) -> Union[sparse.csr_matrix, Dataset]:
170
+ """Linear graph (undirected).
171
+
172
+ Parameters
173
+ ----------
174
+ n : int
175
+ Number of nodes.
176
+ metadata : bool
177
+ If ``True``, return a `Dataset` object with metadata.
178
+
179
+ Returns
180
+ -------
181
+ adjacency or graph : Union[sparse.csr_matrix, Dataset]
182
+ Adjacency matrix or graph with metadata (positions).
183
+
184
+ Example
185
+ -------
186
+ >>> from sknetwork.data import linear_graph
187
+ >>> adjacency = linear_graph(5)
188
+ >>> adjacency.shape
189
+ (5, 5)
190
+ """
191
+ graph = linear_digraph(n, True)
192
+ adjacency = graph.adjacency
193
+ adjacency = adjacency + adjacency.T
194
+ if metadata:
195
+ graph.adjacency = adjacency
196
+ return graph
197
+ else:
198
+ return adjacency
199
+
200
+
201
+ def cyclic_position(n: int) -> np.ndarray:
202
+ """Position nodes on a circle of unit radius.
203
+
204
+ Parameters
205
+ ----------
206
+ n : int
207
+ Number of nodes.
208
+
209
+ Returns
210
+ -------
211
+ position : np.ndarray
212
+ Position of nodes.
213
+ """
214
+ t = 2 * pi * np.arange(n).astype(float) / n
215
+ x = np.cos(t)
216
+ y = np.sin(t)
217
+ position = np.array((x, y)).T
218
+ return position
219
+
220
+
221
+ def cyclic_digraph(n: int = 3, metadata: bool = False) -> Union[sparse.csr_matrix, Dataset]:
222
+ """Cyclic graph (directed).
223
+
224
+ Parameters
225
+ ----------
226
+ n : int
227
+ Number of nodes.
228
+ metadata : bool
229
+ If ``True``, return a `Dataset` object with metadata.
230
+
231
+ Returns
232
+ -------
233
+ adjacency or graph : Union[sparse.csr_matrix, Dataset]
234
+ Adjacency matrix or graph with metadata (positions).
235
+
236
+ Example
237
+ -------
238
+ >>> from sknetwork.data import cyclic_digraph
239
+ >>> adjacency = cyclic_digraph(5)
240
+ >>> adjacency.shape
241
+ (5, 5)
242
+ """
243
+ row = np.arange(n)
244
+ col = np.array(list(np.arange(1, n)) + [0])
245
+ adjacency = sparse.csr_matrix((np.ones(len(row), dtype=int), (row, col)), shape=(n, n))
246
+
247
+ if metadata:
248
+ graph = Dataset()
249
+ graph.adjacency = adjacency
250
+ graph.position = cyclic_position(n)
251
+ return graph
252
+ else:
253
+ return adjacency
254
+
255
+
256
+ def cyclic_graph(n: int = 3, metadata: bool = False) -> Union[sparse.csr_matrix, Dataset]:
257
+ """Cyclic graph (undirected).
258
+
259
+ Parameters
260
+ ----------
261
+ n : int
262
+ Number of nodes.
263
+ metadata : bool
264
+ If ``True``, return a `Dataset` object with metadata.
265
+
266
+ Returns
267
+ -------
268
+ adjacency or graph : Union[sparse.csr_matrix, Dataset]
269
+ Adjacency matrix or graph with metadata (positions).
270
+
271
+ Example
272
+ -------
273
+ >>> from sknetwork.data import cyclic_graph
274
+ >>> adjacency = cyclic_graph(5)
275
+ >>> adjacency.shape
276
+ (5, 5)
277
+ """
278
+ graph = cyclic_digraph(n, True)
279
+ graph.adjacency = directed2undirected(graph.adjacency)
280
+ if metadata:
281
+ return graph
282
+ else:
283
+ return graph.adjacency
284
+
285
+
286
+ def grid(n1: int = 10, n2: int = 10, metadata: bool = False) -> Union[sparse.csr_matrix, Dataset]:
287
+ """Grid (undirected).
288
+
289
+ Parameters
290
+ ----------
291
+ n1, n2 : int
292
+ Grid dimension.
293
+ metadata : bool
294
+ If ``True``, return a `Dataset` object with metadata.
295
+
296
+ Returns
297
+ -------
298
+ adjacency or graph : Union[sparse.csr_matrix, Dataset]
299
+ Adjacency matrix or graph with metadata (positions).
300
+
301
+ Example
302
+ -------
303
+ >>> from sknetwork.data import grid
304
+ >>> adjacency = grid(10, 5)
305
+ >>> adjacency.shape
306
+ (50, 50)
307
+ """
308
+ nodes = [(i1, i2) for i1 in range(n1) for i2 in range(n2)]
309
+ edges = [((i1, i2), (i1 + 1, i2)) for i1 in range(n1 - 1) for i2 in range(n2)]
310
+ edges += [((i1, i2), (i1, i2 + 1)) for i1 in range(n1) for i2 in range(n2 - 1)]
311
+ node_id = {u: i for i, u in enumerate(nodes)}
312
+ edges = list(map(lambda edge: (node_id[edge[0]], node_id[edge[1]]), edges))
313
+ adjacency = from_edge_list(edges, reindex=False, matrix_only=True)
314
+ if metadata:
315
+ graph = Dataset()
316
+ graph.adjacency = adjacency
317
+ graph.position = np.array(nodes)
318
+ return graph
319
+ else:
320
+ return adjacency
321
+
322
+
323
+ def star(n_branches: int = 3, metadata: bool = False) -> Union[sparse.csr_matrix, Dataset]:
324
+ """Star (undirected).
325
+
326
+ Parameters
327
+ ----------
328
+ n_branches : int
329
+ Number of branches.
330
+ metadata : bool
331
+ If ``True``, return a `Dataset` object with metadata (positions).
332
+
333
+ Returns
334
+ -------
335
+ adjacency or graph : Union[sparse.csr_matrix, Dataset]
336
+ Adjacency matrix or graph with metadata (positions).
337
+
338
+ Example
339
+ -------
340
+ >>> from sknetwork.data import star
341
+ >>> adjacency = star()
342
+ >>> adjacency.shape
343
+ (4, 4)
344
+ """
345
+ edges = [(0, i+1) for i in range(n_branches)]
346
+ adjacency = from_edge_list(edges, reindex=False, matrix_only=True)
347
+ if metadata:
348
+ graph = Dataset()
349
+ graph.adjacency = adjacency
350
+ angles = 2 * np.pi * np.arange(n_branches) / n_branches
351
+ x = [0] + list(np.cos(angles))
352
+ y = [0] + list(np.sin(angles))
353
+ graph.position = np.vstack([x, y]).T
354
+ return graph
355
+ else:
356
+ return adjacency
357
+
358
+
359
+ def albert_barabasi(n: int = 100, degree: int = 3, directed: bool = False, seed: Optional[int] = None) \
360
+ -> sparse.csr_matrix:
361
+ """Albert-Barabasi model.
362
+
363
+ Parameters
364
+ ----------
365
+ n : int
366
+ Number of nodes.
367
+ degree : int
368
+ Degree of incoming nodes (less than **n**).
369
+ directed : bool
370
+ If ``True``, return a directed graph.
371
+ seed :
372
+ Seed of the random generator (optional).
373
+
374
+ Returns
375
+ -------
376
+ adjacency : sparse.csr_matrix
377
+ Adjacency matrix.
378
+
379
+ Example
380
+ -------
381
+ >>> from sknetwork.data import albert_barabasi
382
+ >>> adjacency = albert_barabasi(30, 3)
383
+ >>> adjacency.shape
384
+ (30, 30)
385
+
386
+ References
387
+ ----------
388
+ Albert, R., Barabási, L. (2002). `Statistical mechanics of complex networks
389
+ <https://journals.aps.org/rmp/abstract/10.1103/RevModPhys.74.47>`_
390
+ Reviews of Modern Physics.
391
+ """
392
+ random_state = check_random_state(seed)
393
+ degrees = np.zeros(n, int)
394
+ degrees[:degree] = degree - 1
395
+ edges = [(i, j) for i in range(degree) for j in range(i)]
396
+ for i in range(degree, n):
397
+ neighbors = random_state.choice(a=i, p=degrees[:i]/degrees.sum(), size=degree, replace=False)
398
+ degrees[neighbors] += 1
399
+ degrees[i] = degree
400
+ edges += [(i, j) for j in neighbors]
401
+ return from_edge_list(edges, directed=directed, reindex=False, matrix_only=True)
402
+
403
+
404
+ def watts_strogatz(n: int = 100, degree: int = 6, prob: float = 0.05, seed: Optional[int] = None,
405
+ metadata: bool = False) -> Union[sparse.csr_matrix, Dataset]:
406
+ """Watts-Strogatz model.
407
+
408
+ Parameters
409
+ ----------
410
+ n :
411
+ Number of nodes.
412
+ degree :
413
+ Initial degree of nodes.
414
+ prob :
415
+ Probability of edge modification.
416
+ seed :
417
+ Seed of the random generator (optional).
418
+ metadata :
419
+ If ``True``, return a `Dataset` object with metadata.
420
+ Returns
421
+ -------
422
+ adjacency or graph : Union[sparse.csr_matrix, Dataset]
423
+ Adjacency matrix or graph with metadata (positions).
424
+
425
+ Example
426
+ -------
427
+ >>> from sknetwork.data import watts_strogatz
428
+ >>> adjacency = watts_strogatz(30, 4, 0.02)
429
+ >>> adjacency.shape
430
+ (30, 30)
431
+
432
+ References
433
+ ----------
434
+ Watts, D., Strogatz, S. (1998). Collective dynamics of small-world networks, Nature.
435
+ """
436
+ random_state = check_random_state(seed)
437
+ edges = np.array([(i, (i + j + 1) % n) for i in range(n) for j in range(degree // 2)])
438
+ row, col = edges[:, 0], edges[:, 1]
439
+ adjacency = sparse.coo_matrix((np.ones_like(row, int), (row, col)), shape=(n, n))
440
+ adjacency = sparse.lil_matrix(adjacency + adjacency.T)
441
+ nodes = np.arange(n)
442
+ for i in range(n):
443
+ neighbors = adjacency.rows[i]
444
+ candidates = list(set(nodes) - set(neighbors) - {i})
445
+ for j in neighbors:
446
+ if random_state.random() < prob:
447
+ node = random_state.choice(candidates)
448
+ adjacency[i, node] = 1
449
+ adjacency[node, i] = 1
450
+ adjacency[i, j] = 0
451
+ adjacency[j, i] = 0
452
+ adjacency = sparse.csr_matrix(adjacency, shape=adjacency.shape)
453
+ if metadata:
454
+ graph = Dataset()
455
+ graph.adjacency = adjacency
456
+ graph.position = cyclic_position(n)
457
+ return graph
458
+ else:
459
+ return adjacency