RingFp

© 2005 John Abbott
GNU Free Documentation License, Version 1.2



index page

User documentation for the class RingFpImpl

The class RingFpImpl is NOT intended for direct use by casual CoCoA library users. Instead consult QuotientRing.txt, in particular the functions NewZmod and NewQuotientRing.

In the directory examples/ there is a small example program showing how small finite fields (with known implementation) can be created and used: ex-RingFp2.C.

To create a ring of this type use one of the pseudo-constructors:

    NewRingFp(Z, p) -- Z ring of integers, p a machine integer
    NewRingFp(Z, P) -- Z ring of integers, P a large integer (type ZZ)
    NewRingFp(Z, I) -- Z ring of integers, I an ideal of Z

The pseudo-constructors will fail if the characteristic is not prime or is too large: the error signalled by throwing a CoCoA::ErrorInfo whose code is CoCoA::ERR::BadSmallFpChar.

If you seek a means for fast arithmetic in small finite fields consult the documentation about SmallFpImpl, SmallFpLogImpl, and SmallFpDoubleImpl. All arithmetic on elements of a RingFpImpl is actually carried out by a SmallFpImpl object.

Maintainer documentation for the class RingFpImpl

The class RingFpImpl is intended to implement small, prime finite fields. The constructor is more complicated than one might expect, this is because the RingFpImpl object must store a little extra information to fulfil its role as a QuotientRingBase. Currently, the characteristic must be prime (otherwise it wouldn't be a field) and must also be small enough that its square fits into a SmallFpElem_t (probably unsigned long, see the file config.H); if not, a CoCoAError is signalled.

Extreme efficiency is NOT one of the main features of this version; contrast this with SmallFpImpl.

The class RingFpImpl derives from QuotientRingBase, which in turn is derived from RingBase: see QuotientRing and ring for more details. Note that there is no RingFp class; a RingFpImpl object can only be accessed as a QuotientRing.

Note the use of "argument checking" static member functions in the ctor: this is because const data members must be initialized before the main body of the ctor is entered.

A member typedef RingFpImpl::value_t specifies the type used for representing the value of an element of a RingFpImpl: this is a typedef for SmallFpElem_t which is defined in config.H (to facilitate tuning for different platforms).

The data members are those of a QuotientRingBase (which are used only for answering queries about a QuotientRing), plus the characteristic of the field (held as an value_t in myModulus), and an auto-pointer to a copy of the zero and one elements of the ring.

The zero and one elements of the ring is held in an auto_ptr<> for consistency with the implementation of other rings -- in this simple class it is not really necessary for exception safety.

This implementation is very simplistic: almost every operation is delegated to the class SmallFpImpl. The implementation class has been separated so that its inline member functions can be used directly by some other special case code (e.g. polynomials with SmallFp coeffs). See SmallFpImpl.txt for details. I note that the residues are represented as the least non-negative value in the residue class.

The largest permitted modulus for a RingFpImpl may depend on the platform. On a 32-bit machine the modulus must surely be less than 65536 -- refer to SmallFpImpl.txt for details. A 64-bit machine may allow larger characteristics.

Although it may seem wasteful to use heap memory for the values of elements in a RingFpLogImpl, trying to make them "inline" leads to lots of problems. Originally we had implemented the values as "inline", and the resulting problems delayed CoCoALib by almost a year.

Bugs, shortcomings and other ideas

Why does the class RingFp not exist? Well, my current thoughts are that since a RingFp would not do anything special which a QuotientRing cannot do, it seems needless extra complication to create a "useless" class. In particular, it cannot offer better run-time performance. If you want to compute quickly modulo a small prime you must use SmallFpImpl directly.

Probably RingFp, RingFpLog and RingFpDouble could be replaced by instances of a template class -- the template parameter would be SmallFpImpl, SmallFpLogImpl or SmallFpDoubleImpl accordingly.

Why do all the member functions blindly forward their calls to the SmallFpImpl member functions? This means that the error message for division by zero (say) will refer to SmallFpImpl rather than RingFpImpl. Does this really matter that much? Obviously the much same applies to RingFpLogImpl and RingFpDoubleImpl.