\(\newcommand{\W}[1]{ \; #1 \; }\) \(\newcommand{\R}[1]{ {\rm #1} }\) \(\newcommand{\B}[1]{ {\bf #1} }\) \(\newcommand{\D}[2]{ \frac{\partial #1}{\partial #2} }\) \(\newcommand{\DD}[3]{ \frac{\partial^2 #1}{\partial #2 \partial #3} }\) \(\newcommand{\Dpow}[2]{ \frac{\partial^{#1}}{\partial {#2}^{#1}} }\) \(\newcommand{\dpow}[2]{ \frac{ {\rm d}^{#1}}{{\rm d}\, {#2}^{#1}} }\)
base_complex.hpp¶
View page sourceEnable use of AD<Base> where Base is std::complex<double>¶
Example¶
The file complex_poly.cpp contains an example use of
std::complex<double>
type for a CppAD Base type.
Include Order¶
This file is included before <cppad/cppad.hpp>
so it is necessary to define the error handler
in addition to including
base_require.hpp
# include <limits>
# include <complex>
# include <cppad/base_require.hpp>
# include <cppad/core/cppad_assert.hpp>
CondExpOp¶
The type std::complex<double>
does not support the
<
, <=
, >=
, and >
operators; see
Not Ordered .
Hence these operators and CondExpOp
function are defined by
# define CPPAD_TEMP(op) \
inline bool operator op( \
const std::complex<double>& left , \
const std::complex<double>& right ) \
{ CppAD::ErrorHandler::Call( \
true , __LINE__ , __FILE__ , \
"std::complex<double> " #op " std::complex<double>" , \
"Error: std::complex is not an ordered type" \
); \
return false; \
}
namespace CppAD {
CPPAD_TEMP(<)
CPPAD_TEMP(<=)
CPPAD_TEMP(>=)
CPPAD_TEMP(>)
inline std::complex<double> CondExpOp(
enum CppAD::CompareOp cop ,
const std::complex<double> &left ,
const std::complex<double> &right ,
const std::complex<double> &trueCase ,
const std::complex<double> &falseCase )
{ CppAD::ErrorHandler::Call(
true , __LINE__ , __FILE__ ,
"std::complex<float> CondExpOp(...)",
"Error: cannot use CondExp with a complex type"
);
return std::complex<double>(0);
}
}
# undef CPPAD_TEMP
CondExpRel¶
The CPPAD_COND_EXP_REL macro invocation
namespace CppAD {
CPPAD_COND_EXP_REL( std::complex<double> )
}
used CondExpOp
above to
define CondExp
Rel for std::complex<double>
arguments
and Rel equal to
Lt
, Le
, Eq
, Ge
, and Gt
.
EqualOpSeq¶
Complex numbers do not carry operation sequence information. Thus they are equal in this sense if and only if there values are equal.
namespace CppAD {
inline bool EqualOpSeq(
const std::complex<double> &x ,
const std::complex<double> &y )
{ return x == y;
}
}
Identical¶
Complex numbers do not carry operation sequence information. Thus they are all parameters so the identical functions just check values.
namespace CppAD {
inline bool IdenticalCon(const std::complex<double> &x)
{ return true; }
inline bool IdenticalZero(const std::complex<double> &x)
{ return (x == std::complex<double>(0., 0.) ); }
inline bool IdenticalOne(const std::complex<double> &x)
{ return (x == std::complex<double>(1., 0.) ); }
inline bool IdenticalEqualCon(
const std::complex<double> &x, const std::complex<double> &y)
{ return (x == y); }
}
Ordered¶
Complex types do not support comparison operators,
# undef CPPAD_USER_MACRO
# define CPPAD_USER_MACRO(Fun) \
inline bool Fun(const std::complex<double>& x) \
{ CppAD::ErrorHandler::Call( \
true , __LINE__ , __FILE__ , \
#Fun"(x)", \
"Error: cannot use " #Fun " with x complex<double> " \
); \
return false; \
}
namespace CppAD {
CPPAD_USER_MACRO(LessThanZero)
CPPAD_USER_MACRO(LessThanOrZero)
CPPAD_USER_MACRO(GreaterThanOrZero)
CPPAD_USER_MACRO(GreaterThanZero)
inline bool abs_geq(
const std::complex<double>& x ,
const std::complex<double>& y )
{ return std::abs(x) >= std::abs(y); }
}
Integer¶
The implementation of this function must agree with the CppAD user specifications for complex arguments to the Integer function:
namespace CppAD {
inline int Integer(const std::complex<double> &x)
{ return static_cast<int>( x.real() ); }
}
azmul¶
namespace CppAD {
CPPAD_AZMUL( std::complex<double> )
}
isnan¶
The gcc 4.1.1 complier defines the function
int std::complex<double>::isnan
(std::complex<double>
z )
(which is not specified in the C++ 1998 standard ISO/IEC 14882). This causes an ambiguity between the function above and the CppAD isnan template function. We avoid this ambiguity by defining a non-template version of this function in the CppAD namespace.
namespace CppAD {
inline bool isnan(const std::complex<double>& z)
{ return (z != z);
}
}
Valid Unary Math¶
The following macro invocations define the standard unary
math functions that are valid with complex arguments and are
required to use AD< std::complex<double> >
.
namespace CppAD {
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, cos)
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, cosh)
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, exp)
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, log)
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sin)
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sinh)
CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sqrt)
}
Invalid Unary Math¶
The following macro definition and invocations define the standard unary
math functions that are invalid with complex arguments and are
required to use AD< std::complex<double> >
.
# undef CPPAD_USER_MACRO
# define CPPAD_USER_MACRO(Fun) \
inline std::complex<double> Fun(const std::complex<double>& x) \
{ CppAD::ErrorHandler::Call( \
true , __LINE__ , __FILE__ , \
#Fun"(x)", \
"Error: cannot use " #Fun " with x complex<double> " \
); \
return std::complex<double>(0); \
}
namespace CppAD {
CPPAD_USER_MACRO(abs)
CPPAD_USER_MACRO(fabs)
CPPAD_USER_MACRO(acos)
CPPAD_USER_MACRO(asin)
CPPAD_USER_MACRO(atan)
CPPAD_USER_MACRO(sign)
CPPAD_USER_MACRO(asinh)
CPPAD_USER_MACRO(acosh)
CPPAD_USER_MACRO(atanh)
CPPAD_USER_MACRO(erf)
CPPAD_USER_MACRO(erfc)
CPPAD_USER_MACRO(expm1)
CPPAD_USER_MACRO(log1p)
}
pow¶
The following defines a CppAD::pow
function that
is required to use AD< std::complex<double> >
:
namespace CppAD {
inline std::complex<double> pow(
const std::complex<double> &x ,
const std::complex<double> &y )
{ return std::pow(x, y); }
}
numeric_limits¶
The following defines the CppAD numeric_limits
for the type std::complex<double>
:
namespace CppAD {
CPPAD_NUMERIC_LIMITS(double, std::complex<double>)
}
to_string¶
The following defines the function CppAD to_string
for the type std::complex<double>
:
namespace CppAD {
CPPAD_TO_STRING(std::complex<double>)
}