#18758: Allow actions of a parent on itself
-------------------------------------+------------------------
       Reporter:  SimonKing          |        Owner:
           Type:  enhancement        |       Status:  new
       Priority:  major              |    Milestone:  sage-6.8
      Component:  coercion           |   Resolution:
       Keywords:  actions on itself  |    Merged in:
        Authors:                     |    Reviewers:
Report Upstream:  N/A                |  Work issues:
         Branch:                     |       Commit:
   Dependencies:  #18756             |     Stopgaps:
-------------------------------------+------------------------

Comment (by SimonKing):

 I haven't pushed my branch yet. Anyway, what I can do is the following:
 {{{
 sage: class MyElement(Element):
 ....:     def __init__(self, P, L):
 ....:         Element.__init__(self, P)
 ....:         self.l = L
 ....:     def _repr_(self):
 ....:         return "<{}>".format(self.l)
 ....:     def _add_(self, other):
 ....:         return self.parent()(zip(self.l, other.l))
 ....:     def _mul_(self, other):
 ....:         return self.parent()(self.l+other.l)
 sage: class MyMElement(ModuleElement):
 ....:     def __init__(self, P, L):
 ....:         ModuleElement.__init__(self, P)
 ....:         self.l = L
 ....:     def _repr_(self):
 ....:         return "<{}>".format(self.l)
 ....:     def _add_(self, other):
 ....:         return self.parent()(zip(self.l, other.l))
 ....:     def _mul_(self, other):
 ....:         return self.parent()(self.l+other.l)
 sage: class MyRElement(RingElement):
 ....:     def __init__(self, P, L):
 ....:         RingElement.__init__(self, P)
 ....:         self.l = L
 ....:     def _repr_(self):
 ....:         return "<{}>".format(self.l)
 ....:     def _add_(self, other):
 ....:         return self.parent()(zip(self.l, other.l))
 ....:     def _mul_(self, other):
 ....:         return self.parent()(self.l+other.l)
 sage: class MyParent(Parent):
 ....:     Element = MyElement
 sage: class MyMParent(Parent):
 ....:     Element = MyMElement
 sage: class MyRParent(Parent):
 ....:     Element = MyRElement
 sage: P = MyParent(category=Rings())
 sage: l = P([1,2])
 sage: l*l
 <[1, 2, 1, 2]>
 sage: PM = MyMParent(category=Rings())
 sage: lM = PM([1,2])
 sage: lM*lM
 <[1, 2, 1, 2]>
 sage: PR = MyRParent(category=Rings())
 sage: lR = PR([1,2])
 sage: lR*lR
 <[1, 2, 1, 2]>
 sage: %timeit l*l
 The slowest run took 4.68 times longer than the fastest. This could mean
 that an intermediate result is being cached
 100000 loops, best of 3: 8.77 µs per loop
 sage: %timeit lM*lM
 The slowest run took 6.35 times longer than the fastest. This could mean
 that an intermediate result is being cached
 100000 loops, best of 3: 7.89 µs per loop
 sage: %timeit lR*lR
 The slowest run took 7.06 times longer than the fastest. This could mean
 that an intermediate result is being cached
 100000 loops, best of 3: 7.22 µs per loop
 }}}

 Explanation:
 1. In P, we use Element as starting point. It has no `__mul__`, hence,
 `__mul__` is obtained from some element method of the category of rings.
 2. In PM, we use !ModuleElement as starting point.
     - It has a `__mul__` method that in vanilla Sage would refuse to carry
 a ring structure. Hence, the above wouldn't work in vanilla Sage. I have
 changed the coercion framework so that it does not complain about a ring
 structure.
     - Since it has a `__mul__` method, it cannot inherit a ring
 multiplication from the category element methods. Instead, the parent
 inherits `_get_action_` from parent methods, as per #18756.
 3. This would be the "classical" way to define a ring structure.

 As you can see, of course a specialised cythoned `__mul__` method for
 rings is fastest. The first approach is taken in
 `CombinatorialFreeModule`, if I understand correctly, and is slowest (not
 by much, but it is). The new approach to use an action of self on itself
 somehow is in the middle, speed-wise.

 Before I push my branch, I'll see what happens if I provide `Element` with
 a default `__mul__` method that simply calls the coercion model. It will
 of course make the first approach impossible, but I guess it would speed-
 up the second (i.e., new) approach.

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