Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coercion for homsets #14279

Open
simon-king-jena opened this issue Mar 15, 2013 · 5 comments
Open

Coercion for homsets #14279

simon-king-jena opened this issue Mar 15, 2013 · 5 comments

Comments

@simon-king-jena
Copy link
Member

Homsets are parents that, up to now, do not use Sage's coercion model and do not use element classes. Morphisms are elements that, up to now, would define a custom __mul__ and __add__ and so on.

The purpose of this ticket is to use the new framework. As you can imagine, this involves many changes. One important change: I let sage.categories.map.Map inherit from sage.structure.element.ModuleElement. Not all homsets are modules, of course, but when they are, then one can simply define single underscore _add_, _rmul_ and _composition_ (the latter is for composition of maps) as usual, so that one does not need to overload __mul__ so often.

Another important change: Domain and codomain of a morphism used to be parents, but that's wrong, because parents are CategoryObjects that contain elements, but we can speak of morphisms (purely categorically) without elements. Hence, I changed domain and codomain into CategoryObject.

In sage.homology, no reasonable base classes were used: Everything was directly inheriting from SageObject. I improved this.

While I was at it, I was fixing some homset related pickling problems, and I implemented a cache for a parent where that has been previously tried unsuccessfully.

It is difficult to say what component this ticket belongs to. I try "categories".

Depends on #11490
Depends on #14214
Depends on #14249
Depends on #14225
Depends on #14278

Component: categories

Work Issues: documentation

Author: Simon King

Issue created by migration from https://trac.sagemath.org/ticket/14279

@simon-king-jena
Copy link
Member Author

Attachment: trac_14279-new_coercion_for_homsets.patch.gz

Main patch, needs better documentation of the changes

@simon-king-jena
Copy link
Member Author

comment:1

I change it into "needs review", in order to let the patchbot do some work.

However, it will need a second patch, that improves documentation. But I certainly would like to get some input at that point.

@simon-king-jena
Copy link
Member Author

Composition action

@simon-king-jena
Copy link
Member Author

comment:2

Attachment: trac_14279-composition_action.patch.gz

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/cdef 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
  1. 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
  1. 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

TODO

Provide another patch, namely for documentation.

@jdemeyer jdemeyer modified the milestones: sage-5.11, sage-5.12 Aug 13, 2013
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.1, sage-6.2 Jan 30, 2014
@rwst
Copy link

rwst commented Mar 31, 2014

Work Issues: documentation

@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.2, sage-6.3 May 6, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.3, sage-6.4 Aug 10, 2014
@mkoeppe mkoeppe removed this from the sage-6.4 milestone Dec 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants