source: trunk/ADOL-C/include/adolc/adtl.h @ 708

Last change on this file since 708 was 708, checked in by kulshres, 3 years ago

Merge branch 'master' of 'gitclone' into 'svn'

The following changes have been merged:

commit e2291bde44a282a133894b0db350aeb0b92a87db
Author: Mladen Banovic <mladenbanovic2705@…>
Date: Fri Jul 8 10:15:51 2016 +0200

Add methods getNumLiveVar and getNumDir in adtl.h, change counter type in FOR_I_EQ_0_LT_NUMDIR macro to size_t (instead of int). Update chunk size of BOOST pool in adouble_tl.cpp according to adouble::numDir.

commit 2ffb294465b973bfd4bf1f73d84478f8233c0d2f
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Thu Jun 23 12:32:14 2016 +0200

implement missing ref_eq_mult_p und ref_eq_min_p in ho_rev.c

somehow these were left out when parameters were being implemented.

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit 8cf0e5c1bd36f1dcf3be72cd67de631b2e1d0ee6
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Thu Jun 23 12:31:04 2016 +0200

make sure the result is the last locint written in trace for each operation

since we're trying to generate ascii traces in the future, we'll need this
convention that the last location is the result, and previous locations
are arguments. This has been the case for almost all operations anyway
except for a few new one's that I wrote without keeping this in mind.

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit 9ae0ff220f37463f2ed85cafc8a626c24e472f2f
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Tue Jun 21 14:16:27 2016 +0200

on some compilers newer boost interferes with AC_FUNC_MALLOC test

so do AC_FUNC_MALLOC and AC_FUNC_REALLOC as usual and check for boost
library later.

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit b746f620772cc8cce53e8f350adc6281279caf72
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Mon Jun 20 15:32:22 2016 +0200

make Klaus Röbenack's name UTF-8 instead of ISO-8859-1

These are the only places where we're not simple ASCII or UTF-8 already

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit 1171aa3961b5eb46a5d2ee64751c02a393a8a6f5
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Fri Jun 17 10:42:39 2016 +0200

correct short_ref document about include file

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit 2c6b2aac2ef04431ece2c6ff80e574aa2e58814b
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Fri Jun 17 10:40:34 2016 +0200

correct error message to new semantics

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit 506cde73451740bf0a15eff7d4abb158ee719ab0
Author: mflehmig <martin.flehmig@…>
Date: Fri Jun 17 10:14:26 2016 +0200

Fixed include of ADOL-C header.

ADOL-C header was included in old fashion (without adolc directory) for this example.

commit 2a023d3281d3d6d9824bad724a5768e3ee2fff94
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Thu Jun 16 13:50:39 2016 +0200

Try to use boost::pool for allocating advals in traceless vector mode

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit 80f1e2019ac1faab96fe06f3e9da47efcc1bcd23
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Mon May 23 15:13:22 2016 +0200

correct a reference in doc and rebuild

commit d7ab5283afe58bacb2e8739d72ede4e17f4c8081
Author: Mladen Banovic <mladenbanovic2705@…>
Date: Fri May 20 16:42:13 2016 +0200

Update section 7 of adolc-manual related to the Traceless forward differentiation.

commit bedb8e36f959c5272e4610fe504acc83208e5e9d
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Tue May 17 16:09:36 2016 +0200

macro name correction

commit 92ff596a0331776901df7f172ca347572e3daafd
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Tue May 17 15:56:17 2016 +0200

Add a warning about using static build of ADOL-C

static build of ADOL-C does not call constructors
for internal global objects, thereby causing
segmentation faults.

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

File size: 51.9 KB
Line 
1/*----------------------------------------------------------------------------
2 ADOL-C -- Automatic Differentiation by Overloading in C++
3 File:     adouble.cpp
4 Revision: $Id$
5 Contents: adtl.h contains that declaratins of procedures used to
6           define various tapeless adouble operations.
7
8 Copyright (c) Andrea Walther, Andreas Griewank, Andreas Kowarz,
9               Hristo Mitev, Sebastian Schlenkrich, Jean Utke, Olaf Vogel,
10               Benjamin Letschert, Kshitij Kulshreshtha
11
12 This file is part of ADOL-C. This software is provided as open source.
13 Any use, reproduction, or distribution of the software constitutes
14 recipient's acceptance of the terms of the accompanying license file.
15
16----------------------------------------------------------------------------*/
17#ifndef ADOLC_ADTL_H
18#define ADOLC_ADTL_H
19
20#include <ostream>
21#include <adolc/internal/common.h>
22#include <list>
23#include <stdexcept>
24
25#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
26#define COMPILER_HAS_CXX11
27#else
28#error "please use -std=c++11 compiler flag with a C++11 compliant compiler"
29#endif
30
31#if USE_BOOST_POOL
32#include <boost/pool/pool_alloc.hpp>
33#endif
34
35using std::ostream;
36using std::istream;
37using std::list;
38using std::logic_error;
39
40namespace adtl {
41
42double makeNaN();
43double makeInf();
44
45enum Mode {
46    ADTL_ZOS = 0x1,
47    ADTL_FOV = 0x3,
48    ADTL_INDO = 0x5,
49    ADTL_FOV_INDO = 0x7
50};
51
52class adouble;
53
54class refcounter {
55private:
56    ADOLC_DLL_EXPIMP static size_t refcnt;
57    ADOLC_DLL_EXPORT friend void setNumDir(const size_t p);
58    ADOLC_DLL_EXPORT friend void setMode(enum Mode newmode);
59    friend class adouble;
60public:
61    refcounter() { ++refcnt; }
62    ~refcounter() { --refcnt; }
63    inline static size_t getNumLiveVar() {return refcnt;}
64};
65
66class func_ad {
67public:
68    virtual int operator() (int n, adouble *x, int m, adouble *y) = 0;
69};
70
71class adouble {
72public:
73    inline adouble();
74    inline adouble(const double v);
75    inline adouble(const double v, const double* adv);
76    inline adouble(const adouble& a);
77    inline ~adouble();
78
79    // sign
80    inline adouble operator - () const;
81    inline adouble operator + () const;
82
83    // addition
84    inline adouble operator + (const double v) const;
85    inline adouble operator + (const adouble& a) const;
86    inline friend
87    adouble operator + (const double v, const adouble& a);
88
89    // substraction
90    inline adouble operator - (const double v) const;
91    inline adouble operator - (const adouble& a) const;
92    inline friend
93    adouble operator - (const double v, const adouble& a);
94
95    // multiplication
96    inline adouble operator * (const double v) const;
97    inline adouble operator * (const adouble& a) const;
98    inline friend
99    adouble operator * (const double v, const adouble& a);
100
101    // division
102    inline adouble operator / (const double v) const;
103    inline adouble operator / (const adouble& a) const;
104    inline friend
105    adouble operator / (const double v, const adouble& a);
106
107    // inc/dec
108    inline adouble operator ++ ();
109    inline adouble operator ++ (int);
110    inline adouble operator -- ();
111    inline adouble operator -- (int);
112
113    // functions
114    inline friend adouble tan(const adouble &a);
115    inline friend adouble exp(const adouble &a);
116    inline friend adouble log(const adouble &a);
117    inline friend adouble sqrt(const adouble &a);
118    inline friend adouble sin(const adouble &a);
119    inline friend adouble cos(const adouble &a);
120    inline friend adouble asin(const adouble &a);
121    inline friend adouble acos(const adouble &a);
122    inline friend adouble atan(const adouble &a);
123
124    inline friend adouble atan2(const adouble &a, const adouble &b);
125    inline friend adouble pow(const adouble &a, double v);
126    inline friend adouble pow(const adouble &a, const adouble &b);
127    inline friend adouble pow(double v, const adouble &a);
128    inline friend adouble log10(const adouble &a);
129
130    inline friend adouble sinh (const adouble &a);
131    inline friend adouble cosh (const adouble &a);
132    inline friend adouble tanh (const adouble &a);
133#if defined(ATRIG_ERF)
134    inline friend adouble asinh (const adouble &a);
135    inline friend adouble acosh (const adouble &a);
136    inline friend adouble atanh (const adouble &a);
137#endif
138    inline friend adouble fabs (const adouble &a);
139    inline friend adouble ceil (const adouble &a);
140    inline friend adouble floor (const adouble &a);
141    inline friend adouble fmax (const adouble &a, const adouble &b);
142    inline friend adouble fmax (double v, const adouble &a);
143    inline friend adouble fmax (const adouble &a, double v);
144    inline friend adouble fmin (const adouble &a, const adouble &b);
145    inline friend adouble fmin (double v, const adouble &a);
146    inline friend adouble fmin (const adouble &a, double v);
147    inline friend adouble ldexp (const adouble &a, const adouble &b);
148    inline friend adouble ldexp (const adouble &a, const double v);
149    inline friend adouble ldexp (const double v, const adouble &a);
150    inline friend double frexp (const adouble &a, int* v);
151#if defined(ATRIG_ERF)
152    inline friend adouble erf (const adouble &a);
153#endif
154
155    inline friend void condassign( adouble &res, const adouble &cond,
156            const adouble &arg1, const adouble &arg2 );
157    inline friend void condassign( adouble &res, const adouble &cond,
158            const adouble &arg );
159    inline friend void condeqassign( adouble &res, const adouble &cond,
160            const adouble &arg1, const adouble &arg2 );
161    inline friend void condeqassign( adouble &res, const adouble &cond,
162            const adouble &arg );
163
164    /*******************  nontemporary results  ***************************/
165    // assignment
166    inline adouble& operator = (const double v);
167    inline adouble& operator = (const adouble& a);
168
169    // addition
170    inline adouble& operator += (const double v);
171    inline adouble& operator += (const adouble& a);
172
173    // substraction
174    inline adouble& operator -= (const double v);
175    inline adouble& operator -= (const adouble& a);
176
177    // multiplication
178    inline adouble& operator *= (const double v);
179    inline adouble& operator *= (const adouble& a);
180
181    // division
182    inline adouble& operator /= (const double v);
183    inline adouble& operator /= (const adouble& a);
184
185    // not
186    inline int operator ! () const;
187
188    // comparision
189    inline int operator != (const adouble&) const;
190    inline int operator != (const double) const;
191    inline friend int operator != (const double, const adouble&);
192
193    inline int operator == (const adouble&) const;
194    inline int operator == (const double) const;
195    inline friend int operator == (const double, const adouble&);
196
197    inline int operator <= (const adouble&) const;
198    inline int operator <= (const double) const;
199    inline friend int operator <= (const double, const adouble&);
200
201    inline int operator >= (const adouble&) const;
202    inline int operator >= (const double) const;
203    inline friend int operator >= (const double, const adouble&);
204
205    inline int operator >  (const adouble&) const;
206    inline int operator >  (const double) const;
207    inline friend int operator >  (const double, const adouble&);
208
209    inline int operator <  (const adouble&) const;
210    inline int operator <  (const double) const;
211    inline friend int operator <  (const double, const adouble&);
212
213    /*******************  getter / setter  ********************************/
214    inline double getValue() const;
215    inline void setValue(const double v);
216    inline const double* const getADValue() const;
217    inline void setADValue(const double* v);
218
219    inline double getADValue(const unsigned int p) const;
220    inline void setADValue(const unsigned int p, const double v);
221    inline explicit operator double const&();
222    inline explicit operator double&&();
223    inline explicit operator double();
224
225protected:
226    inline const list<unsigned int>& get_pattern() const;
227    inline void add_to_pattern(const list<unsigned int>& v);
228    inline size_t get_pattern_size() const;
229    inline void delete_pattern();
230
231public:
232    ADOLC_DLL_EXPORT friend int ADOLC_Init_sparse_pattern(adouble *a, int n,unsigned int start_cnt);
233    ADOLC_DLL_EXPORT friend int ADOLC_get_sparse_pattern(const adouble *const b, int m, unsigned int **&pat);
234    ADOLC_DLL_EXPORT friend int ADOLC_get_sparse_jacobian( func_ad *const func, int n, int m, int repeat, double* basepoints, int *nnz, unsigned int **rind, unsigned int **cind, double **values);
235#if 0
236    ADOLC_DLL_EXPORT friend int ADOLC_get_sparse_jacobian(int n, int m, adouble *x, int *nnz, unsigned int *rind, unsigned int *cind, double *values);
237#endif
238    /*******************  i/o operations  *********************************/
239    ADOLC_DLL_EXPORT friend ostream& operator << ( ostream&, const adouble& );
240    ADOLC_DLL_EXPORT friend istream& operator >> ( istream&, adouble& );
241
242private:
243#if USE_BOOST_POOL
244    static boost::pool<boost::default_user_allocator_new_delete>* advalpool;
245#endif
246    double val;
247    double *adval;
248    list<unsigned int> pattern;
249    refcounter __rcnt;
250    inline static bool _do_val();
251    inline static bool _do_adval();
252    inline static bool _do_indo();
253    ADOLC_DLL_EXPIMP static size_t numDir;
254    ADOLC_DLL_EXPIMP static enum Mode forward_mode;
255    inline friend void setNumDir(const size_t p);
256    inline friend size_t getNumDir();
257    inline friend void setMode(enum Mode newmode);
258};
259
260}
261
262#include <cmath>
263#include <iostream>
264#include <limits>
265
266namespace adtl {
267
268enum ModeMask {
269    ADTL_Z_MASK = 0x1,
270    ADTL_F_MASK = 0x2,
271    ADTL_I_MASK = 0x4
272};
273
274#if defined(HAVE_BUILTIN_EXPECT) && HAVE_BUILTIN_EXPECT
275#define likely(x)    __builtin_expect(!!(x), 1)
276#define unlikely(x)  __builtin_expect(!!(x), 0)
277#endif
278
279#ifndef likely
280#define likely(x) (x)
281#endif
282#ifndef unlikely
283#define unlikely(x) (x)
284#endif
285
286inline bool adouble::_do_val() {
287    return ((forward_mode & ADTL_Z_MASK) == ADTL_Z_MASK);
288}
289#define do_val() likely(adouble::_do_val())
290#define no_do_val() unlikely(!adouble::_do_val())
291
292inline bool adouble::_do_adval() {
293    return ((forward_mode & ADTL_F_MASK) == ADTL_F_MASK);
294}
295#define do_adval() likely(adouble::_do_adval())
296#define no_do_adval() unlikely(!adouble::_do_adval())
297
298inline bool adouble::_do_indo() {
299    return ((forward_mode & ADTL_I_MASK) == ADTL_I_MASK);
300}
301#define do_indo() unlikely(adouble::_do_indo())
302#define no_do_indo() likely(!adouble::_do_indo())
303
304inline void setNumDir(const size_t p) {
305    if (refcounter::refcnt > 0) {
306        fprintf(DIAG_OUT, "ADOL-C Warning: Tapeless: Setting numDir could change memory allocation of\n derivatives in existing adoubles and may lead to erronious results\n or memory corruption\n Number of currently existing adoubles = %zu\n", refcounter::refcnt);
307    }
308    if (p < 1) {
309        fprintf(DIAG_OUT, "ADOL-C Error: Tapeless: You are being a moron now.\n");
310        abort();
311    }
312    adouble::numDir = p;
313#if USE_BOOST_POOL
314    if (adouble::advalpool != NULL) {
315        delete adouble::advalpool;
316        adouble::advalpool = NULL;
317    }
318    adouble::advalpool = new boost::pool<boost::default_user_allocator_new_delete>(adouble::numDir*sizeof(double));
319#endif
320}
321
322inline size_t getNumDir() {return adouble::numDir;}
323
324inline void setMode(enum Mode newmode) {
325    if (refcounter::refcnt > 0) {
326        fprintf(DIAG_OUT, "ADOL-C Warning: Tapeless: Setting mode will the change the mode of\n computation in previously computed variables and may lead to erronious results\n or memory corruption\n Number of currently existing adoubles = %zu\n", refcounter::refcnt);
327    }
328    adouble::forward_mode = newmode;
329}
330
331inline double makeNaN() {
332    return ADOLC_MATH_NSP::numeric_limits<double>::quiet_NaN();
333}
334
335inline double makeInf() {
336    return ADOLC_MATH_NSP::numeric_limits<double>::infinity();
337}
338
339#define FOR_I_EQ_0_LT_NUMDIR for (size_t _i=0; _i < adouble::numDir; ++_i)
340#define ADVAL_I              adval[_i]
341#define ADV_I                adv[_i]
342#define V_I                  v[_i]
343
344/*******************************  ctors  ************************************/
345inline adouble::adouble() : val(0), adval(NULL) {
346    if (do_adval())
347#if USE_BOOST_POOL
348        adval = reinterpret_cast<double*>(advalpool->malloc());
349#else
350        adval = new double[adouble::numDir];
351#endif
352    if (do_indo()) {
353     if (!pattern.empty())
354          pattern.clear();
355    }
356}
357
358inline adouble::adouble(const double v) : val(v), adval(NULL) {
359    if (do_adval()) {
360#if USE_BOOST_POOL
361        adval = reinterpret_cast<double*>(advalpool->malloc());
362#else
363        adval = new double[adouble::numDir];
364#endif
365        FOR_I_EQ_0_LT_NUMDIR
366            ADVAL_I = 0.0;
367    }
368    if (do_indo()) {
369     if (!pattern.empty())
370          pattern.clear();
371    }
372}
373
374inline adouble::adouble(const double v, const double* adv) : val(v), adval(NULL) {
375    if (do_adval()) {
376#if USE_BOOST_POOL
377        adval = reinterpret_cast<double*>(advalpool->malloc());
378#else
379        adval = new double[adouble::numDir];
380#endif
381        FOR_I_EQ_0_LT_NUMDIR
382            ADVAL_I=ADV_I;
383    }
384    if (do_indo()) {
385     if (!pattern.empty())
386          pattern.clear();
387    }
388}
389
390inline adouble::adouble(const adouble& a) : val(a.val), adval(NULL) {
391    if (do_adval()) {
392#if USE_BOOST_POOL
393        adval = reinterpret_cast<double*>(advalpool->malloc());
394#else
395        adval = new double[adouble::numDir];
396#endif
397        FOR_I_EQ_0_LT_NUMDIR
398            ADVAL_I=a.ADVAL_I;
399    }
400    if (do_indo()) {
401     if (!pattern.empty())
402          pattern.clear();
403
404     add_to_pattern(a.get_pattern());
405    }
406}
407
408/*******************************  dtors  ************************************/
409inline adouble::~adouble() {
410    if (adval != NULL)
411#if USE_BOOST_POOL
412        advalpool->free(adval);
413#else
414        delete[] adval;
415#endif
416#if 0
417    if ( !pattern.empty() )
418        pattern.clear();
419#endif
420}
421
422/*************************  temporary results  ******************************/
423// sign
424inline adouble adouble::operator - () const {
425    adouble tmp;
426    if (do_val())
427        tmp.val=-val;
428    if (do_adval())
429        FOR_I_EQ_0_LT_NUMDIR
430            tmp.ADVAL_I=-ADVAL_I;
431    if (do_indo())
432        tmp.add_to_pattern( get_pattern() );
433    return tmp;
434}
435
436inline adouble adouble::operator + () const {
437    return *this;
438}
439
440// addition
441inline adouble adouble::operator + (const double v) const {
442    adouble tmp(val+v, adval);
443    if (do_indo())
444        tmp.add_to_pattern( get_pattern() ) ;
445    return tmp;
446}
447
448inline adouble adouble::operator + (const adouble& a) const {
449    adouble tmp;
450    if (do_val())
451        tmp.val=val+a.val;
452    if (do_adval())
453        FOR_I_EQ_0_LT_NUMDIR
454            tmp.ADVAL_I=ADVAL_I+a.ADVAL_I;
455    if (do_indo()) {
456        tmp.add_to_pattern( get_pattern()  );
457        tmp.add_to_pattern( a.get_pattern() );
458    }
459    return tmp;
460}
461
462inline adouble operator + (const double v, const adouble& a) {
463    adouble tmp(v+a.val, a.adval);
464    if (do_indo())
465        tmp.add_to_pattern( a.get_pattern() );
466    return tmp;
467}
468
469// subtraction
470inline adouble adouble::operator - (const double v) const {
471    adouble tmp(val-v, adval);
472    if (do_indo())
473        tmp.add_to_pattern( get_pattern() );
474    return tmp;
475}
476
477inline adouble adouble::operator - (const adouble& a) const {
478    adouble tmp;
479    if (do_val())
480        tmp.val=val-a.val;
481    if (do_adval())
482        FOR_I_EQ_0_LT_NUMDIR
483            tmp.ADVAL_I=ADVAL_I-a.ADVAL_I;
484    if (do_indo()) {
485        tmp.add_to_pattern( get_pattern() );
486        tmp.add_to_pattern( a.get_pattern() );
487    }
488    return tmp;
489}
490
491inline adouble operator - (const double v, const adouble& a) {
492    adouble tmp;
493    if (do_val())
494        tmp.val=v-a.val;
495    if (do_adval())
496        FOR_I_EQ_0_LT_NUMDIR
497            tmp.ADVAL_I=-a.ADVAL_I;
498    if (do_indo())
499        tmp.add_to_pattern( a.get_pattern() );
500    return tmp;
501}
502
503// multiplication
504inline adouble adouble::operator * (const double v) const {
505    adouble tmp;
506    if (do_val())
507        tmp.val=val*v;
508    if (do_adval())
509        FOR_I_EQ_0_LT_NUMDIR
510            tmp.ADVAL_I=ADVAL_I*v;
511    if (do_indo())
512        tmp.add_to_pattern( get_pattern() );
513    return tmp;
514}
515
516inline adouble adouble::operator * (const adouble& a) const {
517    adouble tmp;
518    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
519        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
520        throw logic_error("incorrect function call, errorcode=1");
521    }
522    if (do_val())
523        tmp.val=val*a.val;
524    if (likely(adouble::_do_adval() && adouble::_do_val()))
525        FOR_I_EQ_0_LT_NUMDIR
526            tmp.ADVAL_I=ADVAL_I*a.val+val*a.ADVAL_I;
527    if (do_indo()) {
528        tmp.add_to_pattern(   get_pattern() );
529        tmp.add_to_pattern( a.get_pattern() );
530    }
531    return tmp;
532}
533
534inline adouble operator * (const double v, const adouble& a) {
535    adouble tmp;
536    if (do_val())
537        tmp.val=v*a.val;
538    if (do_adval())
539        FOR_I_EQ_0_LT_NUMDIR
540            tmp.ADVAL_I=v*a.ADVAL_I;
541    if (do_indo())
542        tmp.add_to_pattern( a.get_pattern() );
543    return tmp;
544}
545
546// division
547inline adouble adouble::operator / (const double v) const {
548    adouble tmp;
549    if (do_val())
550        tmp.val=val/v;
551    if (do_adval())
552        FOR_I_EQ_0_LT_NUMDIR
553            tmp.ADVAL_I=ADVAL_I/v;
554    if (do_indo())
555        tmp.add_to_pattern( get_pattern() );
556    return tmp;
557}
558
559inline adouble adouble::operator / (const adouble& a) const {
560    adouble tmp;
561    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
562        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
563        throw logic_error("incorrect function call, errorcode=1");
564    }
565    if (do_val())
566        tmp.val=val/a.val;
567    if (likely(adouble::_do_adval() && adouble::_do_val()))
568        FOR_I_EQ_0_LT_NUMDIR
569            tmp.ADVAL_I=(ADVAL_I*a.val-val*a.ADVAL_I)/(a.val*a.val);
570    if (do_indo()) {
571        tmp.add_to_pattern(   get_pattern() );
572        tmp.add_to_pattern( a.get_pattern() );
573    }
574    return tmp;
575}
576
577inline adouble operator / (const double v, const adouble& a) {
578    adouble tmp;
579    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
580        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
581        throw logic_error("incorrect function call, errorcode=1");
582    }
583    if (do_val())
584        tmp.val=v/a.val;
585    if (likely(adouble::_do_adval() && adouble::_do_val()))
586        FOR_I_EQ_0_LT_NUMDIR
587            tmp.ADVAL_I=(-v*a.ADVAL_I)/(a.val*a.val);
588    if (do_indo())
589        tmp.add_to_pattern( a.get_pattern() );
590    return tmp;
591}
592
593// inc/dec
594inline adouble adouble::operator ++ () {
595    if (do_val())
596        ++val;
597    return *this;
598}
599
600inline adouble adouble::operator ++ (int) {
601    adouble tmp;
602    if (do_val())
603        tmp.val=val++;
604    if (do_adval())
605        FOR_I_EQ_0_LT_NUMDIR
606            tmp.ADVAL_I=ADVAL_I;
607    if (do_indo())
608        tmp.add_to_pattern( get_pattern() );
609    return tmp;
610}
611
612inline adouble adouble::operator -- () {
613    if (do_val())
614        --val;
615    return *this;
616}
617
618inline adouble adouble::operator -- (int) {
619    adouble tmp;
620    if (do_val())
621        tmp.val=val--;
622    if (do_adval())
623        FOR_I_EQ_0_LT_NUMDIR
624            tmp.ADVAL_I=ADVAL_I;
625    if (do_indo())
626        tmp.add_to_pattern( get_pattern() );
627    return tmp;
628}
629
630// functions
631inline adouble tan(const adouble& a) {
632    adouble tmp;
633    double tmp2;
634    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
635        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
636        throw logic_error("incorrect function call, errorcode=1");
637    }
638    if (do_val()) 
639        tmp.val=ADOLC_MATH_NSP::tan(a.val);   
640    if (likely(adouble::_do_adval() && adouble::_do_val())) {
641        tmp2=ADOLC_MATH_NSP::cos(a.val);
642        tmp2*=tmp2;
643        FOR_I_EQ_0_LT_NUMDIR
644            tmp.ADVAL_I=a.ADVAL_I/tmp2;
645    }
646    if (do_indo()) 
647        tmp.add_to_pattern( a.get_pattern() );
648    return tmp;
649}
650
651inline adouble exp(const adouble &a) {
652    adouble tmp;
653    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
654        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
655        throw logic_error("incorrect function call, errorcode=1");
656    }
657    if (do_val()) 
658        tmp.val=ADOLC_MATH_NSP::exp(a.val);
659    if (likely(adouble::_do_adval() && adouble::_do_val())) 
660        FOR_I_EQ_0_LT_NUMDIR
661            tmp.ADVAL_I=tmp.val*a.ADVAL_I;
662    if (do_indo()) 
663        tmp.add_to_pattern( a.get_pattern() );
664    return tmp;
665}
666
667inline adouble log(const adouble &a) {
668    adouble tmp;
669    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
670        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
671        throw logic_error("incorrect function call, errorcode=1");
672    }
673    if (do_val()) 
674        tmp.val=ADOLC_MATH_NSP::log(a.val);
675    if (likely(adouble::_do_adval() && adouble::_do_val())) {
676        FOR_I_EQ_0_LT_NUMDIR
677            if (a.val>0) tmp.ADVAL_I=a.ADVAL_I/a.val;
678            else if (a.val==0 && a.ADVAL_I != 0.0) {
679                int sign = (a.ADVAL_I < 0)  ? -1 : 1;
680                tmp.ADVAL_I=sign*makeInf();
681            } else tmp.ADVAL_I=makeNaN();
682    }
683    if (do_indo()) 
684        tmp.add_to_pattern( a.get_pattern() );
685    return tmp;
686}
687
688inline adouble sqrt(const adouble &a) {
689    adouble tmp;
690    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
691        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
692        throw logic_error("incorrect function call, errorcode=1");
693    }
694    if (do_val()) 
695        tmp.val=ADOLC_MATH_NSP::sqrt(a.val);
696    if (likely(adouble::_do_adval() && adouble::_do_val())) {
697        FOR_I_EQ_0_LT_NUMDIR
698            if (a.val>0) tmp.ADVAL_I=a.ADVAL_I/(tmp.val*2);
699            else if (a.val==0.0 && a.ADVAL_I != 0.0) {
700                int sign = (a.ADVAL_I < 0) ? -1 : 1;
701                tmp.ADVAL_I=sign * makeInf();
702            } else tmp.ADVAL_I=makeNaN();
703    }
704    if (do_indo()) 
705        tmp.add_to_pattern( a.get_pattern() );
706    return tmp;
707}
708
709inline adouble sin(const adouble &a) {
710    adouble tmp;
711    double tmp2;
712    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
713        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
714        throw logic_error("incorrect function call, errorcode=1");
715    }
716    if (do_val()) 
717        tmp.val=ADOLC_MATH_NSP::sin(a.val);
718    if (likely(adouble::_do_adval() && adouble::_do_val())) {
719        tmp2=ADOLC_MATH_NSP::cos(a.val);
720        FOR_I_EQ_0_LT_NUMDIR
721            tmp.ADVAL_I=tmp2*a.ADVAL_I;
722    }
723    if (do_indo()) 
724        tmp.add_to_pattern( a.get_pattern() );
725    return tmp;
726}
727
728inline adouble cos(const adouble &a) {
729    adouble tmp;
730    double tmp2;
731    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
732        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
733        throw logic_error("incorrect function call, errorcode=1");
734    }
735    if (do_val()) 
736        tmp.val=ADOLC_MATH_NSP::cos(a.val);
737    if (likely(adouble::_do_adval() && adouble::_do_val())) {
738        tmp2=-ADOLC_MATH_NSP::sin(a.val);
739        FOR_I_EQ_0_LT_NUMDIR
740            tmp.ADVAL_I=tmp2*a.ADVAL_I;
741    }
742    if (do_indo()) 
743        tmp.add_to_pattern( a.get_pattern() );
744    return tmp;
745}
746
747inline adouble asin(const adouble &a) {
748    adouble tmp;
749    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
750        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
751        throw logic_error("incorrect function call, errorcode=1");
752    }
753    if (do_val()) 
754        tmp.val=ADOLC_MATH_NSP::asin(a.val);
755    if (likely(adouble::_do_adval() && adouble::_do_val())) {
756        double tmp2=ADOLC_MATH_NSP::sqrt(1-a.val*a.val);
757        FOR_I_EQ_0_LT_NUMDIR
758            tmp.ADVAL_I=a.ADVAL_I/tmp2;
759    }
760    if (do_indo()) 
761        tmp.add_to_pattern( a.get_pattern() );
762    return tmp;
763}
764
765inline adouble acos(const adouble &a) {
766    adouble tmp;
767    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
768        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
769        throw logic_error("incorrect function call, errorcode=1");
770    }
771    if (do_val()) 
772        tmp.val=ADOLC_MATH_NSP::acos(a.val);
773    if (likely(adouble::_do_adval() && adouble::_do_val())) {
774        double tmp2=-ADOLC_MATH_NSP::sqrt(1-a.val*a.val);
775        FOR_I_EQ_0_LT_NUMDIR
776            tmp.ADVAL_I=a.ADVAL_I/tmp2;
777    }
778    if (do_indo()) 
779        tmp.add_to_pattern( a.get_pattern() );
780    return tmp;
781}
782
783inline adouble atan(const adouble &a) {
784    adouble tmp;
785    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
786        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
787        throw logic_error("incorrect function call, errorcode=1");
788    }
789    if (do_val()) 
790        tmp.val=ADOLC_MATH_NSP::atan(a.val);
791    if (likely(adouble::_do_adval() && adouble::_do_val())) {
792        double tmp2=1+a.val*a.val;
793        tmp2=1/tmp2;
794        if (tmp2!=0)
795            FOR_I_EQ_0_LT_NUMDIR
796                tmp.ADVAL_I=a.ADVAL_I*tmp2;
797        else
798            FOR_I_EQ_0_LT_NUMDIR
799                tmp.ADVAL_I=0.0;
800    }
801    if (do_indo()) 
802        tmp.add_to_pattern( a.get_pattern() );
803    return tmp;
804}
805
806inline adouble atan2(const adouble &a, const adouble &b) {
807    adouble tmp;
808    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
809        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
810        throw logic_error("incorrect function call, errorcode=1");
811    }
812    if (do_val()) 
813        tmp.val=ADOLC_MATH_NSP::atan2(a.val, b.val);
814    if (likely(adouble::_do_adval() && adouble::_do_val())) {
815        double tmp2=a.val*a.val;
816        double tmp3=b.val*b.val;
817        double tmp4=tmp3/(tmp2+tmp3);
818        if (tmp4!=0)
819            FOR_I_EQ_0_LT_NUMDIR
820                tmp.ADVAL_I=(a.ADVAL_I*b.val-a.val*b.ADVAL_I)/tmp3*tmp4;
821        else
822            FOR_I_EQ_0_LT_NUMDIR
823                tmp.ADVAL_I=0.0;
824    }
825    if (do_indo()) {
826        tmp.add_to_pattern( a.get_pattern() );
827        tmp.add_to_pattern( b.get_pattern() );
828    }
829    return tmp;
830}
831
832inline adouble pow(const adouble &a, double v) {
833    adouble tmp;
834    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
835        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
836        throw logic_error("incorrect function call, errorcode=1");
837    }
838    if (do_val()) 
839        tmp.val=ADOLC_MATH_NSP::pow(a.val, v);
840    if (likely(adouble::_do_adval() && adouble::_do_val())) {
841        double tmp2=v*ADOLC_MATH_NSP::pow(a.val, v-1);
842        FOR_I_EQ_0_LT_NUMDIR
843            tmp.ADVAL_I=tmp2*a.ADVAL_I;
844    }
845    if (do_indo()) 
846        tmp.add_to_pattern( a.get_pattern() );
847    return tmp;
848}
849
850inline adouble pow(const adouble &a, const adouble &b) {
851    adouble tmp;
852    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
853        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
854        throw logic_error("incorrect function call, errorcode=1");
855    }
856    if (do_val()) 
857        tmp.val=ADOLC_MATH_NSP::pow(a.val, b.val);
858    if (likely(adouble::_do_adval() && adouble::_do_val())) {
859        double tmp2=b.val*ADOLC_MATH_NSP::pow(a.val, b.val-1);
860        double tmp3=ADOLC_MATH_NSP::log(a.val)*tmp.val;
861        FOR_I_EQ_0_LT_NUMDIR
862            tmp.ADVAL_I=tmp2*a.ADVAL_I+tmp3*b.ADVAL_I;
863    }
864    if (do_indo()) {
865        tmp.add_to_pattern( a.get_pattern() );
866        tmp.add_to_pattern( b.get_pattern() );
867    }
868    return tmp;
869}
870
871inline adouble pow(double v, const adouble &a) {
872    adouble tmp;
873    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
874        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
875        throw logic_error("incorrect function call, errorcode=1");
876    }
877    if (do_val()) 
878        tmp.val=ADOLC_MATH_NSP::pow(v, a.val);
879    if (likely(adouble::_do_adval() && adouble::_do_val())) {
880        double tmp2=tmp.val*ADOLC_MATH_NSP::log(v);
881        FOR_I_EQ_0_LT_NUMDIR
882            tmp.ADVAL_I=tmp2*a.ADVAL_I;
883    }
884    if (do_indo()) 
885        tmp.add_to_pattern( a.get_pattern() );
886    return tmp;
887}
888
889inline adouble log10(const adouble &a) {
890    adouble tmp;
891    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
892        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
893        throw logic_error("incorrect function call, errorcode=1");
894    }
895    if (do_val()) 
896        tmp.val=ADOLC_MATH_NSP::log10(a.val);
897    if (likely(adouble::_do_adval() && adouble::_do_val())) {
898        double tmp2=ADOLC_MATH_NSP::log((double)10)*a.val;
899        FOR_I_EQ_0_LT_NUMDIR
900            tmp.ADVAL_I=a.ADVAL_I/tmp2;
901    }
902    if (do_indo()) 
903        tmp.add_to_pattern( a.get_pattern() );
904    return tmp;
905}
906
907inline adouble sinh (const adouble &a) {
908    adouble tmp;
909    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
910        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
911        throw logic_error("incorrect function call, errorcode=1");
912    }
913    if (do_val()) 
914        tmp.val=ADOLC_MATH_NSP::sinh(a.val);
915    if (likely(adouble::_do_adval() && adouble::_do_val())) {
916        double tmp2=ADOLC_MATH_NSP::cosh(a.val);
917        FOR_I_EQ_0_LT_NUMDIR
918            tmp.ADVAL_I=a.ADVAL_I*tmp2;
919    }
920    if (do_indo()) 
921        tmp.add_to_pattern( a.get_pattern() );
922    return tmp;
923}
924
925inline adouble cosh (const adouble &a) {
926    adouble tmp;
927    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
928        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
929        throw logic_error("incorrect function call, errorcode=1");
930    }
931    if (do_val()) 
932        tmp.val=ADOLC_MATH_NSP::cosh(a.val);
933    if (likely(adouble::_do_adval() && adouble::_do_val())) {
934        double tmp2=ADOLC_MATH_NSP::sinh(a.val);
935        FOR_I_EQ_0_LT_NUMDIR
936            tmp.ADVAL_I=a.ADVAL_I*tmp2;
937    }
938    if (do_indo()) 
939        tmp.add_to_pattern( a.get_pattern() );
940    return tmp;
941}
942
943inline adouble tanh (const adouble &a) {
944    adouble tmp;
945    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
946        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
947        throw logic_error("incorrect function call, errorcode=1");
948    }
949    if (do_val()) 
950        tmp.val=ADOLC_MATH_NSP::tanh(a.val);
951    if (likely(adouble::_do_adval() && adouble::_do_val())) {
952        double tmp2=ADOLC_MATH_NSP::cosh(a.val);
953        tmp2*=tmp2;
954        FOR_I_EQ_0_LT_NUMDIR
955            tmp.ADVAL_I=a.ADVAL_I/tmp2;
956    }
957    if (do_indo()) 
958        tmp.add_to_pattern( a.get_pattern() );
959    return tmp;
960}
961
962#if defined(ATRIG_ERF)
963inline adouble asinh (const adouble &a) {
964    adouble tmp;
965    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
966        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
967        throw logic_error("incorrect function call, errorcode=1");
968    }
969    if (do_val()) 
970        tmp.val=ADOLC_MATH_NSP_ERF::asinh(a.val);
971    if (likely(adouble::_do_adval() && adouble::_do_val())) {
972        double tmp2=ADOLC_MATH_NSP::sqrt(a.val*a.val+1);
973        FOR_I_EQ_0_LT_NUMDIR
974            tmp.ADVAL_I=a.ADVAL_I/tmp2;
975    }
976    if (do_indo()) 
977        tmp.add_to_pattern( a.get_pattern() );
978    return tmp;
979}
980
981inline adouble acosh (const adouble &a) {
982    adouble tmp;
983    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
984        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
985        throw logic_error("incorrect function call, errorcode=1");
986    }
987    if (do_val()) 
988        tmp.val=ADOLC_MATH_NSP_ERF::acosh(a.val);
989    if (likely(adouble::_do_adval() && adouble::_do_val())) {
990        double tmp2=ADOLC_MATH_NSP::sqrt(a.val*a.val-1);
991        FOR_I_EQ_0_LT_NUMDIR
992            tmp.ADVAL_I=a.ADVAL_I/tmp2;
993    }
994    if (do_indo()) 
995        tmp.add_to_pattern( a.get_pattern() );
996    return tmp;
997}
998
999inline adouble atanh (const adouble &a) {
1000    adouble tmp;
1001    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
1002        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1003        throw logic_error("incorrect function call, errorcode=1");
1004    }
1005    if (do_val()) 
1006        tmp.val=ADOLC_MATH_NSP_ERF::atanh(a.val);
1007    if (likely(adouble::_do_adval() && adouble::_do_val())) {
1008        double tmp2=1-a.val*a.val;
1009        FOR_I_EQ_0_LT_NUMDIR
1010            tmp.ADVAL_I=a.ADVAL_I/tmp2;
1011    }
1012    if (do_indo()) 
1013        tmp.add_to_pattern( a.get_pattern() );
1014    return tmp;
1015}
1016#endif
1017
1018inline adouble fabs (const adouble &a) {
1019    adouble tmp;
1020    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
1021        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1022        throw logic_error("incorrect function call, errorcode=1");
1023    }
1024    if (do_val()) 
1025        tmp.val=ADOLC_MATH_NSP::fabs(a.val);
1026    if (likely(adouble::_do_adval() && adouble::_do_val())) {
1027        int as=0;
1028        if (a.val>0) as=1;
1029        if (a.val<0) as=-1;
1030        if (as!=0)
1031            FOR_I_EQ_0_LT_NUMDIR
1032                tmp.ADVAL_I=a.ADVAL_I*as;
1033        else
1034            FOR_I_EQ_0_LT_NUMDIR {
1035                as=0;
1036                if (a.ADVAL_I>0) as=1;
1037                if (a.ADVAL_I<0) as=-1;
1038                tmp.ADVAL_I=a.ADVAL_I*as;
1039            }
1040    }
1041    if (do_indo()) 
1042        tmp.add_to_pattern( a.get_pattern() );
1043    return tmp;
1044}
1045
1046inline adouble ceil (const adouble &a) {
1047    adouble tmp;
1048    if (do_val()) 
1049        tmp.val=ADOLC_MATH_NSP::ceil(a.val);
1050    if (do_adval())
1051        FOR_I_EQ_0_LT_NUMDIR
1052            tmp.ADVAL_I=0.0;
1053    return tmp;
1054}
1055
1056inline adouble floor (const adouble &a) {
1057    adouble tmp;
1058    if (do_val()) 
1059        tmp.val=ADOLC_MATH_NSP::floor(a.val);
1060    if (do_adval())
1061        FOR_I_EQ_0_LT_NUMDIR
1062            tmp.ADVAL_I=0.0;
1063    return tmp;
1064}
1065
1066inline adouble fmax (const adouble &a, const adouble &b) {
1067    adouble tmp;
1068    if (unlikely(!adouble::_do_val() && (adouble::_do_adval() || adouble::_do_indo()))) {
1069        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1070        throw logic_error("incorrect function call, errorcode=1");
1071    }   
1072    double tmp2=a.val-b.val;
1073    if (tmp2<0) {
1074        if (do_val()) 
1075            tmp.val=b.val;
1076        if (do_adval())
1077            FOR_I_EQ_0_LT_NUMDIR
1078                tmp.ADVAL_I=b.ADVAL_I;
1079        if (do_indo()) 
1080            tmp.add_to_pattern( b.get_pattern() );
1081    } else {
1082        if (do_val()) 
1083            tmp.val=a.val;
1084        if (tmp2>0) {
1085            if (do_adval())
1086                FOR_I_EQ_0_LT_NUMDIR
1087                    tmp.ADVAL_I=a.ADVAL_I;
1088            if (do_indo()) 
1089                tmp.add_to_pattern( a.get_pattern() );
1090        } else {
1091            if (do_adval())
1092                FOR_I_EQ_0_LT_NUMDIR
1093                {
1094                    if (a.ADVAL_I<b.ADVAL_I) tmp.ADVAL_I=b.ADVAL_I;
1095                    else tmp.ADVAL_I=a.ADVAL_I;
1096                }
1097            if (do_indo()) {
1098                tmp.add_to_pattern( a.get_pattern() );
1099                tmp.add_to_pattern( b.get_pattern() );
1100            }
1101        }
1102    }
1103    return tmp;
1104}
1105
1106inline adouble fmax (double v, const adouble &a) {
1107    adouble tmp;
1108    if (unlikely(!adouble::_do_val() && (adouble::_do_adval() || adouble::_do_indo()))) {
1109        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1110        throw logic_error("incorrect function call, errorcode=1");
1111    }   
1112    double tmp2=v-a.val;
1113    if (tmp2<0) {
1114        if (do_val()) 
1115            tmp.val=a.val;
1116        if (do_adval())
1117            FOR_I_EQ_0_LT_NUMDIR
1118                tmp.ADVAL_I=a.ADVAL_I;
1119        if (do_indo()) 
1120            tmp.add_to_pattern( a.get_pattern() );
1121    } else {
1122        if (do_val()) 
1123            tmp.val=v;
1124        if (tmp2>0) {
1125            if (do_adval())
1126                FOR_I_EQ_0_LT_NUMDIR
1127                    tmp.ADVAL_I=0.0;
1128        } else {
1129            if (do_adval())
1130                FOR_I_EQ_0_LT_NUMDIR
1131                {
1132                    if (a.ADVAL_I>0) tmp.ADVAL_I=a.ADVAL_I;
1133                    else tmp.ADVAL_I=0.0;
1134                }
1135            if (do_indo()) 
1136                tmp.add_to_pattern( a.get_pattern() );
1137        }
1138    }
1139    return tmp;
1140}
1141
1142inline adouble fmax (const adouble &a, double v) {
1143    adouble tmp;
1144    if (unlikely(!adouble::_do_val() && (adouble::_do_adval() || adouble::_do_indo()))) {
1145        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1146        throw logic_error("incorrect function call, errorcode=1");
1147    }   
1148    double tmp2=a.val-v;
1149    if (tmp2<0) {
1150        if (do_val()) 
1151            tmp.val=v;
1152        if (do_adval())
1153            FOR_I_EQ_0_LT_NUMDIR
1154                tmp.ADVAL_I=0.0;
1155    } else {
1156        if (do_val()) 
1157            tmp.val=a.val;
1158        if (tmp2>0) {
1159            if (do_adval())
1160                FOR_I_EQ_0_LT_NUMDIR
1161                    tmp.ADVAL_I=a.ADVAL_I;
1162            if (do_indo()) 
1163                tmp.add_to_pattern( a.get_pattern() );
1164        } else {
1165            if (do_adval())
1166                FOR_I_EQ_0_LT_NUMDIR
1167                {
1168                    if (a.ADVAL_I>0) tmp.ADVAL_I=a.ADVAL_I;
1169                    else tmp.ADVAL_I=0.0;
1170                }
1171            if (do_indo()) 
1172                tmp.add_to_pattern( a.get_pattern() );
1173        }
1174    }
1175    return tmp;
1176}
1177
1178inline adouble fmin (const adouble &a, const adouble &b) {
1179    adouble tmp;
1180    if (unlikely(!adouble::_do_val() && (adouble::_do_adval() || adouble::_do_indo()))) {
1181        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1182        throw logic_error("incorrect function call, errorcode=1");
1183    }   
1184    double tmp2=a.val-b.val;
1185    if (tmp2<0) {
1186        if (do_val()) 
1187            tmp.val=a.val;
1188        if (do_adval())
1189            FOR_I_EQ_0_LT_NUMDIR
1190                tmp.ADVAL_I=a.ADVAL_I;
1191        if (do_indo()) 
1192            tmp.add_to_pattern( a.get_pattern() );
1193    } else {
1194        if (do_val()) 
1195            tmp.val=b.val;
1196        if (tmp2>0) {
1197            if (do_adval())
1198                FOR_I_EQ_0_LT_NUMDIR
1199                    tmp.ADVAL_I=b.ADVAL_I;
1200            if (do_indo()) 
1201                tmp.add_to_pattern( b.get_pattern() );
1202        } else {
1203            if (do_adval())
1204                FOR_I_EQ_0_LT_NUMDIR
1205                {
1206                    if (a.ADVAL_I<b.ADVAL_I) tmp.ADVAL_I=a.ADVAL_I;
1207                    else tmp.ADVAL_I=b.ADVAL_I;
1208                }
1209            if (do_indo()) {
1210                tmp.add_to_pattern( a.get_pattern() );
1211                tmp.add_to_pattern( b.get_pattern() );
1212
1213            }
1214        }
1215    }
1216    return tmp;
1217}
1218
1219inline adouble fmin (double v, const adouble &a) {
1220    adouble tmp;
1221    if (unlikely(!adouble::_do_val() && (adouble::_do_adval() || adouble::_do_indo()))) {
1222        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1223        throw logic_error("incorrect function call, errorcode=1");
1224    }   
1225    double tmp2=v-a.val;
1226    if (tmp2<0) {
1227        if (do_val()) 
1228            tmp.val=v;
1229        if (do_adval())
1230            FOR_I_EQ_0_LT_NUMDIR
1231                tmp.ADVAL_I=0.0;
1232    } else {
1233        if (do_val()) 
1234            tmp.val=a.val;
1235        if (tmp2>0) {
1236            if (do_adval())
1237                FOR_I_EQ_0_LT_NUMDIR
1238                    tmp.ADVAL_I=a.ADVAL_I;
1239            if (do_indo()) 
1240                tmp.add_to_pattern( a.get_pattern() );
1241        } else {
1242            if (do_adval())
1243                FOR_I_EQ_0_LT_NUMDIR
1244                {
1245                    if (a.ADVAL_I<0) tmp.ADVAL_I=a.ADVAL_I;
1246                    else tmp.ADVAL_I=0.0;
1247                }
1248            if (do_indo()) 
1249                tmp.add_to_pattern( a.get_pattern() );
1250        }
1251    }
1252    return tmp;
1253}
1254
1255inline adouble fmin (const adouble &a, double v) {
1256    adouble tmp;
1257    if (unlikely(!adouble::_do_val() && (adouble::_do_adval() || adouble::_do_indo()))) {
1258        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1259        throw logic_error("incorrect function call, errorcode=1");
1260    }   
1261    double tmp2=a.val-v;
1262    if (tmp2<0) {
1263        if (do_val()) 
1264            tmp.val=a.val;
1265        if (do_adval())
1266            FOR_I_EQ_0_LT_NUMDIR
1267                tmp.ADVAL_I=a.ADVAL_I;
1268        if (do_indo()) 
1269            tmp.add_to_pattern( a.get_pattern() );
1270    } else {
1271        if (do_val()) 
1272            tmp.val=v;
1273        if (tmp2>0) {
1274            if (do_adval())
1275                FOR_I_EQ_0_LT_NUMDIR
1276                    tmp.ADVAL_I=0.0;
1277        } else {
1278            if (do_adval())
1279                FOR_I_EQ_0_LT_NUMDIR
1280                {
1281                    if (a.ADVAL_I<0) tmp.ADVAL_I=a.ADVAL_I;
1282                    else tmp.ADVAL_I=0.0;
1283                }
1284            if (do_indo()) 
1285                tmp.add_to_pattern( a.get_pattern() );
1286        }
1287    }
1288    return tmp;
1289}
1290
1291inline adouble ldexp (const adouble &a, const adouble &b) {
1292    adouble tmp = a*pow(2.,b);
1293    if (do_indo()) {
1294        tmp.add_to_pattern( a.get_pattern() ) ;
1295        tmp.add_to_pattern( b.get_pattern() ) ;
1296    }
1297    return tmp;
1298}
1299
1300inline adouble ldexp (const adouble &a, const double v) {
1301    return a*ADOLC_MATH_NSP::pow(2.,v);
1302}
1303
1304inline adouble ldexp (const double v, const adouble &a) {
1305    adouble tmp = v*pow(2.,a);
1306    if (do_indo()) 
1307        tmp.add_to_pattern( a.get_pattern() ) ;
1308    return tmp;
1309}
1310
1311inline double frexp (const adouble &a, int* v) {
1312    if (no_do_val()) {
1313        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1314        throw logic_error("incorrect function call, errorcode=1");
1315    }   
1316    return ADOLC_MATH_NSP::frexp(a.val, v);
1317}
1318
1319#if defined(ATRIG_ERF)
1320inline adouble erf (const adouble &a) {
1321    adouble tmp;
1322    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
1323        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1324        throw logic_error("incorrect function call, errorcode=1");
1325    }
1326    if (do_val()) 
1327        tmp.val=ADOLC_MATH_NSP_ERF::erf(a.val);
1328    if (likely(adouble::_do_adval() && adouble::_do_val())) {
1329        double tmp2 = 2.0 /
1330            ADOLC_MATH_NSP_ERF::sqrt(ADOLC_MATH_NSP::acos(-1.0)) *
1331            ADOLC_MATH_NSP_ERF::exp(-a.val*a.val);
1332        FOR_I_EQ_0_LT_NUMDIR
1333            tmp.ADVAL_I=tmp2*a.ADVAL_I;
1334    }
1335    if (do_indo()) 
1336        tmp.add_to_pattern( a.get_pattern() ) ;
1337    return tmp;
1338}
1339#endif
1340
1341inline void condassign( adouble &res, const adouble &cond,
1342                        const adouble &arg1, const adouble &arg2 ) {
1343    if (no_do_val()) {
1344        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1345        throw logic_error("incorrect function call, errorcode=1");
1346    }
1347    if (do_val()) {
1348        if (cond.getValue() > 0) 
1349            res = arg1;
1350        else
1351            res = arg2;
1352    }
1353}
1354
1355inline void condassign( adouble &res, const adouble &cond,
1356                        const adouble &arg ) {
1357    if (no_do_val()) {
1358        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1359        throw logic_error("incorrect function call, errorcode=1");
1360    }
1361    if (do_val()) {
1362        if (cond.getValue() > 0) 
1363            res = arg;
1364    }
1365}
1366
1367inline void condeqassign( adouble &res, const adouble &cond,
1368                          const adouble &arg1, const adouble &arg2 ) {
1369    if (no_do_val()) {
1370        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1371        throw logic_error("incorrect function call, errorcode=1");
1372    }
1373    if (do_val()) {
1374        if (cond.getValue() >= 0) 
1375            res = arg1;
1376        else
1377            res = arg2;
1378    }
1379}
1380
1381inline void condeqassign( adouble &res, const adouble &cond,
1382                          const adouble &arg ) {
1383    if (no_do_val()) {
1384        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1385        throw logic_error("incorrect function call, errorcode=1");
1386    }
1387    if (do_val()) {
1388        if (cond.getValue() >= 0) 
1389            res = arg;
1390    }
1391}
1392
1393
1394
1395/*******************  nontemporary results  *********************************/
1396inline adouble& adouble::operator = (const double v) {
1397    if (do_val()) 
1398        val=v;
1399    if (do_adval()) 
1400        FOR_I_EQ_0_LT_NUMDIR
1401            ADVAL_I=0.0;
1402    if (do_indo())
1403        if (!pattern.empty()) pattern.clear();
1404    return *this;
1405}
1406
1407inline adouble& adouble::operator = (const adouble& a) {
1408    if (do_val()) 
1409        val=a.val;
1410    if (do_adval()) 
1411        FOR_I_EQ_0_LT_NUMDIR
1412            ADVAL_I=a.ADVAL_I;
1413    if (do_indo()) {
1414        if (!pattern.empty()) pattern.clear();
1415        add_to_pattern( a.get_pattern() );
1416    }
1417    return *this;
1418}
1419
1420inline adouble& adouble::operator += (const double v) {
1421    if (do_val()) 
1422        val+=v;
1423    return *this;
1424}
1425
1426inline adouble& adouble::operator += (const adouble& a) {
1427    if (do_val()) 
1428        val=val+a.val;
1429    if (do_adval()) 
1430        FOR_I_EQ_0_LT_NUMDIR
1431            ADVAL_I+=a.ADVAL_I;
1432    if (do_indo()) 
1433        add_to_pattern( a.get_pattern() );
1434    return *this;
1435}
1436
1437inline adouble& adouble::operator -= (const double v) {
1438    if (do_val()) 
1439        val-=v;
1440    return *this;
1441}
1442
1443inline adouble& adouble::operator -= (const adouble& a) {
1444    if (do_val()) 
1445        val=val-a.val;
1446    if (do_adval()) 
1447        FOR_I_EQ_0_LT_NUMDIR
1448            ADVAL_I-=a.ADVAL_I;
1449    if (do_indo()) 
1450        add_to_pattern( a.get_pattern() ) ;
1451    return *this;
1452}
1453
1454inline adouble& adouble::operator *= (const double v) {
1455    if (do_val()) 
1456        val=val*v;
1457    if (do_adval()) 
1458        FOR_I_EQ_0_LT_NUMDIR
1459            ADVAL_I*=v;
1460    return *this;
1461}
1462
1463inline adouble& adouble::operator *= (const adouble& a) {
1464    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
1465        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1466        throw logic_error("incorrect function call, errorcode=1");
1467    }
1468    if (likely(adouble::_do_adval() && adouble::_do_val())) 
1469        FOR_I_EQ_0_LT_NUMDIR
1470            ADVAL_I=ADVAL_I*a.val+val*a.ADVAL_I;
1471    if (do_val()) 
1472        val*=a.val;
1473    if (do_indo()) 
1474        add_to_pattern( a.get_pattern() ) ;
1475    return *this;
1476}
1477
1478inline adouble& adouble::operator /= (const double v) {
1479    if (do_val()) 
1480        val/=v;
1481    if (do_adval()) 
1482        FOR_I_EQ_0_LT_NUMDIR
1483            ADVAL_I/=v;
1484    return *this;
1485}
1486
1487inline adouble& adouble::operator /= (const adouble& a) {
1488    if (unlikely(!adouble::_do_val() && adouble::_do_adval())) {
1489        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1490        throw logic_error("incorrect function call, errorcode=1");
1491    }
1492    if (likely(adouble::_do_adval() && adouble::_do_val())) 
1493        FOR_I_EQ_0_LT_NUMDIR
1494            ADVAL_I=(ADVAL_I*a.val-val*a.ADVAL_I)/(a.val*a.val);
1495    if (do_val()) 
1496        val=val/a.val;
1497    if (do_indo()) 
1498        add_to_pattern( a.get_pattern() ) ;
1499    return *this;
1500}
1501
1502// not
1503inline int adouble::operator ! () const {
1504    if (no_do_val()) {
1505        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1506        throw logic_error("incorrect function call, errorcode=1");
1507    }
1508    return val==0.0;
1509}
1510
1511// comparision
1512inline int adouble::operator != (const adouble &a) const {
1513    if (no_do_val()) {
1514        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1515        throw logic_error("incorrect function call, errorcode=1");
1516    }
1517    return val!=a.val;
1518}
1519
1520inline int adouble::operator != (const double v) const {
1521    if (no_do_val()) {
1522        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1523        throw logic_error("incorrect function call, errorcode=1");
1524    }
1525    return val!=v;
1526}
1527
1528inline int operator != (const double v, const adouble &a) {
1529    if (no_do_val()) {
1530        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1531        throw logic_error("incorrect function call, errorcode=1");
1532    }
1533    return v!=a.val;
1534}
1535
1536inline int adouble::operator == (const adouble &a) const {
1537    if (no_do_val()) {
1538        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1539        throw logic_error("incorrect function call, errorcode=1");
1540    }
1541    return val==a.val;
1542}
1543
1544inline int adouble::operator == (const double v) const {
1545    if (no_do_val()) {
1546        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1547        throw logic_error("incorrect function call, errorcode=1");
1548    }
1549    return val==v;
1550}
1551
1552inline int operator == (const double v, const adouble &a) {
1553    if (no_do_val()) {
1554        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1555        throw logic_error("incorrect function call, errorcode=1");
1556    }
1557    return v==a.val;
1558}
1559
1560inline int adouble::operator <= (const adouble &a) const {
1561    if (no_do_val()) {
1562        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1563        throw logic_error("incorrect function call, errorcode=1");
1564    }
1565    return val<=a.val;
1566}
1567
1568inline int adouble::operator <= (const double v) const {
1569    if (no_do_val()) {
1570        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1571        throw logic_error("incorrect function call, errorcode=1");
1572    }
1573    return val<=v;
1574}
1575
1576inline int operator <= (const double v, const adouble &a) {
1577    if (no_do_val()) {
1578        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1579        throw logic_error("incorrect function call, errorcode=1");
1580    }
1581    return v<=a.val;
1582}
1583
1584inline int adouble::operator >= (const adouble &a) const {
1585    if (no_do_val()) {
1586        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1587        throw logic_error("incorrect function call, errorcode=1");
1588    }
1589    return val>=a.val;
1590}
1591
1592inline int adouble::operator >= (const double v) const {
1593    if (no_do_val()) {
1594        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1595        throw logic_error("incorrect function call, errorcode=1");
1596    }
1597    return val>=v;
1598}
1599
1600inline int operator >= (const double v, const adouble &a) {
1601    if (no_do_val()) {
1602        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1603        throw logic_error("incorrect function call, errorcode=1");
1604    }
1605    return v>=a.val;
1606}
1607
1608inline int adouble::operator >  (const adouble &a) const {
1609    if (no_do_val()) {
1610        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1611        throw logic_error("incorrect function call, errorcode=1");
1612    }
1613    return val>a.val;
1614}
1615
1616inline int adouble::operator >  (const double v) const {
1617    if (no_do_val()) {
1618        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1619        throw logic_error("incorrect function call, errorcode=1");
1620    }
1621    return val>v;
1622}
1623
1624inline int operator >  (const double v, const adouble &a) {
1625    if (no_do_val()) {
1626        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1627        throw logic_error("incorrect function call, errorcode=1");
1628    }
1629    return v>a.val;
1630}
1631
1632inline int adouble::operator <  (const adouble &a) const {
1633    if (no_do_val()) {
1634        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1635        throw logic_error("incorrect function call, errorcode=1");
1636    }
1637    return val<a.val;
1638}
1639
1640inline int adouble::operator <  (const double v) const {
1641    if (no_do_val()) {
1642        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1643        throw logic_error("incorrect function call, errorcode=1");
1644    }
1645    return val<v;
1646}
1647
1648inline int operator <  (const double v, const adouble &a) {
1649    if (no_do_val()) {
1650        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1651        throw logic_error("incorrect function call, errorcode=1");
1652    }
1653    return v<a.val;
1654}
1655
1656/*******************  getter / setter  **************************************/
1657inline adouble::operator double const & () {
1658    if (no_do_val()) {
1659        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1660        throw logic_error("incorrect function call, errorcode=1");
1661    }
1662    return val;
1663}
1664
1665inline adouble::operator double && () {
1666    if (no_do_val()) {
1667        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1668        throw logic_error("incorrect function call, errorcode=1");
1669    }
1670    return (double&&)val;
1671}
1672
1673inline adouble::operator double() {
1674    if (no_do_val()) {
1675        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1676        throw logic_error("incorrect function call, errorcode=1");
1677    }
1678    return val;
1679}
1680
1681
1682inline double adouble::getValue() const {
1683    if (no_do_val()) {
1684        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1685        throw logic_error("incorrect function call, errorcode=1");
1686    }
1687    return val;
1688}
1689
1690inline void adouble::setValue(const double v) {
1691    if (no_do_val()) {
1692        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1693        throw logic_error("incorrect function call, errorcode=1");
1694    }
1695    val=v;
1696}
1697
1698inline const double *const adouble::getADValue() const {
1699    if (no_do_adval()) {
1700        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1701        throw logic_error("incorrect function call, errorcode=1");
1702    }
1703    return adval;
1704}
1705
1706inline void adouble::setADValue(const double *const v) {
1707    if (no_do_adval()) {
1708        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1709        throw logic_error("incorrect function call, errorcode=1");
1710    }
1711    FOR_I_EQ_0_LT_NUMDIR
1712    ADVAL_I=V_I;
1713}
1714
1715inline double adouble::getADValue(const unsigned int p) const {
1716    if (no_do_adval()) {
1717        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1718        throw logic_error("incorrect function call, errorcode=1");
1719    }
1720    if (p>=adouble::numDir) 
1721    {
1722        fprintf(DIAG_OUT, "Derivative array accessed out of bounds"\
1723                " while \"getADValue(...)\"!!!\n");
1724        throw logic_error("incorrect function call, errorcode=-1");
1725    }
1726    return adval[p];
1727}
1728
1729inline void adouble::setADValue(const unsigned int p, const double v) {
1730    if (no_do_adval()) {
1731        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1732        throw logic_error("incorrect function call, errorcode=1");
1733    }
1734    if (p>=adouble::numDir) 
1735    {
1736        fprintf(DIAG_OUT, "Derivative array accessed out of bounds"\
1737                " while \"setADValue(...)\"!!!\n");
1738        throw logic_error("incorrect function call, errorcode=-1");
1739    }
1740    adval[p]=v;
1741}
1742
1743inline const list<unsigned int>& adouble::get_pattern() const {
1744    if (no_do_indo()) {
1745        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1746        throw logic_error("incorrect function call, errorcode=1");
1747    }
1748    return pattern;
1749}
1750
1751inline void adouble::delete_pattern() {
1752    if (no_do_indo()) {
1753        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1754        throw logic_error("incorrect function call, errorcode=1");
1755    }
1756    if ( !pattern.empty() )
1757        pattern.clear();
1758}
1759
1760inline void adouble::add_to_pattern(const list<unsigned int>& v) {
1761    if (no_do_indo()) {
1762        fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1763        throw logic_error("incorrect function call, errorcode=1");
1764    }
1765    if (likely( pattern != v)) {
1766        if( !v.empty() ){
1767            list<unsigned int> cv = v;
1768            //pattern.splice(pattern.end(), cv);
1769            pattern.merge(cv);
1770            //if (pattern.size() > refcounter::refcnt) {
1771            //pattern.sort();
1772            pattern.unique();
1773                //}
1774        }
1775    }
1776}
1777
1778inline size_t adouble::get_pattern_size() const {
1779    if (no_do_indo()) {
1780     fprintf(DIAG_OUT, "ADOL-C error: Tapeless: Incorrect mode, call setMode(enum Mode mode)\n");
1781     throw logic_error("incorrect function call, errorcode=1");
1782    }
1783    size_t s=0;
1784    if( !pattern.empty() )
1785      s = pattern.size();
1786    return s;
1787}
1788
1789}
1790#endif
Note: See TracBrowser for help on using the repository browser.