Skip to content

Commit

Permalink
Use cpdef's union and find
Browse files Browse the repository at this point in the history
Typecast `union` as `void` to a-void the "C struct/union cannot be declared cpdef" error.
  • Loading branch information
gmou3 committed Apr 22, 2024
1 parent ae06474 commit 1298483
Show file tree
Hide file tree
Showing 18 changed files with 151 additions and 154 deletions.
12 changes: 6 additions & 6 deletions src/sage/combinat/bijectionist.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ def set_constant_blocks(self, P):
P = sorted(self._sorter["A"](p) for p in P)
for p in P:
for a in p:
self._P.join(p[0], a)
self._P.union(p[0], a)

self._compute_possible_block_values()

Expand Down Expand Up @@ -1678,7 +1678,7 @@ def merge_until_split():
try:
solution = different_values(tP[i1], tP[i2])
except StopIteration:
tmp_P.join(tP[i1], tP[i2])
tmp_P.union(tP[i1], tP[i2])
if len(multiple_preimages[tZ]) == 2:
del multiple_preimages[tZ]
else:
Expand Down Expand Up @@ -2198,7 +2198,7 @@ def _preprocess_intertwining_relations(self):
for a_tuple, image_set in updated_images.items():
image = image_set.pop()
while image_set:
P.join(image, image_set.pop())
P.union(image, image_set.pop())
something_changed = True
# we keep a representative
image_set.add(image)
Expand Down Expand Up @@ -3091,9 +3091,9 @@ def _disjoint_set_roots(d):
sage: from sage.combinat.bijectionist import _disjoint_set_roots
sage: d = DisjointSet('abcde')
sage: d.join("a", "b")
sage: d.join("a", "c")
sage: d.join("e", "d")
sage: d.union("a", "b")
sage: d.union("a", "c")
sage: d.union("e", "d")
sage: _disjoint_set_roots(d)
dict_keys(['a', 'e'])
"""
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/designs/designs_pyx.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ def is_group_divisible_design(groups,blocks,v,G=None,K=None,lambd=1,verbose=Fals
for i in range(n):
for j in range(i + 1, n):
if matrix[i * n + j] == 0:
groups.join(i, j)
groups.union(i, j)
groups = list(groups.root_to_elements_dict().values())

# Group sizes are element of G
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/designs/incidence_structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,7 @@ def is_connected(self) -> bool:
for B in self._blocks:
x = B[0]
for i in range(1, len(B)):
D.join(x, B[i])
D.union(x, B[i])
return D.number_of_subsets() == 1

def is_simple(self) -> bool:
Expand Down
6 changes: 3 additions & 3 deletions src/sage/combinat/posets/hasse_diagram.py
Original file line number Diff line number Diff line change
Expand Up @@ -3230,15 +3230,15 @@ def fill_to_interval(S):
if part: # Skip empty parts
c = part[0]
for e in fill_to_interval(part):
cong.join(e, c)
cong.union(e, c)
t = cong.number_of_subsets()

# Following is needed for cases like
# posets.BooleanLattice(3).congruence([(0,1), (0,2), (0,4)])
for c in list(cong):
r = c[0]
for v in fill_to_interval(c):
cong.join(r, v)
cong.union(r, v)

todo = {cong.find(e) for part in parts for e in part}

Expand Down Expand Up @@ -3291,7 +3291,7 @@ def fill_to_interval(S):
while c is not None:
newblock = cong.find(c)
for i in self.interval(c, d):
cong.join(newblock, i)
cong.union(newblock, i)
C = cong.root_to_elements_dict()[cong.find(newblock)]
mins = [i for i in C if all(i_ not in C for i_ in self.neighbor_in_iterator(i))]
maxs = [i for i in C if all(i_ not in C for i_ in self.neighbor_out_iterator(i))]
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/set_partition.py
Original file line number Diff line number Diff line change
Expand Up @@ -2356,7 +2356,7 @@ def from_arcs(self, arcs, n):
"""
P = DisjointSet(range(1, n + 1))
for i, j in arcs:
P.join(i, j)
P.union(i, j)
return self.element_class(self, P)

def from_rook_placement_gamma(self, rooks, n):
Expand Down
10 changes: 5 additions & 5 deletions src/sage/combinat/words/finite_word.py
Original file line number Diff line number Diff line change
Expand Up @@ -5201,16 +5201,16 @@ def overlap_partition(self, other, delay=0, p=None, involution=None):
S = zip(islice(self, int(delay), None), other)
if involution is None:
for a, b in S:
p.join(a, b)
p.union(a, b)
elif isinstance(involution, WordMorphism):
for a, b in S:
p.join(a, b)
p.union(a, b)
# take the first letter of the word
p.join(involution(a)[0], involution(b)[0])
p.union(involution(a)[0], involution(b)[0])
elif callable(involution):
for a, b in S:
p.join(a, b)
p.join(involution(a), involution(b))
p.union(a, b)
p.union(involution(a), involution(b))
else:
raise TypeError("involution (=%s) must be callable" % involution)
return p
Expand Down
2 changes: 1 addition & 1 deletion src/sage/graphs/connectivity.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2540,7 +2540,7 @@ def spqr_tree(G, algorithm="Hopcroft_Tarjan", solver=None, verbose=0,
if cocycles_count[fe] == 2 and len(virtual_edge_to_cycles[fe]) == 2:
# This virtual edge is only between 2 cycles
C1, C2 = virtual_edge_to_cycles[fe]
DS.join(C1, C2)
DS.union(C1, C2)
cycles_list[C1].delete_edge(fe)
cycles_list[C2].delete_edge(fe)
cocycles_count[fe] -= 2
Expand Down
2 changes: 1 addition & 1 deletion src/sage/graphs/generators/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ def RandomBlockGraph(m, k, kmax=None, incidence_structure=False, seed=None):
# structure to keep a unique identifier per merged vertices
DS = DisjointSet([i for u in B for i in B[u]])
for u, v in T.edges(sort=True, labels=0):
DS.join(choice(B[u]), choice(B[v]))
DS.union(choice(B[u]), choice(B[v]))

# We relabel vertices in the range [0, m*(k-1)] and build the incidence
# structure
Expand Down
2 changes: 1 addition & 1 deletion src/sage/graphs/generic_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -12657,7 +12657,7 @@ def contract_edges(self, edges):
DS = DisjointSet(self.vertex_iterator())

for u, v, label in edge_list:
DS.join(u, v)
DS.union(u, v)

self.delete_edges(edge_list)
edges_incident = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ def gamma_classes(graph):
e = frozenset([v1, v])
for vi in component[1:]:
ei = frozenset([vi, v])
pieces.join(e, ei)
pieces.union(e, ei)
return {frozenset(chain.from_iterable(loe)): loe for loe in pieces}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ def is_valid_tree_decomposition(G, T):
for Xi in X:
for Xj in T.neighbor_iterator(Xi):
if Xj in X:
D.join(Xi, Xj)
D.union(Xi, Xj)
if D.number_of_subsets() > 1:
return False

Expand Down
6 changes: 3 additions & 3 deletions src/sage/graphs/partial_cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,9 +335,9 @@ def is_partial_cube(G, certificate=False):
if diff not in neighbors:
return fail
neighbor = neighbors[diff]
unionfind.join(contracted.edge_label(v, w),
unionfind.union(contracted.edge_label(v, w),
contracted.edge_label(root, neighbor))
unionfind.join(contracted.edge_label(w, v),
unionfind.union(contracted.edge_label(w, v),
contracted.edge_label(neighbor, root))
labeled.add_edge(v, w)

Expand All @@ -356,7 +356,7 @@ def is_partial_cube(G, certificate=False):
if vi == wi:
return fail
if newgraph.has_edge(vi, wi):
unionfind.join(newgraph.edge_label(vi, wi), t)
unionfind.union(newgraph.edge_label(vi, wi), t)
else:
newgraph.add_edge(vi, wi, t)
contracted = newgraph
Expand Down
30 changes: 15 additions & 15 deletions src/sage/graphs/spanning_tree.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -345,17 +345,17 @@ def kruskal_iterator(G, by_weight=True, weight_function=None, check_weight=False
yield from G.edge_iterator()
return

cdef DisjointSet_of_hashables disjointset = DisjointSet_of_hashables(G)
cdef DisjointSet_of_hashables union_find = DisjointSet_of_hashables(G)
by_weight, weight_function = G._get_weight_function(by_weight=by_weight,
weight_function=weight_function,
check_weight=check_weight)
yield from kruskal_iterator_from_edges(G.edge_iterator(), disjointset,
yield from kruskal_iterator_from_edges(G.edge_iterator(), union_find,
by_weight=by_weight,
weight_function=weight_function,
check_weight=False)


def kruskal_iterator_from_edges(edges, disjointset, by_weight=True,
def kruskal_iterator_from_edges(edges, union_find, by_weight=True,
weight_function=None, check_weight=False):
"""
Return an iterator implementation of Kruskal algorithm on list of edges.
Expand All @@ -364,7 +364,7 @@ def kruskal_iterator_from_edges(edges, disjointset, by_weight=True,
- ``edges`` -- list of edges
- ``disjointset`` -- a
- ``union_find`` -- a
:class:`~sage.sets.disjoint_set.DisjointSet_of_hashables` encoding a
forest
Expand Down Expand Up @@ -416,13 +416,13 @@ def kruskal_iterator_from_edges(edges, disjointset, by_weight=True,
# Kruskal's algorithm
for e in edges:
# acyclic test via union-find
u = disjointset.find(e[0])
v = disjointset.find(e[1])
u = union_find.find(e[0])
v = union_find.find(e[1])
if u != v:
yield e
# merge the trees
disjointset.join(u, v)
if disjointset.number_of_subsets() == 1:
union_find.union(u, v)
if union_find.number_of_subsets() == 1:
return


Expand Down Expand Up @@ -657,7 +657,7 @@ def filter_kruskal_iterator(G, threshold=10000, by_weight=True, weight_function=
# Parameter to equally divide edges with weight equal the to pivot
cdef bint ch = True
# Data structure to record the vertices in each tree of the forest
cdef DisjointSet_of_hashables disjointset = DisjointSet_of_hashables(g)
cdef DisjointSet_of_hashables union_find = DisjointSet_of_hashables(g)

#
# Iteratively partition the list of edges
Expand All @@ -668,12 +668,12 @@ def filter_kruskal_iterator(G, threshold=10000, by_weight=True, weight_function=
if end - begin < threshold:
# Filter edges connecting vertices of a same tree
L = [edges[e_index[i]] for i in range(begin, end + 1)
if disjointset.find(edges[e_index[i]][0]) != disjointset.find(edges[e_index[i]][1])]
yield from kruskal_iterator_from_edges(L, disjointset,
if union_find.find(edges[e_index[i]][0]) != union_find.find(edges[e_index[i]][1])]
yield from kruskal_iterator_from_edges(L, union_find,
by_weight=by_weight,
weight_function=weight_function,
check_weight=False)
if disjointset.number_of_subsets() == 1:
if union_find.number_of_subsets() == 1:
return
continue

Expand Down Expand Up @@ -908,7 +908,7 @@ def boruvka(G, by_weight=True, weight_function=None, check_weight=True, check=Fa
component2 = partitions.find(e[1])

if component1 != component2:
partitions.join(component1, component2)
partitions.union(component1, component2)
T.append(e)
numConComp = numConComp - 1

Expand Down Expand Up @@ -1436,7 +1436,7 @@ def edge_disjoint_spanning_trees(G, k, by_weight=False, weight_function=None, ch

if augmenting_sequence_found:
# We perform the corresponding augmentation
partition[i].join(v, w)
partition[i].union(v, w)

while fe in edge_label:
F[edge_index[fe]].delete_edge(fe)
Expand All @@ -1450,7 +1450,7 @@ def edge_disjoint_spanning_trees(G, k, by_weight=False, weight_function=None, ch

else:
# x and y are in a same tree in every Fi, so in a same clump
partition[0].join(x, y)
partition[0].union(x, y)

res = [F[i] for i in range(1, k + 1) if F[i].size() == G.order() - 1]
if len(res) != k:
Expand Down
2 changes: 1 addition & 1 deletion src/sage/groups/perm_gps/permgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5347,7 +5347,7 @@ def __init__(self, gens, action, domain, gap_group=None, category=None, canonica
for g_orbit in g_orbits:
for o in g_orbit:
for i in range(1, len(o)):
D.join(o[0], o[i])
D.union(o[0], o[i])
self._orbits = tuple(tuple(o) for o in D)

PermutationGroup_generic.__init__(self, gens=gens,
Expand Down
12 changes: 6 additions & 6 deletions src/sage/matroids/graphic_matroid.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def _rank(self, X):
# This counts components:
DS_vertices = DisjointSet(vertices)
for (u, v, l) in edges:
DS_vertices.join(u, v)
DS_vertices.union(u, v)
return (len(vertices) - DS_vertices.number_of_subsets())

# Representation:
Expand Down Expand Up @@ -665,7 +665,7 @@ def _corank(self, X):
not_our_edges = self.groundset_to_edges(self._groundset.difference(X))
DS_vertices = DisjointSet(all_vertices)
for u, v, l in not_our_edges:
DS_vertices.join(u, v)
DS_vertices.union(u, v)
return len(X) - (DS_vertices.number_of_subsets() - Integer(1))

def _is_circuit(self, X):
Expand Down Expand Up @@ -777,7 +777,7 @@ def _max_independent(self, X):
DS_vertices = DisjointSet(vertices)
for (u, v, l) in edges:
if DS_vertices.find(u) != DS_vertices.find(v):
DS_vertices.join(u, v)
DS_vertices.union(u, v)
our_set.add(l)
return frozenset(our_set)

Expand Down Expand Up @@ -811,13 +811,13 @@ def _max_coindependent(self, X):
our_set = set()
DS_vertices = DisjointSet(all_vertices)
for (u, v, l) in not_our_edges:
DS_vertices.join(u, v)
DS_vertices.union(u, v)

for (u, v, l) in edges:
if DS_vertices.find(u) == DS_vertices.find(v):
our_set.add(l)
else:
DS_vertices.join(u, v)
DS_vertices.union(u, v)
return frozenset(our_set)

def _circuit(self, X):
Expand Down Expand Up @@ -876,7 +876,7 @@ def _circuit(self, X):
for u, v, l in edges:
edge_set.add((u, v, l))
if DS_vertices.find(u) != DS_vertices.find(v):
DS_vertices.join(u, v)
DS_vertices.union(u, v)
else:
break
else:
Expand Down
2 changes: 1 addition & 1 deletion src/sage/rings/polynomial/multi_polynomial_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,7 @@ def connected_components(self):
DS = DisjointSet(set().union(*vss))
for u, *vs in vss:
for v in vs:
DS.join(u, v)
DS.union(u, v)

Ps = {} # map root element -> polynomials in this component
for f, vs in zip(self, vss):
Expand Down
8 changes: 4 additions & 4 deletions src/sage/sets/disjoint_set.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ cdef class DisjointSet_class(SageObject):
cpdef number_of_subsets(self)

cdef class DisjointSet_of_integers(DisjointSet_class):
cpdef find(self, int i)
cpdef join(self, int i, int j)
cpdef int find(self, int i)
cpdef void union(self, int i, int j)
cpdef root_to_elements_dict(self)
cpdef element_to_root_dict(self)
cpdef to_digraph(self)
Expand All @@ -30,8 +30,8 @@ cdef class DisjointSet_of_hashables(DisjointSet_class):
cdef list _int_to_el
cdef dict _el_to_int
cdef DisjointSet_of_integers _d
cpdef find(self, e)
cpdef join(self, e, f)
cpdef int find(self, e)
cpdef void union(self, e, f)
cpdef root_to_elements_dict(self)
cpdef element_to_root_dict(self)
cpdef to_digraph(self)
Loading

0 comments on commit 1298483

Please sign in to comment.