Skip to content

Commit 9a43090

Browse files
committed
feat: added create_square_lattice()
1 parent 41ded70 commit 9a43090

File tree

4 files changed

+73
-8
lines changed

4 files changed

+73
-8
lines changed

src/codegen/types.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ VECTOR_INT:
5454
OUTCONV: "%I% = igraph_vector_int_t_to_numpy_array(%C%)"
5555

5656
VECTOR_BOOL:
57-
# we can convert anything into a bool
58-
PY_TYPE: Iterable[Any]
57+
# we can convert anything into a bool, but we declare the type as
58+
# Iterable[bool] only to nudge the user towards using bools
59+
PY_TYPE: Iterable[bool]
5960
PY_RETURN_TYPE: npt.NDArray[np_type_of_igraph_bool_t]
6061
INCONV:
6162
IN: "%C% = iterable_to_igraph_vector_bool_t_view(%I%)"

src/igraph_ctypes/_internal/functions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ def wheel(n: int, mode: WheelMode = WheelMode.OUT, center: int = 0) -> _Graph:
424424
return graph
425425

426426

427-
def square_lattice(dimvector: Iterable[int], nei: int = 1, directed: bool = False, mutual: bool = False, periodic: Optional[Iterable[Any]] = None) -> _Graph:
427+
def square_lattice(dimvector: Iterable[int], nei: int = 1, directed: bool = False, mutual: bool = False, periodic: Optional[Iterable[bool]] = None) -> _Graph:
428428
"""Type-annotated wrapper for ``igraph_square_lattice``."""
429429
# Prepare input arguments
430430
c_graph = _Graph()
@@ -4636,7 +4636,7 @@ def community_fluid_communities(graph: _Graph, no_of_communities: int) -> npt.ND
46364636
return membership
46374637

46384638

4639-
def community_label_propagation(graph: _Graph, mode: NeighborMode = NeighborMode.ALL, weights: Optional[Iterable[float]] = None, initial: Optional[Iterable[int]] = None, fixed: Optional[Iterable[Any]] = None) -> npt.NDArray[np_type_of_igraph_integer_t]:
4639+
def community_label_propagation(graph: _Graph, mode: NeighborMode = NeighborMode.ALL, weights: Optional[Iterable[float]] = None, initial: Optional[Iterable[int]] = None, fixed: Optional[Iterable[bool]] = None) -> npt.NDArray[np_type_of_igraph_integer_t]:
46404640
"""Type-annotated wrapper for ``igraph_community_label_propagation``."""
46414641
# Prepare input arguments
46424642
c_graph = graph

src/igraph_ctypes/constructors.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
from typing import Iterable
1+
from typing import Iterable, Optional, Union
22

33
from .graph import Graph
4-
from ._internal.functions import create, famous
4+
from ._internal.functions import create, famous, square_lattice
55

6-
__all__ = ("create_empty_graph", "create_graph_from_edge_list")
6+
__all__ = (
7+
"create_empty_graph",
8+
"create_famous_graph",
9+
"create_graph_from_edge_list",
10+
"create_square_lattice",
11+
)
712

813

914
def create_empty_graph(n: int, directed: bool = False) -> Graph:
@@ -39,3 +44,34 @@ def create_graph_from_edge_list(
3944
the maximum edge ID in the edge list
4045
"""
4146
return Graph(_wrap=create(edges, n, directed))
47+
48+
49+
def create_square_lattice(
50+
dimvector: Iterable[int],
51+
nei: int = 1,
52+
directed: bool = False,
53+
mutual: bool = False,
54+
periodic: Union[bool, Iterable[bool]] = False,
55+
) -> Graph:
56+
"""Creates a square lattice graph.
57+
58+
Parameters:
59+
dimvector: number of vertices along each dimension of the lattice
60+
directed: whether the generated lattice should be directed
61+
mutual: whether the vertices should be connected in both directions
62+
if the lattice is directed
63+
periodic: whether the lattice should be periodic along each dimension.
64+
`True` or `False` means a periodic or an aperiodic lattice along
65+
_all_ dimensions. You may supply an iterable having the same
66+
length as the number of dimensions to specify periodicity along
67+
each dimension separately.
68+
"""
69+
if not hasattr(periodic, "__iter__"):
70+
num_dims = len(list(dimvector))
71+
periodic_per_dim = [bool(periodic)] * num_dims
72+
else:
73+
periodic_per_dim = list(periodic) # type: ignore
74+
75+
return Graph(
76+
_wrap=square_lattice(dimvector, nei, directed, mutual, periodic_per_dim)
77+
)

test/test_constructors.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
import pytest
22

33
from numpy import array, ndarray
4+
from numpy.testing import assert_array_equal
45

5-
from igraph_ctypes.constructors import create_famous_graph, create_graph_from_edge_list
6+
from igraph_ctypes.constructors import (
7+
create_famous_graph,
8+
create_graph_from_edge_list,
9+
create_square_lattice,
10+
)
11+
from igraph_ctypes._internal.functions import get_edgelist
612

713

814
def test_create_famous_graph():
@@ -37,3 +43,25 @@ def test_create_graph_from_edge_list(edges, n, directed):
3743

3844
for i, edge in enumerate(edges):
3945
assert list(g.edge(i)) == list(edge)
46+
47+
48+
def test_create_square_lattice():
49+
g = create_square_lattice([4, 3])
50+
51+
assert not g.is_directed()
52+
assert g.vcount() == 12 and g.ecount() == 17
53+
# fmt: off
54+
assert_array_equal(
55+
get_edgelist(g._instance),
56+
array([0, 1, 0, 4, 1, 2, 1, 5, 2, 3, 2, 6, 3, 7,
57+
4, 5, 4, 8, 5, 6, 5, 9, 6, 7, 6, 10, 7, 11,
58+
8, 9, 9, 10, 10, 11])
59+
)
60+
# fmt: on
61+
62+
g = create_square_lattice(
63+
[4, 3], directed=True, mutual=True, periodic=[False, True]
64+
)
65+
66+
assert g.is_directed()
67+
assert g.vcount() == 12 and g.ecount() == 42

0 commit comments

Comments
 (0)