hypergraphz 0.1.5__py3-none-win_amd64.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.
@@ -0,0 +1,28 @@
1
+ """HypergraphZ — Python bindings for the HypergraphZ Zig library."""
2
+
3
+ from ._errors import (
4
+ CycleDetectedError,
5
+ HyperedgeNotFoundError,
6
+ HypergraphZError,
7
+ IndexOutOfBoundsError,
8
+ NoPathError,
9
+ NotBuiltError,
10
+ NotEnoughVerticesError,
11
+ VertexNotFoundError,
12
+ )
13
+ from ._graph import Hypergraph
14
+ from ._query import HyperedgeQuery, VertexQuery
15
+
16
+ __all__ = [
17
+ "Hypergraph",
18
+ "HyperedgeQuery",
19
+ "VertexQuery",
20
+ "HypergraphZError",
21
+ "NotBuiltError",
22
+ "VertexNotFoundError",
23
+ "HyperedgeNotFoundError",
24
+ "CycleDetectedError",
25
+ "NoPathError",
26
+ "IndexOutOfBoundsError",
27
+ "NotEnoughVerticesError",
28
+ ]
@@ -0,0 +1,321 @@
1
+ """ctypes declarations for the HypergraphZ shared library.
2
+
3
+ This module is private. Users interact with Hypergraph in _graph.py instead.
4
+ """
5
+
6
+ import ctypes
7
+ import pathlib
8
+ import sys
9
+
10
+ _here = pathlib.Path(__file__).parent
11
+
12
+ _NAMES = {
13
+ "linux": "libhypergraphz.so",
14
+ "darwin": "libhypergraphz.dylib",
15
+ "win32": "hypergraphz.dll",
16
+ }
17
+
18
+ _lib_path = _here / _NAMES.get(sys.platform, "libhypergraphz.so")
19
+ if not _lib_path.exists():
20
+ raise OSError(
21
+ f"HypergraphZ native library not found at {_lib_path}. "
22
+ "Run `zig build lib -Doptimize=ReleaseFast` then copy the output "
23
+ "from zig-out/lib/ into python/hypergraphz/."
24
+ )
25
+
26
+ lib = ctypes.CDLL(str(_lib_path))
27
+
28
+ # ── Types ──────────────────────────────────────────────────────────────────────
29
+
30
+ _Handle = ctypes.c_void_p
31
+ _Id = ctypes.c_uint32
32
+ _PId = ctypes.POINTER(_Id)
33
+ _PPId = ctypes.POINTER(_PId)
34
+ _PSize = ctypes.POINTER(ctypes.c_size_t)
35
+ _PPSize = ctypes.POINTER(ctypes.POINTER(ctypes.c_size_t))
36
+ _PDouble = ctypes.POINTER(ctypes.c_double)
37
+ _PPDouble = ctypes.POINTER(_PDouble)
38
+ _PUInt8 = ctypes.POINTER(ctypes.c_uint8)
39
+ _PPUInt8 = ctypes.POINTER(_PUInt8)
40
+ _PHandle = ctypes.POINTER(_Handle)
41
+
42
+ # ── Error ──────────────────────────────────────────────────────────────────────
43
+
44
+ lib.hgz_last_error.restype = ctypes.c_size_t
45
+ lib.hgz_last_error.argtypes = [ctypes.c_char_p, ctypes.c_size_t]
46
+
47
+ # ── Memory ─────────────────────────────────────────────────────────────────────
48
+
49
+ lib.hgz_free.restype = None
50
+ lib.hgz_free.argtypes = [ctypes.c_void_p]
51
+
52
+ # ── Lifecycle ──────────────────────────────────────────────────────────────────
53
+
54
+ lib.hgz_create.restype = _Handle
55
+ lib.hgz_create.argtypes = []
56
+
57
+ lib.hgz_destroy.restype = None
58
+ lib.hgz_destroy.argtypes = [_Handle]
59
+
60
+ lib.hgz_build.restype = ctypes.c_int
61
+ lib.hgz_build.argtypes = [_Handle]
62
+
63
+ lib.hgz_clear.restype = None
64
+ lib.hgz_clear.argtypes = [_Handle]
65
+
66
+ # ── Vertices ───────────────────────────────────────────────────────────────────
67
+
68
+ lib.hgz_add_vertex.restype = ctypes.c_int
69
+ lib.hgz_add_vertex.argtypes = [_Handle, ctypes.c_char_p, ctypes.c_size_t, ctypes.POINTER(_Id)]
70
+
71
+ lib.hgz_delete_vertex.restype = ctypes.c_int
72
+ lib.hgz_delete_vertex.argtypes = [_Handle, _Id]
73
+
74
+ lib.hgz_update_vertex.restype = ctypes.c_int
75
+ lib.hgz_update_vertex.argtypes = [_Handle, _Id, ctypes.c_char_p, ctypes.c_size_t]
76
+
77
+ lib.hgz_get_vertex_json.restype = ctypes.c_int
78
+ lib.hgz_get_vertex_json.argtypes = [_Handle, _Id, ctypes.POINTER(ctypes.c_char_p), _PSize]
79
+
80
+ lib.hgz_vertex_count.restype = ctypes.c_size_t
81
+ lib.hgz_vertex_count.argtypes = [_Handle]
82
+
83
+ lib.hgz_get_all_vertex_ids.restype = ctypes.c_int
84
+ lib.hgz_get_all_vertex_ids.argtypes = [_Handle, _PPId, _PSize]
85
+
86
+ # ── Hyperedges ─────────────────────────────────────────────────────────────────
87
+
88
+ lib.hgz_add_hyperedge.restype = ctypes.c_int
89
+ lib.hgz_add_hyperedge.argtypes = [_Handle, ctypes.c_char_p, ctypes.c_size_t, ctypes.POINTER(_Id)]
90
+
91
+ lib.hgz_delete_hyperedge.restype = ctypes.c_int
92
+ lib.hgz_delete_hyperedge.argtypes = [_Handle, _Id, ctypes.c_bool]
93
+
94
+ lib.hgz_update_hyperedge.restype = ctypes.c_int
95
+ lib.hgz_update_hyperedge.argtypes = [_Handle, _Id, ctypes.c_char_p, ctypes.c_size_t]
96
+
97
+ lib.hgz_get_hyperedge_json.restype = ctypes.c_int
98
+ lib.hgz_get_hyperedge_json.argtypes = [_Handle, _Id, ctypes.POINTER(ctypes.c_char_p), _PSize]
99
+
100
+ lib.hgz_hyperedge_count.restype = ctypes.c_size_t
101
+ lib.hgz_hyperedge_count.argtypes = [_Handle]
102
+
103
+ lib.hgz_get_all_hyperedge_ids.restype = ctypes.c_int
104
+ lib.hgz_get_all_hyperedge_ids.argtypes = [_Handle, _PPId, _PSize]
105
+
106
+ # ── Relations ──────────────────────────────────────────────────────────────────
107
+
108
+ lib.hgz_append_vertices.restype = ctypes.c_int
109
+ lib.hgz_append_vertices.argtypes = [_Handle, _Id, ctypes.POINTER(_Id), ctypes.c_size_t]
110
+
111
+ lib.hgz_get_hyperedge_vertex_ids.restype = ctypes.c_int
112
+ lib.hgz_get_hyperedge_vertex_ids.argtypes = [_Handle, _Id, _PPId, _PSize]
113
+
114
+ lib.hgz_get_vertex_hyperedge_ids.restype = ctypes.c_int
115
+ lib.hgz_get_vertex_hyperedge_ids.argtypes = [_Handle, _Id, _PPId, _PSize]
116
+
117
+ # ── Traversal ──────────────────────────────────────────────────────────────────
118
+
119
+ lib.hgz_find_shortest_path.restype = ctypes.c_int
120
+ lib.hgz_find_shortest_path.argtypes = [_Handle, _Id, _Id, _PPId, _PSize]
121
+
122
+ lib.hgz_is_connected.restype = ctypes.c_int
123
+ lib.hgz_is_connected.argtypes = [_Handle]
124
+
125
+ # ── Algorithms ─────────────────────────────────────────────────────────────────
126
+
127
+ lib.hgz_get_connected_components.restype = ctypes.c_int
128
+ lib.hgz_get_connected_components.argtypes = [
129
+ _Handle,
130
+ _PPId,
131
+ ctypes.POINTER(ctypes.POINTER(ctypes.c_size_t)),
132
+ _PSize,
133
+ ]
134
+
135
+ lib.hgz_find_cut_vertices.restype = ctypes.c_int
136
+ lib.hgz_find_cut_vertices.argtypes = [_Handle, _PPId, _PSize]
137
+
138
+ lib.hgz_get_vertex_neighborhood.restype = ctypes.c_int
139
+ lib.hgz_get_vertex_neighborhood.argtypes = [_Handle, _Id, _PPId, _PSize]
140
+
141
+ lib.hgz_topological_sort.restype = ctypes.c_int
142
+ lib.hgz_topological_sort.argtypes = [_Handle, _PPId, _PSize]
143
+
144
+ # ── Degree ─────────────────────────────────────────────────────────────────────
145
+
146
+ lib.hgz_get_vertex_indegree.restype = ctypes.c_int
147
+ lib.hgz_get_vertex_indegree.argtypes = [_Handle, _Id, _PSize]
148
+
149
+ lib.hgz_get_vertex_outdegree.restype = ctypes.c_int
150
+ lib.hgz_get_vertex_outdegree.argtypes = [_Handle, _Id, _PSize]
151
+
152
+ # ── Boolean queries ─────────────────────────────────────────────────────────────
153
+
154
+ lib.hgz_is_reachable.restype = ctypes.c_int
155
+ lib.hgz_is_reachable.argtypes = [_Handle, _Id, _Id]
156
+
157
+ lib.hgz_has_cycle.restype = ctypes.c_int
158
+ lib.hgz_has_cycle.argtypes = [_Handle]
159
+
160
+ lib.hgz_is_k_uniform.restype = ctypes.c_int
161
+ lib.hgz_is_k_uniform.argtypes = [_Handle, ctypes.c_size_t]
162
+
163
+ # ── Extended traversal ─────────────────────────────────────────────────────────
164
+
165
+ lib.hgz_bfs.restype = ctypes.c_int
166
+ lib.hgz_bfs.argtypes = [_Handle, _Id, _PPId, _PSize]
167
+
168
+ lib.hgz_dfs.restype = ctypes.c_int
169
+ lib.hgz_dfs.argtypes = [_Handle, _Id, _PPId, _PSize]
170
+
171
+ lib.hgz_random_walk.restype = ctypes.c_int
172
+ lib.hgz_random_walk.argtypes = [_Handle, _Id, ctypes.c_size_t, _PPId, _PSize]
173
+
174
+ # ── Orphan queries ──────────────────────────────────────────────────────────────
175
+
176
+ lib.hgz_get_orphan_vertices.restype = ctypes.c_int
177
+ lib.hgz_get_orphan_vertices.argtypes = [_Handle, _PPId, _PSize]
178
+
179
+ lib.hgz_get_orphan_hyperedges.restype = ctypes.c_int
180
+ lib.hgz_get_orphan_hyperedges.argtypes = [_Handle, _PPId, _PSize]
181
+
182
+ # ── Set operations ─────────────────────────────────────────────────────────────
183
+
184
+ lib.hgz_get_intersections.restype = ctypes.c_int
185
+ lib.hgz_get_intersections.argtypes = [_Handle, ctypes.POINTER(_Id), ctypes.c_size_t, _PPId, _PSize]
186
+
187
+ lib.hgz_get_hyperedges_connecting.restype = ctypes.c_int
188
+ lib.hgz_get_hyperedges_connecting.argtypes = [_Handle, _Id, _Id, _PPId, _PSize]
189
+
190
+ # ── Endpoints ──────────────────────────────────────────────────────────────────
191
+
192
+ lib.hgz_get_endpoints.restype = ctypes.c_int
193
+ lib.hgz_get_endpoints.argtypes = [
194
+ _Handle,
195
+ _PPId,
196
+ _PPId,
197
+ _PSize, # initial: he_ids, v_ids, count
198
+ _PPId,
199
+ _PPId,
200
+ _PSize, # terminal: he_ids, v_ids, count
201
+ ]
202
+
203
+ # ── Relation mutations ─────────────────────────────────────────────────────────
204
+
205
+ lib.hgz_prepend_vertices.restype = ctypes.c_int
206
+ lib.hgz_prepend_vertices.argtypes = [_Handle, _Id, ctypes.POINTER(_Id), ctypes.c_size_t]
207
+
208
+ lib.hgz_insert_vertex.restype = ctypes.c_int
209
+ lib.hgz_insert_vertex.argtypes = [_Handle, _Id, _Id, ctypes.c_size_t]
210
+
211
+ lib.hgz_insert_vertices.restype = ctypes.c_int
212
+ lib.hgz_insert_vertices.argtypes = [
213
+ _Handle,
214
+ _Id,
215
+ ctypes.POINTER(_Id),
216
+ ctypes.c_size_t,
217
+ ctypes.c_size_t,
218
+ ]
219
+
220
+ lib.hgz_remove_vertex_from_hyperedge.restype = ctypes.c_int
221
+ lib.hgz_remove_vertex_from_hyperedge.argtypes = [_Handle, _Id, _Id]
222
+
223
+ lib.hgz_remove_vertex_at_index.restype = ctypes.c_int
224
+ lib.hgz_remove_vertex_at_index.argtypes = [_Handle, _Id, ctypes.c_size_t]
225
+
226
+ # ── Centrality and PageRank ────────────────────────────────────────────────────
227
+
228
+ lib.hgz_compute_centrality.restype = ctypes.c_int
229
+ lib.hgz_compute_centrality.argtypes = [_Handle, _PPId, _PPDouble, _PPDouble, _PPDouble, _PSize]
230
+
231
+ lib.hgz_compute_page_rank.restype = ctypes.c_int
232
+ lib.hgz_compute_page_rank.argtypes = [
233
+ _Handle,
234
+ ctypes.c_double,
235
+ ctypes.c_size_t,
236
+ ctypes.c_double,
237
+ _PPId,
238
+ _PPDouble,
239
+ _PSize,
240
+ _PSize,
241
+ ctypes.POINTER(ctypes.c_bool),
242
+ ]
243
+
244
+ # ── Structural analysis ────────────────────────────────────────────────────────
245
+
246
+ lib.hgz_get_inclusions.restype = ctypes.c_int
247
+ lib.hgz_get_inclusions.argtypes = [_Handle, _PPId, _PPId, _PSize]
248
+
249
+ lib.hgz_get_nestedness_profile.restype = ctypes.c_int
250
+ lib.hgz_get_nestedness_profile.argtypes = [_Handle, _PPSize, _PPSize, _PPSize, _PSize]
251
+
252
+ lib.hgz_incidence_matrix.restype = ctypes.c_int
253
+ lib.hgz_incidence_matrix.argtypes = [_Handle, _PPUInt8, _PPId, _PPId, _PSize, _PSize]
254
+
255
+ lib.hgz_incidence_matrix_coo.restype = ctypes.c_int
256
+ lib.hgz_incidence_matrix_coo.argtypes = [
257
+ _Handle,
258
+ _PPId,
259
+ _PPId, # row_indices, col_indices
260
+ _PPId,
261
+ _PPId, # vertex_ids, hyperedge_ids
262
+ _PSize,
263
+ _PSize,
264
+ _PSize, # nnz, n_vertices, n_hyperedges
265
+ ]
266
+
267
+ lib.hgz_laplacian.restype = ctypes.c_int
268
+ lib.hgz_laplacian.argtypes = [_Handle, ctypes.c_uint8, _PPDouble, _PPId, _PSize]
269
+
270
+ lib.hgz_find_all_paths.restype = ctypes.c_int
271
+ lib.hgz_find_all_paths.argtypes = [_Handle, _Id, _Id, _PPId, _PPSize, _PSize]
272
+
273
+ # ── Sub-graph operations ───────────────────────────────────────────────────────
274
+
275
+ lib.hgz_clone.restype = ctypes.c_int
276
+ lib.hgz_clone.argtypes = [_Handle, _PHandle]
277
+
278
+ lib.hgz_get_dual.restype = ctypes.c_int
279
+ lib.hgz_get_dual.argtypes = [_Handle, _PHandle]
280
+
281
+ lib.hgz_get_k_skeleton.restype = ctypes.c_int
282
+ lib.hgz_get_k_skeleton.argtypes = [_Handle, ctypes.c_size_t, _PHandle]
283
+
284
+ lib.hgz_expand_to_graph.restype = ctypes.c_int
285
+ lib.hgz_expand_to_graph.argtypes = [_Handle, _PHandle]
286
+
287
+ lib.hgz_expand_to_star.restype = ctypes.c_int
288
+ lib.hgz_expand_to_star.argtypes = [_Handle, _PHandle]
289
+
290
+ lib.hgz_get_line_graph.restype = ctypes.c_int
291
+ lib.hgz_get_line_graph.argtypes = [_Handle, _PHandle]
292
+
293
+ lib.hgz_get_vertex_induced_subhypergraph.restype = ctypes.c_int
294
+ lib.hgz_get_vertex_induced_subhypergraph.argtypes = [
295
+ _Handle,
296
+ ctypes.POINTER(_Id),
297
+ ctypes.c_size_t,
298
+ _PHandle,
299
+ ]
300
+
301
+ lib.hgz_get_edge_induced_subhypergraph.restype = ctypes.c_int
302
+ lib.hgz_get_edge_induced_subhypergraph.argtypes = [
303
+ _Handle,
304
+ ctypes.POINTER(_Id),
305
+ ctypes.c_size_t,
306
+ _PHandle,
307
+ ]
308
+
309
+ lib.hgz_get_core.restype = ctypes.c_int
310
+ lib.hgz_get_core.argtypes = [_Handle, ctypes.c_size_t, ctypes.c_size_t, _PHandle]
311
+
312
+ lib.hgz_get_transitive_closure.restype = ctypes.c_int
313
+ lib.hgz_get_transitive_closure.argtypes = [_Handle, _PHandle]
314
+
315
+ # ── Codec ──────────────────────────────────────────────────────────────────────
316
+
317
+ lib.hgz_save.restype = ctypes.c_int
318
+ lib.hgz_save.argtypes = [_Handle, ctypes.c_char_p]
319
+
320
+ lib.hgz_load.restype = ctypes.c_int
321
+ lib.hgz_load.argtypes = [ctypes.c_char_p, ctypes.POINTER(_Handle)]
hypergraphz/_errors.py ADDED
@@ -0,0 +1,55 @@
1
+ import ctypes
2
+
3
+
4
+ class HypergraphZError(Exception):
5
+ pass
6
+
7
+
8
+ class NotBuiltError(HypergraphZError):
9
+ pass
10
+
11
+
12
+ class VertexNotFoundError(HypergraphZError):
13
+ pass
14
+
15
+
16
+ class HyperedgeNotFoundError(HypergraphZError):
17
+ pass
18
+
19
+
20
+ class CycleDetectedError(HypergraphZError):
21
+ pass
22
+
23
+
24
+ class NoPathError(HypergraphZError):
25
+ pass
26
+
27
+
28
+ class IndexOutOfBoundsError(HypergraphZError):
29
+ pass
30
+
31
+
32
+ class NotEnoughVerticesError(HypergraphZError):
33
+ pass
34
+
35
+
36
+ _CODE_TO_EXC: dict[int, type[HypergraphZError]] = {
37
+ -2: NotBuiltError,
38
+ -3: VertexNotFoundError,
39
+ -4: HyperedgeNotFoundError,
40
+ -5: CycleDetectedError,
41
+ -7: NoPathError,
42
+ -8: IndexOutOfBoundsError,
43
+ -9: NotEnoughVerticesError,
44
+ }
45
+
46
+
47
+ def raise_for_code(code: int, lib: ctypes.CDLL) -> None:
48
+ """Raise the appropriate exception for a negative return code."""
49
+ if code >= 0:
50
+ return
51
+ buf = ctypes.create_string_buffer(512)
52
+ n = lib.hgz_last_error(buf, 512)
53
+ msg = buf.raw[:n].decode("utf-8", errors="replace")
54
+ exc_type = _CODE_TO_EXC.get(code, HypergraphZError)
55
+ raise exc_type(msg)