Ask Your Question

construction of product rings Z/nZ x Z/mZ

asked 2013-07-11 18:46:09 +0200

jack77 gravatar image


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:

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 flag offensive close merge delete


Good question! I need this myself.

Stefan gravatar imageStefan ( 2013-08-29 11:32:42 +0200 )edit

3 Answers

Sort by ยป oldest newest most voted

answered 2013-09-12 19:13:28 +0200

Stefan gravatar image

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 and, in Sage do sage: %runfile # from command line


load # from notebook.

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)

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

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

    def _add_(self, other):
        C = self.__class__
        z = zip(self._data, other._data)
        return C(tuple(zz[0]._add_(zz[1]) for zz in z), parent=self.parent())

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

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

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

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

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

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

        - ``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:
                if len(args[0]) != len(self._rings):
                    raise TypeError  # also if args[0] has no len()
                z = zip(self._rings, args[0])
            except TypeError:
                z = zip(self._rings, [args[0] for x in self._rings])
            raise TypeError("Wrong number of ring elements")
        return self.element_class(tuple(zz[0](zz[1]) 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):
        Returns the ``n``-th power of self as a vector space.
        from sage.modules ...
edit flag offensive delete link 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

GA3165 gravatar imageGA3165 ( 2021-03-30 16:22:32 +0200 )edit

answered 2013-07-11 19:16:58 +0200

kcrisman gravatar image

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: type(R5)
sage: elem*elem
(9, 4)
sage: elem.summand_projection(1)
sage: type(elem.summand_projection(1))

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

edit flag offensive delete link 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

jack77 gravatar imagejack77 ( 2013-07-12 05:18:09 +0200 )edit

answered 2013-07-11 19:17:28 +0200

tmonteil gravatar image

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

sage: elem.parent().category()
Category of Cartesian products of monoids
edit flag offensive delete link more


Right... but the question is what went wrong?

kcrisman gravatar imagekcrisman ( 2013-07-11 20:01:31 +0200 )edit

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

jack77 gravatar imagejack77 ( 2013-07-12 05:13:28 +0200 )edit

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

tmonteil gravatar imagetmonteil ( 2013-07-12 09:54:54 +0200 )edit

Your Answer

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

Add Answer

Question Tools


Asked: 2013-07-11 18:46:09 +0200

Seen: 1,194 times

Last updated: Sep 12 '13