Ask Your Question
1

inheriting from CombinatorialFreeModule

asked 2012-08-30 21:08:46 +0100

shacsmuggler gravatar image

updated 2015-01-14 10:27:10 +0100

FrédéricC gravatar image

I am trying to write a class that inherits from CombinatorialFreeModule. My problem is correctly inheriting from the element class. I have the following code:

from sage.sets.family import Family
from sage.categories.all import GradedAlgebrasWithBasis
from sage.combinat.free_module import CombinatorialFreeModule, CombinatorialFreeModuleElement
from sage.categories.all import tensor

class TestRing(CombinatorialFreeModule):

    def __init__(self, R, G):
        super(TestRing, self).__init__(R, G)

class TestRingElement(CombinatorialFreeModuleElement):

    def __init__(self, M, x):
        super(TestRingElement, self).__init__(M, x)
        self.data = x

I can create a TestRing object and get its basis elements as follows:

sage: R = TestRing(QQ, ('a','b'))
sage: a,b = R.basis()

My problem is that a and b have no data attribute. They are not instances of the TestRingElement class:

sage: a.d
a.db     a.dump   a.dumps  
sage: isinstance( a, TestRingElement )
False

I want to be able to add more attributes to the elements of my module. Can someone tell me the correct way to do this?

Incidentally, this code breaks when I call TestRing with a list as its second argument, instead of a tuple. Though, if I create a list inside the constructor (based on input to the constructor) and use that when I call the parent constructor, everything runs fine. Can anyone tell me why the code breaks in the first instance? Or, why does it work in the second instance?

Thanks!

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
0

answered 2012-08-31 00:56:40 +0100

As far as I understand it, when you call CombinatorialFreeModule(R, basis_keys), it doesn't call its __init__ method right away: first it calls its __classcall_private__ method, which does things like convert basis_keys to a hashable type:

    if isinstance(basis_keys, (list, tuple)):
        basis_keys = FiniteEnumeratedSet(basis_keys)

Then this gets passed to the __init__ method. As a result, giving the same names for the generators results in the identical object (not just equal, but identical):

sage: M1 = CombinatorialFreeModule(ZZ, ['a', 'b', 'c'])
sage: M2 = CombinatorialFreeModule(ZZ, ('a', 'b', 'c'))
sage: M1 is M2
True

This works for me:

from sage.combinat.free_module import CombinatorialFreeModule, CombinatorialFreeModuleElement

class TestRingElement(CombinatorialFreeModuleElement):

    def __init__(self, M, x):
        super(TestRingElement, self).__init__(M, x)
        self.data = x

class TestRing(CombinatorialFreeModule):

    Element = TestRingElement

    @staticmethod
    def __classcall__(self, R, G):
        from sage.sets.all import FiniteEnumeratedSet
        if isinstance(G, (list, tuple)):
            G = FiniteEnumeratedSet(G)
        return super(TestRing, self).__classcall__(self, R, G)

    def __init__(self, R, G):
        CombinatorialFreeModule.__init__(self, R, G)

You could check the Sage library for other classes which are based on CombinatorialFreeModule. I wrote the code in sage.algebras.steenrod.steenrod_algebra, for instance. A simpler example is in sage.categories.examples.hopf_algebras_with_basis.

edit flag offensive delete link more
0

answered 2012-08-30 21:30:49 +0100

shacsmuggler gravatar image

updated 2012-08-30 21:31:50 +0100

So, I asked my question just a few minutes too soon. I had two problems: I needed to define the TestRingElement before TestRing, and I needed to specify the Element attribute of TestRing. After the right things are imported, the following code runs as expected:

class TestRingElement(CombinatorialFreeModuleElement):

    def __init__(self, M, x):
        super(TestRingElement, self).__init__(M, x)
        self.data = x

class TestRing(CombinatorialFreeModule):

    Element = TestRingElement

    def __init__(self, R, G):
        super(TestRing, self).__init__(R, G)

I am still curious, though, if anyone can answer my other question about passing in lists to the constructor.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2012-08-30 21:08:46 +0100

Seen: 463 times

Last updated: Aug 31 '12