Skip to content

Commit

Permalink
Trac #15704: Stupid waste of time in graphs 1
Browse files Browse the repository at this point in the history
............

The point is that MY computations are never long because of the
add/remove edge functions. I should pay more attention `T_T`

Before
{{{
sage: g = graphs.RandomGNP(1500,.4)
sage: edges = g.edges(labels=False)
sage: %time Graph(edges)
CPU times: user 2.50 s, sys: 0.03 s, total: 2.52 s
Wall time: 2.55 s
Graph on 1500 vertices
sage: h = Graph()
sage: %time h.add_edges(edges)
CPU times: user 4.90 s, sys: 0.02 s, total: 4.92 s
Wall time: 4.93 s
}}}

After
{{{
sage: g = graphs.RandomGNP(1500,.4)
sage: edges = g.edges(labels=False)
sage: %time Graph(edges)
CPU times: user 2.12 s, sys: 0.02 s, total: 2.14 s
Wall time: 2.16 s
Graph on 1500 vertices
sage: h = Graph()
sage: %time h.add_edges(edges)
CPU times: user 1.48 s, sys: 0.02 s, total: 1.50 s
Wall time: 1.52 s
}}}

Nathann

URL: http://trac.sagemath.org/15704
Reported by: ncohen
Ticket author(s): Nathann Cohen
Reviewer(s): Vincent Delecroix
  • Loading branch information
Release Manager authored and vbraun committed May 12, 2014
2 parents d5a5f2b + 297b1b3 commit da70f28
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/sage/combinat/cluster_algebra_quiver/mutation_class.py
Expand Up @@ -464,7 +464,7 @@ def _is_valid_digraph_edge_set( edges, frozen=0 ):
sage: _is_valid_digraph_edge_set( [[0,1,'a'],[2,3,(1,-1)]] )
The given digraph has edge labels which are not integral or integral 2-tuples.
False
sage: _is_valid_digraph_edge_set( [[0,1],[2,3,(1,-1)]] )
sage: _is_valid_digraph_edge_set( [[0,1,None],[2,3,(1,-1)]] )
True
sage: _is_valid_digraph_edge_set( [[0,1,'a'],[2,3,(1,-1)],[3,2,(1,-1)]] )
The given digraph or edge list contains oriented 2-cycles.
Expand Down
32 changes: 16 additions & 16 deletions src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py
Expand Up @@ -1297,7 +1297,7 @@ def __init__(self, letter, rank, twist=None):
if self._rank > 3: self._info['simply_laced'] = True
self._info['skew_symmetric'] = True
if self._bi_rank == [1,1]:
self._graph.add_edges( [(0,1,2),(1,2)] )
self._graph.add_edges( [(0,1,2),(1,2,None)] )
else:
self._digraph.add_edge( self._rank - 2, 0 )
for i in xrange(self._rank-2):
Expand Down Expand Up @@ -1358,37 +1358,37 @@ def __init__(self, letter, rank, twist=None):
self._rank = rank
self._info['mutation_finite'] = True
self._info['finite'] = True
self._graph.add_edges( [ (0,1),(1,2,(2,-1)),(2,3) ] )
self._graph.add_edges( [ (0,1,None),(1,2,(2,-1)),(2,3,None) ] )
elif rank == 4 and twist == 1:
self._rank = rank + 1
self._info['mutation_finite'] = True
self._info['affine'] = True
self._graph.add_edges( [ (0,1), (1,2),(2,3,(1,-2)),(3,4) ] )
self._graph.add_edges( [ (0,1,None), (1,2,None),(2,3,(1,-2)),(3,4,None) ] )
elif rank == 4 and twist == -1:
self._rank = rank + 1
self._info['mutation_finite'] = True
self._info['affine'] = True
self._graph.add_edges( [ (0,1), (1,2),(2,3,(2,-1)),(3,4) ] )
self._graph.add_edges( [ (0,1,None), (1,2,None),(2,3,(2,-1)),(3,4,None) ] )
elif rank == 4 and (twist == [1,2]):
self._rank = rank + 2
self._info['mutation_finite'] = True
self._info['elliptic'] = True
self._digraph.add_edges( [ (0,1), (1,2), (2,3,(2,-1)), (4,2,(1,-2)), (3,4,2), (4,5), (5,3) ])
self._digraph.add_edges( [ (0,1,None), (1,2,None), (2,3,(2,-1)), (4,2,(1,-2)), (3,4,2), (4,5,None), (5,3,None) ])
elif rank == 4 and (twist == [2,1]):
self._rank = rank + 2
self._info['mutation_finite'] = True
self._info['elliptic'] = True
self._digraph.add_edges( [ (0,1), (1,2), (2,3,(1,-2)), (4,2,(2,-1)), (3,4,2), (4,5), (5,3) ])
self._digraph.add_edges( [ (0,1,None), (1,2,None), (2,3,(1,-2)), (4,2,(2,-1)), (3,4,2), (4,5,None), (5,3,None) ])
elif rank == 4 and twist == [2,2]:
self._rank = rank + 2
self._info['mutation_finite'] = True
self._info['elliptic'] = True
self._digraph.add_edges( [ (0,1), (1,2), (3,1), (2,3,2), (4,2,(2,-1)), (3,4,(1,-2)), (5,4) ] )
self._digraph.add_edges( [ (0,1,None), (1,2,None), (3,1,None), (2,3,2), (4,2,(2,-1)), (3,4,(1,-2)), (5,4,None) ] )
elif rank == 4 and twist == [1,1]:
self._rank = rank + 2
self._info['mutation_finite'] = True
self._info['elliptic'] = True
self._digraph.add_edges( [ (0,1), (1,2), (3,1), (2,3,2), (4,2,(1,-2)), (3,4,(2,-1)), (5,4) ] )
self._digraph.add_edges( [ (0,1,None), (1,2,None), (3,1,None), (2,3,2), (4,2,(1,-2)), (3,4,(2,-1)), (5,4,None) ] )
else:
_mutation_type_error( data )

Expand All @@ -1403,34 +1403,34 @@ def __init__(self, letter, rank, twist=None):
self._rank = rank + 1
self._info['mutation_finite'] = True
self._info['affine'] = True
self._graph.add_edges( [ (0,1),(1,2,(1,-3)) ] )
self._graph.add_edges( [ (0,1,None),(1,2,(1,-3)) ] )
elif rank == 2 and twist == 1:
self._rank = rank + 1
self._info['mutation_finite'] = True
self._info['affine'] = True
self._graph.add_edges( [ (0,1),(1,2,(3,-1)) ] )
self._graph.add_edges( [ (0,1,None),(1,2,(3,-1)) ] )
elif rank == 2 and (twist == [1,3]):
self._rank = rank + 2
self._info['mutation_finite'] = True
self._info['elliptic'] = True
self._digraph.add_edges( [ (0,1), (1,2,(3,-1)),
self._digraph.add_edges( [ (0,1,None), (1,2,(3,-1)),
(3,1,(1,-3)), (2,3,2)] )
elif rank == 2 and (twist == [3,1]):
self._rank = rank + 2
self._info['mutation_finite'] = True
self._info['elliptic'] = True
self._digraph.add_edges( [ (0,1), (1,2,(1,-3)),
self._digraph.add_edges( [ (0,1,None), (1,2,(1,-3)),
(3,1,(3,-1)), (2,3,2)] )
elif rank == 2 and twist == [3,3]:
self._rank = rank + 2
self._info['mutation_finite'] = True
self._info['elliptic'] = True
self._digraph.add_edges( [ (1,0), (0,2,2), (3,0,(3,-1)), (2,1), (2,3, (1,-3))])
self._digraph.add_edges( [ (1,0,None), (0,2,2), (3,0,(3,-1)), (2,1,None), (2,3, (1,-3))])
elif rank == 2 and twist == [1,1]:
self._rank = rank + 2
self._info['mutation_finite'] = True
self._info['elliptic'] = True
self._digraph.add_edges( [ (1,0), (0,2,2), (3,0,(1,-3)), (2,1), (2,3,(3,-1)) ] )
self._digraph.add_edges( [ (1,0,None), (0,2,2), (3,0,(1,-3)), (2,1,None), (2,3,(3,-1)) ] )
else:
_mutation_type_error( data )

Expand Down Expand Up @@ -1519,9 +1519,9 @@ def __init__(self, letter, rank, twist=None):
self._rank = rank
self._info['mutation_finite'] = True
self._info['skew_symmetric'] = True
self._digraph.add_edges( [ (0,1,2),(1,2),(2,0),(2,3),(3,4,2),(4,2),(2,5) ] )
self._digraph.add_edges( [ (0,1,2),(1,2,None),(2,0,None),(2,3,None),(3,4,2),(4,2,None),(2,5,None) ] )
if rank == 7:
self._digraph.add_edges( [ (5,6,2),(6,2) ] )
self._digraph.add_edges( [ (5,6,2),(6,2,None) ] )
else:
_mutation_type_error( data )

Expand Down
16 changes: 9 additions & 7 deletions src/sage/graphs/digraph.py
Expand Up @@ -943,7 +943,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None,
for i in xrange(n):
for j in xrange(n):
if m[k] == '1':
self.add_edge(i, j)
self._backend.add_edge(i, j, None, True)
k += 1
elif format == 'adjacency_matrix':
e = []
Expand All @@ -967,26 +967,28 @@ def __init__(self, data=None, pos=None, loops=None, format=None,
for v in xrange(num_verts):
uu,vv = verts[u], verts[v]
if f(uu,vv):
self.add_edge(uu,vv)
self._backend.add_edge(uu,vv,None,True)
elif format == 'dict_of_dicts':
if convert_empty_dict_labels_to_None:
for u in data:
for v in data[u]:
if multiedges:
self.add_edges([(u,v,l) for l in data[u][v]])
for l in data[u][v]:
self._backend.add_edge(u,v,l,True)
else:
self.add_edge((u,v,data[u][v] if data[u][v] != {} else None))
self._backend.add_edge(u,v,data[u][v] if data[u][v] != {} else None,True)
else:
for u in data:
for v in data[u]:
if multiedges:
self.add_edges([(u,v,l) for l in data[u][v]])
for l in data[u][v]:
self._backend.add_edge(u,v,l,True)
else:
self.add_edge((u,v,data[u][v]))
self._backend.add_edge(u,v,data[u][v],True)
elif format == 'dict_of_lists':
for u in data:
for v in data[u]:
self.add_edge(u,v)
self._backend.add_edge(u,v,None,True)
else:
assert format == 'int'
self._pos = pos
Expand Down
35 changes: 28 additions & 7 deletions src/sage/graphs/generic_graph.py
Expand Up @@ -9034,14 +9034,16 @@ def add_edge(self, u, v=None, label=None):
u, v = u
except Exception:
pass
if not self.allows_loops() and u==v:
return

self._backend.add_edge(u, v, label, self._directed)

def add_edges(self, edges):
"""
Add edges from an iterable container.

All elements of ``edges`` must follow the same format, i.e. have the
same length.

EXAMPLES::

sage: G = graphs.DodecahedralGraph()
Expand All @@ -9052,9 +9054,28 @@ def add_edges(self, edges):
sage: H = DiGraph()
sage: H.add_edges( G.edge_iterator() ); H
Digraph on 20 vertices
sage: H.add_edges(iter([]))

sage: H = Graph()
sage: H.add_edges([(0,1),(0,2)])
sage: H.edges()
[(0, 1, None), (0, 2, None)]
"""
for e in edges:
self.add_edge(e)
it = iter(edges)

try:
e0 = it.next()
except StopIteration:
return

if len(e0) == 3:
self._backend.add_edge(e0[0], e0[1], e0[2], self._directed)
for u,v,label in it:
self._backend.add_edge(u, v, label, self._directed)
else:
self._backend.add_edge(e0[0], e0[1], None, self._directed)
for u,v in it:
self._backend.add_edge(u, v, None, self._directed)

def subdivide_edge(self, *args):
"""
Expand Down Expand Up @@ -9366,7 +9387,7 @@ def delete_multiedge(self, u, v):
::

sage: D = DiGraph(multiedges=True,sparse=True)
sage: D.add_edges([(0,1,1), (0,1,2), (0,1,3), (1,0), (1,2), (2,3)])
sage: D.add_edges([(0,1,1), (0,1,2), (0,1,3), (1,0,None), (1,2,None), (2,3,None)])
sage: D.edges()
[(0, 1, 1), (0, 1, 2), (0, 1, 3), (1, 0, None), (1, 2, None), (2, 3, None)]
sage: D.delete_multiedge( 0, 1 )
Expand Down Expand Up @@ -9846,7 +9867,7 @@ def remove_multiple_edges(self):
::

sage: D = DiGraph(multiedges=True, sparse=True)
sage: D.add_edges( [ (0,1,1), (0,1,2), (0,1,3), (0,1,4), (1,2) ] )
sage: D.add_edges( [ (0,1,1), (0,1,2), (0,1,3), (0,1,4), (1,2,None) ] )
sage: D.edges(labels=False)
[(0, 1), (0, 1), (0, 1), (0, 1), (1, 2)]
sage: D.remove_multiple_edges()
Expand Down Expand Up @@ -13846,7 +13867,7 @@ def to_simple(self):
EXAMPLES::

sage: G = DiGraph(loops=True,multiedges=True,sparse=True)
sage: G.add_edges( [ (0,0), (1,1), (2,2), (2,3,1), (2,3,2), (3,2) ] )
sage: G.add_edges( [ (0,0,None), (1,1,None), (2,2,None), (2,3,1), (2,3,2), (3,2,None) ] )
sage: G.edges(labels=False)
[(0, 0), (1, 1), (2, 2), (2, 3), (2, 3), (3, 2)]
sage: H=G.to_simple()
Expand Down
28 changes: 15 additions & 13 deletions src/sage/graphs/graph.py
Expand Up @@ -1249,7 +1249,6 @@ def __init__(self, data=None, pos=None, loops=None, format=None,
else:
raise ValueError("Edges input must all follow the same format.")


if format is None:
import networkx
data = networkx.MultiGraph(data)
Expand Down Expand Up @@ -1491,6 +1490,8 @@ def __init__(self, data=None, pos=None, loops=None, format=None,
verts = [curve.cremona_label() for curve in data]

# weighted, multiedges, loops, verts and num_verts should now be set
#
# From now on, we actually build the graph

if implementation == 'networkx':
import networkx
Expand Down Expand Up @@ -1557,12 +1558,11 @@ def __init__(self, data=None, pos=None, loops=None, format=None,
for i in xrange(n):
for j in xrange(i):
if m[k] == '1':
self.add_edge(i, j)
self._backend.add_edge(i, j, None, False)
k += 1

elif format == 'sparse6':
for i,j in edges:
self.add_edge(i,j)
self.add_edges(edges)

elif format == 'adjacency_matrix':
e = []
Expand Down Expand Up @@ -1592,32 +1592,34 @@ def __init__(self, data=None, pos=None, loops=None, format=None,
for v in xrange(u+1):
uu,vv = verts[u], verts[v]
if f(uu,vv):
self.add_edge(uu,vv)
self._backend.add_edge(uu,vv,None,False)

elif format == 'dict_of_dicts':
if convert_empty_dict_labels_to_None:
for u in data:
for v in data[u]:
if hash(u) <= hash(v) or v not in data or u not in data[v]:
if multiedges:
self.add_edges([(u,v,l) for l in data[u][v]])
for l in data[u][v]:
self._backend.add_edge(u,v,l,False)
else:
self.add_edge((u,v,data[u][v] if data[u][v] != {} else None))
self._backend.add_edge(u,v,data[u][v] if data[u][v] != {} else None,False)
else:
for u in data:
for v in data[u]:
if hash(u) <= hash(v) or v not in data or u not in data[v]:
if multiedges:
self.add_edges([(u,v,l) for l in data[u][v]])
for l in data[u][v]:
self._backend.add_edge(u,v,l,False)
else:
self.add_edge((u,v,data[u][v]))
self._backend.add_edge(u,v,data[u][v],False)

elif format == 'dict_of_lists':
for u in data:
for v in data[u]:
if multiedges or hash(u) <= hash(v) or \
v not in data or u not in data[v]:
self.add_edge(u,v)
if (multiedges or hash(u) <= hash(v) or
v not in data or u not in data[v]):
self._backend.add_edge(u,v,None,False)

elif format == 'elliptic_curve_congruence':
from sage.rings.arith import lcm, prime_divisors
Expand All @@ -1642,7 +1644,7 @@ def __init__(self, data=None, pos=None, loops=None, format=None,
P = prime_divisors(n)
p_edges = [p for p in p_edges if p in P]
if len(p_edges) > 0:
self.add_edge(E.cremona_label(), F.cremona_label(), str(p_edges)[1:-1])
self._backend.add_edge(E.cremona_label(), F.cremona_label(), str(p_edges)[1:-1], False)
else:
assert format == 'int'

Expand Down

0 comments on commit da70f28

Please sign in to comment.