First time here? Check out the FAQ!

Ask Your Question
1

inheriting from CombinatorialFreeModule

asked 12 years ago

shacsmuggler gravatar image

updated 10 years ago

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!

Preview: (hide)

2 Answers

Sort by » oldest newest most voted
0

answered 12 years ago

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.

Preview: (hide)
link
0

answered 12 years ago

shacsmuggler gravatar image

updated 12 years ago

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.

Preview: (hide)
link

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: 12 years ago

Seen: 479 times

Last updated: Aug 31 '12