lines 12-305 of file: include/cppad/core/base_complex.hpp {xrst_begin base_complex.hpp} {xrst_spell complier ge isnan } Enable use of AD where Base is std::complex ######################################################### {xrst_toc_hidden example/general/complex_poly.cpp } Example ******* The file :ref:`complex_poly.cpp-name` contains an example use of ``std::complex`` type for a CppAD *Base* type. Include Order ************* This file is included before ```` so it is necessary to define the error handler in addition to including :ref:`base_require.hpp` {xrst_spell_off} {xrst_code cpp} */ # include # include # include # include /* {xrst_code} {xrst_spell_on} CondExpOp ********* The type ``std::complex`` does not support the ``<`` , ``<=`` , ``>=`` , and ``>`` operators; see :ref:`base_cond_exp@CondExpTemplate@Not Ordered` . Hence these operators and ``CondExpOp`` function are defined by {xrst_spell_off} {xrst_code cpp} */ # define CPPAD_TEMP(op) \ inline bool operator op( \ const std::complex& left , \ const std::complex& right ) \ { CppAD::ErrorHandler::Call( \ true , __LINE__ , __FILE__ , \ "std::complex " #op " std::complex" , \ "Error: std::complex is not an ordered type" \ ); \ return false; \ } namespace CppAD { CPPAD_TEMP(<) CPPAD_TEMP(<=) CPPAD_TEMP(>=) CPPAD_TEMP(>) inline std::complex CondExpOp( enum CppAD::CompareOp cop , const std::complex &left , const std::complex &right , const std::complex &trueCase , const std::complex &falseCase ) { CppAD::ErrorHandler::Call( true , __LINE__ , __FILE__ , "std::complex CondExpOp(...)", "Error: cannot use CondExp with a complex type" ); return std::complex(0); } } # undef CPPAD_TEMP /* {xrst_code} {xrst_spell_on} CondExpRel ********** The :ref:`CPPAD_COND_EXP_REL` macro invocation {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { CPPAD_COND_EXP_REL( std::complex ) } /* {xrst_code} {xrst_spell_on} used ``CondExpOp`` above to define ``CondExp`` *Rel* for ``std::complex`` 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. {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { inline bool EqualOpSeq( const std::complex &x , const std::complex &y ) { return x == y; } } /* {xrst_code} {xrst_spell_on} Identical ********* Complex numbers do not carry operation sequence information. Thus they are all parameters so the identical functions just check values. {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { inline bool IdenticalCon(const std::complex &x) { return true; } inline bool IdenticalZero(const std::complex &x) { return (x == std::complex(0., 0.) ); } inline bool IdenticalOne(const std::complex &x) { return (x == std::complex(1., 0.) ); } inline bool IdenticalEqualCon( const std::complex &x, const std::complex &y) { return (x == y); } } /* {xrst_code} {xrst_spell_on} Ordered ******* Complex types do not support comparison operators, {xrst_spell_off} {xrst_code cpp} */ # undef CPPAD_USER_MACRO # define CPPAD_USER_MACRO(Fun) \ inline bool Fun(const std::complex& x) \ { CppAD::ErrorHandler::Call( \ true , __LINE__ , __FILE__ , \ #Fun"(x)", \ "Error: cannot use " #Fun " with x complex " \ ); \ 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& x , const std::complex& y ) { return std::abs(x) >= std::abs(y); } } /* {xrst_code} {xrst_spell_on} Integer ******* The implementation of this function must agree with the CppAD user specifications for complex arguments to the :ref:`Integer` function: {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { inline int Integer(const std::complex &x) { return static_cast( x.real() ); } } /* {xrst_code} {xrst_spell_on} azmul ***** {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { CPPAD_AZMUL( std::complex ) } /* {xrst_code} {xrst_spell_on} isnan ***** The gcc 4.1.1 complier defines the function ``int std::complex::isnan`` ( ``std::complex`` *z* ) (which is not specified in the C++ 1998 standard ISO/IEC 14882). This causes an ambiguity between the function above and the CppAD :ref:`isnan` template function. We avoid this ambiguity by defining a non-template version of this function in the CppAD namespace. {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { inline bool isnan(const std::complex& z) { return (z != z); } } /* {xrst_code} {xrst_spell_on} 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 >`` . {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { CPPAD_STANDARD_MATH_UNARY(std::complex, cos) CPPAD_STANDARD_MATH_UNARY(std::complex, cosh) CPPAD_STANDARD_MATH_UNARY(std::complex, exp) CPPAD_STANDARD_MATH_UNARY(std::complex, log) CPPAD_STANDARD_MATH_UNARY(std::complex, sin) CPPAD_STANDARD_MATH_UNARY(std::complex, sinh) CPPAD_STANDARD_MATH_UNARY(std::complex, sqrt) } /* {xrst_code} {xrst_spell_on} 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 >`` . {xrst_spell_off} {xrst_code cpp} */ # undef CPPAD_USER_MACRO # define CPPAD_USER_MACRO(Fun) \ inline std::complex Fun(const std::complex& x) \ { CppAD::ErrorHandler::Call( \ true , __LINE__ , __FILE__ , \ #Fun"(x)", \ "Error: cannot use " #Fun " with x complex " \ ); \ return std::complex(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) } /* {xrst_code} {xrst_spell_on} pow *** The following defines a ``CppAD::pow`` function that is required to use ``AD< std::complex >`` : {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { inline std::complex pow( const std::complex &x , const std::complex &y ) { return std::pow(x, y); } } /* {xrst_code} {xrst_spell_on} numeric_limits ************** The following defines the CppAD :ref:`numeric_limits-name` for the type ``std::complex`` : {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { CPPAD_NUMERIC_LIMITS(double, std::complex) } /* {xrst_code} {xrst_spell_on} to_string ********* The following defines the function CppAD :ref:`to_string-name` for the type ``std::complex`` : {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { CPPAD_TO_STRING(std::complex) } /* {xrst_code} {xrst_spell_on} {xrst_end base_complex.hpp}