#15820: Implement sequences of bounded integers
--------------------------------------------+------------------------
       Reporter:  SimonKing                 |        Owner:
           Type:  enhancement               |       Status:  new
       Priority:  major                     |    Milestone:  sage-6.3
      Component:  algebra                   |   Resolution:
       Keywords:  sequence bounded integer  |    Merged in:
        Authors:                            |    Reviewers:
Report Upstream:  N/A                       |  Work issues:
         Branch:                            |       Commit:
   Dependencies:                            |     Stopgaps:
--------------------------------------------+------------------------

Comment (by SimonKing):

 Some variation on the theme: One can create fused types from two cdef
 classes, and then one can work with specialisations of functions as
 follows:
 {{{
 #!python

 ctypedef fused str_or_int:
     str
     int

 # make the function do different things on different types,
 # to better see the difference
 cpdef str_or_int times_two(str_or_int var):
     if str_or_int is int:
         return var+var
     else:
         return var+'+'+var

 # forward declaration of cdef classes and their fusion
 cdef class Bar_int
 cdef class Bar_str
 cdef fused Bar:
     Bar_int
     Bar_str

 # a function that can be specialised to either of the two extension
 classes
 def twice(Bar self):
     # and inside, we specialised a function depending
     # on the type of an attribute --- at compile time!!
     return type(self)(times_two(self.data))

 cdef class Bar_str:
     cdef str data
     def __init__(self, data):
         self.data = data
     def __repr__(self):
         return self.data
     # First possibility: Use the "templated" function as a method
     twice_ = twice[Bar_str]
     # second possibility: Wrap the "templated" function
     cpdef Bar_str twice__(self):
         return twice(self)

 # The same, with the other Specialisation of <Bar>
 cdef class Bar_int:
     cdef int data
     def __init__(self, data):
         self.data = data
     def __repr__(self):
         return "int(%d)"%self.data
     twice_ = twice[Bar_int]
     cpdef Bar_int twice__(self):
         return twice(self)
 }}}
 Time-wise, we see that wrapping the "templated" function is slower than
 using it as an attribute:
 {{{
 sage: b1 = Bar_str('abc')
 sage: b1.twice_()
 abc+abc
 sage: b1.twice__()
 abc+abc
 sage: %timeit b1.twice_()
 1000000 loops, best of 3: 759 ns per loop
 sage: %timeit b1.twice__()
 100000 loops, best of 3: 13.7 µs per loop
 sage: b2 = Bar_int(5)
 sage: b2.twice_()
 int(10)
 sage: b2.twice__()
 int(10)
 sage: %timeit b2.twice_()
 1000000 loops, best of 3: 539 ns per loop
 sage: %timeit b2.twice__()
 100000 loops, best of 3: 9.2 µs per loop
 }}}

 __Summary and further comments__

 - We can reduce the code duplication to something like this:
   {{{
 <define templated function foo_ depending on a fused type Bar with
 specialisations Bar1, Bar2,...>
 cdef class Bar1:
     foo = foo_[Bar1]
 cdef class Bar2:
     foo = foo_[Bar2]
 ...
   }}}
   I hope this level of copy-and-paste can be afforded. At least, it gives
 good speed.
 - In my tests I found the following:
   - It is impossible to make `foo_` a cpdef function. Otherwise, the
 assignment `foo = foo_` fails with the statement that `foo_` can not be
 turned into a Python type.
   - It is impossible to chose the same name for the templated function and
 for the method it is turned into. Doing
     {{{
 class Bar1:
     foo_ = foo_
     }}}
     results in an error saying that `Bar1` has not attribute `foo_`.
   - With the syntax above, both `twice_` and `twice__` have been put into
 the class' `__dict__`. I did not succeed to turn it into the equivalent of
 a cdef method.

--
Ticket URL: <http://trac.sagemath.org/ticket/15820#comment:46>
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