Skip to content

Commit 38a50ab

Browse files
committed
feat: more conversion functions
1 parent 4e176d3 commit 38a50ab

File tree

4 files changed

+237
-25
lines changed

4 files changed

+237
-25
lines changed

src/codegen/internal_functions.py.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ from .types import (
2020
from .wrappers import _Graph, _Matrix, _MatrixInt, _Vector, _VectorBool, _VectorInt
2121

2222
# fmt: off
23+
# flake8: noqa: E743
2324
# The rest of this file is generated by Stimulus

src/codegen/types.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,15 @@ VERTEX:
108108
IN: "%C% = vertexlike_to_igraph_integer_t(%I%)"
109109
OUT: "%C% = igraph_integer_t(0)"
110110

111+
VERTEX_COLOR:
112+
PY_TYPE: Iterable[int]
113+
PY_RETURN_TYPE: npt.NDArray[np_type_of_igraph_integer_t]
114+
INCONV:
115+
IN: "%C% = vertex_colors_to_igraph_vector_int_t_view(%I%, %I1%)"
116+
INOUT: "%C% = vertex_colors_to_igraph_vector_int_t(%I%, %I1%)"
117+
OUT: "%C% = _VectorInt.create(0)"
118+
OUTCONV: "%I% = igraph_vector_int_t_to_numpy_array(%C%)"
119+
111120
VERTEX_INDICES:
112121
PY_TYPE: Iterable[VertexLike]
113122
PY_RETURN_TYPE: npt.NDArray[np_type_of_igraph_integer_t]
@@ -146,6 +155,15 @@ EDGE:
146155
IN: "%C% = edgelike_to_igraph_integer_t(%I%)"
147156
OUT: "%C% = igraph_integer_t(0)"
148157

158+
EDGE_COLOR:
159+
PY_TYPE: Iterable[int]
160+
PY_RETURN_TYPE: npt.NDArray[np_type_of_igraph_integer_t]
161+
INCONV:
162+
IN: "%C% = edge_colors_to_igraph_vector_int_t_view(%I%, %I1%)"
163+
INOUT: "%C% = edge_colors_to_igraph_vector_int_t(%I%, %I1%)"
164+
OUT: "%C% = _VectorInt.create(0)"
165+
OUTCONV: "%I% = igraph_vector_int_t_to_numpy_array(%C%)"
166+
149167
EDGE_INDICES:
150168
PY_TYPE: Iterable[EdgeLike]
151169
PY_RETURN_TYPE: npt.NDArray[np_type_of_igraph_integer_t]
@@ -171,6 +189,15 @@ EDGEWEIGHTS:
171189
OUT: "%C% = _Vector.create(0)"
172190
OUTCONV: "%I% = igraph_vector_t_to_numpy_array(%C%)"
173191

192+
EDGE_CAPACITY:
193+
PY_TYPE: Iterable[float]
194+
PY_RETURN_TYPE: npt.NDArray[np_type_of_igraph_real_t]
195+
INCONV:
196+
IN: "%C% = edge_capacities_to_igraph_vector_t_view(%I%, %I1%)"
197+
INOUT: "%C% = edge_capacities_to_igraph_vector_t(%I%, %I1%)"
198+
OUT: "%C% = _Vector.create(0)"
199+
OUTCONV: "%I% = igraph_vector_t_to_numpy_array(%C%)"
200+
174201
BIPARTITE_TYPES:
175202
PY_TYPE: Iterable[Any]
176203
PY_RETURN_TYPE: npt.NDArray[np_type_of_igraph_bool_t]

src/igraph_ctypes/_internal/conversion.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@
7272
__all__ = (
7373
"any_to_igraph_bool_t",
7474
"edgelike_to_igraph_integer_t",
75+
"edge_capacities_to_igraph_vector_t",
76+
"edge_capacities_to_igraph_vector_t_view",
77+
"edge_colors_to_igraph_vector_t",
78+
"edge_colors_to_igraph_vector_t_view",
7579
"edge_selector_to_igraph_es_t",
7680
"edge_weights_to_igraph_vector_t",
7781
"edge_weights_to_igraph_vector_t_view",
@@ -98,6 +102,8 @@
98102
"vertexlike_to_igraph_integer_t",
99103
"vertex_pairs_to_igraph_vector_int_t",
100104
"vertex_selector_to_igraph_vs_t",
105+
"vertex_colors_to_igraph_vector_t",
106+
"vertex_colors_to_igraph_vector_t_view",
101107
"vertex_qty_to_igraph_vector_t",
102108
"vertex_qty_to_igraph_vector_t_view",
103109
)
@@ -164,6 +170,26 @@ def edge_weights_to_igraph_vector_t_view(
164170
return iterable_to_igraph_vector_t_view(weights) if weights is not None else None
165171

166172

173+
# Currently we handle capacities the same way as weights; this might change in
174+
# the future
175+
edge_capacities_to_igraph_vector_t = edge_weights_to_igraph_vector_t
176+
edge_capacities_to_igraph_vector_t_view = edge_weights_to_igraph_vector_t_view
177+
178+
179+
def edge_colors_to_igraph_vector_t(colors: Iterable[int], graph: _Graph) -> _VectorInt:
180+
"""Converts a Python iterable of integers to a vector of edge colors."""
181+
return iterable_to_igraph_vector_int_t(colors)
182+
183+
184+
def edge_colors_to_igraph_vector_t_view(
185+
colors: Iterable[int], graph: _Graph
186+
) -> _VectorInt:
187+
"""Converts a Python iterable of integers to a vector of edge colors,
188+
possibly creating a shallow view if the input is an appropriate NumPy array.
189+
"""
190+
return iterable_to_igraph_vector_int_t_view(colors)
191+
192+
167193
def iterable_edge_indices_to_igraph_vector_int_t(
168194
indices: Iterable[EdgeLike],
169195
) -> _VectorInt:
@@ -514,6 +540,22 @@ def vertex_selector_to_igraph_vs_t(
514540
return _VertexSelector.create_with(igraph_vs_1, index)
515541

516542

543+
def vertex_colors_to_igraph_vector_t(
544+
colors: Iterable[int], graph: _Graph
545+
) -> _VectorInt:
546+
"""Converts a Python iterable of integers to a vector of vertex colors."""
547+
return iterable_to_igraph_vector_int_t(colors)
548+
549+
550+
def vertex_colors_to_igraph_vector_t_view(
551+
colors: Iterable[int], graph: _Graph
552+
) -> _VectorInt:
553+
"""Converts a Python iterable of integers to a vector of vertex colors,
554+
possibly creating a shallow view if the input is an appropriate NumPy array.
555+
"""
556+
return iterable_to_igraph_vector_int_t_view(colors)
557+
558+
517559
def vertex_qty_to_igraph_vector_t(weights: Iterable[float], graph: _Graph) -> _Vector:
518560
"""Converts a Python iterable of floating-point numbers to a vector of
519561
vertex-related quantities.
@@ -531,9 +573,7 @@ def vertex_qty_to_igraph_vector_t_view(
531573
When the input is `None`, the return value will also be `None`, which is
532574
interpreted by the C core of igraph as all edges having equal weight.
533575
"""
534-
return (
535-
vertex_qty_to_igraph_vector_t(weights, graph) if weights is not None else None
536-
)
576+
return iterable_to_igraph_vector_t_view(weights) if weights else None
537577

538578

539579
################################################################################

src/igraph_ctypes/_internal/functions.py

Lines changed: 166 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from .wrappers import _Graph, _Matrix, _MatrixInt, _Vector, _VectorBool, _VectorInt
2121

2222
# fmt: off
23+
# flake8: noqa: E743
2324
# The rest of this file is generated by Stimulus
2425

2526

@@ -4911,23 +4912,150 @@ def induced_subgraph_map(graph: _Graph, vids: VertexSelector, impl: SubgraphImpl
49114912
# Construct return value
49124913
return res, map, invmap
49134914

4914-
# igraph_gomory_hu_tree: no Python type known for type: EDGE_CAPACITY
49154915

4916-
# igraph_maxflow: no Python type known for type: EDGE_CAPACITY
4916+
def gomory_hu_tree(graph: _Graph, capacity: Optional[Iterable[float]] = None) -> Tuple[_Graph, npt.NDArray[np_type_of_igraph_real_t]]:
4917+
"""Type-annotated wrapper for ``igraph_gomory_hu_tree``."""
4918+
# Prepare input arguments
4919+
c_graph = graph
4920+
c_tree = _Graph()
4921+
c_flows = _Vector.create(0)
4922+
c_capacity = edge_capacities_to_igraph_vector_t_view(capacity, graph) if capacity is not None else None
4923+
4924+
# Call wrapped function
4925+
igraph_gomory_hu_tree(c_graph, c_tree, c_flows, c_capacity)
4926+
4927+
# Prepare output arguments
4928+
tree = c_tree.mark_initialized()
4929+
flows = igraph_vector_t_to_numpy_array(c_flows)
4930+
4931+
# Construct return value
4932+
return tree, flows
4933+
4934+
# igraph_maxflow: no Python type known for type: MAXFLOW_STATS
4935+
4936+
# igraph_maxflow_value: no Python type known for type: MAXFLOW_STATS
4937+
4938+
4939+
def mincut_value(graph: _Graph, capacity: Optional[Iterable[float]] = None) -> float:
4940+
"""Type-annotated wrapper for ``igraph_mincut_value``."""
4941+
# Prepare input arguments
4942+
c_graph = graph
4943+
c_res = igraph_real_t()
4944+
c_capacity = edge_capacities_to_igraph_vector_t_view(capacity, graph) if capacity is not None else None
4945+
4946+
# Call wrapped function
4947+
igraph_mincut_value(c_graph, c_res, c_capacity)
4948+
4949+
# Prepare output arguments
4950+
res = c_res.value
4951+
4952+
# Construct return value
4953+
return res
4954+
4955+
4956+
def st_mincut(graph: _Graph, source: VertexLike, target: VertexLike, capacity: Optional[Iterable[float]] = None) -> Tuple[float, npt.NDArray[np_type_of_igraph_integer_t], npt.NDArray[np_type_of_igraph_integer_t], npt.NDArray[np_type_of_igraph_integer_t]]:
4957+
"""Type-annotated wrapper for ``igraph_st_mincut``."""
4958+
# Prepare input arguments
4959+
c_graph = graph
4960+
c_value = igraph_real_t()
4961+
c_cut = _VectorInt.create(0)
4962+
c_partition1 = _VectorInt.create(0)
4963+
c_partition2 = _VectorInt.create(0)
4964+
c_source = vertexlike_to_igraph_integer_t(source)
4965+
c_target = vertexlike_to_igraph_integer_t(target)
4966+
c_capacity = edge_capacities_to_igraph_vector_t_view(capacity, graph) if capacity is not None else None
4967+
4968+
# Call wrapped function
4969+
igraph_st_mincut(c_graph, c_value, c_cut, c_partition1, c_partition2, c_source, c_target, c_capacity)
4970+
4971+
# Prepare output arguments
4972+
value = c_value.value
4973+
cut = igraph_vector_int_t_to_numpy_array(c_cut)
4974+
partition1 = igraph_vector_int_t_to_numpy_array(c_partition1)
4975+
partition2 = igraph_vector_int_t_to_numpy_array(c_partition2)
4976+
4977+
# Construct return value
4978+
return value, cut, partition1, partition2
4979+
4980+
4981+
def st_mincut_value(graph: _Graph, source: VertexLike, target: VertexLike, capacity: Optional[Iterable[float]] = None) -> float:
4982+
"""Type-annotated wrapper for ``igraph_st_mincut_value``."""
4983+
# Prepare input arguments
4984+
c_graph = graph
4985+
c_res = igraph_real_t()
4986+
c_source = vertexlike_to_igraph_integer_t(source)
4987+
c_target = vertexlike_to_igraph_integer_t(target)
4988+
c_capacity = edge_capacities_to_igraph_vector_t_view(capacity, graph) if capacity is not None else None
4989+
4990+
# Call wrapped function
4991+
igraph_st_mincut_value(c_graph, c_res, c_source, c_target, c_capacity)
4992+
4993+
# Prepare output arguments
4994+
res = c_res.value
4995+
4996+
# Construct return value
4997+
return res
4998+
4999+
5000+
def mincut(graph: _Graph, capacity: Optional[Iterable[float]] = None) -> Tuple[float, npt.NDArray[np_type_of_igraph_integer_t], npt.NDArray[np_type_of_igraph_integer_t], npt.NDArray[np_type_of_igraph_integer_t]]:
5001+
"""Type-annotated wrapper for ``igraph_mincut``."""
5002+
# Prepare input arguments
5003+
c_graph = graph
5004+
c_value = igraph_real_t()
5005+
c_partition1 = _VectorInt.create(0)
5006+
c_partition2 = _VectorInt.create(0)
5007+
c_cut = _VectorInt.create(0)
5008+
c_capacity = edge_capacities_to_igraph_vector_t_view(capacity, graph) if capacity is not None else None
5009+
5010+
# Call wrapped function
5011+
igraph_mincut(c_graph, c_value, c_partition1, c_partition2, c_cut, c_capacity)
5012+
5013+
# Prepare output arguments
5014+
value = c_value.value
5015+
partition1 = igraph_vector_int_t_to_numpy_array(c_partition1)
5016+
partition2 = igraph_vector_int_t_to_numpy_array(c_partition2)
5017+
cut = igraph_vector_int_t_to_numpy_array(c_cut)
5018+
5019+
# Construct return value
5020+
return value, partition1, partition2, cut
5021+
49175022

4918-
# igraph_maxflow_value: no Python type known for type: EDGE_CAPACITY
5023+
def residual_graph(graph: _Graph, capacity: Iterable[float], flow: Iterable[float]) -> Tuple[_Graph, npt.NDArray[np_type_of_igraph_real_t]]:
5024+
"""Type-annotated wrapper for ``igraph_residual_graph``."""
5025+
# Prepare input arguments
5026+
c_graph = graph
5027+
c_capacity = edge_capacities_to_igraph_vector_t_view(capacity, graph)
5028+
c_residual = _Graph()
5029+
c_residual_capacity = _Vector.create(0)
5030+
c_flow = iterable_to_igraph_vector_t_view(flow)
49195031

4920-
# igraph_mincut_value: no Python type known for type: EDGE_CAPACITY
5032+
# Call wrapped function
5033+
igraph_residual_graph(c_graph, c_capacity, c_residual, c_residual_capacity, c_flow)
49215034

4922-
# igraph_st_mincut: no Python type known for type: EDGE_CAPACITY
5035+
# Prepare output arguments
5036+
residual = c_residual.mark_initialized()
5037+
residual_capacity = igraph_vector_t_to_numpy_array(c_residual_capacity)
49235038

4924-
# igraph_st_mincut_value: no Python type known for type: EDGE_CAPACITY
5039+
# Construct return value
5040+
return residual, residual_capacity
49255041

4926-
# igraph_mincut: no Python type known for type: EDGE_CAPACITY
49275042

4928-
# igraph_residual_graph: no Python type known for type: EDGE_CAPACITY
5043+
def reverse_residual_graph(graph: _Graph, capacity: Iterable[float], flow: Iterable[float]) -> _Graph:
5044+
"""Type-annotated wrapper for ``igraph_reverse_residual_graph``."""
5045+
# Prepare input arguments
5046+
c_graph = graph
5047+
c_capacity = edge_capacities_to_igraph_vector_t_view(capacity, graph)
5048+
c_residual = _Graph()
5049+
c_flow = iterable_to_igraph_vector_t_view(flow)
49295050

4930-
# igraph_reverse_residual_graph: no Python type known for type: EDGE_CAPACITY
5051+
# Call wrapped function
5052+
igraph_reverse_residual_graph(c_graph, c_capacity, c_residual, c_flow)
5053+
5054+
# Prepare output arguments
5055+
residual = c_residual.mark_initialized()
5056+
5057+
# Construct return value
5058+
return residual
49315059

49325060
# igraph_st_vertex_connectivity: no Python type known for type: VCONNNEI
49335061

@@ -5079,7 +5207,23 @@ def dominator_tree(graph: _Graph, root: VertexLike, mode: NeighborMode = Neighbo
50795207

50805208
# igraph_all_st_mincuts: no Python type known for type: EDGESET_LIST
50815209

5082-
# igraph_even_tarjan_reduction: no Python type known for type: EDGE_CAPACITY
5210+
5211+
def even_tarjan_reduction(graph: _Graph) -> Tuple[_Graph, npt.NDArray[np_type_of_igraph_real_t]]:
5212+
"""Type-annotated wrapper for ``igraph_even_tarjan_reduction``."""
5213+
# Prepare input arguments
5214+
c_graph = graph
5215+
c_graphbar = _Graph()
5216+
c_capacity = _Vector.create(0)
5217+
5218+
# Call wrapped function
5219+
igraph_even_tarjan_reduction(c_graph, c_graphbar, c_capacity)
5220+
5221+
# Prepare output arguments
5222+
graphbar = c_graphbar.mark_initialized()
5223+
capacity = igraph_vector_t_to_numpy_array(c_capacity)
5224+
5225+
# Construct return value
5226+
return graphbar, capacity
50835227

50845228

50855229
def is_separator(graph: _Graph, candidate: VertexSelector) -> bool:
@@ -5206,11 +5350,11 @@ def isoclass_create(size: int, number: int, directed: bool = True) -> _Graph:
52065350
# Construct return value
52075351
return graph
52085352

5209-
# igraph_isomorphic_vf2: no Python type known for type: VERTEX_COLOR
5353+
# igraph_isomorphic_vf2: no Python type known for type: ISOCOMPAT_FUNC
52105354

5211-
# igraph_count_isomorphisms_vf2: no Python type known for type: VERTEX_COLOR
5355+
# igraph_count_isomorphisms_vf2: no Python type known for type: ISOCOMPAT_FUNC
52125356

5213-
# igraph_get_isomorphisms_vf2: no Python type known for type: VERTEX_COLOR
5357+
# igraph_get_isomorphisms_vf2: no Python type known for type: VECTOR_INT_LIST
52145358

52155359

52165360
def subisomorphic(graph1: _Graph, graph2: _Graph) -> bool:
@@ -5229,15 +5373,15 @@ def subisomorphic(graph1: _Graph, graph2: _Graph) -> bool:
52295373
# Construct return value
52305374
return iso
52315375

5232-
# igraph_subisomorphic_vf2: no Python type known for type: VERTEX_COLOR
5376+
# igraph_subisomorphic_vf2: no Python type known for type: ISOCOMPAT_FUNC
52335377

5234-
# igraph_subisomorphic_function_vf2: no Python type known for type: VERTEX_COLOR
5378+
# igraph_subisomorphic_function_vf2: no Python type known for type: ISOMORPHISM_FUNC
52355379

5236-
# igraph_count_subisomorphisms_vf2: no Python type known for type: VERTEX_COLOR
5380+
# igraph_count_subisomorphisms_vf2: no Python type known for type: ISOCOMPAT_FUNC
52375381

5238-
# igraph_get_subisomorphisms_vf2: no Python type known for type: VERTEX_COLOR
5382+
# igraph_get_subisomorphisms_vf2: no Python type known for type: VECTOR_INT_LIST
52395383

5240-
# igraph_canonical_permutation: no Python type known for type: VERTEX_COLOR
5384+
# igraph_canonical_permutation: no Python type known for type: BLISSSH
52415385

52425386

52435387
def permute_vertices(graph: _Graph, permutation: Iterable[int]) -> _Graph:
@@ -5256,11 +5400,11 @@ def permute_vertices(graph: _Graph, permutation: Iterable[int]) -> _Graph:
52565400
# Construct return value
52575401
return res
52585402

5259-
# igraph_isomorphic_bliss: no Python type known for type: VERTEX_COLOR
5403+
# igraph_isomorphic_bliss: no Python type known for type: BLISSSH
52605404

5261-
# igraph_automorphisms: no Python type known for type: VERTEX_COLOR
5405+
# igraph_automorphisms: no Python type known for type: BLISSSH
52625406

5263-
# igraph_automorphism_group: no Python type known for type: VERTEX_COLOR
5407+
# igraph_automorphism_group: no Python type known for type: VERTEXSET_LIST
52645408

52655409
# igraph_subisomorphic_lad: no Python type known for type: VERTEXSET_LIST
52665410

@@ -5695,7 +5839,7 @@ def tree_game(n: int, directed: bool = False, method: RandomTreeMethod = RandomT
56955839
# Construct return value
56965840
return graph
56975841

5698-
# igraph_vertex_coloring_greedy: no Python type known for type: VERTEX_COLOR
5842+
# igraph_vertex_coloring_greedy: no Python type known for type: GREEDY_COLORING_HEURISTIC
56995843

57005844

57015845
def deterministic_optimal_imitation(graph: _Graph, vid: VertexLike, quantities: Iterable[float], strategies: Iterable[int], optimality: Optimality = Optimality.MAXIMUM, mode: NeighborMode = NeighborMode.OUT) -> None:

0 commit comments

Comments
 (0)