#13501: Fix two bugs in sage.misc.c3's implementation of the algorithm C3
-------------------------------------------+--------------------------------
       Reporter:  nthiery                  |         Owner:              
           Type:  defect                   |        Status:  needs_review
       Priority:  major                    |     Milestone:  sage-5.4    
      Component:  categories               |    Resolution:              
       Keywords:  method resolution order  |   Work issues:              
Report Upstream:  N/A                      |     Reviewers:  Simon King  
        Authors:  Nicolas M. ThiƩry        |     Merged in:              
   Dependencies:  #12895                   |      Stopgaps:              
-------------------------------------------+--------------------------------

Comment (by SimonKing):

 Using `<size_t><void *>` rather than the objects seems to work, speed-
 wise! With your benchmark, I get
 {{{
    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  7000/500    0.197    0.000    0.671    0.001 {sage.misc.c3.C3_algorithm}
 }}}
 using the following patch:
 {{{
 diff --git a/sage/misc/c3.pyx b/sage/misc/c3.pyx
 --- a/sage/misc/c3.pyx
 +++ b/sage/misc/c3.pyx
 @@ -186,16 +186,20 @@
      # ``tails'') . Each tail is stored reversed, so that we can use a
      # cheap pop() in lieue of pop(0). A duplicate of the tail is
      # stored as a set in ``tailsets`` for cheap membership testing.
 +    # Since we actually want comparison by identity, not equality,
 +    # what we store is the set of memory locations of objects
 +    cdef object O, X
      cdef list tails = [getattr(obj, attribute) for obj in args]
      tails.append(args)
 -    tails              = [list(reversed(tail)) for tail in tails]
 -    cdef list heads    = [tail.pop()           for tail in tails]
 -    cdef list tailsets = [set(tail)            for tail in tails]
 +    tails              = [list(reversed(tail))     for tail in tails]
 +    cdef list heads    = [tail.pop()               for tail in tails]
 +    cdef list tailsets = [set([<size_t><void *>O for O in tail]) for tail
 in tails]

      cdef int i, j, nbheads
      nbheads = len(heads)
 -    cdef object O, X
      cdef bint next_item_found
 +    cdef set tail_set
 +    cdef list tail_list

      while nbheads:
          for i from 0 <= i < nbheads:
 @@ -205,7 +209,8 @@
              for j from 0 <= j < nbheads:
                  if j == i:
                      continue
 -                if O in tailsets[j]:
 +                tail_set = tailsets[j]
 +                if <size_t><void *>O in tail_set:
                      next_item_found = False
                      break
              if next_item_found:
 @@ -215,11 +220,13 @@
                  # j goes down so that ``del heads[j]`` does not screw up
 the numbering
                  for j from nbheads > j >= 0:
                      if heads[j] is O:
 -                        try:
 -                            X = tails[j].pop()
 +                        tail_list = tails[j]
 +                        if tail_list:
 +                            X = tail_list.pop()
                              heads[j] = X
 -                            tailsets[j].remove(X)
 -                        except IndexError:
 +                            tail_set = tailsets[j]
 +                            tail_set.remove(<size_t><void *>X)
 +                        else:
                              del heads[j]
                              del tails[j]
                              del tailsets[j]
 }}}

 I am now running `make ptest` with that patch, and if it works, then I'll
 post it here "officially", and we can start cross-reviewing.

-- 
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/13501#comment:20>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sage-trac?hl=en.

Reply via email to