Skip to content

Commit 95a0543

Browse files
Ensure Link.deconnect_sum completely decomposes the diagram
Previously, if the link was a diagrammatic connected sum of more than two links, Spherogram sometimes did not return the the complete decomposition. For example if L = L_1 # L_2 # L_3, it might return [L_1, L_2 # L_3] or even just L itself. (The latter seems to have only happened when there was a pair of 2-cycles in the dual graph sharing a common edge.)
1 parent cb5b278 commit 95a0543

File tree

1 file changed

+71
-7
lines changed

1 file changed

+71
-7
lines changed

spherogram_src/links/simplify.py

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,11 @@ def __init__(self, link):
4747

4848
def two_cycles(self):
4949
"""
50-
Find all two cycles and yield them as a pair of CrossingStrands which
51-
are dual to the edges in the cycle.
50+
Find all two cycles and yield them as a pair of
51+
CrossingStrands which are dual to the edges in the cycle.
5252
53-
The crossing strands are
54-
oriented consistently with respect to one of the faces which a
55-
vertex for the cycle.
53+
The crossing strands are oriented consistently with respect to
54+
one of the faces which a vertex for the cycle.
5655
"""
5756
for face0 in self.vertices:
5857
for dual_edge0 in self.incident(face0):
@@ -298,19 +297,41 @@ def dual_graph_as_nx(link, graph_class=nx.Graph):
298297
interface={face.label: edge, neighbor.label: opp_edge})
299298

300299
G.edge_to_face = to_face_index
300+
G.faces = faces
301301
return G
302302

303303

304-
def deconnect_sum(link):
304+
def disjoint_deconnect_sum_once(link):
305305
"""
306306
Warning: Destroys the original link.
307+
308+
If the diagram is an obvious connected sum, return a decomposition
309+
of the link into nontrivial summands. A summand may itself still
310+
be a connected sum.
311+
312+
This is just a helper function for deconnect_sum.
313+
314+
Here is a connect sum of 3 trefoils, but we'll only pull off 1 at this
315+
step.
316+
317+
>>> K = Link('DT: iaibiahcgefd.001010111')
318+
>>> sorted(len(P) for P in disjoint_deconnect_sum_once(K))
319+
[3, 6]
307320
"""
308321
G = dual_graph_as_nx(link, nx.MultiGraph)
322+
faces_used = set()
309323
for path in simple_cycles(G, 2):
310324
if len(path) == 2:
311325
face0, face1 = path
326+
327+
# Ensure all cycles we use are disjoint.
328+
if face0 in faces_used or face1 in faces_used:
329+
continue
330+
else:
331+
faces_used.update(path)
332+
333+
# Identify where we need to change things.
312334
edges = G[face0][face1]
313-
assert len(edges) == 2
314335
cs0 = edges[0]['interface'][face0]
315336
cs1 = edges[1]['interface'][face0]
316337

@@ -325,6 +346,49 @@ def deconnect_sum(link):
325346
return link.split_link_diagram(destroy_original=True)
326347

327348

349+
def deconnect_sum(link):
350+
"""
351+
Warning: Destroys the original link.
352+
353+
>>> L = Link('K5a1')
354+
>>> L = L.connected_sum(Link('K6a2'))
355+
>>> L = L.connected_sum(Link('K6a3'))
356+
>>> L = L.connected_sum(Link('K7a1'))
357+
>>> len(L)
358+
24
359+
>>> sorted(len(P) for P in deconnect_sum(L))
360+
[5, 6, 6, 7]
361+
362+
Here's 3 trefoils:
363+
>>> K = Link('DT: iaibiahcgefd.001010111')
364+
>>> sorted(len(P) for P in deconnect_sum(K))
365+
[3, 3, 3]
366+
367+
"""
368+
369+
# A diagrammatic connected sum corresponds to a path in the dual
370+
# graph of length 2. The tricky case is when there are several
371+
# such paths, as they may overlap or even cross. We deal with
372+
# this by doing several rounds of cutting along families of
373+
# disjoint paths.
374+
375+
active = [link]
376+
finished = []
377+
378+
while active:
379+
work_remains = []
380+
for A in active:
381+
pieces = disjoint_deconnect_sum_once(A)
382+
if len(pieces) == 1:
383+
finished += pieces
384+
else:
385+
work_remains += pieces
386+
387+
active = work_remains
388+
389+
return finished
390+
391+
328392
def dual_edges(overstrand, graph):
329393
"""
330394
Find the set of crossings and edges of the dual graph encountered

0 commit comments

Comments
 (0)