The class RingFpLogImpl
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:
NewRingFpLog(Z, p) -- Z ring of integers, p a machine integer NewRingFpLog(Z, P) -- Z ring of integers, P a large integer (type ZZ) NewRingFpLog(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 RingFpLogImpl
is actually carried out by
a SmallFpLogImpl
object.
The class RingFpLogImpl
is intended to represent small, prime finite
fields. The constructor is more complicated than one might expect, this
is because the RingFpLogImpl
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).
Furthermore, the characteristic must also be less than 65536 even on
machines with 64-bit arithmetic -- larger values are prohibited as the
internal tables would become excessively large. Creating a
RingFpLogImpl
of characteristic p takes time roughly linear in p;
space consumption is linear in p. A CoCoAError is signalled if the
characteristic is too large or not prime.
Extreme efficiency is NOT one of the main features of this version.
The class RingFpLogImpl
derives from QuotientRingBase
, which
in turn is derived from RingBase
: see QuotientRing
and
ring
for more details. Note that there is no RingFpLog
class;
a RingFpLogImpl
object can only be accessed via 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 RingFpLogImpl::value_t
specifies the type used for
representing the value of an element of a RingFpLogImpl
: currently
this is a typedef for SmallFpLogElem_t
which is defined in config.H.
Essentially all operations are delegated to the class SmallFpLogImpl
.
The two classes are separate so that the inline operations of
SmallFpLogImpl
can be accessed directly in certain other special case
implementations (e.g. polynomials with coeffs in a SmallFp). See the
documentation in SmallFpLogImpl.txt for details. I note that the
residues are represented as the least non-negative value in the residue
class.
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.
The largest permitted modulus for a RingFpLogImpl
may depend on the
platform. On a 32-bit machine the modulus must surely be less than
65536 -- refer to SmallFpLogImpl.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 -- see RingFp
for more details
See also some comments in the "bugs" section of RingFp.txt.
The code is not very smart in the case of characteristic 2.
Run-time performance is disappointing.
I wonder if this code will ever prove useful to anyone.