CppAD: A C++ Algorithmic Differentiation Package  20130918
base_complex.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_BASE_COMPLEX_INCLUDED
00003 # define CPPAD_BASE_COMPLEX_INCLUDED
00004 /* --------------------------------------------------------------------------
00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 Bradley M. Bell
00006 
00007 CppAD is distributed under multiple licenses. This distribution is under
00008 the terms of the
00009                     Eclipse Public License Version 1.0.
00010 
00011 A copy of this license is included in the COPYING file of this distribution.
00012 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00013 -------------------------------------------------------------------------- */
00014 # include <limits>
00015 # include <complex>
00016 
00017 // needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
00018 # include <cppad/thread_alloc.hpp>
00019 
00020 /*
00021 $begin base_complex.hpp$$
00022 $spell
00023      eps
00024      abs_geq
00025      Rel
00026      Lt Le Eq Ge Gt
00027      imag
00028      gcc
00029      isnan
00030      cppad.hpp
00031      sqrt
00032      exp
00033      cos
00034      std
00035      const
00036      CppAD
00037      Op
00038      inline
00039      enum
00040      undef
00041      acos
00042      asin
00043      atan
00044      erf
00045      Cond
00046      namespace
00047      bool
00048 $$
00049 
00050 $index complex, double Base$$
00051 $index Base, double complex$$
00052 $index double, complex Base$$
00053 
00054 $section Enable use of AD<Base> where Base is std::complex<double>$$
00055 
00056 $children%
00057      example/complex_poly.cpp%
00058      example/not_complex_ad.cpp
00059 %$$
00060 
00061 $head Example$$
00062 The file $cref complex_poly.cpp$$ contains an example use of
00063 $code std::complex<double>$$ type for a CppAD $icode Base$$ type.
00064 It returns true if it succeeds and false otherwise.
00065 
00066 $head See Also$$
00067 The file $cref not_complex_ad.cpp$$ contains an example using
00068 complex arithmetic where the function is not complex differentiable.
00069 
00070 $head Include Order$$
00071 This file is included before $code <cppad/cppad.hpp>$$
00072 so it is necessary to define the error handler
00073 in addition to including
00074 $cref/base_require.hpp/base_require/Include Order/$$
00075 $codep */
00076 # include <limits>
00077 # include <complex>
00078 # include <cppad/base_require.hpp>
00079 # include <cppad/local/cppad_assert.hpp>
00080 
00081 /* $$
00082 
00083 $head CondExpOp$$
00084 The type $code std::complex<double>$$ does not supports the
00085 $code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators; see
00086 $cref/not ordered/base_cond_exp/CondExpTemplate/Not Ordered/$$.
00087 Hence its $code CondExpOp$$ function is defined by
00088 $codep */
00089 namespace CppAD {
00090      inline std::complex<double> CondExpOp(
00091           enum CppAD::CompareOp      cop        ,
00092           const std::complex<double> &left      ,
00093           const std::complex<double> &right     ,
00094           const std::complex<double> &trueCase  ,
00095           const std::complex<double> &falseCase )
00096      {    CppAD::ErrorHandler::Call(
00097                true     , __LINE__ , __FILE__ ,
00098                "std::complex<float> CondExpOp(...)",
00099                "Error: cannot use CondExp with a complex type"
00100           );
00101           return std::complex<double>(0);
00102      }
00103 }
00104 /* $$
00105 
00106 $head CondExpRel$$
00107 The $cref/CPPAD_COND_EXP_REL/base_cond_exp/CondExpRel/$$ macro invocation
00108 $codep */
00109 namespace CppAD {
00110      CPPAD_COND_EXP_REL( std::complex<double> )
00111 }
00112 /* $$
00113 used $code CondExpOp$$ above to
00114 define $codei%CondExp%Rel%$$ for $code std::complex<double>$$ arguments
00115 and $icode%Rel%$$ equal to
00116 $code Lt$$, $code Le$$, $code Eq$$, $code Ge$$, and $code Gt$$.
00117 
00118 $head EqualOpSeq$$
00119 Complex numbers do not carry operation sequence information. 
00120 Thus they are equal in this sense if and only if there values are equal.  
00121 $codep */
00122 namespace CppAD {
00123      inline bool EqualOpSeq(
00124           const std::complex<double> &x , 
00125           const std::complex<double> &y )
00126      {    return x == y; 
00127      }
00128 }
00129 /* $$
00130 
00131 $head Identical$$
00132 Complex numbers do not carry operation sequence information. 
00133 Thus they are all parameters so the identical functions just check values.
00134 $codep */
00135 namespace CppAD {
00136      inline bool IdenticalPar(const std::complex<double> &x)
00137      {    return true; }
00138      inline bool IdenticalZero(const std::complex<double> &x)
00139      {    return (x == std::complex<double>(0., 0.) ); }
00140      inline bool IdenticalOne(const std::complex<double> &x)
00141      {    return (x == std::complex<double>(1., 0.) ); }
00142      inline bool IdenticalEqualPar(
00143           const std::complex<double> &x, const std::complex<double> &y)
00144      {    return (x == y); }
00145 }
00146 /* $$
00147 
00148 $head Ordered$$
00149 Complex types do not support comparison operators, 
00150 $codep */
00151 # undef  CPPAD_USER_MACRO
00152 # define CPPAD_USER_MACRO(Fun)                                     \
00153 inline bool Fun(const std::complex<double>& x)                     \
00154 {      CppAD::ErrorHandler::Call(                                  \
00155                true     , __LINE__ , __FILE__ ,                    \
00156                #Fun"(x)",                                          \
00157                "Error: cannot use " #Fun " with x complex<double> " \
00158        );                                                          \
00159        return false;                                               \
00160 }
00161 namespace CppAD {
00162      CPPAD_USER_MACRO(LessThanZero)
00163      CPPAD_USER_MACRO(LessThanOrZero)
00164      CPPAD_USER_MACRO(GreaterThanOrZero)
00165      CPPAD_USER_MACRO(GreaterThanZero)
00166      inline bool abs_geq(
00167           const std::complex<double>& x , 
00168           const std::complex<double>& y )
00169      {    return std::abs(x) >= std::abs(y); }
00170 }
00171 /* $$
00172 
00173 $head Integer$$
00174 The implementation of this function must agree
00175 with the CppAD user specifications for complex arguments to the
00176 $cref/Integer/Integer/x/Complex Types/$$ function:
00177 $codep */
00178 namespace CppAD {
00179      inline int Integer(const std::complex<double> &x)
00180      {    return static_cast<int>( x.real() ); }
00181 }
00182 /* $$
00183 
00184 $head isnan$$
00185 The gcc 4.1.1 complier defines the function
00186 $codei%
00187      int std::complex<double>::isnan( std::complex<double> %z% )
00188 %$$
00189 (which is not specified in the C++ 1998 standard ISO/IEC 14882).
00190 This causes an ambiguity between the function above and the CppAD
00191 $cref/isnan/nan/$$ template function.
00192 We avoid this ambiguity by defining a non-template version of
00193 this function in the CppAD namespace.
00194 $codep */
00195 namespace CppAD {
00196      inline bool isnan(const std::complex<double>& z)
00197      {    return (z != z);
00198      }
00199 }
00200 /* $$
00201 
00202 $head Valid Unary Math$$
00203 The following macro invocations define the standard unary 
00204 math functions that are valid with complex arguments and are
00205 required to use $code AD< std::complex<double> >$$.
00206 $codep */
00207 namespace CppAD {
00208      CPPAD_STANDARD_MATH_UNARY(std::complex<double>, cos)
00209      CPPAD_STANDARD_MATH_UNARY(std::complex<double>, cosh)
00210      CPPAD_STANDARD_MATH_UNARY(std::complex<double>, exp)
00211      CPPAD_STANDARD_MATH_UNARY(std::complex<double>, log)
00212      CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sin)
00213      CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sinh)
00214      CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sqrt)
00215 }
00216 /* $$
00217 
00218 $head Invalid Unary Math$$
00219 The following macro definition and invocations define the standard unary 
00220 math functions that are invalid with complex arguments and are
00221 required to use $code AD< std::complex<double> >$$.
00222 $codep */
00223 # undef  CPPAD_USER_MACRO
00224 # define CPPAD_USER_MACRO(Fun)                                     \
00225 inline std::complex<double> Fun(const std::complex<double>& x)     \
00226 {      CppAD::ErrorHandler::Call(                                  \
00227                true     , __LINE__ , __FILE__ ,                    \
00228                #Fun"(x)",                                          \
00229                "Error: cannot use " #Fun " with x complex<double> " \
00230        );                                                          \
00231        return std::complex<double>(0);                             \
00232 }
00233 namespace CppAD {
00234      CPPAD_USER_MACRO(abs)
00235      CPPAD_USER_MACRO(acos)
00236      CPPAD_USER_MACRO(asin)
00237      CPPAD_USER_MACRO(atan)
00238      CPPAD_USER_MACRO(sign)
00239 }
00240 /* $$
00241 
00242 $head pow $$
00243 The following defines a $code CppAD::pow$$ function that
00244 is required to use $code AD< std::complex<double> >$$:
00245 $codep */
00246 namespace CppAD {
00247      inline std::complex<double> pow(
00248           const std::complex<double> &x , 
00249           const std::complex<double> &y )
00250      {    return std::pow(x, y); }
00251 }
00252 /*$$
00253 
00254 $head limits$$
00255 The following defines the numeric limits functions
00256 $code epsilon$$, $code min$$, and $code max$$ for the type
00257 $code std::complex<double>$$.
00258 It also defines the deprecated $code epsilon$$ function:
00259 $codep */
00260 namespace CppAD {
00261      template <>
00262      class numeric_limits< std::complex<double> > {
00263      public:
00264           // machine epsilon
00265           static  std::complex<double> epsilon(void)
00266           {    double eps = std::numeric_limits<double>::epsilon();
00267                return std::complex<double>(eps, 0.0);
00268           }
00269           // minimum positive normalized value
00270           static  std::complex<double> min(void)
00271           {    double min = std::numeric_limits<double>::min();
00272                return std::complex<double>(min, 0.0);
00273           }
00274           // maximum finite value
00275           static  std::complex<double> max(void)
00276           {    double max = std::numeric_limits<double>::max();
00277                return std::complex<double>(max, 0.0);
00278           }
00279      };
00280      // deprecated machine epsilon
00281      template <> 
00282      inline std::complex<double> epsilon< std::complex<double> > (void)
00283      {    return numeric_limits< std::complex<double> >::epsilon(); }
00284 }
00285 /* $$
00286 $end
00287 */
00288 # undef  CPPAD_USER_MACRO_ONE
00289 # define CPPAD_USER_MACRO_ONE(Fun)                                 \
00290 inline bool Fun(const std::complex<float>& x)                      \
00291 {      CppAD::ErrorHandler::Call(                                  \
00292                true     , __LINE__ , __FILE__ ,                    \
00293                #Fun"(x)",                                          \
00294                "Error: cannot use " #Fun " with x complex<float> " \
00295        );                                                          \
00296        return false;                                               \
00297 }
00298 # undef  CPPAD_USER_MACRO_TWO
00299 # define CPPAD_USER_MACRO_TWO(Fun)                                 \
00300 inline std::complex<float> Fun(const std::complex<float>& x)       \
00301 {      CppAD::ErrorHandler::Call(                                  \
00302                true     , __LINE__ , __FILE__ ,                    \
00303                #Fun"(x)",                                          \
00304                "Error: cannot use " #Fun " with x complex<float> " \
00305        );                                                          \
00306        return std::complex<float>(0);                              \
00307 }
00308 namespace CppAD {
00309      // CondExpOp ------------------------------------------------------
00310      inline std::complex<float> CondExpOp(
00311           enum CppAD::CompareOp      cop       ,
00312           const std::complex<float> &left      ,
00313           const std::complex<float> &right     ,
00314           const std::complex<float> &trueCase  ,
00315           const std::complex<float> &falseCase )
00316      {    CppAD::ErrorHandler::Call(
00317                true     , __LINE__ , __FILE__ ,
00318                "std::complex<float> CondExpOp(...)",
00319                "Error: cannot use CondExp with a complex type"
00320           );
00321           return std::complex<float>(0);
00322      }
00323      // CondExpRel --------------------------------------------------------
00324      CPPAD_COND_EXP_REL( std::complex<float> )
00325      // EqualOpSeq -----------------------------------------------------
00326      inline bool EqualOpSeq(
00327           const std::complex<float> &x , 
00328           const std::complex<float> &y )
00329      {    return x == y; 
00330      }
00331      // Identical ------------------------------------------------------
00332      inline bool IdenticalPar(const std::complex<float> &x)
00333      {    return true; }
00334      inline bool IdenticalZero(const std::complex<float> &x)
00335      {    return (x == std::complex<float>(0., 0.) ); }
00336      inline bool IdenticalOne(const std::complex<float> &x)
00337      {    return (x == std::complex<float>(1., 0.) ); }
00338      inline bool IdenticalEqualPar(
00339           const std::complex<float> &x, const std::complex<float> &y)
00340      {    return (x == y); }
00341      // Ordered --------------------------------------------------------
00342      CPPAD_USER_MACRO_ONE(LessThanZero)
00343      CPPAD_USER_MACRO_ONE(LessThanOrZero)
00344      CPPAD_USER_MACRO_ONE(GreaterThanOrZero)
00345      CPPAD_USER_MACRO_ONE(GreaterThanZero)
00346      inline bool abs_geq(
00347           const std::complex<float>& x , 
00348           const std::complex<float>& y )
00349      {    return std::abs(x) >= std::abs(y); }
00350      // Integer ------------------------------------------------------
00351      inline int Integer(const std::complex<float> &x)
00352      {    return static_cast<int>( x.real() ); }
00353      // isnan -------------------------------------------------------------
00354      inline bool isnan(const std::complex<float>& z)
00355      {    return (z != z);
00356      }
00357      // Valid standard math functions --------------------------------
00358      CPPAD_STANDARD_MATH_UNARY(std::complex<float>, cos)
00359      CPPAD_STANDARD_MATH_UNARY(std::complex<float>, cosh)
00360      CPPAD_STANDARD_MATH_UNARY(std::complex<float>, exp)
00361      CPPAD_STANDARD_MATH_UNARY(std::complex<float>, log)
00362      CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sin)
00363      CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sinh)
00364      CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sqrt)
00365      // Invalid standrd math functions -------------------------------
00366      CPPAD_USER_MACRO_TWO(abs)
00367      CPPAD_USER_MACRO_TWO(acos)
00368      CPPAD_USER_MACRO_TWO(asin)
00369      CPPAD_USER_MACRO_TWO(atan)
00370      CPPAD_USER_MACRO_TWO(sign)
00371      // The pow function
00372      inline std::complex<float> pow(
00373           const std::complex<float> &x , 
00374           const std::complex<float> &y )
00375      {    return std::pow(x, y); }
00376      // numeric_limits -------------------------------------------------
00377      template <>
00378      class numeric_limits< std::complex<float> > {
00379      public:
00380           /// machine epsilon
00381           static  std::complex<float> epsilon(void)
00382           {    float eps = std::numeric_limits<float>::epsilon();
00383                return std::complex<float>(eps, 0.0);
00384           }
00385           /// minimum positive normalized value
00386           static  std::complex<float> min(void)
00387           {    float min = std::numeric_limits<float>::min();
00388                return std::complex<float>(min, 0.0);
00389           }
00390           /// maximum finite value
00391           static  std::complex<float> max(void)
00392           {    float max = std::numeric_limits<float>::max();
00393                return std::complex<float>(max, 0.0);
00394           }
00395      };
00396      template <> 
00397      inline std::complex<float> epsilon< std::complex<float> >(void)
00398      {    return numeric_limits< std::complex<float> >::epsilon(); }
00399 }
00400 
00401 // undefine macros only used by this file
00402 # undef CPPAD_USER_MACRO
00403 # undef CPPAD_USER_MACRO_ONE
00404 # undef CPPAD_USER_MACRO_TWO
00405 
00406 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines