RingHom

© 2005 John Abbott
GNU Free Documentation License, Version 1.2



index page

User documentation for the files RingHom.H and RingHom.C

The class RingHom is intended to represent homomorphisms between rings. Currently there is no way to represent more general maps between rings. It is possible to create a "partial homomorphism" which can generate run-time errors when applied to certain values.

A RingHom is a "constant object": its value is determined at the moment of its creation, and cannot be changed. There is no default constructor, and assignment of RingHoms is not allowed.

Constructors

Here is a complete list of pseudo-constructors for ring homomorphisms (some are defined in other files, e.g. QuotientRing.H or FractionField.H).

    NewIdentityRingHom(R)
           where R may be any ring, gives the identity homomorphism on R
  
    NewInducedHom(RmodI, phi)
           where RmodI is a [``QuotientRing`` QuotientRing.html], gives the homomorphism induced
           by phi (which must have the base ring of RmodI as its domain,
           and whose kernel must contain the defining ideal of RmodI)
  
    NewZEmbeddingHom(Z, R)
           where Z is the ring of integers (i.e. a [``RingZ`` RingZ.html]), gives the
           unique homomorphism from Z to R
  
    NewPolyRingHom(Rx, S, CoeffHom, xImages)
           where Rx is a [``PolyRing`` PolyRing.html] and CoeffHom is a homomorphism whose
           domain is the coefficient ring of Rx and xImages is a ``vector``
           of ``RingElem`` specifying the images of the indeterminates, gives
           the homomorphism from Rx to S mapping coefficients according to
           CoeffHom and mapping the k-th indeterminate of Rx to the k-th
           value in xImages (i.e. having index k-1)
  
    CoeffEmbeddingHom(P)
           where P is a [``PolyRing`` PolyRing.html], gives the embedding homomorphism from
           the coefficient ring into the polynomial ring.
  
    EmbeddingHom(FrF)
           where FrF is a [``FractionField`` FractionField.html], gives the embedding homomorphism
           from the base ring into the fracion field (i.e. x |-> x/1)
  
    NewInducedHom(FrF, phi)
           where FrF is a [``FractionField`` FractionField.html], gives the homomorphism induced by
           phi (which must have the base ring of FrF as its domain).  Note that
           the resulting homomorphism may be only partial (e.g. if ker(phi) is
           non-trivial, or if the codomain is not a field).

Applying a RingHom

A RingHom may applied using natural syntax: - let phi be an object of type RingHom - let x be an object of type RingElem - let n be of type long or int - let N be an object of type ZZ -

    phi(x)  applies phi to x; error if owner(x) != domain(phi)
    phi(n)  applies phi to n
    phi(N)  applies phi to N

In all cases the result is a RingElem belonging to the codomain of phi. Currently "partial" homomorphisms are allowed, so applying a RingHom could trigger an error (e.g. an induced hom from Q to Z/(3) applied to 1/3).

Composition

Two RingHoms may be composed using a fairly natural syntax: if we have two RingHoms phi:R -> S and theta:S -> T then their composition may be computed using the syntax

   theta(phi)   the composite homomorphism "apply phi first then theta"

Domain and Codomain

We may ask for the domain and codomain of a RingHom phi:

    domain(phi)       gives a const ref to the domain
    codomain(phi)     gives a const ref to the codomain

Note that the domain and codomain are merely rings, they "forget" any special ring type

Kernel

Currently it is not possible to ask for the kernel of a RingHom.

Member Functions for Operations on Raw Values

All operations on a RingHom are invisibly converted into member function calls on a RingHomBase. It is possible to call these member functions directly: the main difference is that the member functions do not perform any sanity checking on their arguments (so they should be slightly faster but if you hand in incompatible arguments, you'll probably get an ugly crash).

Maintainer documentation for the files RingHom.H and RingHom.C

These files contain two "generic" classes (RingHom and RingHomBase), and a trivial concrete class representing the identity ring homomorphism, IdentityRingHom. Most of this section is dedicated to the two generic classes since they represent the primary contribution to the CoCoA library.

The class RingHom is little more than a "reference counting smart pointer" class to objects of type RingHomBase; this latter type is designed to support intrusive reference counting. Beyond its role as a smart pointer RingHom offers four "function application" syntaxes:

    RingElem RingHom::operator()(ConstRefRingElem x) const;
    RingElem RingHom::operator()(long n) const;
    RingElem RingHom::operator()(const ZZ& N) const;
    RingHom RingHom::operator()(const RingHom&) const;

The first three support a natural syntax for applying the homomorphism to a ring element, a small integer, or a large integer. The last offers a fairly natural syntax for creating the composition of two homomorphisms.

The class RingHomBase is a purely abstract class which is used to specify the interface which any concrete ring homomorphism class must offer. In particular this base class already includes an intrusive reference counter, as required by RingHom. It also includes two private data members myDomainValue and myCodomainValue which store the domain and codomain rings. Note that these data fields are plain rings and so "forget" any special ring type which the domain or codomain may have had. Originally I had hoped to preserve any special ring type information, but this seemed to lead to a confusing and complex implementation (which probably would never have worked as I hoped). The two ring fields may be read using the accessor fnuctions:

      const ring& myDomain() const;
      const ring& myCodomain() const;

A concrete class implementing a ring homomorphism must supply definition for the following (pure virtual) functions:

      virtual void myApply(RingBase::RawValue& image, RingBase::ConstRawValue arg) const;
      virtual void myOutputSelf(std::ostream& out) const;

DO NOTE THAT the two arguments to myApply normally belong to DIFFERENT rings. arg belongs to myDomain() whereas image belongs to myCodomain(). The function myOutputSelf should print out a useful description of the homomorphism.

Bugs, Shortcomings and other ideas

First version of the documentation ==> rather spartan.

Cannot compute a kernel of a RingHom.

Arranging for domain(phi) and codomain(phi) to preserve C++ type information about the respective rings (e.g. PolyRing or FractionField rather than simply ring), appears to be difficult to achieve in any reasonable manner. I've decided that it is much simpler just to discard all special type information, and return simply rings. If the user knows something more, he can use a "cast" function like AsFractionField. Even if it were feasible to maintain such C++ type info, there would have to n-squared cases to cover all possible combinations of domain and codomain.

We should implement more special cases: e.g. same vars different coeff ring, PP --> PP, other... Also need some way of handling canonical homomorphisms.

Some special cases of homomorphic embeddings R --> S: (may belong with the special types of ring to which they are associated)