Traits classes for arithmetic

Traits classes are small classes, which are used to deduce new types in specific constructions. By specialization of parametric definitions, they combine flexibility and genericity.

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.

See also:

Arithmetic Kernel

It is often a difficult task to define all the traits related to a new data type. That is why we introduce here the definition of kernels.

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):

All the traits classes for gmp numbers are now defined by their kernel (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.

Rings and Fields

Here are trait classes which test basic properties of the type:

To get the ring and field associated to a given type, we use the following trait classes:

Here are our default definitions:
  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
As one can see we neglect the overflow problem that can occurs with 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.

Subset, Supset

The 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.

,_Floating Integer, Rational, Floating

Any number type is associated to an integer (rational, floating, ieee), by the 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).

Algebraic closure type

This class is a traits class used to specify the type corresponding to the algebraic closure of a given type 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>

Real closure type

The class 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