# HG changeset patch
# User Travis Scrimshaw <tscrim@ucdavis.edu>
# Date 1359992227 28800
# Node ID 032dd7a0e52d118410d1720dad8873b783d9f2ad
# Parent 605233157dc94826ba55455ac55706081c914c36
Trac #13840: Speedup of IntegerListsLex by converting to float's infinity.
diff git a/sage/combinat/integer_list.py b/sage/combinat/integer_list.py
a

b

AUTHORS: 
30  30  
31  31  import generator 
32  32  from sage.rings.arith import binomial 
33   from sage.rings.infinity import infinity 
34  33  from sage.rings.integer_ring import ZZ 
35  34  from sage.misc.lazy_attribute import lazy_attribute 
36  35  import __builtin__ 
… 
… 
def first(n, min_length, max_length, flo 
50  49  
51  50  Preconditions: 
52  51  
53    minslope < maxslope 
 52   ``minslope < maxslope`` 
54  53  
55    floor and ceiling need to satisfy the slope constraints, 
56   e.g. be obtained fromcomp2floor or comp2ceil 
 54   ``floor`` and ``ceiling`` need to satisfy the slope constraints, 
 55  e.g. be obtained ``fromcomp2floor`` or ``comp2ceil`` 
57  56  
58    floor must be below ceiling to ensure 
 57   ``floor`` must be below ``ceiling`` to ensure 
59  58  the existence a valid composition 
60  59  
61  60  TESTS:: 
… 
… 
def first(n, min_length, max_length, flo 
118  117  if n == 0: # There is nothing more to do 
119  118  return result 
120  119  
121   if min_slope == infinity: 
 120  if min_slope == float('inf'): 
122  121  for i in range(1, min_length+1): 
123  122  if n <= ceiling(i)  result[i1]: #1 for indexing 
124  123  result[i1] += n 
… 
… 
def rightmost_pivot(comp, min_length, ma 
259  258  
260  259  highX = x 
261  260  lowX = x 
262   
 261  
263  262  while not (ceilingx_x >= floorx_x and 
264  263  (G >= 0 or 
265  264  ( y < max_length +1 and 
… 
… 
def rightmost_pivot(comp, min_length, ma 
282  281  
283  282  
284  283  #Update G 
285   if max_slope == infinity: 
 284  if max_slope == float('+inf'): 
286  285  #In this case, we have 
287  286  #  ceiling_x(i) = ceiling(i) for i > x 
288  287  # G >= 0 or G = 1 
… 
… 
def rightmost_pivot(comp, min_length, ma 
303  302  #Update F 
304  303  if y < max_length+1: 
305  304  F += comp[x1]  floorx_x 
306   if min_slope != infinity: 
 305  if min_slope != float('inf'): 
307  306  F += (lowX  x) * (oldfloorx_x  (floorx_x + min_slope)) 
308  307  temp = floor(lowX)  (floorx_x + min_slope_lowX) 
309  308  while lowX > x and temp >= 0: 
… 
… 
def next(comp, min_length, max_length, f 
344  343  ## // Efficiency note: they are not wrapped more than once, since 
345  344  ## // the method Next calls first, but not the converse. 
346  345  
347   if min_slope == infinity: 
 346  if min_slope == float('inf'): 
348  347  new_floor = lambda i: floor(x+(i1)) 
349  348  else: 
350  349  new_floor = lambda i: max(floor(x+(i1)), low+(i1)*min_slope) 
351  350  
352   if max_slope == infinity: 
 351  if max_slope == float('+inf'): 
353  352  new_ceiling = lambda i: comp[x1]  1 if i == 1 else ceiling(x+(i1)) 
354  353  else: 
355  354  new_ceiling = lambda i: min(ceiling(x+(i1)), high+(i1)*max_slope) 
… 
… 
def iterator(n, min_length, max_length, 
388  387  
389  388  return generator.concat(iterators) 
390  389  else: 
391   f = first(n, min_length, max_length, floor, ceiling, min_slope, max_slope) 
 390  f = first(n, min_length, max_length, floor, ceiling, min_slope, max_slope) 
392  391  if f == None: 
393  392  return generator.element(None, 0) 
394  393  return generator.successor(f, succ) 
… 
… 
def upper_bound(min_length, max_length, 
557  556  sage: integer_list.upper_bound(0,4,f(0), f(1),infinity,infinity) 
558  557  4 
559  558  sage: integer_list.upper_bound(0, infinity, f(0), f(1), infinity, infinity) 
560   +Infinity 
 559  inf 
561  560  sage: integer_list.upper_bound(0, infinity, f(0), f(1), infinity, 1) 
562  561  1 
563  562  sage: integer_list.upper_bound(0, infinity, f(0), f(5), infinity, 1) 
… 
… 
def upper_bound(min_length, max_length, 
566  565  9 
567  566  """ 
568  567  from sage.functions.all import floor as flr 
569   if max_length < infinity: 
 568  if max_length < float('inf'): 
570  569  return sum( [ ceiling(j) for j in range(max_length)] ) 
571   elif max_slope < 0 and ceiling(1) < infinity: 
 570  elif max_slope < 0 and ceiling(1) < float('inf'): 
572  571  maxl = flr(ceiling(1)/max_slope) 
573  572  return ceiling(1)*(maxl+1) + binomial(maxl+1,2)*max_slope 
574  573  #FIXME: only checking the first 10000 values, but that should generally 
… 
… 
def upper_bound(min_length, max_length, 
576  575  elif [ceiling(j) for j in range(10000)] == [0]*10000: 
577  576  return 0 
578  577  else: 
579   return infinity 
 578  return float('inf') 
580  579  
581  580  
582  581  
… 
… 
class IntegerListsLex(CombinatorialClass 
881  880  """ 
882  881  def __init__(self, 
883  882  n, 
884   length = None, min_length=0, max_length=infinity, 
 883  length = None, min_length=0, max_length=float('+inf'), 
885  884  floor=None, ceiling = None, 
886   min_part = 0, max_part = infinity, 
887   min_slope=infinity, max_slope=infinity, 
 885  min_part = 0, max_part = float('+inf'), 
 886  min_slope=float('inf'), max_slope=float('+inf'), 
888  887  name = None, 
889  888  element_constructor = None): 
890  889  """ 
… 
… 
class IntegerListsLex(CombinatorialClass 
900  899  sage: C.cardinality().parent() is ZZ 
901  900  True 
902  901  """ 
 902  # Convert to float infinity 
 903  from sage.rings.infinity import infinity 
 904  if max_slope == infinity: 
 905  max_slope = float('+inf') 
 906  if min_slope == infinity: 
 907  min_slope = float('inf') 
 908  if max_length == infinity: 
 909  max_length = float('inf') 
 910  if max_part == infinity: 
 911  max_part = float('+inf') 
 912  
903  913  if floor is None: 
904  914  self.floor_list = [] 
905   elif type(floor) is type([]): # FIXME: how to refer to type list rather than the function list above? 
 915  elif isinstance(floor, __builtin__.list): 
906  916  self.floor_list = floor 
907  917  # Make sure the floor list will make the list satisfy the constraints 
908   if max_slope != infinity: 
 918  if max_slope != float('+inf'): 
909  919  for i in reversed(range(len(self.floor_list)1)): 
910  920  self.floor_list[i] = max(self.floor_list[i], self.floor_list[i+1]  max_slope) 
911   if min_slope != infinity: 
 921  if min_slope != float('inf'): 
912  922  for i in range(1, len(self.floor_list)): 
913  923  self.floor_list[i] = max(self.floor_list[i], self.floor_list[i1] + min_slope) 
914  924  else: 
915  925  self.floor = floor 
916  926  if ceiling is None: 
917  927  self.ceiling_list = [] 
918   elif type(ceiling) is type([]): 
 928  elif isinstance(ceiling, __builtin__.list): 
919  929  self.ceiling_list = ceiling 
920  930  # Make sure the ceiling list will make the list satisfy the constraints 
921   if max_slope != infinity: 
 931  if max_slope != float('+inf'): 
922  932  for i in range(1, len(self.ceiling_list)): 
923  933  self.ceiling_list[i] = min(self.ceiling_list[i], self.ceiling_list[i1] + max_slope) 
924   if min_slope != infinity: 
 934  if min_slope != float('inf'): 
925  935  for i in reversed(range(len(self.ceiling_list)1)): 
926  936  self.ceiling_list[i] = min(self.ceiling_list[i], self.ceiling_list[i+1]  min_slope) 
927  937  else: 
… 
… 
class IntegerListsLex(CombinatorialClass 
1026  1036  3, 
1027  1037  <function <lambda> at 0x...>, 
1028  1038  <function <lambda> at 0x...>, 
1029   Infinity, 
1030   +Infinity] 
 1039  inf, 
 1040  inf] 
1031  1041  
1032  1042  """ 
1033  1043  return [self.min_length, self.max_length, 
… 
… 
class IntegerListsLex(CombinatorialClass 
1105  1115  True 
1106  1116  """ 
1107  1117  return type(v) is type([]) and is_a(v, *(self.build_args())) and sum(v) in self.n_range 
 1118  