# construction of product rings Z/nZ x Z/mZ

Hello,

is it possible in Sage to construct a product ring of two integer modulo rings?

When just creating an cartesian_product, it is for example not possible to add its elements:

R5=Integers(5)
R3=Integers(3)
CR=R5.cartesian_product(R3)
elem=CR((3,2)) # ok, element construction
elem*elem # ok
elem+elem # fails
CR.list() #  not implemented
CR.list_of_elements_of_multiplicative_group # not implemented

edit retag close merge delete

Sort by » oldest newest most voted

The code below (following this tutorial) seems to do the trick. I might turn it into an addition to the Sage codebase at some point (it needs documentation and tests for that, at the very least), but I don't have the time. If you feel like doing that, be my guest!

Just save to product_ring.py and, in Sage do sage: %runfile product_ring.py # from command line

or

import sage
from sage.rings.ring import Ring
from sage.rings.all import ZZ
from sage.structure.element import RingElement
from sage.categories.category import Category
from sage.structure.unique_representation import UniqueRepresentation
from sage.categories.rings import Rings
from sage.categories.pushout import ConstructionFunctor

class ProductRingElement(RingElement):
def __init__(self, data, parent=None):
if parent is None:
raise ValueError, "The parent must be provided"
self._data = tuple(data)
RingElement.__init__(self,parent)

def _repr_(self):
return "(" + ", ".join(x._repr_() for x in self._data) + ")"

def __cmp__(self, other):
return cmp(self._data, other._data)

C = self.__class__
z = zip(self._data, other._data)
return C(tuple(zz._add_(zz) for zz in z), parent=self.parent())

def _sub_(self, other):
C = self.__class__
z = zip(self._data, other._data)
return C(tuple(zz._sub_(zz) for zz in z), parent=self.parent())

def _mul_(self, other):
C = self.__class__
z = zip(self._data, other._data)
return C(tuple(zz._mul_(zz) for zz in z), parent=self.parent())

def _div_(self, other):
C = self.__class__
z = zip(self._data, other._data)
return C(tuple(zz._div_(zz) for zz in z), parent=self.parent())

def __iter__(self):
r"""
Returns an iterator of the entries of self.
"""
for x in self._data:
yield x

class ProductRing(UniqueRepresentation, Ring):
r"""
The product ring of a finite number of rings, with elementwise addition
and multiplication.
"""
Element = ProductRingElement

def __init__(self,rings, base=ZZ, category=None):
r"""
INPUT:

- rings -- a tuple of rings.
"""
from sage.categories.rings import Rings

if not all(R.is_ring() for R in rings):
raise TypeError("Expected a tuple of rings as input.")
self._rings = tuple(rings)
Ring.__init__(self, base=base, category=category or Rings())

def _repr_(self):
return "Product ring: (" + ", ".join(R._repr_() for R in self._rings) + ")"

def _element_constructor_(self, *args, **kwds):
if len(args) == len(self._rings):
z = zip(self._rings, args)
elif len(args) == 1:
try:
if len(args) != len(self._rings):
raise TypeError  # also if args has no len()
z = zip(self._rings, args)
except TypeError:
z = zip(self._rings, [args for x in self._rings])
else:
raise TypeError("Wrong number of ring elements")
return self.element_class(tuple(zz(zz) for zz in z), parent=self, **kwds)

def _coerce_map_from_(self, S):
if all(R.has_coerce_map_from(S) for R in self._rings):
return True

def __pow__(self,n):
r"""
Returns the n-th power of self as a vector space.
"""
from sage.modules ...
more

Thanks for the code. Someone, please explain to me how to use this code to construct the product of rings in jupiter? Thanks again

Here is part of the problem - the Cartesian product business seems to be about categories, not the actual rings. And it doesn't really give you what you want. In fact, I find this all somewhat disturbing.

sage: type(CR)
sage.sets.cartesian_product.CartesianProduct_with_category
sage: type(R5)
sage.rings.finite_rings.integer_mod_ring.IntegerModRing_generic_with_category
sage: elem*elem
(9, 4)
sage: elem.summand_projection(1)
2
sage: type(elem.summand_projection(1))
sage.rings.integer.Integer


You can do it with just the groups, but of course that's not what you want.

more

'You can do it with just the groups' - you mean using summand_projection? 'of course that's not what you want' - yes, I would like something more comfortable

It seems that CR forgot its ring structure, and kept only its multiplicative operation:

sage: elem.parent().category()
Category of Cartesian products of monoids

more

Well, the question is, is there a way to construct the product ring Z/nZ x Z/mZ in sage

I do not know, i asked to the sage.categories specialists.