Include Files
This file base_adolc.hpp requires adouble to be defined.
In addition, it is included before <cppad/cppad.hpp>,
but it needs to include parts of CppAD that are used by this file.
This is done with the following include commands:
# include <adolc/adolc.h>
# include <cppad/base_require.hpp>
CondExpOp
The type adouble supports a conditional assignment function
with the syntax
condassign(a, b, c, d)
which evaluates to
a = (b > 0) ? c : d;
This enables one to include conditionals in the recording of
adouble operations and later evaluation for different
values of the independent variables
(in the same spirit as the CppAD CondExp
function).
namespace CppAD {
inline adouble CondExpOp(
enum CppAD::CompareOp cop ,
const adouble &left ,
const adouble &right ,
const adouble &trueCase ,
const adouble &falseCase )
{ adouble result;
switch( cop )
{
case CompareLt: // left < rightcondassign(result, right - left, trueCase, falseCase);
break;
case CompareLe: // left <= rightcondassign(result, left - right, falseCase, trueCase);
break;
case CompareEq: // left == rightcondassign(result, left - right, falseCase, trueCase);
condassign(result, right - left, falseCase, result);
break;
case CompareGe: // left >= rightcondassign(result, right - left, falseCase, trueCase);
break;
case CompareGt: // left > rightcondassign(result, left - right, trueCase, falseCase);
break;
default:
CppAD::ErrorHandler::Call(
true , __LINE__ , __FILE__ ,
"CppAD::CondExp",
"Error: for unknown reason."
);
result = trueCase;
}
return result;
}
}
EqualOpSeq
The Adolc user interface does not specify a way to determine if
two adouble variables correspond to the same operations sequence.
Make EqualOpSeq an error if it gets used:
Identical
The Adolc user interface does not specify a way to determine if an
adouble depends on the independent variables.
To be safe (but slow) return false in all the cases below.
Unary Standard Math
The following required
functions
are defined by the Adolc package for the adouble base case:
acos,
acosh,
asin,
asinh,
atan,
atanh,
cos,
cosh,
erf,
exp,
fabs,
log,
sin,
sinh,
sqrt,
tan.
erfc
If you provide --enable-atrig-erf on the configure command line,
the adolc package supports all the c++11 math functions except
erfc, expm1, and log1p.
For the reason, we make using erfc an error:
namespace CppAD {
# defineCPPAD_BASE_ADOLC_NO_SUPPORT(fun) \
inline adouble fun(const adouble& x) \
{ CPPAD_ASSERT_KNOWN( \
false, \
#fun ": adolc does not support this function" \
); \
return 0.0; \
}
CPPAD_BASE_ADOLC_NO_SUPPORT(erfc)
CPPAD_BASE_ADOLC_NO_SUPPORT(expm1)
CPPAD_BASE_ADOLC_NO_SUPPORT(log1p)
# undef CPPAD_BASE_ADOLC_NO_SUPPORT
}
sign
This required
function is defined using the
codassign function so that its adouble operation sequence
does not depend on the value of
x
.
namespace CppAD {
inline adouble sign(const adouble& x)
{ adouble s_plus, s_minus, half(.5);
// set s_plus to sign(x)/2, except for case x == 0, s_plus = -.5condassign(s_plus, +x, -half, +half);
// set s_minus to -sign(x)/2, except for case x == 0, s_minus = -.5condassign(s_minus, -x, -half, +half);
// set s to sign(x)return s_plus - s_minus;
}
}
abs
This required
function uses the adolc fabs
function:
hash_code
It appears that an adouble object can have fields
that are not initialized.
This results in a valgrind error when these fields are used by the
default
hashing function.
For this reason, the adouble class overrides the default definition.
namespace CppAD {
inline unsigned short hash_code(const adouble& x)
{ unsigned short code = 0;
double value = x.value();
if( value == 0.0 )
return code;
double log_x = std::log( fabs( value ) );
// assume log( std::numeric_limits<double>::max() ) is near 700
code = static_cast<unsigned short>(
(CPPAD_HASH_TABLE_SIZE / 700 + 1) * log_x
);
code = code % CPPAD_HASH_TABLE_SIZE;
return code;
}
}
Note that after the hash codes match, the
Identical
function will be used
to make sure two values are the same and one can replace the other.
A more sophisticated implementation of the Identical function
would detect which adouble values depend on the
adouble independent variables (and hence can change).
Input File: include/cppad/example/base_adolc.hpp