@@ -5270,19 +5270,24 @@ def factor(self):
5270
5270
sage: P.factor()
5271
5271
Traceback (most recent call last):
5272
5272
...
5273
- NotImplementedError: the poset is not connected
5273
+ NotImplementedError: the poset is empty or not connected
5274
5274
5275
5275
sage: P = posets.Crown(2)
5276
5276
sage: P.factor()
5277
5277
[Finite poset containing 4 elements]
5278
5278
5279
5279
sage: Poset().factor()
5280
- [Finite poset containing 0 elements]
5280
+ Traceback (most recent call last):
5281
+ ...
5282
+ NotImplementedError: the poset is empty or not connected
5281
5283
5282
5284
sage: factor(posets.BooleanLattice(2))
5283
5285
[Finite poset containing 2 elements,
5284
5286
Finite poset containing 2 elements]
5285
5287
5288
+ sage: factor(Poset(DiGraph([[0,1],[1,2],[0,3]])))
5289
+ [Finite poset containing 4 elements]
5290
+
5286
5291
REFERENCES:
5287
5292
5288
5293
.. [Feig1986] Joan Feigenbaum, *Directed Cartesian-Product Graphs
@@ -5293,10 +5298,13 @@ def factor(self):
5293
5298
from sage .graphs .graph import Graph
5294
5299
from sage .misc .flatten import flatten
5295
5300
dg = self ._hasse_diagram
5296
- if not dg .is_connected ():
5297
- raise NotImplementedError ('the poset is not connected' )
5301
+ if not dg .is_connected () or not dg . order () :
5302
+ raise NotImplementedError ('the poset is empty or not connected' )
5298
5303
if Integer (dg .num_verts ()).is_prime ():
5299
5304
return [self ]
5305
+ if sum (e for _ , e in self .degree_polynomial ().factor ()) == 1 :
5306
+ return [self ]
5307
+
5300
5308
G = dg .to_undirected ()
5301
5309
is_product , dic = G .is_cartesian_product (relabeling = True )
5302
5310
if not is_product :
@@ -5307,34 +5315,39 @@ def factor(self):
5307
5315
v0 = next (iter (dic .values ()))
5308
5316
n = len (v0 )
5309
5317
factors_range = range (n )
5310
- fusion = Graph (n )
5311
5318
5312
5319
def edge_color (va , vb ):
5313
5320
for i in range (n ):
5314
5321
if va [i ] != vb [i ]:
5315
5322
return i
5316
5323
5324
+ neighbors_table = {x : [[y for y in prod_dg .neighbor_iterator (x )
5325
+ if edge_color (x , y ) == i ]
5326
+ for i in factors_range ]
5327
+ for x in prod_dg }
5328
+
5329
+ fusion_edges = []
5317
5330
for i0 , i1 in Subsets (factors_range , 2 ):
5318
5331
for x in prod_dg :
5319
- neigh0 = [y for y in prod_dg .neighbor_iterator (x )
5320
- if edge_color (x , y ) == i0 ]
5321
- neigh1 = [z for z in prod_dg .neighbor_iterator (x )
5322
- if edge_color (x , z ) == i1 ]
5332
+ neigh0 = neighbors_table [x ][i0 ]
5333
+ neigh1 = neighbors_table [x ][i1 ]
5323
5334
for x0 , x1 in product (neigh0 , neigh1 ):
5324
5335
_x2 = list (x0 )
5325
5336
_x2 [i1 ] = x1 [i1 ]
5326
5337
x2 = tuple (_x2 )
5327
5338
A0 = prod_dg .has_edge (x , x0 )
5328
5339
B0 = prod_dg .has_edge (x1 , x2 )
5329
5340
if A0 != B0 :
5330
- fusion . add_edge ([i0 , i1 ])
5341
+ fusion_edges . append ([i0 , i1 ])
5331
5342
break
5332
5343
A1 = prod_dg .has_edge (x , x1 )
5333
5344
B1 = prod_dg .has_edge (x0 , x2 )
5334
5345
if A1 != B1 :
5335
- fusion . add_edge ([i0 , i1 ])
5346
+ fusion_edges . append ([i0 , i1 ])
5336
5347
break
5337
5348
5349
+ fusion = Graph ([list (range (n )), fusion_edges ],
5350
+ format = "vertices_and_edges" )
5338
5351
resu = []
5339
5352
for s in fusion .connected_components (sort = False ):
5340
5353
subg = [x for x in prod_dg if all (x [i ] == v0 [i ] for i in factors_range
0 commit comments