NumericTraits.h

Classes

NumericTraits -- Relationships between numeric data types (full description)
NumericTraits_F -- NumericTraits specialization for Float (full description)
NumericTraits_D -- NumericTraits specialization for Double (full description)
NumericTraits_C -- NumericTraits specialization for Complex (full description)
NumericTraits_DC -- NumericTraits specialization for DComplex (full description)

template <class T> class NumericTraits

Interface

Public Members
static uInt size()
static void setImag(T &, const BaseType &)
static BaseType getValue(const T &, const uInt)
static void setValue(T &, const BaseType &, const uInt)

Description

Review Status

Reviewed By:
nkilleen
Date Reviewed:
1996/12/12
Programs:
Tests:

Etymology

A trait is a characteristic feature. NumericTraits defines relationships between and characteristics of Numeric data types.

Synopsis

This templated class contains a number of typedefs and definitions that describe the relationship between different numeric data types and there characteristics. Its use is in templated classes either where the use of one type implictly implies the use of a corresponding one or where a characteristic value differs with templating argument. Use of this class often avoids the need for double templating.

Currently this class defines the following relationships:

value_type
The template type itself. The name value_type is the C++ standard (e.g. DComplex::value_type equals double)
BaseType
The numeric base type. I.e. Double for Double and DComplex; Float for Float and Complex
ConjugateType
The corresponding complex type for a real type, and real type for a complex type. It is the type of the result if a Fourier Transform was to be done.
PrecisionType
The Type of the next higher numerical precision. I.e. Double or DComplex

And the following characteristics:

epsilon
A Double containing the smallest value such that 1+epsilon is different from 1.
minimum
A Double containing the smallest positive representable number, excluding denormalised numbers.
maximum
A Double containing the largest representable number.
size()
The number of numeric values in the templated entity. It will be 2 for complex numbers; 1 for real numbers.
setImag(T &other, const BaseType &val)
Set an imaginary part (for complex numbers) or a NOP (for reals).
getValue(T &other, const uInt n)
Get the n%size()-th value in the argument. For complex numbers the sequence is real, imaginary part.
setValue(T &other, const BaseType &val, const uInt n)
Set the n%size()-th value in the argument. For complex numbers the sequence is real, imaginary part.

For complex numbers these values are applicable to the real or imaginary components separately.

The use of this class is best illustrated in a number of examples.

A default template declaration is required by the C++ standard. It should never be used, except through the specialisations. The default types for ConjugateType and PrecisionType are deliberatly set to a non-numeric type to further discourage the use of the non-specialized class defined below. It also helps when using this class with the Sun native compiler.

Warning The specialized instantiations seem to have a name with an appended code. This is only for cxx2html reasons. The name is in all cases NumericTraits

Example

Example 1:

Suppose you are writing a templated class that needs to do Fourier Transforms. The FFTServer class can do FFT's of Float or Double data types, but you need to doubly template it on the conjugate data type. To avoid having the conjugate data type appear as a template in the class you are writing you can use the ConjugateType typedef.
    template<class T> class myClass {
    private:
    FFTServer<T, NumericTraits<T>::ConjugateType> server;
    }
    
The ConjugateType transforms

Example 2:

Suppose you have a templated numerical integrator class. Because the individual samples can be negative it is possible to add two numbers of nearly equal magnitude but opposite sign and lose precision considerably. One way to combat this is to make the accumulator variable the next higher precision numerical type. The PrecisionType typedef defines what type this is
    template<class T> class Integrator {
    private:
    NumericTraits<T>::PrecisionType accumulator;
    }
    
The PrecisionType transforms

Example 3:

Suppose you have a templated class that needs to use the allNear functions from ArrayMath to determine if a templated Array is near one. The tolerance argument to the allNear function will depend on the template type and this is not known until the template is instantiated. The epsilon trait can be used to supply this value.

    template<class T> void myClass<T>::myFunction(Array<T> & aArray) {
      if (allNear(aArray, T(1), NumericTraits<T>::epsilon))
        return;
    // Do something
    }
    

NumericTraits<T>::epsilon
is FLT_EPSILON for Float and Complex types and DBL_EPSILON for Double and DComplex data types.
NumericTraits<T>::minimum
is FLT_MIN for Float and complex Types and DBL_MIN for Double and DComplex data types.
NumericTraits<T>::maximum
is FLT_MAX for Float and complex Types and DBL_MAX for Double and DComplex data types.
See the C class/namespace for the values of these variables.

Motivation

This is a nice way to make the Convolver class singly templated (as it should be), even though the FFTServer it contains is doubly templated.

Template Type Argument Requirements (T)

Thrown Exceptions

To Do

Member Description

static uInt size()

Number of relevant numeric values

static void setImag(T &, const BaseType &)

Set the imaginary part of a complex value only (a NOP for reals)

static BaseType getValue(const T &, const uInt)

Get the n%size()-th numeric value

static void setValue(T &, const BaseType &, const uInt)

Set the n%size()-th numeric value

template <> class NumericTraits_F<Float>

Interface

static uInt size()
static void setImag(value_type &, const BaseType &)
static BaseType getValue(const value_type &other, const uInt)
static void setValue(value_type &other, const BaseType &val, const uInt)

Description

Member Description

static uInt size()

Number of relevant numeric values

static void setImag(value_type &, const BaseType &)

Set the imaginary part of a complex value only (a NOP for reals)

static BaseType getValue(const value_type &other, const uInt)

Get the n%size()-th numeric value

static void setValue(value_type &other, const BaseType &val, const uInt)

Set the n%size()-th numeric value

template <> class NumericTraits_D<Double>

Interface

static uInt size()
static void setImag(value_type &, const BaseType &)
static BaseType getValue(const value_type &other, const uInt)
static void setValue(value_type &other, const BaseType &val, const uInt)

Description

Member Description

static uInt size()

Number of relevant numeric values

static void setImag(value_type &, const BaseType &)

Set the imaginary part of a complex value only (a NOP for reals)

static BaseType getValue(const value_type &other, const uInt)

Get the n%size()-th numeric value

static void setValue(value_type &other, const BaseType &val, const uInt)

Set the n%size()-th numeric value

template <> class NumericTraits_C<Complex>

Interface

static uInt size()
static void setImag(value_type &other, const BaseType &val)
static BaseType getValue(const value_type &other, const uInt n)
static void setValue(value_type &other, const BaseType &val, const uInt n)

Description

Member Description

static uInt size()

Number of relevant numeric values

static void setImag(value_type &other, const BaseType &val)

Set the imaginary part of a complex value only (a NOP for reals)

static BaseType getValue(const value_type &other, const uInt n)

Get the n%size()-th numeric value

static void setValue(value_type &other, const BaseType &val, const uInt n)

Set the n%size()-th numeric value

template <> class NumericTraits_DC<DComplex>

Interface

static uInt size()
static void setImag(value_type &other, const BaseType &val)
static BaseType getValue(const value_type &other, const uInt n)
static void setValue(value_type &other, const BaseType &val, const uInt n)

Description

Member Description

static uInt size()

Number of relevant numeric values

static void setImag(value_type &other, const BaseType &val)

Set the imaginary part of a complex value only (a NOP for reals)

static BaseType getValue(const value_type &other, const uInt n)

Get the n%size()-th numeric value

static void setValue(value_type &other, const BaseType &val, const uInt n)

Set the n%size()-th numeric value