#16453: Cythonize quiver paths
-------------------------------------+-------------------------------------
       Reporter:  SimonKing          |        Owner:
           Type:  enhancement        |       Status:  needs_review
       Priority:  major              |    Milestone:  sage-6.4
      Component:  algebra            |   Resolution:
       Keywords:                     |    Merged in:
        Authors:  Simon King         |    Reviewers:
Report Upstream:  N/A                |  Work issues:  Fix issue in bounded
         Branch:                     |  integer sequences
  u/SimonKing/cythonize_quiver_paths |       Commit:
   Dependencies:  #15820             |  73ac68974379d51ff7a4a22aed7539b480668be8
                                     |     Stopgaps:
-------------------------------------+-------------------------------------

Comment (by SimonKing):

 In my applications, I will likely use paths as dictionary keys, I will
 multiply them, I will (for two-sided modules) test subpath containment or
 (for right modules) detect initial segments, and I will extract sub-paths.

 The following benchmark may thus be representative for what is needed for
 two-sided modules:
 {{{
 sage: def test1(p1,p2):
 ....:     D = {}
 ....:     for i in range(1,100):
 ....:         D[p2^i*p1*p2^i] = i
 ....:     q = p2^10*p1*p2^50
 ....:     for x in D.keys():
 ....:         assert x.has_subpath(q) or D[x] < 50
 ....:     q = p2*p1*p2^120
 ....:     for x in D.keys():
 ....:         assert q.has_initial_segment(x[(D[x]-1)*len(p2):])
 ....:
 }}}
 Let's apply this to the dense encoding:
 {{{
 sage: S = DiGraph({0:{1:['a'], 2:['b']}, 1:{0:['c'], 1:['d']},
 2:{0:['e'],2:['f']}}).path_semigroup()
 sage: S.inject_variables()
 Defining e_0, e_1, e_2, a, b, c, d, e, f
 sage: p1 = a*d*c*b*f*e
 sage: p2 = b*e*a*c
 sage: %timeit test1(p1,p2)
 1 loops, best of 3: 420 ms per loop
 }}}
 And for the non-dense encoding:
 {{{
 sage: S = DiGraph({0:{1:['a'], 2:['b']}, 1:{0:['c'], 1:['d']},
 2:{0:['e'],2:['f']}}).path_semigroup(False)
 sage: S.inject_variables()
 Defining e_0, e_1, e_2, a, b, c, d, e, f
 sage: p1 = a*d*c*b*f*e
 sage: p2 = b*e*a*c
 sage: %timeit test1(p1,p2)
 100 loops, best of 3: 4.26 ms per loop
 }}}

 The following benchmark hopefully addresses the tasks that are important
 in the case of right modules:
 {{{
 sage: def test2(p1,p2):
 ....:     D = {}
 ....:     for i in range(1,100):
 ....:         D[p2^i*p1*p2^i] = i
 ....:     q = p2^10*p1*p2^50
 ....:     for x in D.keys():
 ....:         assert D[x]<10 or
 (x[(D[x]-10)*len(p2):].has_initial_segment(q) or D[x]<50)
 ....:
 }}}
 In the dense encoding:
 {{{
 sage: S = DiGraph({0:{1:['a'], 2:['b']}, 1:{0:['c'], 1:['d']},
 2:{0:['e'],2:['f']}}).path_semigroup()
 sage: S.inject_variables()
 Defining e_0, e_1, e_2, a, b, c, d, e, f
 sage: p1 = a*d*c*b*f*e
 sage: p2 = b*e*a*c
 sage: %timeit test2(p1,p2)
 1 loops, best of 3: 306 ms per loop
 }}}
 Versus the non-dense:
 {{{
 sage: S = DiGraph({0:{1:['a'], 2:['b']}, 1:{0:['c'], 1:['d']},
 2:{0:['e'],2:['f']}}).path_semigroup(False)
 sage: S.inject_variables()
 Defining e_0, e_1, e_2, a, b, c, d, e, f
 sage: p1 = a*d*c*b*f*e
 sage: p2 = b*e*a*c
 sage: %timeit test2(p1,p2)
 100 loops, best of 3: 3.99 ms per loop
 }}}

 The last benchmark shows that I should certainly avoid computing overlap
 (gcd) in the dense encoding:
 {{{
 sage: def test3(p1,p2):
 ....:     D = {}
 ....:     for i in range(1,100):
 ....:         D[p2^i*p1*p2^i] = i
 ....:     q = p2^10*p1*p2^50
 ....:     for x in D.keys():
 ....:         assert D[x]<10 or
 (x[(D[x]-10)*len(p2):].has_initial_segment(q) or D[x]<50)
 ....:     q = p2*p1*p2^120
 ....:     for x in D.keys():
 ....:         assert all(q.gcd(x))
 ....:
 }}}
 The dense encoding:
 {{{
 sage: S = DiGraph({0:{1:['a'], 2:['b']}, 1:{0:['c'], 1:['d']},
 2:{0:['e'],2:['f']}}).path_semigroup()
 sage: S.inject_variables()
 Defining e_0, e_1, e_2, a, b, c, d, e, f
 sage: p1 = a*d*c*b*f*e
 sage: p2 = b*e*a*c
 sage: %timeit test3(p1,p2)
 1 loops, best of 3: 1.44 s per loop
 }}}
 The non-dense encoding:
 {{{
 sage: S = DiGraph({0:{1:['a'], 2:['b']}, 1:{0:['c'], 1:['d']},
 2:{0:['e'],2:['f']}}).path_semigroup(False)
 sage: S.inject_variables()
 Defining e_0, e_1, e_2, a, b, c, d, e, f
 sage: p1 = a*d*c*b*f*e
 sage: p2 = b*e*a*c
 sage: %timeit test3(p1,p2)
 100 loops, best of 3: 9.31 ms per loop
 }}}

 Looks like the non-dense encoding beats the dense encoding in all tests.
 However, in the following test, the dense encoding is slightly faster:
 {{{
 sage: def test4(p1,p2):
 ....:     D = {}
 ....:     for i in range(1,100):
 ....:         D[p2^i*p1*p2^i] = i
 ....:     q = p2^10
 ....:     for x in D.keys():
 ....:         assert x.has_initial_segment(q) or D[x]<10
 ....:
 }}}
 Dense:
 {{{
 sage: S = DiGraph({0:{1:['a'], 2:['b']}, 1:{0:['c'], 1:['d']},
 2:{0:['e'],2:['f']}}).path_semigroup()
 sage: S.inject_variables()
 Defining e_0, e_1, e_2, a, b, c, d, e, f
 sage: p1 = a*d*c*b*f*e
 sage: p2 = b*e*a*c
 sage: %timeit test4(p1,p2)
 1000 loops, best of 3: 1.47 ms per loop
 }}}
 Non-dense:
 {{{
 sage: S = DiGraph({0:{1:['a'], 2:['b']}, 1:{0:['c'], 1:['d']},
 2:{0:['e'],2:['f']}}).path_semigroup(False)
 sage: S.inject_variables()
 Defining e_0, e_1, e_2, a, b, c, d, e, f
 sage: p1 = a*d*c*b*f*e
 sage: p2 = b*e*a*c
 sage: %timeit test4(p1,p2)
 1000 loops, best of 3: 1.57 ms per loop
 }}}

 __Conclusion__

 It seems to me that the dense encoding may be an interesting idea, but for
 most (if not all) applications is not better than the simpler non-dense
 encoding.

 __Question__

 Shall I simply remove the dense implementation? Or should I turn it into a
 separate element class, so that a potential user may benefit from
 alternative implementations?

--
Ticket URL: <http://trac.sagemath.org/ticket/16453#comment:63>
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 unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/d/optout.

Reply via email to