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}