FractionField is an abstract class (inheriting from
representing a fraction field of an effective GCD domain.
RingElem FractionField for operations on its elements.
NewFractionField(R)-- creates a new
ring, more precisely a
FractionField, whose elements are formal fractions of elements of
Ris a true GCD domain, see
RingQQ()-- produces the CoCoA
ringwhich represents QQ, the field of rational numbers, fraction field of
RingQQ()several times will always produce the same unique ring in CoCoALib.
FractionField(R)-- sort of downcast the ring
Rto a fraction field; will throw an
ErrorInfoobject with code
S be a
Sis actually a
FractionFieldPtr(S)-- pointer to the fraction field impl (for calling mem fns); will throw an
ErrorInfoobject with code
In addition to the standard
ring operations, a
may be used in other functions.
FrF be a
ringit is the
FractionFieldof -- an identical copy of
R, not merely an isomorphic
InducedHom(FrF, phi)-- phi:
FractionField is wholly analogous to the class
i.e. a reference counting smart pointer. The only difference is that
FractionField knows that the
myRingPtr data member actually points to
an instance of a class derived from
FractionFieldBase (and so can
safely apply a
static_cast when the pointer value is accessed).
FractionFieldBase is an abstract class derived from
It adds a few pure virtual functions to those contained in
virtual const ring& myBaseRing() const; virtual ConstRawPtr myRawNum(ConstRawPtr rawq) const; // NB result belongs to BaseRing!! virtual ConstRawPtr myRawDen(ConstRawPtr rawq) const; // NB result belongs to BaseRing!! virtual const RingHom& myEmbeddingHom() const; virtual RingHom myInducedHomCtor(const RingHom& phi) const;
myBaseRing returns a reference to the
ring (guaranteed to be an effective GCD
domain) supplied to the constructor.
myRawDen) produces a raw pointer to a value belonging to
BaseRing ( and *NOT* to the
FractionField!); these two functions *practically*
*oblige* the implementation of
FractionField to represent a value as a pair of
raw values "belonging" to the
BaseRing. Note that, while the value belongs to
BaseRing, the resources are owned by the
EmbeddingHom returns the embedding homomorphism from the
FractionField; it actually returns a reference to a fixed homomorpism
InducedHom creates a new homomorpism from the
FractionField to another
ring S given a homomorpism from the
BaseRing to S.
FractionFieldImpl implements a general fraction field. Its
elements are just pairs of
RawValues belonging to the
(see the struct
FractionFieldElem). For this implementation the
emphasis was clearly on simplicity over speed (at least partly because
we do not expect
FractionFieldImpl to be used much). For polynomials
whose coefficients lie in a
FractionField we plan to implement a
ring which uses a common denominator representation for
the whole polynomial. If you want to make this code faster, see some
of the comments in the bugs section.
Important: while fractions are guaranteed to be reduced (i.e. no common factor exists between numerator and denominator), it is rather hard to ensure that they are canonical since in general we can multiply numerator and denominator by any unit. See a bug comment about normalizing units.
myNew are not exception safe: memory would be leaked if
space for the numerator were successfully allocated while allocation for
the denominator failed -- nobody would clean up the resources consumed
by the numerator. Probably need a sort of
auto_ptr for holding
temporary bits of a value.
Should partial homomorphisms be allowed: e.g. from QQ to ZZ/(3)? Mathematically it is a bit dodgy, but in practice all works out fine provided you don't divide by zero. I think it would be too useful (e.g. for chinese remaindering methods) to be banned. Given phi:ZZ->ZZ[x] it might be risky to induce QQ->ZZ[x]; note that ker(phi)=0, so this is not a sufficient criterion!
Currently you can make a
FractionField only from a ring satisfying
IsTrueGCDDomain; in principle one could create a
of any integral domain (it just wouldn't be possible to cancel factors
without a GCD -- so probably not terribly practical). I'll wait until
someone really needs it before allowing it.
It is not clear how to make the denominator positive when the GCD domain is ZZ (so the fraction field is QQ). In general we would need the GCD domain to supply a normalizing unit: such a function could return 1 unless we have some special desire to normalize the denominator in a particular way. HERE'S A CONUNDRUM: FractionField(Q[x]) -- all rationals are units, and so we could end up with horrible representations like (22/7)/(22/7) instead of just 1. MUST FIX THIS!!
The printing function is TERRIBLE!
myIsRational is incomplete: it will fail to recognise rationals whose
numerator and denominator have been multiplied by non-trivial units. BAD BUG!
myIsInteger does work correctly.