Ask Your Question
1

How to create an object representing the set {a*S + b*T | a,b in ZZ}?

asked 9 years ago

Stepan gravatar image

I would like to construct an object which represents the following set {aS + bT | a,b in ZZ} where S, T are given. If S and T are two linearly independent vectors, I can manage to do it by constructing a submodule and then changing its base ring to ZZ, if the ambient field of the vector space is QQ.

sage: V = VectorSpace(QQ,2)
sage: S = V.submodule_with_basis([[1,1],[2,1]])
sage: S = S.change_ring(ZZ)
sage: S

However, I would like to have S = 1 and T equal to some irrational algebraic. In this case, I am unable to construct my set using a submodule of a vector space as above (the changing of ring expects the entries of elements of the vector space to be elements of QQ...). Is there some good way to use the SageMath's structures to produce this set?

I can construct a generic free module and map from and to QQ(T), but I was wondering if there is a better way.

Preview: (hide)

1 Answer

Sort by » oldest newest most voted
0

answered 9 years ago

vdelecroix gravatar image

updated 9 years ago

Dobrý den,

There is no direct way to do it. The question is what properties of the set do you want to use? Here is a simple class that more or less do what you wanted

from sage.misc.mrange import cantor_product

from sage.structure.parent import Parent
from sage.rings.qqbar import AA

class RealZZSubmodule(Parent):
    def __init__(self, elts):
        self._elts = [AA(x) for x in elts]
        Parent.__init__(self, category=(InfiniteEnumeratedSets(), Modules(ZZ)), facade=(AA,))

    def _repr_(self):
        return "ZZ-module generated by {}".format(self._elts)       

    def an_element(self):
        return self._elts[0]

    def _element_constructor_(self, arg):
        if isinstance(arg, (tuple,list)):
            assert len(arg) == len(self._elts)
            return sum(c*e for c,e in zip(arg, self._elts))
        elif arg in AA:
            raise NotImplementedError("please do it?")

    def __iter__(self):
        for i in cantor_product(ZZ, repeat=len(self._elts)):
            yield self(i)

With it you can do the following

sage: sqrt2 = AA(2).sqrt()
sage: R = RealZZSubmodule([1,sqrt2])
sage: R.cardinality()
+Infinity
sage: R
ZZ-module generated by [1, 1.414213562373095?]
sage: R((1,0))
1
sage: R((0,1))
1.414213562373095?
sage: R((8, -5))
0.9289321881345248?
sage: it = iter(R)
sage: for _ in range(10):
....:     print next(it)
0
1
1.414213562373095?
-1
2.414213562373095?
-1.414213562373095?
2
0.4142135623730951?
-0.4142135623730951?
2.828427124746190?

In order to make it answers less trivial questions you need to implement more methods...

Preview: (hide)
link

Comments

Hello Vincent,

thank you for your answer! My motivation however was to use SageMath's structures, not really implement my class as I was exploring its possibilities.

Anyway, to get what I need I will have to do my class anyway, so thanks.

Stepan gravatar imageStepan ( 9 years ago )

Your Answer

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

Add Answer

Question Tools

1 follower

Stats

Asked: 9 years ago

Seen: 277 times

Last updated: Nov 23 '15