Prev Next

AD<Base> Requirements for Base Type

Purpose
This section lists the requirements for the type Base so that the type AD<Base> can be used. In the case where Base is float, double, std::complex<float>, std::complex<double>, or AD<Other>, these requirements are provided by including he file cppad/cppad.hpp.

Warning
This is a preliminary version of these specifications and it is subject to change in future versions of CppAD.

Numeric Type
The type Base must support all the operations for a NumericType .

declare.hpp
The base type requirements must be included before the rest of CppAD. It is however necessary to declare the enum type CompareOp (and possible other things). This should be done with the following include command:
     # include <cppad/local/declare.hpp>

abs
The type Base must support the syntax
     
y = abs(x)
which computes the absolute value of it's argument. The argument x has prototype
     const 
Base &x
and the return value y has prototype
     
Base y
The CppAD abs derivative calculation assumes that the type Base is ordered; i.e.,  \[
     {\rm abs} (x) = \left\{ \begin{array}{ll}
          x & {\rm if} \; x \geq 0
          \\
          - x & {\rm otherwise}
     \end{array} \right.
\] 


Ordered Type
If the type Base supports the less than and unary minus operators, its abs function can be defined by
namespace CppAD {
     inline 
Base abs(const Base &x)
     {    if( x < Base(0) )
               return - x;
          return x;
     }
}

Not Ordered
If the type Base does not support ordering, derivatives of its abs function will not be computed correctly. In this case one might (but need not) define abs as follows:
namespace CppAD {
     inline 
Base abs(const Base &x)
     {    // attempt to use abs with a 
Base argument
          assert(0);
          return x;
     }
}

CondExp
The type Base must support the syntax
     
result = CondExpOp(copleftrighttrueCasefalseCase)
which computes the result for the corresponding CondExp function. The argument cop has prototype
     enum CppAD::CompareOp 
cop
The possible values for this enum type are CompareLt, CompareLe, CompareEq, CompareGe, and CompareGt. The other arguments have the prototype
     const 
Base      &left ,
     const 
Base     &right ,
     const 
Base  &trueCase ,
     const 
Base &falseCase )
The result has prototype
     
Base  &result

Ordered Type
If Base is a relatively simple type (does not record operations for future calculations) and it supports <, <=, ==, >=, and > operators its CondExpOp function can be defined by
namespace CppAD {
     inline 
Base CondExpOp(
     enum CppAD::CompareOp      cop ,
     const 
Base             &left ,
     const 
Base            &right ,
     const 
Base         &trueCase ,
     const 
Base        &falseCase )
     {    return CppAD::CondExpTemplate(
               cop, left, right, trueCase, falseCase);
     }
}

Not Ordered
If the type Base does not support ordering, the CondExpOp function does not make sense. In this case one might (but need not) define CondExpOp as follows:
namespace CppAD {
     inline 
Base CondExpOp(
     enum CompareOp      cop ,
     const 
Base      &left ,
     const 
Base     &right ,
     const 
Base  &trueCase ,
     const 
Base &falseCase )
     {    // attempt to use CondExp with a 
Base argument
          assert(0);
          return 
Base(0);
     }
}

EqualOpSeq
If function EqualOpSeq is used with arguments of type AD<Base>, the type Base must support the syntax
     
b = EqualOpSeq(xy)
which returns true if and only if x is equal to y (this is used by the EqualOpSeq function). The arguments x and y have prototype
     const 
Base &x
     const 
Base &y
The return value b has prototype
     bool 
b

Suggestion
If Base is a relatively simple type (does not record operations for future calculations), the EqualOpSeq function can be defined by
namespace CppAD {
     inline 
Base EqualOpSeq(const Base &x, const Base &y)
     {    return x == y; }
}

erf
The type Base must support the syntax
     
y = erf(x)
which computes the erf function. The argument x has prototype
     const 
Base &x
and the return value y has prototype
     
Base y

Suggestion
If the type Base does not have a definition for the erf function, you could make its use by AD<Base> an error as follows:
namespace CppAD {
     inline 
Base erf(const Base &x)
     {    assert (0);
          return 
Base(0); 
     }
}

Identical
If the type Base records what operations are preformed by AD<Base>, CppAD must know if the Base value corresponding to an operation will be the same. For example, suppose the current operation is between two AD<Base> objects where Base is AD<double>; some optimizations depend on one of the objects being a parameter as well as its corresponding Base value also being a parameter. In general, the type Base must support the following functions:
Syntax Result
b = IdenticalPar(x)    the Base value will always be the same
b = IdenticalZero(x)    x equals zero and IdenticalPar(x)
b = IdenticalOne(x)    x equals one and IdenticalPar(x)
b = IdenticalEqualPar(xy)    x equals y, IdenticalPar(x) and IdenticalPar(y)
The argument x has prototype
     const 
Base x
If it is present, the argument y has prototype
     const 
Base y
The result b has prototype
     bool 
b

Suggestion
Note that false is a slow but safer option for all of these functions. If Base is a relatively simple type (does not record operations for future calculations), the IdenticalPar function can be defined by
namespace CppAD {
     inline bool IdenticalPar(const 
Base &x)
     {    return true; }
}
and the IdenticalZero function can be defined by
namespace CppAD {
     inline bool IdenticalZero(const 
Base &x)
        {       return x == Base(0); }
}
The other functions could be defined in a similar manner.

If the Base type records operations and may change the value of x or y during some future calculation, these functions should return false. If you are not sure what should be returned, false is a safer value (but makes some calculations slower).

Integer
The type Base must support the syntax
     
i = Integer(x)
which converts x to an int. The argument x has prototype
     const 
Base &x
and the return value i has prototype
     int 
i

Suggestion
The Base version of the Integer function might be defined by
namespace CppAD {
     inline int Integer(const 
Base &x)
     {    return static_cast<int>(x); }
}

Ordered
So that CppAD can be used with a base type that does not support the ordering operations >, >=, <, or <=, Base must support the following functions:
Syntax Result
b = GreaterThanZero(x)     x > 0
b = GreaterThanOrZero(x)     x \geq 0
b = LessThanZero(x)     x < 0
b = LessThanOrZero(x)     x \leq 0
The argument x has prototype
     const 
Base &x
and the result b has prototype
     bool 
b

Ordered Type
If the type Base supports ordered operations, these functions should have their corresponding definitions. For example,
namespace CppAD {
     inline bool GreaterThanZero(const 
Base &x)
     {    return (x > 0);
     }
}
The other functions would replace > by the corresponding operator.

Not Ordered
If the type Base does not support ordering, one might (but need not) define GreaterThanZero as follows:
namespace CppAD {
     inline bool GreaterThanZero(const 
Base &x)
     {    // attempt to use GreaterThanZero with a 
Base argument
          assert(0);
          return x;
     }
}
The other functions would have the corresponding definition.

pow
The type Base must support the syntax
     
z = pow(xy)
which computes  z = x^y . The arguments x and y have prototypes
     const 
Base &x
     const 
Base &y
The return value z has prototype
     
Base z

Standard Math Unary
The type Base must support the following standard math unary functions :
Syntax Result
y = acos(x) inverse cosine
y = asin(x) inverse sine
y = atan(x) inverse tangent
y = cos(x) cosine
y = cosh(x) hyperbolic cosine
y = exp(x) exponential
y = log(x) natural logarithm
y = sin(x) sine
y = sinh(x) hyperbolic sine
y = sqrt(x) square root
y = tan(x) tangent
The argument x has prototype
     const 
Base &x
and the result y has prototype
     
Base y

Example
The files base_complex.hpp and base_adolc.hpp contain example implementations of these requirements.
Input File: omh/base_require.omh