# HG changeset patch
# User Nathann Cohen <nathann.cohen@gmail.com>
# Date 1358962778 3600
# Node ID ffa112def1286bbce6d47eb6fb0b8a8d7f20c3e7
# Parent 46c148d364a31d689e8f2ada71b44cdf611d2651
Speedup in GenericGraph.relabel() and two new options
diff git a/sage/graphs/generic_graph.py b/sage/graphs/generic_graph.py
a

b


15550  15550  # could pass format='all' to get QQbar eigenvalues and eigenspaces 
15551  15551  # which would be a change in default behavior 
15552  15552  return M.right_eigenspaces(format='galois', algebraic_multiplicity=False) 
15553   
 15553  
15554  15554  ### Automorphism and isomorphism 
15555  15555  
15556   def relabel(self, perm=None, inplace=True, return_map=False): 
 15556  def relabel(self, perm=None, inplace=True, return_map=False, check_input = True, complete_partial_function = True): 
15557  15557  r""" 
15558  15558  Relabels the vertices of ``self`` 
15559  15559  
… 
… 

15566  15566  
15567  15567   ``return_map``  a boolean (default: ``False``) 
15568  15568  
 15569   ``check_input`` (boolean)  whether to test input for 
 15570  correctness. *This can potentially be very timeconsuming !*. 
 15571  
 15572   ``complete_partial_function`` (boolean)  whether to automatically 
 15573  complete the permutation if some elements of the graph are not 
 15574  associated with any new name. In this case, those elements are not 
 15575  relabeled *This can potentially be very timeconsuming !*. 
 15576  
15569  15577  If ``perm`` is a function ``f``, then each vertex ``v`` is 
15570  15578  relabeled to ``f(v)``. 
15571  15579  
… 
… 

15593  15601  If ``return_map`` is ``True`` a dictionary representing the 
15594  15602  relabelling map is returned (incompatible with ``inplace==False``). 
15595  15603  
15596   
15597   EXAMPLES:: 
15598   
 15604  EXAMPLES:: 
 15605  
15599  15606  sage: G = graphs.PathGraph(3) 
15600  15607  sage: G.am() 
15601  15608  [0 1 0] 
15602  15609  [1 0 1] 
15603  15610  [0 1 0] 
15604   
 15611  
15605  15612  Relabeling using a dictionary:: 
15606   
 15613  
15607  15614  sage: G.relabel({1:2,2:1}, inplace=False).am() 
15608  15615  [0 0 1] 
15609  15616  [0 0 1] 
15610  15617  [1 1 0] 
15611   
 15618  
15612  15619  Relabeling using a list:: 
15613   
 15620  
15614  15621  sage: G.relabel([0,2,1], inplace=False).am() 
15615  15622  [0 0 1] 
15616  15623  [0 0 1] 
15617  15624  [1 1 0] 
15618  15625  
15619  15626  Relabeling using a tuple:: 
15620   
 15627  
15621  15628  sage: G.relabel((0,2,1), inplace=False).am() 
15622  15629  [0 0 1] 
15623  15630  [0 0 1] 
15624  15631  [1 1 0] 
15625   
 15632  
15626  15633  Relabeling using a Sage permutation:: 
15627   
 15634  
15628  15635  sage: from sage.groups.perm_gps.permgroup_named import SymmetricGroup 
15629  15636  sage: S = SymmetricGroup(3) 
15630  15637  sage: gamma = S('(1,2)') 
… 
… 

15653  15660  NotImplementedError: Non injective relabeling 
15654  15661  
15655  15662  Relabeling to simpler labels:: 
15656   
 15663  
15657  15664  sage: G = graphs.CubeGraph(3) 
15658  15665  sage: G.vertices() 
15659  15666  ['000', '001', '010', '011', '100', '101', '110', '111'] 
15660  15667  sage: G.relabel() 
15661  15668  sage: G.vertices() 
15662  15669  [0, 1, 2, 3, 4, 5, 6, 7] 
15663   
 15670  
15664  15671  Recovering the relabeling with ``return_map``:: 
15665  15672  
15666  15673  sage: G = graphs.CubeGraph(3) 
… 
… 

15675  15682  {0: 10, 1: 11, 2: 12} 
15676  15683  
15677  15684  TESTS:: 
15678   
 15685  
15679  15686  sage: P = Graph(graphs.PetersenGraph()) 
15680  15687  sage: P.delete_edge([0,1]) 
15681  15688  sage: P.add_edge((4,5)) 
15682  15689  sage: P.add_edge((2,6)) 
15683  15690  sage: P.delete_vertices([0,1]) 
15684  15691  sage: P.relabel() 
15685   
 15692  
15686  15693  The attributes are properly updated too 
15687   
15688   :: 
15689   
 15694  
 15695  :: 
 15696  
15690  15697  sage: G = graphs.PathGraph(5) 
15691  15698  sage: G.set_vertices({0: 'before', 1: 'delete', 2: 'after'}) 
15692  15699  sage: G.set_boundary([1,2,3]) 
… 
… 

15711  15718  """ 
15712  15719  from sage.groups.perm_gps.permgroup_element import PermutationGroupElement 
15713  15720  
 15721  if not inplace: 
 15722  from copy import copy 
 15723  G = copy(self) 
 15724  perm2 = G.relabel(perm, 
 15725  return_map= return_map, 
 15726  check_input = check_input, 
 15727  complete_partial_function = complete_partial_function) 
 15728  
 15729  if return_map: 
 15730  return G, perm2 
 15731  else: 
 15732  return G 
 15733  
15714  15734  # If perm is not a dictionary, we build one ! 
15715  15735  
15716  15736  if perm is None: 
… 
… 

15720  15740  perm[v] = i 
15721  15741  i += 1 
15722  15742  
 15743  complete_partial_function = False 
 15744  check_input = False 
 15745  
15723  15746  elif isinstance(perm, dict): 
15724  15747  
15725  15748  # If all vertices do not have a new label, the code will touch the 
… 
… 

15742  15765  
15743  15766  elif callable(perm): 
15744  15767  perm = dict( [ i, perm(i) ] for i in self.vertices() ) 
 15768  complete_partial_function = False 
15745  15769  
15746  15770  else: 
15747  15771  raise TypeError("Type of perm is not supported for relabeling.") 
15748  15772  
15749   if not inplace: 
15750   from copy import copy 
15751   G = copy(self) 
15752   G.relabel(perm) 
15753   if return_map: 
15754   return G, perm 
15755   return G 
15756   
15757   keys = perm.keys() 
15758   verts = self.vertices() 
15759   if len(set(perm.values())) < len(keys): 
15760   raise NotImplementedError, "Non injective relabeling" 
15761   for v in verts: 
15762   if v not in keys: 
15763   perm[v] = v 
15764   for v in perm.iterkeys(): 
15765   if v in verts: 
15766   try: 
15767   hash(perm[v]) 
15768   except TypeError: 
15769   raise ValueError("perm dictionary must be of the format {a:a1, b:b1, ...} where a,b,... are vertices and a1,b1,... are hashable") 
 15773  # Whether to complete the relabeling function if some vertices do not 
 15774  # appear in the permutation. 
 15775  if complete_partial_function: 
 15776  for v in self: 
 15777  if v not in perm: 
 15778  perm[v] = v 
 15779  
 15780  # Whether to check input 
 15781  if check_input: 
 15782  if len(set(perm.values())) < len(perm): 
 15783  raise NotImplementedError, "Non injective relabeling" 
 15784  
 15785  for v in perm.iterkeys(): 
 15786  if v in self: 
 15787  try: 
 15788  hash(perm[v]) 
 15789  except TypeError: 
 15790  raise ValueError("perm dictionary must be of the format {a:a1, b:b1, ...} where a,b,... are vertices and a1,b1,... are hashable") 
 15791  
15770  15792  self._backend.relabel(perm, self._directed) 
15771  15793  
15772  15794  attributes_to_update = ('_pos', '_assoc', '_embedding') 
… 
… 

15787  15809  """ 
15788  15810  Returns the number of edges from vertex to an edge in cell. In the 
15789  15811  case of a digraph, returns a tuple (in_degree, out_degree). 
15790   
15791   EXAMPLES:: 
15792   
 15812  
 15813  EXAMPLES:: 
 15814  
15793  15815  sage: G = graphs.CubeGraph(3) 
15794  15816  sage: cell = G.vertices()[:3] 
15795  15817  sage: G.degree_to_cell('011', cell) 
15796  15818  2 
15797  15819  sage: G.degree_to_cell('111', cell) 
15798  15820  0 
15799   
15800   :: 
15801   
 15821  
 15822  :: 
 15823  
15802  15824  sage: D = DiGraph({ 0:[1,2,3], 1:[3,4], 3:[4,5]}) 
15803  15825  sage: cell = [0,1,2] 
15804  15826  sage: D.degree_to_cell(5, cell) 