The class RingFpDoubleImpl
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:
NewRingFpDouble(Z, p) -- Z ring of integers, p a machine integer NewRingFpDouble(Z, P) -- Z ring of integers, P a large integer (type ZZ) NewRingFpDouble(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.
The class RingFpDoubleImpl
is intended to represent small, prime
finite fields. The constructor is more complicated than one might
expect; this is because the RingFpDoubleImpl
object must store a
little extra information to fulfil its role as a QuotientRing
.
Currently, the characteristic must be prime (otherwise it wouldn't be a
field). Furthermore, the characteristic p must also be small enough
that all integers up to p*(p+1) can be represented exactly as double
s.
Creating a RingFpDoubleImpl
takes almost constant time (except for the
primality check). An error is signalled (i.e. a CoCoA::ErrorInfo
is
thrown) if the characteristic is too large or not prime.
Extreme efficiency is NOT one of the main features of this version:
contrast with SmallFpDoubleImpl
.
The class RingFpDoubleImpl
derives from QuotientRingBase
,
which in turn is derived from RingBase
: see QuotientRing
and
ring
for more details. Note that there is no RingFpDouble
class; a RingFpDoubleImpl
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 specifies the type used internally for representing
the value of an element of a RingFpDoubleImpl
: currently this is just
SmallFpDoubleImpl::value_t
which is double
.
Essentially all operations are delegated to the class SmallFpDoubleImpl
.
The two classes are separate so that the inline operations of
SmallFpDoubleImpl
can be accessed directly in certain other special case
implementations (e.g. polynomials with coeffs in a SmallFp). See the
documentation in SmallFpDoubleImpl.txt for details.
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 RingFpImpl
may depend on the
platform. If IEEE doubles are used then moduli up to 67108859 are
permitted -- refer to SmallFpDoubleImpl.txt for details.
Although it may seem wasteful to use heap memory for the values of
elements in a RingFpDoubleImpl
, trying to make them "inline" leads to
lots of problems -- see RingFp
for more details.
Can reduction modulo p be made faster?
Run-time performance is disappointing.
I wonder if this code will ever prove useful to anyone.