We use the following conventions: The type defined by a trait class is denoted by T
. The integer value defined by a trait class is denoted by V
. For example, the trait kernelof
(see below), defines the arithmetic kernel associated to C
by kernelof<C>::T
.
Usually the default value is type::null_t
for traits defining a type and type::false_t
for boolean traits. Traits on arithmetic data types are not directly specialized, each trait class, say X
, uses the trait X_
for specialization. The reason for this mechanism is that generally the traits do not depend on type qualifiers, such as const
or &
. For instance, {kernelof<const C&>T} is associated to kernelof_<C>::T
.
synaps/arithm/traits.h
Until now synaps used gmp library for extended, rational and integer arithmetic, and traits were defined for each gmp particular data type. In this release of synaps library, the gmp numbers are put together into a kernel named GMP
which is simply a data structure containing the following type definition (as typedef
):
integer
, assumed to be an exact integer implementation.rational
, assumed to be an exact rational implementation.floating
, assumed to be an extended floating point arithmetic.ieee
, assumed to be a fixed precision ieee compliant number type.GMP
kernel), available by the traits class kernelof
.
By default, kernelof_<X>::T
is type::null_t
.
After an #include <synaps/arithm/gmp.h>
, kernelof<X>::T
is GMP
for X =
ZZ
, QQ
, RR
.
This new feature will soon allow synaps library to work with other library than GMP
, such as CLN
.
isring<C>
is a boolean trait, which specifies if C
implements a ring.isfield<C>
is also provided. Notice that we consider double
as field.
ringof<X,Y>::T
specify which data type can be used to represent sum and multiplication between type X
and type Y
. For example, given a kernel K
, ringof<K::integer,K::floating>::T
K::integer
. It is used for example in the dotproduct of two different vector types.fieldof<X,Y>::T
is similar for field operations. Notice again that we consider double
as a field.ringof<K::integer,K::floating>::T --> K::floating ringof<K::integer,K::rational>::T --> K::rational ringof<K::integer,K::ieee>::T --> K::ieee ringof<K::floating,K::rational>::T --> K::rational ringof<K::floating,K::ieee>::T --> K::floating ringof<K::ieee,K::rational>::T --> K::rational fieldof<K::integer,K::floating>::T --> K::rational fieldof<K::integer,K::rational>::T --> K::rational fieldof<K::integer,K::ieee>::T --> K::rational fieldof<K::floating,K::rational>::T --> K::rational fieldof<K::floating,K::ieee>::T --> K::floating fieldof<K::ieee,K::rational>::T --> K::rational
floating
and ieee
data types for ring operations.
For field operations we take the supset that can represent each inverses, when the two data types are inexact we take the best of the two.
Note that if a type C
is exact for the operations it implement then isexact<C>::T
is true_t
.
subsetof<X,Y>
trait is a boolean trait class, specifying if X
is a subset of Y
. For example given a kernel K
, subsetof<K::integer,K::rational>
T
is true_t.
The sup<X,Y>
is a more general concept used to choose a data type enclosing X
and Y
for all these operations, it correspond to default value of
ringof
and fieldof
, if sup<X,Y>
is not defined but X
issubsetof
of Y
, then sup<X,Y>
is defined by Y
.
integerof
(rationalof,floatingof,ieeeof
) trait.
For number type defined outside a kernel, ieeeof
defines double
.
isinteger<C>::T
(isrational,isfloating,isieee
) is true_t
if C
is an integer (rational, floating, ieee).
C
. This type is given by algebraic_closure<C>::T
. It can be used as follows:
algebraic_closure< complex<double> >::T // is complex<double> algebraic_closure<double>::T // is complex<double>
realof<C>
is a traits class used to specify the type corresponding to the real closure of C
. This type is given by \ realof<C>::T
. Here is an example:
realof<complex<double> >::T // is double realof<double>::T // is double