helios-network 0.10.1__tar.gz

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.
Files changed (30) hide show
  1. helios_network-0.10.1/PKG-INFO +239 -0
  2. helios_network-0.10.1/README.md +225 -0
  3. helios_network-0.10.1/docs/API.md +142 -0
  4. helios_network-0.10.1/docs/PYDOC.md +77 -0
  5. helios_network-0.10.1/examples/attributes.py +16 -0
  6. helios_network-0.10.1/examples/basic_usage.py +14 -0
  7. helios_network-0.10.1/examples/conversions.py +27 -0
  8. helios_network-0.10.1/examples/generate_umap_example_networks.py +244 -0
  9. helios_network-0.10.1/examples/saving_loading.py +15 -0
  10. helios_network-0.10.1/examples/selectors.py +22 -0
  11. helios_network-0.10.1/examples/toroidal_dimensions_plot.py +216 -0
  12. helios_network-0.10.1/examples/toroidal_dimensions_table.py +110 -0
  13. helios_network-0.10.1/examples/toroidal_methods_order2_plot.py +418 -0
  14. helios_network-0.10.1/examples/toroidal_order2_method_average_fivex_r40.png +0 -0
  15. helios_network-0.10.1/examples/toroidal_order2_method_average_large.png +0 -0
  16. helios_network-0.10.1/examples/toroidal_order2_method_average_tenx_r40.png +0 -0
  17. helios_network-0.10.1/examples/toroidal_order2_method_average_xlarge.png +0 -0
  18. helios_network-0.10.1/examples/toroidal_order2_method_average_xlarge_r40.png +0 -0
  19. helios_network-0.10.1/examples/toroidal_order2_method_average_xxlarge_r40.png +0 -0
  20. helios_network-0.10.1/meson.build +96 -0
  21. helios_network-0.10.1/pyproject.toml +28 -0
  22. helios_network-0.10.1/src/helios_network/__init__.py +291 -0
  23. helios_network-0.10.1/src/helios_network/_conversions.py +272 -0
  24. helios_network-0.10.1/src/helios_network/_core.c +3675 -0
  25. helios_network-0.10.1/src/helios_network/_node_link_json.py +313 -0
  26. helios_network-0.10.1/src/helios_network/_wrapper.py +2419 -0
  27. helios_network-0.10.1/src/helios_network/umap.py +556 -0
  28. helios_network-0.10.1/tests/test_conversions.py +56 -0
  29. helios_network-0.10.1/tests/test_network.py +869 -0
  30. helios_network-0.10.1/tests/test_umap.py +216 -0
@@ -0,0 +1,239 @@
1
+ Metadata-Version: 2.1
2
+ Name: helios-network
3
+ Version: 0.10.1
4
+ Summary: Helios Network Python bindings
5
+ Author: Helios
6
+ License: MIT
7
+ Requires-Python: >=3.9
8
+ Provides-Extra: umap
9
+ Requires-Dist: numpy>=1.23; extra == "umap"
10
+ Requires-Dist: scipy>=1.10; extra == "umap"
11
+ Requires-Dist: umap-learn>=0.5.7; extra == "umap"
12
+ Requires-Dist: pynndescent>=0.5.12; extra == "umap"
13
+ Description-Content-Type: text/markdown
14
+
15
+ # Helios Network (Python)
16
+
17
+ Python bindings for the Helios Network C core.
18
+
19
+ ## Quick start
20
+
21
+ ```python
22
+ from helios_network import AttributeScope, AttributeType, Network
23
+
24
+ network = Network(directed=False)
25
+ node_ids = network.add_nodes(3)
26
+ network.add_edges([(node_ids[0], node_ids[1])])
27
+
28
+ network.define_attribute(AttributeScope.Node, "weight", AttributeType.Double, 1)
29
+ network.nodes["weight"] = 1.0
30
+
31
+ # Auto-define attributes on assignment
32
+ network.nodes["score"] = 2.5
33
+
34
+ network.define_attribute(AttributeScope.Network, "title", AttributeType.String, 1)
35
+ network.network["title"] = "demo"
36
+ print(network.graph["title"])
37
+ network["title"] = "demo2"
38
+
39
+ # Node access
40
+ print(network.nodes[node_ids[0]]["weight"])
41
+ network.nodes[[node_ids[0], node_ids[1]]]["weight"] = [2.0, 3.0]
42
+
43
+ for node in network.nodes:
44
+ node["weight"] = 4.0
45
+ ```
46
+
47
+ ## Selectors
48
+
49
+ - `network.nodes[id]` returns a node view
50
+ - `network.nodes[[id1, id2]]` returns a selector for active nodes
51
+ - `network.nodes["attr"]` returns a list of attribute values for active nodes
52
+ - `network.nodes["attr"] = value` assigns a constant to all active nodes
53
+ - `network.nodes[[id1, id2]]["attr"] = [v1, v2]` assigns per-node values
54
+
55
+ Edge access mirrors node access via `network.edges`, with `network.edges.pairs()` yielding `(source, target)` tuples.
56
+
57
+ For large generated graphs, avoid materializing Python `(source, target)` tuples:
58
+
59
+ ```python
60
+ from array import array
61
+
62
+ network.add_nodes(1_000_000)
63
+ network.add_edges_from_arrays(
64
+ array("I", sources),
65
+ array("I", targets),
66
+ )
67
+ ```
68
+
69
+ ## Network Generators
70
+
71
+ The Python package exposes native generators as module-level constructors:
72
+
73
+ ```python
74
+ from helios_network import generate_watts_strogatz
75
+
76
+ network = generate_watts_strogatz(
77
+ 5_000,
78
+ neighbor_level=2,
79
+ rewiring_probability=0.01,
80
+ seed=1,
81
+ )
82
+ ```
83
+
84
+ Available generators include `generate_stochastic_block_model`,
85
+ `generate_barabasi_albert`, `generate_watts_strogatz`,
86
+ `generate_random_geometric`, `generate_waxman`,
87
+ `generate_configuration_model`, and `generate_lattice_2d`.
88
+
89
+ ### Edge indices
90
+
91
+ ```python
92
+ for edge_id, (source, target) in network.edges.with_indices():
93
+ print(edge_id, source, target)
94
+ ```
95
+
96
+ ## Measurements and Community Detection
97
+
98
+ The Python wrapper exposes the native measurement APIs:
99
+
100
+ ```python
101
+ degree = network.measure_degree(direction="both")
102
+ components = network.measure_connected_components(mode="weak")
103
+ leiden = network.leiden_modularity(
104
+ resolution=1.0,
105
+ seed=42,
106
+ out_node_community_attribute="community",
107
+ )
108
+ ```
109
+
110
+ `leiden_modularity(...)` is an alias for `measure_leiden_modularity(...)`. It
111
+ writes an unsigned-integer node attribute and returns `community_count`,
112
+ `modularity`, and `values_by_node`.
113
+
114
+ To label only major components for filtering or visualization:
115
+
116
+ ```python
117
+ major = network.label_major_components(
118
+ mode="weak",
119
+ max_components=3,
120
+ min_size=100,
121
+ out_node_component_attribute="major_component",
122
+ )
123
+ ```
124
+
125
+ Selected components receive rank labels `1..N` by decreasing size. Other nodes
126
+ receive `0` by default.
127
+
128
+ The Leiden comparison harness in `research/benchmarks/leiden_compare/` uses a
129
+ conda environment file:
130
+
131
+ ```bash
132
+ conda env create -f research/benchmarks/leiden_compare/environment.yml
133
+ conda run -n helios-leiden-compare python -m pip install -e python --no-build-isolation
134
+ conda run -n helios-leiden-compare python research/benchmarks/leiden_compare/compare_leiden.py
135
+ ```
136
+
137
+ ## Installation
138
+
139
+ Standard install:
140
+
141
+ ```bash
142
+ python -m pip install ./python --upgrade
143
+ ```
144
+
145
+ Editable install (recommended during development):
146
+
147
+ ```bash
148
+ python -m pip install -e python --no-build-isolation
149
+ ```
150
+
151
+ `mesonpy` editable builds require `--no-build-isolation`.
152
+
153
+ If editable install fails, install build tools in the active environment:
154
+
155
+ ```bash
156
+ python -m pip install meson ninja meson-python
157
+ python -m pip install -e python --no-build-isolation
158
+ ```
159
+
160
+ ## Optional conversions
161
+
162
+ NetworkX and igraph conversions are optional. Install when needed:
163
+
164
+ ```bash
165
+ python -m pip install networkx
166
+ python -m pip install igraph
167
+ ```
168
+
169
+ ## UMAP export
170
+
171
+ Install the optional UMAP stack when you want a Helios-ready fuzzy graph or
172
+ kNN graph export:
173
+
174
+ ```bash
175
+ python -m pip install ./python[umap]
176
+ ```
177
+
178
+ ```python
179
+ from helios_network import HeliosUMAP
180
+
181
+ umap_export = HeliosUMAP(
182
+ n_neighbors=15,
183
+ min_dist=0.1,
184
+ build_knn_network=True,
185
+ )
186
+
187
+ network = umap_export.fit_network(X)
188
+ network.save_bxnet("embedding.bxnet")
189
+
190
+ # Optional directed kNN export
191
+ umap_export.knn_network_.save_zxnet("embedding-knn.zxnet")
192
+ ```
193
+
194
+ If you want only the UMAP graph construction output for `helios-web-next`
195
+ to lay out from scratch, use the graph-only export path instead:
196
+
197
+ ```python
198
+ graph_network = umap_export.fit_graph_network(X)
199
+ graph_network.save_zxnet("umap-graph.zxnet")
200
+ ```
201
+
202
+ The fit graph export writes:
203
+
204
+ - node attributes: `umap_embedding`, `_helios_visuals_position`, `umap_mass`
205
+ - edge attribute: `umap_weight`
206
+ - network attributes that let `helios-web-next` auto-enable UMAP force mode on import
207
+
208
+ The graph-only export writes the same UMAP edge weights and graph metadata, but
209
+ omits `umap_embedding` and `_helios_visuals_position` so `helios-web-next` can
210
+ start its own realtime UMAP-like layout from scratch.
211
+
212
+ ## Examples
213
+
214
+ From `python/`:
215
+
216
+ ```bash
217
+ python examples/basic_usage.py
218
+ python examples/toroidal_dimensions_table.py
219
+ python examples/toroidal_dimensions_plot.py --skip-plot
220
+ python examples/toroidal_dimensions_plot.py
221
+ python examples/toroidal_dimensions_plot.py --large --skip-plot
222
+ python examples/generate_umap_example_networks.py --sizes 200 2000 20000
223
+ ```
224
+
225
+ `toroidal_dimensions_plot.py` uses `matplotlib` for plotting local dimension curves. Install it with:
226
+
227
+ ```bash
228
+ python -m pip install matplotlib
229
+ ```
230
+
231
+ ## Vector attributes
232
+
233
+ Attributes with dimension > 1 accept vector assignments:
234
+
235
+ ```python
236
+ network.define_attribute(AttributeScope.Node, "i3", AttributeType.Integer, 3)
237
+ network.nodes["i3"] = [1, 2, 3] # broadcast to all nodes
238
+ network.nodes[[0, 1]]["i3"] = [[4, 5, 6], [7, 8, 9]]
239
+ ```
@@ -0,0 +1,225 @@
1
+ # Helios Network (Python)
2
+
3
+ Python bindings for the Helios Network C core.
4
+
5
+ ## Quick start
6
+
7
+ ```python
8
+ from helios_network import AttributeScope, AttributeType, Network
9
+
10
+ network = Network(directed=False)
11
+ node_ids = network.add_nodes(3)
12
+ network.add_edges([(node_ids[0], node_ids[1])])
13
+
14
+ network.define_attribute(AttributeScope.Node, "weight", AttributeType.Double, 1)
15
+ network.nodes["weight"] = 1.0
16
+
17
+ # Auto-define attributes on assignment
18
+ network.nodes["score"] = 2.5
19
+
20
+ network.define_attribute(AttributeScope.Network, "title", AttributeType.String, 1)
21
+ network.network["title"] = "demo"
22
+ print(network.graph["title"])
23
+ network["title"] = "demo2"
24
+
25
+ # Node access
26
+ print(network.nodes[node_ids[0]]["weight"])
27
+ network.nodes[[node_ids[0], node_ids[1]]]["weight"] = [2.0, 3.0]
28
+
29
+ for node in network.nodes:
30
+ node["weight"] = 4.0
31
+ ```
32
+
33
+ ## Selectors
34
+
35
+ - `network.nodes[id]` returns a node view
36
+ - `network.nodes[[id1, id2]]` returns a selector for active nodes
37
+ - `network.nodes["attr"]` returns a list of attribute values for active nodes
38
+ - `network.nodes["attr"] = value` assigns a constant to all active nodes
39
+ - `network.nodes[[id1, id2]]["attr"] = [v1, v2]` assigns per-node values
40
+
41
+ Edge access mirrors node access via `network.edges`, with `network.edges.pairs()` yielding `(source, target)` tuples.
42
+
43
+ For large generated graphs, avoid materializing Python `(source, target)` tuples:
44
+
45
+ ```python
46
+ from array import array
47
+
48
+ network.add_nodes(1_000_000)
49
+ network.add_edges_from_arrays(
50
+ array("I", sources),
51
+ array("I", targets),
52
+ )
53
+ ```
54
+
55
+ ## Network Generators
56
+
57
+ The Python package exposes native generators as module-level constructors:
58
+
59
+ ```python
60
+ from helios_network import generate_watts_strogatz
61
+
62
+ network = generate_watts_strogatz(
63
+ 5_000,
64
+ neighbor_level=2,
65
+ rewiring_probability=0.01,
66
+ seed=1,
67
+ )
68
+ ```
69
+
70
+ Available generators include `generate_stochastic_block_model`,
71
+ `generate_barabasi_albert`, `generate_watts_strogatz`,
72
+ `generate_random_geometric`, `generate_waxman`,
73
+ `generate_configuration_model`, and `generate_lattice_2d`.
74
+
75
+ ### Edge indices
76
+
77
+ ```python
78
+ for edge_id, (source, target) in network.edges.with_indices():
79
+ print(edge_id, source, target)
80
+ ```
81
+
82
+ ## Measurements and Community Detection
83
+
84
+ The Python wrapper exposes the native measurement APIs:
85
+
86
+ ```python
87
+ degree = network.measure_degree(direction="both")
88
+ components = network.measure_connected_components(mode="weak")
89
+ leiden = network.leiden_modularity(
90
+ resolution=1.0,
91
+ seed=42,
92
+ out_node_community_attribute="community",
93
+ )
94
+ ```
95
+
96
+ `leiden_modularity(...)` is an alias for `measure_leiden_modularity(...)`. It
97
+ writes an unsigned-integer node attribute and returns `community_count`,
98
+ `modularity`, and `values_by_node`.
99
+
100
+ To label only major components for filtering or visualization:
101
+
102
+ ```python
103
+ major = network.label_major_components(
104
+ mode="weak",
105
+ max_components=3,
106
+ min_size=100,
107
+ out_node_component_attribute="major_component",
108
+ )
109
+ ```
110
+
111
+ Selected components receive rank labels `1..N` by decreasing size. Other nodes
112
+ receive `0` by default.
113
+
114
+ The Leiden comparison harness in `research/benchmarks/leiden_compare/` uses a
115
+ conda environment file:
116
+
117
+ ```bash
118
+ conda env create -f research/benchmarks/leiden_compare/environment.yml
119
+ conda run -n helios-leiden-compare python -m pip install -e python --no-build-isolation
120
+ conda run -n helios-leiden-compare python research/benchmarks/leiden_compare/compare_leiden.py
121
+ ```
122
+
123
+ ## Installation
124
+
125
+ Standard install:
126
+
127
+ ```bash
128
+ python -m pip install ./python --upgrade
129
+ ```
130
+
131
+ Editable install (recommended during development):
132
+
133
+ ```bash
134
+ python -m pip install -e python --no-build-isolation
135
+ ```
136
+
137
+ `mesonpy` editable builds require `--no-build-isolation`.
138
+
139
+ If editable install fails, install build tools in the active environment:
140
+
141
+ ```bash
142
+ python -m pip install meson ninja meson-python
143
+ python -m pip install -e python --no-build-isolation
144
+ ```
145
+
146
+ ## Optional conversions
147
+
148
+ NetworkX and igraph conversions are optional. Install when needed:
149
+
150
+ ```bash
151
+ python -m pip install networkx
152
+ python -m pip install igraph
153
+ ```
154
+
155
+ ## UMAP export
156
+
157
+ Install the optional UMAP stack when you want a Helios-ready fuzzy graph or
158
+ kNN graph export:
159
+
160
+ ```bash
161
+ python -m pip install ./python[umap]
162
+ ```
163
+
164
+ ```python
165
+ from helios_network import HeliosUMAP
166
+
167
+ umap_export = HeliosUMAP(
168
+ n_neighbors=15,
169
+ min_dist=0.1,
170
+ build_knn_network=True,
171
+ )
172
+
173
+ network = umap_export.fit_network(X)
174
+ network.save_bxnet("embedding.bxnet")
175
+
176
+ # Optional directed kNN export
177
+ umap_export.knn_network_.save_zxnet("embedding-knn.zxnet")
178
+ ```
179
+
180
+ If you want only the UMAP graph construction output for `helios-web-next`
181
+ to lay out from scratch, use the graph-only export path instead:
182
+
183
+ ```python
184
+ graph_network = umap_export.fit_graph_network(X)
185
+ graph_network.save_zxnet("umap-graph.zxnet")
186
+ ```
187
+
188
+ The fit graph export writes:
189
+
190
+ - node attributes: `umap_embedding`, `_helios_visuals_position`, `umap_mass`
191
+ - edge attribute: `umap_weight`
192
+ - network attributes that let `helios-web-next` auto-enable UMAP force mode on import
193
+
194
+ The graph-only export writes the same UMAP edge weights and graph metadata, but
195
+ omits `umap_embedding` and `_helios_visuals_position` so `helios-web-next` can
196
+ start its own realtime UMAP-like layout from scratch.
197
+
198
+ ## Examples
199
+
200
+ From `python/`:
201
+
202
+ ```bash
203
+ python examples/basic_usage.py
204
+ python examples/toroidal_dimensions_table.py
205
+ python examples/toroidal_dimensions_plot.py --skip-plot
206
+ python examples/toroidal_dimensions_plot.py
207
+ python examples/toroidal_dimensions_plot.py --large --skip-plot
208
+ python examples/generate_umap_example_networks.py --sizes 200 2000 20000
209
+ ```
210
+
211
+ `toroidal_dimensions_plot.py` uses `matplotlib` for plotting local dimension curves. Install it with:
212
+
213
+ ```bash
214
+ python -m pip install matplotlib
215
+ ```
216
+
217
+ ## Vector attributes
218
+
219
+ Attributes with dimension > 1 accept vector assignments:
220
+
221
+ ```python
222
+ network.define_attribute(AttributeScope.Node, "i3", AttributeType.Integer, 3)
223
+ network.nodes["i3"] = [1, 2, 3] # broadcast to all nodes
224
+ network.nodes[[0, 1]]["i3"] = [[4, 5, 6], [7, 8, 9]]
225
+ ```
@@ -0,0 +1,142 @@
1
+ # Helios Network Python API
2
+
3
+ ## Overview
4
+
5
+ The Python bindings expose a high-level `Network` class with convenient node/edge/network selectors. Attributes are backed by the native Helios core and can be created explicitly or implicitly.
6
+
7
+ Key concepts:
8
+ - `network.nodes`, `network.edges`: active-only selectors that allow iteration and batch attribute assignment.
9
+ - `network.network` / `network.graph`: network-scope attribute access (single record).
10
+ - `network["attr"]`: shorthand for network-scope attribute access.
11
+
12
+ ## Creating Networks
13
+
14
+ ```python
15
+ from helios_network import Network
16
+
17
+ network = Network(directed=False)
18
+ ```
19
+
20
+ ### Constructor
21
+
22
+ `Network(directed: bool = False, node_capacity: int | None = None, edge_capacity: int | None = None)`
23
+
24
+ - `directed`: If `True`, edges are directed.
25
+ - `node_capacity`, `edge_capacity`: Optional initial capacities.
26
+
27
+ ## Nodes and Edges
28
+
29
+ ### Iteration
30
+
31
+ ```python
32
+ for node in network.nodes:
33
+ print(node.id)
34
+
35
+ for edge in network.edges:
36
+ print(edge.id, edge.endpoints)
37
+ ```
38
+
39
+ ### Edge pairs
40
+
41
+ ```python
42
+ for source, target in network.edges.pairs():
43
+ print(source, target)
44
+ ```
45
+
46
+ ### Edge indices + endpoints
47
+
48
+ ```python
49
+ for edge_id, (source, target) in network.edges.with_indices():
50
+ print(edge_id, source, target)
51
+ ```
52
+
53
+ ## Attributes
54
+
55
+ ### Auto-definition
56
+
57
+ Assigning to an unknown attribute name will create it automatically based on the assigned value.
58
+
59
+ ```python
60
+ network.nodes["weight"] = 1.0 # creates Double attribute, dimension 1
61
+ network.nodes["i3"] = [1, 2, 3] # creates Integer attribute, dimension 3
62
+ network.edges["weight"] = 0.5 # creates Double attribute on edges
63
+ network["title"] = "demo" # creates String attribute on network scope
64
+ ```
65
+
66
+ ### Explicit definition
67
+
68
+ ```python
69
+ from helios_network import AttributeScope, AttributeType
70
+
71
+ network.define_attribute(AttributeScope.Node, "score", AttributeType.Double, 1)
72
+ ```
73
+
74
+ ### Collection helpers
75
+
76
+ ```python
77
+ network.nodes.define_attribute("score", float)
78
+ network.edges.define_attribute("weight", AttributeType.Double)
79
+ network.network.define_attribute("title", str)
80
+ ```
81
+
82
+ ### Attribute access
83
+
84
+ ```python
85
+ # Single node
86
+ network.nodes[node_id]["score"] = 1.5
87
+ value = network.nodes[node_id]["score"]
88
+
89
+ # Selector
90
+ network.nodes[[id1, id2]]["score"] = [1.0, 2.0]
91
+ values = network.nodes[[id1, id2]]["score"]
92
+
93
+ # All nodes
94
+ network.nodes["score"] = 2.0
95
+ ```
96
+
97
+ ### Vector attributes (dimension > 1)
98
+
99
+ ```python
100
+ network.nodes["i3"] = [1, 2, 3] # broadcast
101
+ network.nodes[[id1, id2]]["i3"] = [[1, 2, 3], [4, 5, 6]]
102
+ ```
103
+
104
+ NumPy arrays with shape `(dim,)` or `(count, dim)` are supported when NumPy is installed.
105
+
106
+ ## Categorical attributes
107
+
108
+ ```python
109
+ network.nodes["label"] = ["a", "b", "a"]
110
+ network.categorize_attribute(AttributeScope.Node, "label")
111
+
112
+ mapping = network.get_category_dictionary(AttributeScope.Node, "label")
113
+ # mapping: {"a": 0, "b": 1, ...}
114
+
115
+ network.set_category_dictionary(AttributeScope.Node, "label", {"x": 10, "y": 11}, remap_existing=True)
116
+ network.decategorize_attribute(AttributeScope.Node, "label")
117
+ ```
118
+
119
+ ## Serialization
120
+
121
+ ```python
122
+ network.save_xnet("graph.xnet")
123
+ network.save_bxnet("graph.bxnet")
124
+ network.save_zxnet("graph.zxnet")
125
+ network.save_gml("graph.gml")
126
+ network.save_node_link_json("graph.json")
127
+
128
+ loaded = read_xnet("graph.xnet")
129
+ loaded_gml = read_gml("graph.gml")
130
+ loaded_json = read_node_link_json("graph.json")
131
+ ```
132
+
133
+ ## Conversions
134
+
135
+ ```python
136
+ from helios_network import to_networkx, from_networkx
137
+
138
+ nx_graph = to_networkx(network)
139
+ network2 = from_networkx(nx_graph)
140
+ ```
141
+
142
+ `to_igraph` / `from_igraph` are available when `igraph` is installed.
@@ -0,0 +1,77 @@
1
+ # Helios Network Python Docstrings
2
+
3
+ Below is a summary of the main classes and methods exposed in the Python API.
4
+ This complements the inline docstrings and `python/docs/API.md`.
5
+
6
+ ## Network
7
+
8
+ `Network(directed=False, node_capacity=None, edge_capacity=None)`
9
+
10
+ - Creates a network wrapper around the native core.
11
+ - Properties:
12
+ - `nodes`, `edges`: active selectors
13
+ - `network`, `graph`, `attributes`: network-scope selectors
14
+ - `__getitem__(name)` / `__setitem__(name, value)`: network-scope shorthand
15
+
16
+ ### Common methods
17
+
18
+ - `node_count() -> int`
19
+ - `edge_count() -> int`
20
+ - `add_nodes(count) -> list[int]`
21
+ - `remove_nodes(indices) -> bool`
22
+ - `add_edges([(from, to), ...]) -> list[int]`
23
+ - `remove_edges(indices) -> bool`
24
+ - `node_indices() -> list[int]`
25
+ - `edge_indices() -> list[int]`
26
+ - `edges_with_indices() -> list[(edge_id, (source, target))]`
27
+
28
+ ### Attribute methods
29
+
30
+ - `define_attribute(scope, name, type, dimension=1) -> bool`
31
+ - `nodes.define_attribute(name, type, dimension=1) -> bool`
32
+ - `edges.define_attribute(name, type, dimension=1) -> bool`
33
+ - `network.define_attribute(name, type, dimension=1) -> bool`
34
+ - `attribute_info(scope, name) -> dict`
35
+ - `set_attribute_value(scope, name, index, value) -> bool`
36
+ - `get_attribute_value(scope, name, index)`
37
+
38
+ ### Categorical helpers
39
+
40
+ - `categorize_attribute(scope, name, sort_order=None, missing_label=None) -> bool`
41
+ - `decategorize_attribute(scope, name, missing_label=None) -> bool`
42
+ - `get_category_dictionary(scope, name) -> dict[label, id]`
43
+ - `set_category_dictionary(scope, name, mapping_or_pairs, remap_existing=True) -> bool`
44
+
45
+ ### Serialization
46
+
47
+ - `save_xnet(path)`
48
+ - `save_bxnet(path)`
49
+ - `save_zxnet(path, compression=6)`
50
+ - `save_gml(path)`
51
+ - `save_node_link_json(path)`
52
+ - `read_gml(path)`
53
+ - `read_node_link_json(path)`
54
+
55
+ ## NodeCollection / EdgeCollection
56
+
57
+ Selectors for active nodes/edges. Support iteration and vectorized assignment.
58
+
59
+ ### Common behaviors
60
+
61
+ - `collection[id]` -> `NodeView` / `EdgeView`
62
+ - `collection[[ids]]` -> selector for multiple items
63
+ - `collection["attr"]` -> list of values
64
+ - `collection["attr"] = value` -> broadcast or per-item assignment
65
+
66
+ ### Convenience
67
+
68
+ - `nodes.define_attribute(name, type, dimension=1)`
69
+ - `edges.define_attribute(name, type, dimension=1)`
70
+ - `network.define_attribute(name, type, dimension=1)`
71
+
72
+ ## NodeView / EdgeView / NetworkView
73
+
74
+ Simple wrappers around a single item (node, edge, network).
75
+
76
+ - `node["attr"]` / `edge["attr"]` / `network["attr"]`
77
+ - `edge.endpoints -> (source, target)`
@@ -0,0 +1,16 @@
1
+ from helios_network import AttributeScope, AttributeType, Network
2
+
3
+ network = Network(directed=True)
4
+ node_ids = network.add_nodes(3)
5
+
6
+ network.define_attribute(AttributeScope.Node, "weight", AttributeType.Double, 1)
7
+ network.define_attribute(AttributeScope.Node, "label", AttributeType.String, 1)
8
+
9
+ network.nodes["weight"] = 1.0
10
+ network.nodes["label"] = [f"node-{idx}" for idx in range(len(node_ids))]
11
+
12
+ network.nodes[[node_ids[0], node_ids[2]]]["weight"] = [2.5, 3.5]
13
+
14
+ for node in network.nodes:
15
+ print(node)
16
+ print(node.id, node["weight"], node["label"])
@@ -0,0 +1,14 @@
1
+ from helios_network import Network
2
+
3
+ network = Network(directed=False)
4
+ node_ids = network.add_nodes(4)
5
+ edge_ids = network.add_edges([
6
+ (node_ids[0], node_ids[1]),
7
+ (node_ids[1], node_ids[2]),
8
+ (node_ids[2], node_ids[3]),
9
+ ])
10
+
11
+ print("nodes:", node_ids)
12
+ print("edges:", edge_ids)
13
+ print("node_count:", network.node_count())
14
+ print("edge_count:", network.edge_count())