CppAD: A C++ Algorithmic Differentiation Package 20110419
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-08 Bradley M. Bell
00006 
00007 CppAD is distributed under multiple licenses. This distribution is under
00008 the terms of the
00009                     Common 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 /*
00015 $begin base_complex.hpp$$
00016 $spell
00017         cppad.hpp
00018         sqrt
00019         exp
00020         cos
00021         std
00022         const
00023         CppAD
00024         Op
00025         inline
00026         enum
00027         undef
00028         acos
00029         asin
00030         atan
00031         erf
00032         Cond
00033         namespace
00034         bool
00035 $$
00036 
00037 $index complex, double Base$$
00038 $index Base, double complex$$
00039 $index double, complex Base$$
00040 
00041 $section Enable use of AD<Base> where Base is std::complex<double>$$
00042 
00043 $children%
00044         example/complex_poly.cpp%
00045         example/not_complex_ad.cpp
00046 %$$
00047 
00048 $head Example$$
00049 The file $cref/ComplexPoly.cpp/$$ contains an example use of
00050 $code std::complex<double>$$ type for a CppAD $italic Base$$ type.
00051 It returns true if it succeeds and false otherwise.
00052 
00053 $head See Also$$
00054 The file $cref/not_complex_ad.cpp/$$ contains an example using
00055 complex arithmetic where the function is not complex differentiable.
00056 
00057 $head Include File$$
00058 This file is included before $code <cppad/cppad.hpp>$$
00059 so it is necessary to define the error handler
00060 in addition to including
00061 $cref/declare.hpp/base_require/declare.hpp/$$
00062 $codep */
00063 # include <complex>
00064 # include <cppad/declare.hpp>
00065 # include <cppad/error_handler.hpp>
00066 /* $$
00067 
00068 $head CondExpOp$$
00069 The conditional expressions $cref/CondExp/$$ 
00070 requires ordered comparisons (e.g., $code <$$)
00071 and the C++ standard complex types do not allow for ordered comparisons.
00072 Thus, we make it an error to use the conditional comparisons 
00073 with complex types:
00074 $codep */
00075 namespace CppAD {
00076         inline std::complex<double> CondExpOp(
00077                 enum CppAD::CompareOp      cop        ,
00078                 const std::complex<double> &left      ,
00079                 const std::complex<double> &right     ,
00080                 const std::complex<double> &trueCase  ,
00081                 const std::complex<double> &falseCase )
00082         {       CppAD::ErrorHandler::Call(
00083                         true     , __LINE__ , __FILE__ ,
00084                         "std::complex<float> CondExpOp(...)",
00085                         "Error: cannot use CondExp with a complex type"
00086                 );
00087                 return std::complex<double>(0);
00088         }
00089 }
00090 /* $$
00091 
00092 $head EqualOpSeq$$
00093 Complex numbers do not carry operation sequence information. 
00094 Thus they are equal in this sense if and only if there values are equal.  
00095 $codep */
00096 namespace CppAD {
00097         inline bool EqualOpSeq(
00098                 const std::complex<double> &x , 
00099                 const std::complex<double> &y )
00100         {       return x == y; 
00101         }
00102 }
00103 /* $$
00104 
00105 $head Identical$$
00106 Complex numbers do not carry operation sequence information. 
00107 Thus they are all parameters so the identical functions just check values.
00108 $codep */
00109 namespace CppAD {
00110         inline bool IdenticalPar(const std::complex<double> &x)
00111         {       return true; }
00112         inline bool IdenticalZero(const std::complex<double> &x)
00113         {       return (x == std::complex<double>(0., 0.) ); }
00114         inline bool IdenticalOne(const std::complex<double> &x)
00115         {       return (x == std::complex<double>(1., 0.) ); }
00116         inline bool IdenticalEqualPar(
00117                 const std::complex<double> &x, const std::complex<double> &y)
00118         {       return (x == y); }
00119 }
00120 /* $$
00121 
00122 $head Ordered$$
00123 
00124 $codep */
00125 namespace CppAD {
00126         inline bool GreaterThanZero(const std::complex<double> &x)
00127         {       CppAD::ErrorHandler::Call(
00128                         true     , __LINE__ , __FILE__ ,
00129                         "GreaterThanZero(x)",
00130                         "Error: cannot use GreaterThanZero with complex"
00131                 );
00132                 return false;
00133         }
00134         inline bool GreaterThanOrZero(const std::complex<double> &x)
00135         {       CppAD::ErrorHandler::Call(
00136                         true     , __LINE__ , __FILE__ ,
00137                         "GreaterThanZero(x)",
00138                         "Error: cannot use GreaterThanZero with complex"
00139                 );
00140                 return false;
00141         }
00142         inline bool LessThanZero(const std::complex<double> &x)
00143         {       CppAD::ErrorHandler::Call(
00144                         true     , __LINE__ , __FILE__ ,
00145                         "LessThanZero(x)",
00146                         "Error: cannot use LessThanZero with complex"
00147                 );
00148                 return false;
00149         }
00150         inline bool LessThanOrZero(const std::complex<double> &x)
00151         {       CppAD::ErrorHandler::Call(
00152                         true     , __LINE__ , __FILE__ ,
00153                         "LessThanZero(x)",
00154                         "Error: cannot use LessThanZero with complex"
00155                 );
00156                 return false;
00157         }
00158 }
00159 /* $$
00160 
00161 $head Integer$$
00162 The implementation of this function must agree
00163 with the CppAD user specifications for complex arguments to the
00164 $cref/Integer/Integer/x/Complex Types/$$ function:
00165 $codep */
00166 namespace CppAD {
00167         inline int Integer(const std::complex<double> &x)
00168         {       return static_cast<int>( x.real() ); }
00169 }
00170 /* $$
00171 
00172 $head Standard Functions$$
00173 
00174 $subhead Valid Complex Functions$$
00175 The following standard math functions,
00176 that are required by $cref/base_require/$$,
00177 are defined by 
00178 $code std::complex$$:
00179 $code cos$$,
00180 $code cosh$$,
00181 $code exp$$,
00182 $code log$$,
00183 $code pow$$,
00184 $code sin$$,
00185 $code sinh$$,
00186 $code sqrt$$.
00187 $codep */
00188 # define CPPAD_USER_MACRO(function)                                   \
00189 inline std::complex<double> function(const std::complex<double> &x)   \
00190 {       return std::function(x); }
00191 
00192 namespace CppAD {
00193         CPPAD_USER_MACRO(cos)
00194         CPPAD_USER_MACRO(cosh)
00195         CPPAD_USER_MACRO(exp)
00196         CPPAD_USER_MACRO(log)
00197         inline std::complex<double> pow(
00198                 const std::complex<double> &x , 
00199                 const std::complex<double> &y )
00200         {       return std::pow(x, y); }
00201         CPPAD_USER_MACRO(sin)
00202         CPPAD_USER_MACRO(sinh)
00203         CPPAD_USER_MACRO(sqrt)
00204 }
00205 # undef CPPAD_USER_MACRO
00206 /* $$
00207 
00208 $subhead Invalid Complex Functions$$
00209 The other standard math functions,
00210 (and $code abs$$) required by $cref/base_require/$$
00211 are not defined for complex types
00212 (see $cref/abs/abs/Complex Types/$$).
00213 Hence we make it an error to use them.
00214 (Note that the standard math functions are not defined in the CppAD namespace.)
00215 $codep */
00216 # define CPPAD_USER_MACRO(function)                                          \
00217 inline std::complex<double> function(const std::complex<double> &x)          \
00218 {      CppAD::ErrorHandler::Call(                                            \
00219                true     , __LINE__ , __FILE__ ,                              \
00220                "std::complex<double>",                                       \
00221                "Error: cannot use " #function " with complex<double> "       \
00222        );                                                                    \
00223        return std::complex<double>(0);                                       \
00224 }
00225 
00226 namespace CppAD {
00227         CPPAD_USER_MACRO(acos)
00228         CPPAD_USER_MACRO(asin)
00229         CPPAD_USER_MACRO(atan)
00230 }
00231 # undef CPPAD_USER_MACRO
00232 /* $$
00233 $end
00234 */
00235 # define CPPAD_VALID_COMPLEX_CASE(function)                           \
00236 inline std::complex<float> function(const std::complex<float> &x)     \
00237 {       return std::function(x); }
00238 
00239 # define CPPAD_INVALID_COMPLEX_CASE(function)                                 \
00240 inline std::complex<float> function(const std::complex<float> &x)             \
00241 {       CppAD::ErrorHandler::Call(                                            \
00242                 true     , __LINE__ , __FILE__ ,                              \
00243                 "std::complex<float>",                                        \
00244                 "Error: cannot use " #function " with a complex type"         \
00245         );                                                                    \
00246         return std::complex<float>(0);                                        \
00247 }
00248 namespace CppAD {
00249         // CondExpOp ------------------------------------------------------
00250         inline std::complex<float> CondExpOp(
00251                 enum CppAD::CompareOp      cop       ,
00252                 const std::complex<float> &left      ,
00253                 const std::complex<float> &right     ,
00254                 const std::complex<float> &trueCase  ,
00255                 const std::complex<float> &falseCase )
00256         {       CppAD::ErrorHandler::Call(
00257                         true     , __LINE__ , __FILE__ ,
00258                         "std::complex<float> CondExpOp(...)",
00259                         "Error: cannot use CondExp with a complex type"
00260                 );
00261                 return std::complex<float>(0);
00262         }
00263         // EqualOpSeq -----------------------------------------------------
00264         inline bool EqualOpSeq(
00265                 const std::complex<float> &x , 
00266                 const std::complex<float> &y )
00267         {       return x == y; 
00268         }
00269         // Identical ------------------------------------------------------
00270         inline bool IdenticalPar(const std::complex<float> &x)
00271         {       return true; }
00272         inline bool IdenticalZero(const std::complex<float> &x)
00273         {       return (x == std::complex<float>(0., 0.) ); }
00274         inline bool IdenticalOne(const std::complex<float> &x)
00275         {       return (x == std::complex<float>(1., 0.) ); }
00276         inline bool IdenticalEqualPar(
00277                 const std::complex<float> &x, const std::complex<float> &y)
00278         {       return (x == y); }
00279         // Ordered --------------------------------------------------------
00280         inline bool GreaterThanZero(const std::complex<float> &x)
00281         {       CppAD::ErrorHandler::Call(
00282                         true     , __LINE__ , __FILE__ ,
00283                         "GreaterThanZero(x)",
00284                         "Error: cannot use GreaterThanZero with complex"
00285                 );
00286                 return false;
00287         }
00288         inline bool GreaterThanOrZero(const std::complex<float> &x)
00289         {       CppAD::ErrorHandler::Call(
00290                         true     , __LINE__ , __FILE__ ,
00291                         "GreaterThanOrZero(x)",
00292                         "Error: cannot use GreaterThanOrZero with complex"
00293                 );
00294                 return false;
00295         }
00296         inline bool LessThanZero(const std::complex<float> &x)
00297         {       CppAD::ErrorHandler::Call(
00298                         true     , __LINE__ , __FILE__ ,
00299                         "LessThanZero(x)",
00300                         "Error: cannot use LessThanZero with complex"
00301                 );
00302                 return false;
00303         }
00304         inline bool LessThanOrZero(const std::complex<float> &x)
00305         {       CppAD::ErrorHandler::Call(
00306                         true     , __LINE__ , __FILE__ ,
00307                         "LessThanOrZero(x)",
00308                         "Error: cannot use LessThanOrZero with complex"
00309                 );
00310                 return false;
00311         }
00312         // Integer ------------------------------------------------------
00313         inline int Integer(const std::complex<float> &x)
00314         {       return static_cast<int>( x.real() ); }
00315         // Valid standard math functions --------------------------------
00316         CPPAD_VALID_COMPLEX_CASE(cos)
00317         CPPAD_VALID_COMPLEX_CASE(cosh)
00318         CPPAD_VALID_COMPLEX_CASE(exp)
00319         CPPAD_VALID_COMPLEX_CASE(log)
00320         inline std::complex<float> pow(
00321                 const std::complex<float> &x , 
00322                 const std::complex<float> &y )
00323         {       return std::pow(x, y); }
00324         CPPAD_VALID_COMPLEX_CASE(sin)
00325         CPPAD_VALID_COMPLEX_CASE(sinh)
00326         CPPAD_VALID_COMPLEX_CASE(sqrt)
00327         // Invalid standrd math functions -------------------------------
00328         CPPAD_INVALID_COMPLEX_CASE(abs)
00329         CPPAD_INVALID_COMPLEX_CASE(acos)
00330         CPPAD_INVALID_COMPLEX_CASE(asin)
00331         CPPAD_INVALID_COMPLEX_CASE(atan)
00332         CPPAD_INVALID_COMPLEX_CASE(erf)
00333 }
00334 # undef CPPAD_INVALID_COMPLEX_CASE
00335 
00336 # endif