CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
base_adolc.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_EXAMPLE_BASE_ADOLC_HPP
2 # define CPPAD_EXAMPLE_BASE_ADOLC_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 /*
14 $begin base_adolc.hpp$$
15 $spell
16  stringstream
17  struct
18  string
19  setprecision
20  str
21  valgrind
22  azmul
23  expm1
24  atanh
25  acosh
26  asinh
27  erf
28  ifndef
29  define
30  endif
31  Rel
32  codassign
33  eps
34  std
35  abs_geq
36  fabs
37  cppad.hpp
38  undef
39  Lt
40  Le
41  Eq
42  Ge
43  Gt
44  namespace
45  cassert
46  condassign
47  hpp
48  bool
49  const
50  Adolc
51  adouble
52  CondExpOp
53  inline
54  enum
55  CppAD
56  pow
57  acos
58  asin
59  atan
60  cos
61  cosh
62  exp
63  sqrt
64 $$
65 
66 
67 $section Enable use of AD<Base> where Base is Adolc's adouble Type$$
68 
69 $head Syntax$$
70 $codei%# include <cppad/example/base_adolc.hpp>
71 %$$
72 $children%
73  example/general/mul_level_adolc.cpp
74 %$$
75 
76 $head Example$$
77 The file $cref mul_level_adolc.cpp$$ contains an example use of
78 Adolc's $code adouble$$ type for a CppAD $icode Base$$ type.
79 It returns true if it succeeds and false otherwise.
80 The file $cref mul_level_adolc_ode.cpp$$ contains a more realistic
81 (and complex) example.
82 
83 $head Include Files$$
84 This file $code base_adolc.hpp$$ requires $code adouble$$ to be defined.
85 In addition, it is included before $code <cppad/cppad.hpp>$$,
86 but it needs to include parts of CppAD that are used by this file.
87 This is done with the following include commands:
88 $srccode%cpp% */
89 # include <adolc/adolc.h>
90 # include <cppad/base_require.hpp>
91 /* %$$
92 
93 $head CondExpOp$$
94 The type $code adouble$$ supports a conditional assignment function
95 with the syntax
96 $codei%
97  condassign(%a%, %b%, %c%, %d%)
98 %$$
99 which evaluates to
100 $codei%
101  %a% = (%b% > 0) ? %c% : %d%;
102 %$$
103 This enables one to include conditionals in the recording of
104 $code adouble$$ operations and later evaluation for different
105 values of the independent variables
106 (in the same spirit as the CppAD $cref CondExp$$ function).
107 $srccode%cpp% */
108 namespace CppAD {
109  inline adouble CondExpOp(
110  enum CppAD::CompareOp cop ,
111  const adouble &left ,
112  const adouble &right ,
113  const adouble &trueCase ,
114  const adouble &falseCase )
115  { adouble result;
116  switch( cop )
117  {
118  case CompareLt: // left < right
119  condassign(result, right - left, trueCase, falseCase);
120  break;
121 
122  case CompareLe: // left <= right
123  condassign(result, left - right, falseCase, trueCase);
124  break;
125 
126  case CompareEq: // left == right
127  condassign(result, left - right, falseCase, trueCase);
128  condassign(result, right - left, falseCase, result);
129  break;
130 
131  case CompareGe: // left >= right
132  condassign(result, right - left, falseCase, trueCase);
133  break;
134 
135  case CompareGt: // left > right
136  condassign(result, left - right, trueCase, falseCase);
137  break;
138  default:
140  true , __LINE__ , __FILE__ ,
141  "CppAD::CondExp",
142  "Error: for unknown reason."
143  );
144  result = trueCase;
145  }
146  return result;
147  }
148 }
149 /* %$$
150 
151 $head CondExpRel$$
152 The $cref/CPPAD_COND_EXP_REL/base_cond_exp/CondExpRel/$$ macro invocation
153 $srccode%cpp% */
154 namespace CppAD {
155  CPPAD_COND_EXP_REL(adouble)
156 }
157 /* %$$
158 
159 $head EqualOpSeq$$
160 The Adolc user interface does not specify a way to determine if
161 two $code adouble$$ variables correspond to the same operations sequence.
162 Make $code EqualOpSeq$$ an error if it gets used:
163 $srccode%cpp% */
164 namespace CppAD {
165  inline bool EqualOpSeq(const adouble &x, const adouble &y)
167  true , __LINE__ , __FILE__ ,
168  "CppAD::EqualOpSeq(x, y)",
169  "Error: adouble does not support EqualOpSeq."
170  );
171  return false;
172  }
173 }
174 /* %$$
175 
176 $head Identical$$
177 The Adolc user interface does not specify a way to determine if an
178 $code adouble$$ depends on the independent variables.
179 To be safe (but slow) return $code false$$ in all the cases below.
180 $srccode%cpp% */
181 namespace CppAD {
182  inline bool IdenticalPar(const adouble &x)
183  { return false; }
184  inline bool IdenticalZero(const adouble &x)
185  { return false; }
186  inline bool IdenticalOne(const adouble &x)
187  { return false; }
188  inline bool IdenticalEqualPar(const adouble &x, const adouble &y)
189  { return false; }
190 }
191 /* %$$
192 
193 $head Integer$$
194 $srccode%cpp% */
195  inline int Integer(const adouble &x)
196  { return static_cast<int>( x.getValue() ); }
197 /* %$$
198 
199 $head azmul$$
200 $srccode%cpp% */
201 namespace CppAD {
202  CPPAD_AZMUL( adouble )
203 }
204 /* %$$
205 
206 $head Ordered$$
207 $srccode%cpp% */
208 namespace CppAD {
209  inline bool GreaterThanZero(const adouble &x)
210  { return (x > 0); }
211  inline bool GreaterThanOrZero(const adouble &x)
212  { return (x >= 0); }
213  inline bool LessThanZero(const adouble &x)
214  { return (x < 0); }
215  inline bool LessThanOrZero(const adouble &x)
216  { return (x <= 0); }
217  inline bool abs_geq(const adouble& x, const adouble& y)
218  { return fabs(x) >= fabs(y); }
219 }
220 /* %$$
221 
222 $head Unary Standard Math$$
223 The following $cref/required/base_require/$$ functions
224 are defined by the Adolc package for the $code adouble$$ base case:
225 $pre
226 $$
227 $code acos$$,
228 $code asin$$,
229 $code atan$$,
230 $code cos$$,
231 $code cosh$$,
232 $code exp$$,
233 $code fabs$$,
234 $code log$$,
235 $code sin$$,
236 $code sinh$$,
237 $code sqrt$$,
238 $code tan$$.
239 
240 $head erf, asinh, acosh, atanh, expm1, log1p$$
241 If the
242 $cref/erf, asinh, acosh, atanh, expm1, log1p
243  /base_std_math
244  /erf, asinh, acosh, atanh, expm1, log1p
245 /$$,
246 functions are supported by the compiler,
247 they must also be supported by a $icode Base$$ type;
248 The adolc package does not support these functions so make
249 their use an error:
250 $srccode%cpp% */
251 namespace CppAD {
252 # define CPPAD_BASE_ADOLC_NO_SUPPORT(fun) \
253  inline adouble fun(const adouble& x) \
254  { CPPAD_ASSERT_KNOWN( \
255  false, \
256  #fun ": adolc does not support this function" \
257  ); \
258  return 0.0; \
259  }
260 # if CPPAD_USE_CPLUSPLUS_2011
267 # endif
268 # undef CPPAD_BASE_ADOLC_NO_SUPPORT
269 }
270 /* %$$
271 
272 $head sign$$
273 This $cref/required/base_require/$$ function is defined using the
274 $code codassign$$ function so that its $code adouble$$ operation sequence
275 does not depend on the value of $icode x$$.
276 $srccode%cpp% */
277 namespace CppAD {
278  inline adouble sign(const adouble& x)
279  { adouble s_plus, s_minus, half(.5);
280  // set s_plus to sign(x)/2, except for case x == 0, s_plus = -.5
281  condassign(s_plus, +x, -half, +half);
282  // set s_minus to -sign(x)/2, except for case x == 0, s_minus = -.5
283  condassign(s_minus, -x, -half, +half);
284  // set s to sign(x)
285  return s_plus - s_minus;
286  }
287 }
288 /* %$$
289 
290 $head abs$$
291 This $cref/required/base_require/$$ function uses the adolc $code fabs$$
292 function:
293 $srccode%cpp% */
294 namespace CppAD {
295  inline adouble abs(const adouble& x)
296  { return fabs(x); }
297 }
298 /* %$$
299 
300 $head pow$$
301 This $cref/required/base_require/$$ function
302 is defined by the Adolc package for the $code adouble$$ base case.
303 
304 $head numeric_limits$$
305 The following defines the CppAD $cref numeric_limits$$
306 for the type $code adouble$$:
307 $srccode%cpp% */
308 namespace CppAD {
309  CPPAD_NUMERIC_LIMITS(double, adouble)
310 }
311 /* %$$
312 
313 $head to_string$$
314 The following defines the CppAD $cref to_string$$ function
315 for the type $code adouble$$:
316 $srccode%cpp% */
317 namespace CppAD {
318  template <> struct to_string_struct<adouble>
319  { std::string operator()(const adouble& x)
320  { std::stringstream os;
321  int n_digits = 1 + std::numeric_limits<double>::digits10;
322  os << std::setprecision(n_digits);
323  os << x.value();
324  return os.str();
325  }
326  };
327 }
328 /* %$$
329 
330 $head hash_code$$
331 It appears that an $code adouble$$ object can have fields
332 that are not initialized.
333 This results in a $code valgrind$$ error when these fields are used by the
334 $cref/default/base_hash/Default/$$ hashing function.
335 For this reason, the $code adouble$$ class overrides the default definition.
336 $srccode|cpp| */
337 namespace CppAD {
338  inline unsigned short hash_code(const adouble& x)
339  { unsigned short code = 0;
340  double value = x.value();
341  if( value == 0.0 )
342  return code;
343  double log_x = std::log( fabs( value ) );
344  // assume log( std::numeric_limits<double>::max() ) is near 700
345  code = static_cast<unsigned short>(
346  (CPPAD_HASH_TABLE_SIZE / 700 + 1) * log_x
347  );
348  code = code % CPPAD_HASH_TABLE_SIZE;
349  return code;
350  }
351 }
352 /* |$$
353 Note that after the hash codes match, the
354 $cref/Identical/base_adolc.hpp/Identical/$$ function will be used
355 to make sure two values are the same and one can replace the other.
356 A more sophisticated implementation of the $code Identical$$ function
357 would detect which $code adouble$$ values depend on the
358 $code adouble$$ independent variables (and hence can change).
359 
360 
361 $end
362 */
363 # endif
364 
std::complex< double > erf(const std::complex< double > &x)
#define CPPAD_BASE_ADOLC_NO_SUPPORT(fun)
Definition: base_adolc.hpp:252
AD< Base > log(const AD< Base > &x)
bool GreaterThanOrZero(const std::complex< double > &x)
#define CPPAD_AZMUL(Base)
AD< Base > abs(const AD< Base > &x)
Definition: abs.hpp:105
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)
std::complex< double > asinh(const std::complex< double > &x)
bool abs_geq(const std::complex< double > &x, const std::complex< double > &y)
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)
std::string operator()(const adouble &x)
Definition: base_adolc.hpp:319
bool LessThanOrZero(const std::complex< double > &x)
std::complex< double > expm1(const std::complex< double > &x)
#define CPPAD_NUMERIC_LIMITS(Other, Base)
Definition: base_limits.hpp:49
std::complex< double > atanh(const std::complex< double > &x)
std::complex< double > sign(const std::complex< double > &x)
bool IdenticalEqualPar(const std::complex< double > &x, const std::complex< double > &y)
int Integer(const adouble &x)
Definition: base_adolc.hpp:195
bool IdenticalOne(const std::complex< double > &x)
bool LessThanZero(const std::complex< double > &x)
#define CPPAD_COND_EXP_REL(Type)
The macro defines the operations.
unsigned short hash_code(const Value &value)
General purpose hash code for an arbitrary value.
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)
#define CPPAD_HASH_TABLE_SIZE
the codes retruned by hash_code are between zero and CPPAD_HASH_TABLE_SIZE minus one.
Definition: base_hash.hpp:82
bool GreaterThanZero(const std::complex< double > &x)
std::complex< double > log1p(const std::complex< double > &x)