1 /* ---------------------------------------------------------------------------
2  ADOL-C -- Automatic Differentiation by Overloading in C++
3 
4  Revision: $Id: adouble.h 775 2020-01-25 14:09:12Z mbanovic $
5  Contents: adouble.h contains the basis for the class of adouble
6            included here are all the possible functions defined on
7            the adouble class.  Notice that, as opposed to ealier versions,
8            both the class adub and the class adouble are derived from a base
9            class (badouble).  See below for further explanation.
10 
11  Copyright (c) Andrea Walther, Andreas Griewank, Andreas Kowarz,
12                Hristo Mitev, Sebastian Schlenkrich, Jean Utke, Olaf Vogel,
13                Benjamin Letschert Kshitij Kulshreshtha
14 
15  This file is part of ADOL-C. This software is provided as open source.
16  Any use, reproduction, or distribution of the software constitutes
17  recipient's acceptance of the terms of the accompanying license file.
18 
19 ---------------------------------------------------------------------------*/
20 
21 #if !defined(ADOLC_ADOUBLE_H)
22 #define ADOLC_ADOUBLE_H 1
23 
24 /****************************************************************************/
25 /*                                                         THIS FILE IS C++ */
26 #ifdef __cplusplus
27 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
28 #define COMPILER_HAS_CXX11
29 #else
30 #error "please use -std=c++11 compiler flag with a C++11 compliant compiler"
31 #endif
32 
33 #include <cstdio>
34 #include <cstdlib>
35 #include <iostream>
36 #include <cmath>
37 #include <stdexcept>
38 
39 #if !defined(SWIGPRE)
40 using std::cout;
41 using std::cin;
42 using std::cerr;
43 using std::ostream;
44 using std::istream;
45 using std::logic_error;
46 #endif
47 
48 #include <adolc/internal/common.h>
49 
50 /* NOTICE: There are automatic includes at the end of this file! */
51 
52 /****************************************************************************/
53 /*                                             FORWARD DECLARATIONS (TAPES) */
54 
55 /*--------------------------------------------------------------------------*/
56 class adouble;
57 class adub;
58 class badouble;
59 class pdouble;
60 
61 /*--------------------------------------------------------------------------*/
62 void ADOLC_DLL_EXPORT condassign( double &res, const double &cond,
63                                   const double &arg1, const double &arg2 );
64 void ADOLC_DLL_EXPORT condassign( double &res, const double &cond,
65                                   const double &arg );
66 
67 void ADOLC_DLL_EXPORT condeqassign( double &res, const double &cond,
68                                     const double &arg1, const double &arg2 );
69 void ADOLC_DLL_EXPORT condeqassign( double &res, const double &cond,
70                                     const double &arg );
71 
72 /****************************************************************************/
73 /*                                                           CLASS BADOUBLE */
74 
75 /**
76    The class badouble contains the basic definitions for
77    the arithmetic operations, comparisons, etc.
78    This is a basic class from which the adub and adouble are
79    derived.  Notice that the constructors/destructors for
80    the class badouble are of the trivial variety.  This is the
81    main difference among badoubles, adubs, and adoubles.
82 */
83 class ADOLC_DLL_EXPORT badouble {
84     friend ADOLC_DLL_EXPORT class pdouble;
85 protected:
86     locint location;
badouble(void)87     badouble( void ) {};
88     // Copy constructor:
89     // must be public when using gcc >= 3.4 and gcc <= 4.3.0
90     // (see GCC 3.4 Release Series - Changes, New Features, and Fixes)
91     // so we make it protected for newer compilers again.
badouble(const badouble & a)92     badouble( const badouble& a ) {};           /* ctor */
badouble(locint lo)93     explicit badouble( locint lo ) {
94         location = lo;
95         isInit = true;
96     };
97 
98     bool isInit;  // marker if the badouble is properly initialized
99 
100 public:
101     /*--------------------------------------------------------------------------*/
102     inline locint loc( void ) const;                         /* Helpful stuff */
103 
104     /*------------------------------------------------------------------------*/
105     badouble& operator >>= ( double& );                        /* Assignments */
106     badouble& operator <<= ( double );
107     void declareIndependent ();
108     void declareDependent ();
109     badouble& operator = ( double );
110     badouble& operator = ( const badouble& );
111     badouble& operator = ( const adub& );
112     double getValue() const;
value()113     inline double value() const {
114         return getValue();
115     }
116     explicit operator double();
117     explicit operator double const&() const;
118     explicit operator double&&();
119     void setValue ( const double );
120     /* badouble& operator = ( const adouble& );
121        !!! olvo 991210: was the same as badouble-assignment */
122 
123     /*--------------------------------------------------------------------------*/
124     friend ADOLC_DLL_EXPORT std::ostream& operator << ( std::ostream&, const badouble& );  /* IO friends */
125     friend ADOLC_DLL_EXPORT std::istream& operator >> ( std::istream&, const badouble& );
126 
127     /*------------------------------------------------------------------------*/
128     badouble& operator += ( double );               /* Operation + Assignment */
129     badouble& operator += ( const badouble& );
130     badouble& operator -= ( double y );
131     badouble& operator -= ( const badouble& );
132     badouble& operator *= ( double );
133     badouble& operator *= ( const badouble& );
134     badouble& operator /= ( double );
135     badouble& operator /= ( const badouble& );
136     /* olvo 991122 n2l: new special op_codes */
137     badouble& operator += ( const adub& );
138     badouble& operator -= ( const adub& );
139 
140     /*--------------------------------------------------------------------------*/
141     badouble& operator = (const pdouble&);
142     badouble& operator += (const pdouble&);
143     badouble& operator -= (const pdouble&);
144     badouble& operator *= (const pdouble&);
145     inline badouble& operator /= (const pdouble&);
146     /*--------------------------------------------------------------------------*/
147     /* Comparison (friends) */
148 #if !defined(ADOLC_ADVANCED_BRANCHING)
149     inline friend bool operator != ( const badouble&, const badouble& );
150     inline friend bool operator == ( const badouble&, const badouble& );
151     inline friend bool operator <= ( const badouble&, const badouble& );
152     inline friend bool operator >= ( const badouble&, const badouble& );
153     inline friend bool operator >  ( const badouble&, const badouble& );
154     inline friend bool operator <  ( const badouble&, const badouble& );
155 #endif
156     inline friend bool operator != ( double, const badouble& );
157     friend ADOLC_DLL_EXPORT bool operator != ( const badouble&, double );
158     inline friend bool operator == ( double, const badouble& );
159     friend ADOLC_DLL_EXPORT bool operator == ( const badouble&, double );
160     inline friend bool operator <= ( double, const badouble& );
161     friend ADOLC_DLL_EXPORT bool operator <= ( const badouble&, double );
162     inline friend bool operator >= ( double, const badouble& );
163     friend ADOLC_DLL_EXPORT bool operator >= ( const badouble&, double );
164     inline friend bool operator >  ( double, const badouble& );
165     friend ADOLC_DLL_EXPORT bool operator >  ( const badouble&, double );
166     inline friend bool operator <  ( double, const badouble& );
167     friend ADOLC_DLL_EXPORT bool operator <  ( const badouble&, double );
168 
169 
170     /*--------------------------------------------------------------------------*/
171     /* Functions friends with both badouble and adub */
172 #define _IN_CLASS_ 1
173 #define _IN_BADOUBLE_ 1
174 #include <adolc/internal/adubfunc.h>
175 #undef _IN_BADOUBLE_
176 #undef _IN_CLASS_
177 
178     /*--------------------------------------------------------------------------*/
179     /* special operators (friends) */
180     friend ADOLC_DLL_EXPORT adouble atan2 ( const badouble&, const badouble& );
181     /* uses condassign internally */
182     friend ADOLC_DLL_EXPORT adouble pow   ( const badouble&, const badouble& );
183     friend ADOLC_DLL_EXPORT adouble pow   ( double, const badouble& );
184     /* User defined version of logarithm to test extend_quad macro */
185     friend ADOLC_DLL_EXPORT adouble myquad( const badouble& );
186 
187     /*--------------------------------------------------------------------------*/
188     /* Conditionals */
189     friend ADOLC_DLL_EXPORT void condassign( adouble &res, const badouble &cond,
190             const badouble &arg1, const badouble &arg2 );
191     friend ADOLC_DLL_EXPORT void condassign( adouble &res, const badouble &cond,
192             const badouble &arg );
193     friend ADOLC_DLL_EXPORT void condeqassign( adouble &res, const badouble &cond,
194             const badouble &arg1, const badouble &arg2 );
195     friend ADOLC_DLL_EXPORT void condeqassign( adouble &res, const badouble &cond,
196             const badouble &arg );
197 
198 #define _IN_CLASS_ 1
199 #define _IN_BADOUBLE_ 1
200 #include <adolc/internal/paramfunc.h>
201 #undef _IN_BADOUBLE_
202 #undef _IN_CLASS_
203 
204 };
205 
206 
207 
208 /****************************************************************************/
209 /*                                                               CLASS ADUB */
210 
211 /*
212    The class Adub
213    ---- Basically used as a temporary result.  The address for an
214         adub is usually generated within an operation.  That address
215         is "freed" when the adub goes out of scope (at destruction time).
216    ---- operates just like a badouble, but it has a destructor defined for it.
217 */
218 #if !defined(SWIGPRE)
219 ADOLC_DLL_EXPORT adub* adubp_from_adub(const adub&);
220 /* s = adolc_vec_dot(x,y,size); <=> s = <x,y>_2 */
221 ADOLC_DLL_EXPORT adub adolc_vec_dot(const adouble*const, const adouble*const, locint);
222 #endif
223 
224 class ADOLC_DLL_EXPORT adub:public badouble {
225     friend ADOLC_DLL_EXPORT class adouble;
226     friend ADOLC_DLL_EXPORT class advector;
227     friend ADOLC_DLL_EXPORT class adubref;
228     friend ADOLC_DLL_EXPORT class pdouble;
229 
230 #if !defined(SWIGPRE)
231     friend adub* adubp_from_adub(const adub&);
232 #endif
233 private:
adub(adub const &)234     adub( adub const &) {
235 	isInit = false;
236         fprintf(DIAG_OUT,"ADOL-C error: illegal copy construction of adub"
237 		" variable\n          ... adub objects must never be copied\n");
238         throw logic_error("illegal constructor call, errorcode=-2");
239     }
adub(void)240     adub( void ) {
241 	isInit = false;
242         fprintf(DIAG_OUT,"ADOL-C error: illegal default construction of adub"
243                 " variable\n");
244         throw logic_error("illegal constructor call, errorcode=-2");
245     }
adub(double)246     explicit adub( double ) {
247 	isInit = false;
248         fprintf(DIAG_OUT,"ADOL-C error: illegal  construction of adub variable"
249                 " from double\n");
250         throw logic_error("illegal constructor call, errorcode=-2");
251     }
252 protected:
253    /* this is the only logically legal constructor, which can be called by
254     * friend classes and functions
255     */
adub(locint lo)256    adub( locint lo ) : badouble(lo) {}
257 
258 public:
259 #if !defined(SWIGPRE)
260     explicit operator adub*() const { return adubp_from_adub(*this); }
261 #endif
262     /*--------------------------------------------------------------------------*/
263 #if !defined(SWIGPRE)
264     /* s = adolc_vec_dot(x,y,size); <=> s = <x,y>_2 */
265     friend adub adolc_vec_dot(const adouble*const, const adouble*const, locint);
266 #endif
267     /* Functions friends with both badouble and adub */
268 #define _IN_CLASS_ 1
269 #define _IN_ADUB_ 1
270 #include <adolc/internal/adubfunc.h>
271 #undef _IN_ADUB_
272 #undef _IN_CLASS_
273 
274     /*--------------------------------------------------------------------------*/
275     /* Parameter dependent functions (friends) */
276 #define _IN_CLASS_ 1
277 #define _IN_ADUB_ 1
278 #include <adolc/internal/paramfunc.h>
279 #undef _IN_ADUB_
280 #undef _IN_CLASS_
281 
282     ~adub();
283 };
284 
285 BEGIN_C_DECLS
286 ADOLC_DLL_EXPORT void ensureContiguousLocations(size_t n);
287 END_C_DECLS
288 
289 /****************************************************************************/
290 /*                                                            CLASS ADOUBLE */
291 /*
292   The class adouble.
293   ---Derived from badouble.  Contains the standard constructors/destructors.
294   ---At construction, it is given a new address, and at destruction, that
295      address is freed.
296 */
297 class ADOLC_DLL_EXPORT adouble:public badouble {
298     friend ADOLC_DLL_EXPORT class advector;
299     friend ADOLC_DLL_EXPORT class pdouble;
300 protected:
301     void initInternal(void); // Init for late initialization
302 public:
303     adouble( const adub& );
304     adouble( const adouble& );
305     adouble( void );
306     adouble( double );
307     /* adub prevents postfix operators to occur on the left
308        side of an assignment which would not work  */
309 #if !defined(SWIGPRE)
310     adub operator++( int );
311     adub operator--( int );
312 #else
313     adub* operator++( int );
314     adub* operator--( int );
315 #endif
316     badouble& operator++( void );
317     badouble& operator--( void );
318     /*   inline double value(); */
319     ~adouble();
320 
321     adouble& operator = ( double );
322     adouble& operator = ( const badouble& );
323     adouble& operator = ( const adouble& );
324     adouble& operator = ( const adub& );
325     adouble& operator = (const pdouble&);
326 
327     inline locint loc(void) const;
328 
329 #if defined(ADOLC_DEFAULT_CONTIG_LOC)
330     void *operator new[](size_t sz) {
331         void *p = ::new char[sz];
332         size_t n = (sz - sizeof(size_t))/sizeof(adouble);
333         ensureContiguousLocations(n);
334         return p;
335     }
336     void operator delete[](void* p) {
337         ::delete[] (char*)p;
338     }
339 #endif
340 };
341 
342 #endif /* __cplusplus */
343 
344 #include <adolc/param.h>
345 #include <adolc/advector.h>
346 
347 #ifdef __cplusplus
348 /****************************************************************************/
349 /*                                                       INLINE DEFINITIONS */
350 
351 /*--------------------------------------------------------------------------*/
loc(void)352 inline locint badouble::loc( void ) const {
353     return location;
354 }
355 
loc(void)356 inline locint adouble::loc( void ) const {
357     const_cast<adouble*>(this)->initInternal();
358     return location;
359 }
360 
361 /*--------------------------------------------------------------------------*/
362 /* Comparison */
363 
364 #if !defined(ADOLC_ADVANCED_BRANCHING)
365 inline bool operator != ( const badouble& u, const badouble& v ) {
366     return (u-v != 0);
367 }
368 
369 inline bool operator == ( const badouble& u, const badouble& v ) {
370     return (u-v == 0);
371 }
372 
373 inline bool operator <= ( const badouble& u, const badouble& v ) {
374     return (u-v <= 0);
375 }
376 
377 inline bool operator >= ( const badouble& u, const badouble& v ) {
378     return (u-v >= 0);
379 }
380 
381 inline bool operator > ( const badouble& u, const badouble& v ) {
382     return (u-v > 0);
383 }
384 
385 inline bool operator < ( const badouble& u, const badouble& v ) {
386     return (u-v < 0);
387 }
388 #endif
389 
390 inline bool operator != ( double coval, const badouble& v) {
391     if (coval)
392         return (-coval+v != 0);
393     else
394         return (v != 0);
395 }
396 
397 inline bool operator == ( double coval, const badouble& v) {
398     if (coval)
399         return (-coval+v == 0);
400     else
401         return (v == 0);
402 }
403 
404 inline bool operator <= ( double coval, const badouble& v ) {
405     if (coval)
406         return (-coval+v >= 0);
407     else
408         return (v >= 0);
409 }
410 
411 inline bool operator >= ( double coval, const badouble& v ) {
412     if (coval)
413         return (-coval+v <= 0);
414     else
415         return (v <= 0);
416 }
417 
418 inline bool operator > ( double coval, const badouble& v ) {
419     if (coval)
420         return (-coval+v < 0);
421     else
422         return (v < 0);
423 }
424 
425 inline bool operator < ( double coval, const badouble& v ) {
426     if (coval)
427         return (-coval+v > 0);
428     else
429         return (v > 0);
430 }
431 
432 #if !defined(SWIGPRE)
433 /*--------------------------------------------------------------------------*/
434 /* Adding a floating point from an adouble  */
435 inline adub operator + ( const badouble& x , double coval ) {
436     return coval + x;
437 }
438 
439 /* Subtract a floating point from an adouble  */
440 inline adub operator - ( const badouble& x , double coval ) {
441     return (-coval) + x;
442 }
443 
444 /*--------------------------------------------------------------------------*/
445 /* Multiply an adouble by a floating point */
446 inline adub operator * (const badouble& x, double coval) {
447     return coval * x;
448 }
449 
450 /*--------------------------------------------------------------------------*/
451 /* Divide an adouble by a floating point */
452 inline adub operator / (const badouble& x, double coval) {
453     return (1.0/coval) * x;
454 }
455 #endif
456 
457 
458 inline badouble& badouble::operator /= (const pdouble& p) {
459     *this *= recipr(p);
460     return *this;
461 }
462 
463 /****************************************************************************/
464 /*                                                                THAT'S ALL*/
465 #endif /* __cplusplus */
466 #endif /* ADOLC_ADOUBLE_H */
467