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

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.

edit retag close merge delete

Sort by » oldest newest most voted

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]

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:

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...

more

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.

( 2015-12-01 07:19:01 +0100 )edit