CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
base_complex.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_CORE_BASE_COMPLEX_HPP
2 # define CPPAD_CORE_BASE_COMPLEX_HPP
3 /* --------------------------------------------------------------------------
4 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
5 
6 CppAD is distributed under multiple licenses. This distribution is under
7 the terms of the
8  Eclipse Public License Version 1.0.
9 
10 A copy of this license is included in the COPYING file of this distribution.
11 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
12 -------------------------------------------------------------------------- */
13 # include <cppad/configure.hpp>
14 # include <limits>
15 # include <complex>
16 
17 // needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
19 
20 /*
21 $begin base_complex.hpp$$
22 $spell
23  azmul
24  expm1
25  atanh
26  acosh
27  asinh
28  endif
29  eps
30  abs_geq
31  Rel
32  Lt Le Eq Ge Gt
33  imag
34  gcc
35  isnan
36  cppad.hpp
37  sqrt
38  exp
39  cos
40  std
41  const
42  CppAD
43  Op
44  inline
45  enum
46  undef
47  acos
48  asin
49  atan
50  erf
51  Cond
52  namespace
53  bool
54 $$
55 
56 
57 $section Enable use of AD<Base> where Base is std::complex<double>$$
58 
59 $children%example/general/complex_poly.cpp
60 %$$
61 $head Example$$
62 The file $cref complex_poly.cpp$$ contains an example use of
63 $code std::complex<double>$$ type for a CppAD $icode Base$$ type.
64 It returns true if it succeeds and false otherwise.
65 
66 $head Include Order$$
67 This file is included before $code <cppad/cppad.hpp>$$
68 so it is necessary to define the error handler
69 in addition to including
70 $cref/base_require.hpp/base_require/Include Order/$$
71 $srccode%cpp% */
72 # include <limits>
73 # include <complex>
74 # include <cppad/base_require.hpp>
76 
77 /* %$$
78 
79 $head CondExpOp$$
80 The type $code std::complex<double>$$ does not supports the
81 $code <$$, $code <=$$, $code ==$$, $code >=$$, and $code >$$ operators; see
82 $cref/not ordered/base_cond_exp/CondExpTemplate/Not Ordered/$$.
83 Hence its $code CondExpOp$$ function is defined by
84 $srccode%cpp% */
85 namespace CppAD {
86  inline std::complex<double> CondExpOp(
87  enum CppAD::CompareOp cop ,
88  const std::complex<double> &left ,
89  const std::complex<double> &right ,
90  const std::complex<double> &trueCase ,
91  const std::complex<double> &falseCase )
93  true , __LINE__ , __FILE__ ,
94  "std::complex<float> CondExpOp(...)",
95  "Error: cannot use CondExp with a complex type"
96  );
97  return std::complex<double>(0);
98  }
99 }
100 /* %$$
101 
102 $head CondExpRel$$
103 The $cref/CPPAD_COND_EXP_REL/base_cond_exp/CondExpRel/$$ macro invocation
104 $srccode%cpp% */
105 namespace CppAD {
106  CPPAD_COND_EXP_REL( std::complex<double> )
107 }
108 /* %$$
109 used $code CondExpOp$$ above to
110 define $codei%CondExp%Rel%$$ for $code std::complex<double>$$ arguments
111 and $icode%Rel%$$ equal to
112 $code Lt$$, $code Le$$, $code Eq$$, $code Ge$$, and $code Gt$$.
113 
114 $head EqualOpSeq$$
115 Complex numbers do not carry operation sequence information.
116 Thus they are equal in this sense if and only if there values are equal.
117 $srccode%cpp% */
118 namespace CppAD {
119  inline bool EqualOpSeq(
120  const std::complex<double> &x ,
121  const std::complex<double> &y )
122  { return x == y;
123  }
124 }
125 /* %$$
126 
127 $head Identical$$
128 Complex numbers do not carry operation sequence information.
129 Thus they are all parameters so the identical functions just check values.
130 $srccode%cpp% */
131 namespace CppAD {
132  inline bool IdenticalPar(const std::complex<double> &x)
133  { return true; }
134  inline bool IdenticalZero(const std::complex<double> &x)
135  { return (x == std::complex<double>(0., 0.) ); }
136  inline bool IdenticalOne(const std::complex<double> &x)
137  { return (x == std::complex<double>(1., 0.) ); }
138  inline bool IdenticalEqualPar(
139  const std::complex<double> &x, const std::complex<double> &y)
140  { return (x == y); }
141 }
142 /* %$$
143 
144 $head Ordered$$
145 Complex types do not support comparison operators,
146 $srccode%cpp% */
147 # undef CPPAD_USER_MACRO
148 # define CPPAD_USER_MACRO(Fun) \
149 inline bool Fun(const std::complex<double>& x) \
150 { CppAD::ErrorHandler::Call( \
151  true , __LINE__ , __FILE__ , \
152  #Fun"(x)", \
153  "Error: cannot use " #Fun " with x complex<double> " \
154  ); \
155  return false; \
156 }
157 namespace CppAD {
162  inline bool abs_geq(
163  const std::complex<double>& x ,
164  const std::complex<double>& y )
165  { return std::abs(x) >= std::abs(y); }
166 }
167 /* %$$
168 
169 $head Integer$$
170 The implementation of this function must agree
171 with the CppAD user specifications for complex arguments to the
172 $cref/Integer/Integer/x/Complex Types/$$ function:
173 $srccode%cpp% */
174 namespace CppAD {
175  inline int Integer(const std::complex<double> &x)
176  { return static_cast<int>( x.real() ); }
177 }
178 /* %$$
179 
180 $head azmul$$
181 $srccode%cpp% */
182 namespace CppAD {
183  CPPAD_AZMUL( std::complex<double> )
184 }
185 /* %$$
186 
187 $head isnan$$
188 The gcc 4.1.1 complier defines the function
189 $codei%
190  int std::complex<double>::isnan( std::complex<double> %z% )
191 %$$
192 (which is not specified in the C++ 1998 standard ISO/IEC 14882).
193 This causes an ambiguity between the function above and the CppAD
194 $cref/isnan/nan/$$ template function.
195 We avoid this ambiguity by defining a non-template version of
196 this function in the CppAD namespace.
197 $srccode%cpp% */
198 namespace CppAD {
199  inline bool isnan(const std::complex<double>& z)
200  { return (z != z);
201  }
202 }
203 /* %$$
204 
205 $head Valid Unary Math$$
206 The following macro invocations define the standard unary
207 math functions that are valid with complex arguments and are
208 required to use $code AD< std::complex<double> >$$.
209 $srccode%cpp% */
210 namespace CppAD {
211  CPPAD_STANDARD_MATH_UNARY(std::complex<double>, cos)
212  CPPAD_STANDARD_MATH_UNARY(std::complex<double>, cosh)
213  CPPAD_STANDARD_MATH_UNARY(std::complex<double>, exp)
214  CPPAD_STANDARD_MATH_UNARY(std::complex<double>, log)
215  CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sin)
216  CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sinh)
217  CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sqrt)
218 }
219 /* %$$
220 
221 $head Invalid Unary Math$$
222 The following macro definition and invocations define the standard unary
223 math functions that are invalid with complex arguments and are
224 required to use $code AD< std::complex<double> >$$.
225 $srccode%cpp% */
226 # undef CPPAD_USER_MACRO
227 # define CPPAD_USER_MACRO(Fun) \
228 inline std::complex<double> Fun(const std::complex<double>& x) \
229 { CppAD::ErrorHandler::Call( \
230  true , __LINE__ , __FILE__ , \
231  #Fun"(x)", \
232  "Error: cannot use " #Fun " with x complex<double> " \
233  ); \
234  return std::complex<double>(0); \
235 }
236 namespace CppAD {
243 # if CPPAD_USE_CPLUSPLUS_2011
250 # endif
251 }
252 /* %$$
253 
254 $head pow $$
255 The following defines a $code CppAD::pow$$ function that
256 is required to use $code AD< std::complex<double> >$$:
257 $srccode%cpp% */
258 namespace CppAD {
259  inline std::complex<double> pow(
260  const std::complex<double> &x ,
261  const std::complex<double> &y )
262  { return std::pow(x, y); }
263 }
264 /* %$$
265 
266 $head numeric_limits$$
267 The following defines the CppAD $cref numeric_limits$$
268 for the type $code std::complex<double>$$:
269 $srccode%cpp% */
270 namespace CppAD {
271  CPPAD_NUMERIC_LIMITS(double, std::complex<double>)
272 }
273 /* %$$
274 
275 $head to_string$$
276 The following defines the function CppAD $cref to_string$$
277 for the type $code std::complex<double>$$:
278 $srccode%cpp% */
279 namespace CppAD {
280  CPPAD_TO_STRING(std::complex<double>)
281 }
282 /* %$$
283 $end
284 */
285 # undef CPPAD_USER_MACRO_ONE
286 # define CPPAD_USER_MACRO_ONE(Fun) \
287 inline bool Fun(const std::complex<float>& x) \
288 { CppAD::ErrorHandler::Call( \
289  true , __LINE__ , __FILE__ , \
290  #Fun"(x)", \
291  "Error: cannot use " #Fun " with x complex<float> " \
292  ); \
293  return false; \
294 }
295 # undef CPPAD_USER_MACRO_TWO
296 # define CPPAD_USER_MACRO_TWO(Fun) \
297 inline std::complex<float> Fun(const std::complex<float>& x) \
298 { CppAD::ErrorHandler::Call( \
299  true , __LINE__ , __FILE__ , \
300  #Fun"(x)", \
301  "Error: cannot use " #Fun " with x complex<float> " \
302  ); \
303  return std::complex<float>(0); \
304 }
305 namespace CppAD {
306  // CondExpOp ------------------------------------------------------
307  inline std::complex<float> CondExpOp(
308  enum CppAD::CompareOp cop ,
309  const std::complex<float> &left ,
310  const std::complex<float> &right ,
311  const std::complex<float> &trueCase ,
312  const std::complex<float> &falseCase )
314  true , __LINE__ , __FILE__ ,
315  "std::complex<float> CondExpOp(...)",
316  "Error: cannot use CondExp with a complex type"
317  );
318  return std::complex<float>(0);
319  }
320  // CondExpRel --------------------------------------------------------
321  CPPAD_COND_EXP_REL( std::complex<float> )
322  // EqualOpSeq -----------------------------------------------------
323  inline bool EqualOpSeq(
324  const std::complex<float> &x ,
325  const std::complex<float> &y )
326  { return x == y;
327  }
328  // Identical ------------------------------------------------------
329  inline bool IdenticalPar(const std::complex<float> &x)
330  { return true; }
331  inline bool IdenticalZero(const std::complex<float> &x)
332  { return (x == std::complex<float>(0., 0.) ); }
333  inline bool IdenticalOne(const std::complex<float> &x)
334  { return (x == std::complex<float>(1., 0.) ); }
335  inline bool IdenticalEqualPar(
336  const std::complex<float> &x, const std::complex<float> &y)
337  { return (x == y); }
338  // Ordered --------------------------------------------------------
343  inline bool abs_geq(
344  const std::complex<float>& x ,
345  const std::complex<float>& y )
346  { return std::abs(x) >= std::abs(y); }
347  // Integer ------------------------------------------------------
348  inline int Integer(const std::complex<float> &x)
349  { return static_cast<int>( x.real() ); }
350  // isnan -------------------------------------------------------------
351  inline bool isnan(const std::complex<float>& z)
352  { return (z != z);
353  }
354  // Valid standard math functions --------------------------------
355  CPPAD_STANDARD_MATH_UNARY(std::complex<float>, cos)
356  CPPAD_STANDARD_MATH_UNARY(std::complex<float>, cosh)
357  CPPAD_STANDARD_MATH_UNARY(std::complex<float>, exp)
358  CPPAD_STANDARD_MATH_UNARY(std::complex<float>, log)
359  CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sin)
360  CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sinh)
361  CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sqrt)
362  // Invalid standrd math functions -------------------------------
368  // The pow function
369  inline std::complex<float> pow(
370  const std::complex<float> &x ,
371  const std::complex<float> &y )
372  { return std::pow(x, y); }
373  // numeric_limits -------------------------------------------------
374  CPPAD_NUMERIC_LIMITS(float, std::complex<float>)
375  // to_string -------------------------------------------------
376  CPPAD_TO_STRING(std::complex<float>)
377 }
378 
379 // undefine macros only used by this file
380 # undef CPPAD_USER_MACRO
381 # undef CPPAD_USER_MACRO_ONE
382 # undef CPPAD_USER_MACRO_TWO
383 
384 # endif
std::complex< double > erf(const std::complex< double > &x)
AD< Base > cosh(const AD< Base > &x)
AD< Base > log(const AD< Base > &x)
#define CPPAD_USER_MACRO(Fun)
std::complex< double > atan(const std::complex< double > &x)
AD< Base > sinh(const AD< Base > &x)
Define the CppAD error checking macros (all of which begin with CPPAD_ASSERT_)
bool GreaterThanOrZero(const std::complex< double > &x)
#define CPPAD_AZMUL(Base)
AD< Base > abs(const AD< Base > &x)
Definition: abs.hpp:105
std::complex< double > acos(const std::complex< double > &x)
bool IdenticalPar(const std::complex< double > &x)
bool EqualOpSeq(const std::complex< double > &x, const std::complex< double > &y)
bool IdenticalZero(const std::complex< double > &x)
AD< Base > exp(const AD< Base > &x)
std::complex< double > asinh(const std::complex< double > &x)
bool abs_geq(const std::complex< double > &x, const std::complex< double > &y)
bool isnan(const Scalar &s)
Definition: nan.hpp:169
static void Call(bool known, int line, const char *file, const char *exp, const char *msg)
std::complex< double > acosh(const std::complex< double > &x)
Type pow(const Type &x, const int &n)
Definition: pow_int.hpp:116
bool LessThanOrZero(const std::complex< double > &x)
std::complex< double > expm1(const std::complex< double > &x)
AD< Base > sqrt(const AD< Base > &x)
#define CPPAD_USER_MACRO_ONE(Fun)
#define CPPAD_NUMERIC_LIMITS(Other, Base)
Definition: base_limits.hpp:49
std::complex< double > atanh(const std::complex< double > &x)
AD< Base > sin(const AD< Base > &x)
#define CPPAD_TO_STRING(Base)
std::complex< double > sign(const std::complex< double > &x)
bool IdenticalEqualPar(const std::complex< double > &x, const std::complex< double > &y)
AD< Base > cos(const AD< Base > &x)
#define CPPAD_USER_MACRO_TWO(Fun)
bool IdenticalOne(const std::complex< double > &x)
std::complex< double > asin(const std::complex< double > &x)
int Integer(const std::complex< double > &x)
bool LessThanZero(const std::complex< double > &x)
#define CPPAD_COND_EXP_REL(Type)
The macro defines the operations.
File used to define the CppAD multi-threading allocator class.
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)
std::complex< double > fabs(const std::complex< double > &x)
bool GreaterThanZero(const std::complex< double > &x)
#define CPPAD_STANDARD_MATH_UNARY(Type, Fun)
This macro defines the function.
std::complex< double > log1p(const std::complex< double > &x)