Prev Next

@(@\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}} }@)@
Enable 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. It returns true if it succeeds and false otherwise.

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 supports the <, <=, ==, >=, and > operators; see not ordered . Hence its CondExpOp function is defined by
namespace CppAD {
     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);
     }
}

CondExpRel
The CPPAD_COND_EXP_REL macro invocation

namespace CppAD {
     CPPAD_COND_EXP_REL( std::complex<double> )
}
used CondExpOp above to define CondExpRel 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 IdenticalPar(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 IdenticalEqualPar(
          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)
# if CPPAD_USE_CPLUSPLUS_2011
     CPPAD_USER_MACRO(erf)
     CPPAD_USER_MACRO(asinh)
     CPPAD_USER_MACRO(acosh)
     CPPAD_USER_MACRO(atanh)
     CPPAD_USER_MACRO(expm1)
     CPPAD_USER_MACRO(log1p)
# endif
}

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

Input File: cppad/core/base_complex.hpp