User documentation for QuotientRing
A QuotientRing
is an abstract class (inheriting from ring
)
representing quotients of a ring
by an ideal
.
See RingElem
QuotientRing for operations on its elements.
Examples
Extended example of use:
RingZZ ZZ = RingZZ(); // a copy of the ring of integers ring ZZmod10 = NewZZmod(10); // represents ZZ/(10) integers modulo 10 ring ZZmod10a = NewQuotientRing(ZZ, ideal(ZZ, 10)); // same as ZZmod10 RingHom phi = QuotientingHom(ZZmod10); // ring hom from ZZ to ZZmod10 RingElem r(ZZmod10, -3); // an element of ZZmod10 RingElem preimage = CanonRepr(r); // an element of ZZ = BaseRing(ZZmod10) ring S = NewZZmod(2); // another ring S, details do not matter much RingHom theta = QuotientingHom(S); // any ring hom from ZZ to S will do instead RingHom theta_bar = NewInducedHom(ZZmod10, theta); // induced ring hom from ZZmod10 to S ring RmodI = NewQuotientRing(NewPolyRing(S,"x,y,z"), "x^2-2, y^3-1");
Constructors and Pseudo-constructors
NewQuotientRing(R, I)
-- creates a newring
representing the quotientR
/I
.I
must be an ideal ofR
; odd things may happen ifI
=R
. IfI
is zero then the result is isomorphic toR
but not equal toR
; arithmetic inR
is more efficient than arithmetic inR
/ideal(0).NewQuotientRing(R, str)
-- creates a newring
representing the quotientR
/I
, whereI
is the ideal inR
generated by the list ofRingElem
in the stringstr
.NewZZmod(n)
-- creates a newring
representing the quotientZZ
/ideal(n
) whereZZ
is the ring of integersRingZZ
andn
is an integer. A CoCoALib error will be thrown ifn
=1 orn
=-1. Currently an error will be thrown also ifn
=0 (see BUGS).QuotientRing
-- sort of downcast the ringR
to a quotient ring; will throw anErrorInfo
object with codeERR::NotQuotRing
if needed.
NewZZmod or NewRingFp?
If n
is a small prime then NewZZmod(n)
produces the same result as
NewRingFp(n)
(or perhaps NewRingFpDouble(n)
). If n
is not a
small prime then NewRingFp(n)
throws an exception whereas NewZZmod(n)
will produce a working quotient ring.
Query and cast
IsQuotientRing(R)
returns true iff R is implemented as aQuotientRing
QuotientRingPtr(R)
returns a pointer to the quotient ring impl (for calling mem fns); will throw anErrorInfo
object with codeERR::NotQuotRing
if needed.
Operations on QuotientRing
In addition to the standard ring
operations, a QuotientRing
may be used in other functions.
Given RmodI
a QuotientRing
(representing R/I)
built as NewQuotientRing(R,I)
with I
is an ideal
of the ring
R
.
BaseRing(RmodI)
-- a reference to the base ring ofRmodI
, namelyR
DefiningIdeal(RmodI)
-- a reference to the idealI
used to createRmodI
ReprRing(RmodI)
-- a reference to the ring used for internal representation of elements ofRmodI
Homomorphisms
QuotientingHom(RmodI)
-- a reference to the quotienting homomorphism fromR
toRmodI
InducedHom(RmodI, phi)
-- wherephi
is aRingHom
fromR
toS
, creates a newRingHom
fromRmodI
toS
. Two types of error may occur:ERR::BadInducingHom
-- ifdomain(phi)
is notBaseRing(RmodI)
ERR::BadInducingHomKer
-- ifphi
does not map the gens ofI
to zero.
Maintainer documentation for QuotientRing, QuotientRingBase, GeneralQuotientRingImpl
While considering the design of this code it may help to keep in mind these two canonical implementations:
-
GeneralQuotientRingImpl
- internally elements are represented as elements of a "representation ring" (which may differ from the base ring) which are kept reduced modulo some ideal (which may differ from the defining ideal)
-
RingFpImpl
- internally elements are represented by machine integers (see doc for RingFpImpl), a representation incompatible with that used for elements of the ring of integers (which is probably the base ring)
QuotientRingBase
is an abstract class derived from RingBase, and is the
base class for all quotient rings. It adds the following four new pure
virtual member functions which must be defined in every concrete
quotient ring:
virtual RingElem myCanonRepr(ConstRawValue r) const; virtual void myReduction(RawValue& image, ConstRawValue arg) const; virtual const RingHom& myQuotientingHom() const; virtual RingHom myInducedHomCtor(const RingHom& InducingHom) const;
The member function myCanonRepr has to return a copy of the value since we cannot be sure that the internal representation is compatible with the internal representation of elements of the base ring.
Bugs, Shortcomings and other ideas
IamTrueGCDDomain
always returns false. We can be clever in some easy
cases, but it is hard in general (think of rings of algebraic integers
which are gcd domains, but not euclidean domains).
Should NewZZmod(n) allow the case n==0? There's no mathematical reason to forbid it, but forbidding it may help detect programmer errors more quickly -- it seems unlikely that one would really want to quotient by ideal(0).
FAIRLY SERIOUS CONFUSION: the code seems to make REPEATED sanity checks see
QuotientRingBase::QuotientRingBase NewQuotientRing QuotientRingHomBase::QuotientRingHomBase NewInducedHom
I suspect that the C++ ctors should use CoCoA_ASSERT instead of checking always (and throwing an exception).
FURTHER SERIOUS CONFUSION: there is ambiguity about the difference between myBaseRing and myReprRing esp. for creating induced homomorphisms: given ring R, and ring S = R/I, create ring T = S/J An induced hom from T should start from a hom with domain S; or is it reasonable to accept a hom with domain R? In this case for T myReprRing is R but myBaseRing is S.
Given a RingHom from a QuotientRing it is not generally possible to obtain a reference to an "inducing hom": consider the hom from ZZ/(2) to ZZ/(2)[x] created by CoeffEmbeddingHom. A RingHom equivalent to the inducing hom can be produced by composing QuotientingHom with the given hom.
20 March 2004: I have added the possibility of making a trivial ring by quotienting: previously this was disallowed for no good reason that I could discern.