#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.