#14279: Coercion for homsets
----------------------------------------------------------+-----------------
Reporter: SimonKing | Owner:
nthiery
Type: defect | Status:
needs_review
Priority: major | Milestone:
sage-5.9
Component: categories | Resolution:
Keywords: | Work issues:
Report Upstream: N/A | Reviewers:
Authors: Simon King | Merged in:
Dependencies: #11490, #14214, #14249, #14225, #14278 | Stopgaps:
----------------------------------------------------------+-----------------
Comment (by SimonKing):
I think it makes sense to introduce a new type of action (i.e., a subclass
of sage.categories.action.Action) for multiplying maps by composition.
The advantages:
* Actions are cached. Hence, only when the action is created for the first
time, it is needed to check whether the codomain of the right factor
matches the domain of the left factor. Currently, this is checked in every
single multiplication.
* Moreover, the action can keep a reference on the homset that contains
the composed map, so that there is no need to call the Hom function in
every single multiplication.
* Using actions is, I think, part of using the new coercion model.
The disadvantage:
* `_get_action_` is a cpdef method. Unfortunately, Python/Cython tends to
confuse cpdef and def methods when one creates a class inheriting from two
different cdef classes. Here, it means that `Homset._get_action_` is not
available when one defines
`sage.modular.abvar.homspace.EndomorphismSubring` as subclass of both
Homset and Ring.
Solution of this problem: Drop Ring. Instead, implement the ring
properties of `EndomorphismSubring` by using the category framework.
These timings show the advantage of using actions (in each example, the
first timing is with both patches, the second timing is with the first
patch only):
1. Both patches
{{{
sage: A = ModularForms(1, 4)
sage: B = ModularForms(1, 16)
sage: C = ModularForms(1, 28)
sage: F = A.Hom(B)(matrix(QQ,1,2,srange(1, 3)))
sage: G = B.Hom(C)(matrix(QQ,2,3,srange(1, 7)))
sage: %timeit x=G*F
10000 loops, best of 3: 95.8 us per loop
}}}
Only first patch:
{{{
sage: %timeit x=G*F
10000 loops, best of 3: 117 us per loop
}}}
__TODO__
Provide another patch, namely for documentation.
2. Both patches
{{{
sage: from sage.categories.morphism import SetMorphism
sage: X.<x> = ZZ[]
sage: Y = ZZ
sage: Z = QQ
sage: phi_xy = SetMorphism(Hom(X, Y, Rings()), lambda p: p[0])
sage: phi_yz = SetMorphism(Hom(Y, Z,
CommutativeAdditiveMonoids()), lambda y: QQ(y)/2)
sage: %timeit x = phi_yz * phi_xy
100000 loops, best of 3: 6.37 us per loop
}}}
Only first patch:
{{{
sage: %timeit x = phi_yz * phi_xy
100000 loops, best of 3: 14.8 us per loop
}}}
3. Both patches:
{{{
sage: R.<x,y> = QQ[]
sage: S.<a,b> = QQ[]
sage: f = R.hom([x+y,x-y],R)
sage: f = R.hom([a+b,a-b])
sage: g = S.hom([x+y,x-y])
sage: %timeit x = f*g
1000 loops, best of 3: 274 us per loop
}}}
First patch only:
{{{
sage: %timeit x = f*g
1000 loops, best of 3: 389 us per loop
}}}
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/14279#comment:2>
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?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.