1 /*----------------------------------------------------------------------------
2 This file is borrowed from ADOL-C tapless version and slightly modified.
3 The original information is:
5 ADOL-C -- Automatic Differentiation by Overloading in C++
7 Revision: $Id: adolc.h,v 1.1.1.1 2008/03/05 09:30:37 gdiso Exp $
8 Contents: adouble.h contains the basis for the class of adouble
9 included here are all the possible functions defined on
10 the adouble class. Notice that, as opposed to ealier versions,
11 both the class adub and the class adouble are derived from a base
12 class (badouble). See below for further explanation.
15 Technical University Dresden
16 Department of Mathematics
17 Institute of Scientific Computing
19 The author promises that I can use adouble.h in gss code covered by BSD license.
20 > There is a license problem I should write to you.
21 > My code is covered by BSD license, but ADOLC is CPL. I don't like to
23 > As a resuit, I'd like to get your written permission of using adouble.h
26 Is it OK for you, if I just confirm it in this email? Then:
27 Hereby I confirm that you can use adouble.h for your project.
31 -----> 20041110 kowarz: tapeless (scalar/vector) forward version added
32 20040423 kowarz: adapted to configure - make - make install
33 20000107 olvo: iostream.h instaed of stream.h
34 19991210 olvo: checking the changes
35 19991122 olvo: new op_codes eq_plus_prod eq_min_prod
38 19981201 olvo: last check:
39 - taputil things changed, includes
40 19980820 olvo: new comparison strategy & some inlines
41 19980709 olvo: modified sign operators
42 ----------------------------------------------------------------------------*/
57 //the max number of independent variable may be used by GSS
58 #define NUMBER_DIRECTIONS 18
63 inline PetscScalar
fmin( const PetscScalar
&x
, const PetscScalar
&y
)
68 inline PetscScalar
fmax( const PetscScalar
&x
, const PetscScalar
&y
)
73 inline PetscScalar
fsign(const PetscScalar
&x
)
74 {return x
>0.0? 1.0:-1.0;}
76 inline PetscScalar
makeNaN() {
86 inline AutoDScalar() {}
87 inline AutoDScalar(const PetscScalar v
);
88 inline AutoDScalar(const PetscScalar v
, const PetscScalar
* adv
);
89 inline AutoDScalar(const AutoDScalar
& a
);
91 /******************* temporary results ******************************/
93 inline const AutoDScalar
operator - () const;
94 inline const AutoDScalar
operator + () const;
97 inline const AutoDScalar
operator + (const PetscScalar v
) const;
98 inline const AutoDScalar
operator + (const AutoDScalar
& a
) const;
100 const AutoDScalar
operator + (const PetscScalar v
, const AutoDScalar
& a
);
103 inline const AutoDScalar
operator - (const PetscScalar v
) const;
104 inline const AutoDScalar
operator - (const AutoDScalar
& a
) const;
106 const AutoDScalar
operator - (const PetscScalar v
, const AutoDScalar
& a
);
109 inline const AutoDScalar
operator * (const PetscScalar v
) const;
110 inline const AutoDScalar
operator * (const AutoDScalar
& a
) const;
112 const AutoDScalar
operator * (const PetscScalar v
, const AutoDScalar
& a
);
115 inline const AutoDScalar
operator / (const PetscScalar v
) const;
116 inline const AutoDScalar
operator / (const AutoDScalar
& a
) const;
118 const AutoDScalar
operator / (const PetscScalar v
, const AutoDScalar
& a
);
121 inline const AutoDScalar
operator ++ ();
122 inline const AutoDScalar
operator ++ (int);
123 inline const AutoDScalar
operator -- ();
124 inline const AutoDScalar
operator -- (int);
127 inline friend const AutoDScalar
tan(const AutoDScalar
&a
);
128 inline friend const AutoDScalar
exp(const AutoDScalar
&a
);
129 inline friend const AutoDScalar
log(const AutoDScalar
&a
);
130 inline friend const AutoDScalar
sqrt(const AutoDScalar
&a
);
131 inline friend const AutoDScalar
sin(const AutoDScalar
&a
);
132 inline friend const AutoDScalar
cos(const AutoDScalar
&a
);
133 inline friend const AutoDScalar
asin(const AutoDScalar
&a
);
134 inline friend const AutoDScalar
acos(const AutoDScalar
&a
);
135 inline friend const AutoDScalar
atan(const AutoDScalar
&a
);
137 inline friend const AutoDScalar
atan2(const AutoDScalar
&a
, const AutoDScalar
&b
);
138 inline friend const AutoDScalar
pow(const AutoDScalar
&a
, PetscScalar v
);
139 inline friend const AutoDScalar
pow(const AutoDScalar
&a
, const AutoDScalar
&b
);
140 inline friend const AutoDScalar
pow(PetscScalar v
, const AutoDScalar
&a
);
141 inline friend const AutoDScalar
log10(const AutoDScalar
&a
);
143 inline friend const AutoDScalar
sinh (const AutoDScalar
&a
);
144 inline friend const AutoDScalar
cosh (const AutoDScalar
&a
);
145 inline friend const AutoDScalar
tanh (const AutoDScalar
&a
);
146 #if defined(ATRIG_ERF)
147 inline friend const AutoDScalar
asinh (const AutoDScalar
&a
);
148 inline friend const AutoDScalar
acosh (const AutoDScalar
&a
);
149 inline friend const AutoDScalar
atanh (const AutoDScalar
&a
);
151 inline friend const AutoDScalar
fabs (const AutoDScalar
&a
);
152 inline friend const AutoDScalar
ceil (const AutoDScalar
&a
);
153 inline friend const AutoDScalar
floor (const AutoDScalar
&a
);
154 inline friend const AutoDScalar
fmax (const AutoDScalar
&a
, const AutoDScalar
&b
);
155 inline friend const AutoDScalar
fmax (PetscScalar v
, const AutoDScalar
&a
);
156 inline friend const AutoDScalar
fmax (const AutoDScalar
&a
, PetscScalar v
);
157 inline friend const AutoDScalar
fmin (const AutoDScalar
&a
, const AutoDScalar
&b
);
158 inline friend const AutoDScalar
fmin (PetscScalar v
, const AutoDScalar
&a
);
159 inline friend const AutoDScalar
fmin (const AutoDScalar
&a
, PetscScalar v
);
160 inline friend const AutoDScalar
ldexp (const AutoDScalar
&a
, const AutoDScalar
&b
);
161 inline friend const AutoDScalar
ldexp (const AutoDScalar
&a
, const PetscScalar v
);
162 inline friend const AutoDScalar
ldexp (const PetscScalar v
, const AutoDScalar
&a
);
163 inline friend PetscScalar
frexp (const AutoDScalar
&a
, int* v
);
164 #if defined(ATRIG_ERF)
165 inline friend const AutoDScalar
erf (const AutoDScalar
&a
);
169 /******************* nontemporary results ***************************/
171 inline void operator = (const PetscScalar v
);
172 inline void operator = (const AutoDScalar
& a
);
175 inline void operator += (const PetscScalar v
);
176 inline void operator += (const AutoDScalar
& a
);
179 inline void operator -= (const PetscScalar v
);
180 inline void operator -= (const AutoDScalar
& a
);
183 inline void operator *= (const PetscScalar v
);
184 inline void operator *= (const AutoDScalar
& a
);
187 inline void operator /= (const PetscScalar v
);
188 inline void operator /= (const AutoDScalar
& a
);
191 inline int operator ! () const;
194 inline int operator != (const AutoDScalar
&) const;
195 inline int operator != (const PetscScalar
) const;
196 inline friend int operator != (const PetscScalar
, const AutoDScalar
&);
198 inline int operator == (const AutoDScalar
&) const;
199 inline int operator == (const PetscScalar
) const;
200 inline friend int operator == (const PetscScalar
, const AutoDScalar
&);
202 inline int operator <= (const AutoDScalar
&) const;
203 inline int operator <= (const PetscScalar
) const;
204 inline friend int operator <= (const PetscScalar
, const AutoDScalar
&);
206 inline int operator >= (const AutoDScalar
&) const;
207 inline int operator >= (const PetscScalar
) const;
208 inline friend int operator >= (const PetscScalar
, const AutoDScalar
&);
210 inline int operator > (const AutoDScalar
&) const;
211 inline int operator > (const PetscScalar
) const;
212 inline friend int operator > (const PetscScalar
, const AutoDScalar
&);
214 inline int operator < (const AutoDScalar
&) const;
215 inline int operator < (const PetscScalar
) const;
216 inline friend int operator < (const PetscScalar
, const AutoDScalar
&);
218 /******************* getter / setter ********************************/
219 inline PetscScalar
getValue() const;
220 inline void setValue(const PetscScalar v
);
221 inline const PetscScalar
* getADValue() const;
222 inline void setADValue(const PetscScalar
* v
);
223 #if defined(NUMBER_DIRECTIONS)
224 inline PetscScalar
getADValue(const unsigned int p
) const;
225 inline void setADValue(const unsigned int p
, const PetscScalar v
);
228 /******************* i/o operations *********************************/
229 inline friend ostream
& operator << ( ostream
&, const AutoDScalar
& );
230 inline friend istream
& operator >> ( istream
&, AutoDScalar
& );
232 static unsigned int numdir
;
233 static void setNumDir(const unsigned int p
)
235 if (p
>NUMBER_DIRECTIONS
) numdir
=NUMBER_DIRECTIONS
;
240 // internal variables
243 PetscScalar adval
[NUMBER_DIRECTIONS
];
246 /******************************* ctors ************************************/
247 AutoDScalar::AutoDScalar(const PetscScalar v
) : val(v
) {
248 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
252 AutoDScalar::AutoDScalar(const PetscScalar v
, const PetscScalar
* adv
) : val(v
) {
253 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
257 AutoDScalar::AutoDScalar(const AutoDScalar
& a
) : val(a
.val
) {
258 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
259 adval
[_i
]=a
.adval
[_i
];
262 /************************* temporary results ******************************/
264 const AutoDScalar
AutoDScalar::operator - () const {
267 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
268 tmp
.adval
[_i
]=-adval
[_i
];
272 const AutoDScalar
AutoDScalar::operator + () const {
277 const AutoDScalar
AutoDScalar::operator + (const PetscScalar v
) const {
278 return AutoDScalar(val
+v
, adval
);
281 const AutoDScalar
AutoDScalar::operator + (const AutoDScalar
& a
) const {
284 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
285 tmp
.adval
[_i
]=adval
[_i
]+a
.adval
[_i
];
289 const AutoDScalar
operator + (const PetscScalar v
, const AutoDScalar
& a
) {
290 return AutoDScalar(v
+a
.val
, a
.adval
);
294 const AutoDScalar
AutoDScalar::operator - (const PetscScalar v
) const {
295 return AutoDScalar(val
-v
, adval
);
298 const AutoDScalar
AutoDScalar::operator - (const AutoDScalar
& a
) const {
301 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
302 tmp
.adval
[_i
]=adval
[_i
]-a
.adval
[_i
];
306 const AutoDScalar
operator - (const PetscScalar v
, const AutoDScalar
& a
) {
309 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
310 tmp
.adval
[_i
]=-a
.adval
[_i
];
315 const AutoDScalar
AutoDScalar::operator * (const PetscScalar v
) const {
318 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
319 tmp
.adval
[_i
]=adval
[_i
]*v
;
323 const AutoDScalar
AutoDScalar::operator * (const AutoDScalar
& a
) const {
326 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
327 tmp
.adval
[_i
]=adval
[_i
]*a
.val
+val
*a
.adval
[_i
];
331 const AutoDScalar
operator * (const PetscScalar v
, const AutoDScalar
& a
) {
334 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
335 tmp
.adval
[_i
]=v
*a
.adval
[_i
];
340 const AutoDScalar
AutoDScalar::operator / (const PetscScalar v
) const {
344 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
345 tmp
.adval
[_i
]=adval
[_i
]*t
;
349 const AutoDScalar
AutoDScalar::operator / (const AutoDScalar
& a
) const {
352 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
353 tmp
.adval
[_i
]=(adval
[_i
]*a
.val
-val
*a
.adval
[_i
])/a
.val
/a
.val
;
357 const AutoDScalar
operator / (const PetscScalar v
, const AutoDScalar
& a
) {
360 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
361 tmp
.adval
[_i
]=(-v
*a
.adval
[_i
])/a
.val
/a
.val
;
366 const AutoDScalar
AutoDScalar::operator ++ () {
371 const AutoDScalar
AutoDScalar::operator ++ (int) {
374 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
375 tmp
.adval
[_i
]=adval
[_i
];
379 const AutoDScalar
AutoDScalar::operator -- () {
384 const AutoDScalar
AutoDScalar::operator -- (int) {
387 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
388 tmp
.adval
[_i
]=adval
[_i
];
393 const AutoDScalar
tan(const AutoDScalar
& a
) {
396 tmp
.val
=::tan(a
.val
);
399 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
400 tmp
.adval
[_i
]=a
.adval
[_i
]/tmp2
;
404 const AutoDScalar
exp(const AutoDScalar
&a
) {
406 tmp
.val
=::exp(a
.val
);
407 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
408 tmp
.adval
[_i
]=tmp
.val
*a
.adval
[_i
];
412 const AutoDScalar
log(const AutoDScalar
&a
) {
414 tmp
.val
=::log(a
.val
);
415 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
416 if (a
.val
>0 || a
.val
==0 && a
.adval
[_i
]>=0) tmp
.adval
[_i
]=a
.adval
[_i
]/a
.val
;
417 else tmp
.adval
[_i
]=makeNaN();
421 const AutoDScalar
sqrt(const AutoDScalar
&a
) {
423 tmp
.val
=::sqrt(a
.val
);
424 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
425 if (a
.val
>0 || a
.val
==0 && a
.adval
[_i
]>=0) tmp
.adval
[_i
]=a
.adval
[_i
]/tmp
.val
/2;
426 else tmp
.adval
[_i
]=makeNaN();
430 const AutoDScalar
sin(const AutoDScalar
&a
) {
433 tmp
.val
=::sin(a
.val
);
435 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
436 tmp
.adval
[_i
]=tmp2
*a
.adval
[_i
];
440 const AutoDScalar
cos(const AutoDScalar
&a
) {
443 tmp
.val
=::cos(a
.val
);
445 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
446 tmp
.adval
[_i
]=tmp2
*a
.adval
[_i
];
450 const AutoDScalar
asin(const AutoDScalar
&a
) {
452 tmp
.val
=::asin(a
.val
);
453 PetscScalar tmp2
=::sqrt(1-a
.val
*a
.val
);
454 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
455 tmp
.adval
[_i
]=a
.adval
[_i
]/tmp2
;
459 const AutoDScalar
acos(const AutoDScalar
&a
) {
461 tmp
.val
=::acos(a
.val
);
462 PetscScalar tmp2
=-::sqrt(1-a
.val
*a
.val
);
463 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
464 tmp
.adval
[_i
]=a
.adval
[_i
]/tmp2
;
468 const AutoDScalar
atan(const AutoDScalar
&a
) {
470 tmp
.val
=::atan(a
.val
);
471 PetscScalar tmp2
=1+a
.val
*a
.val
;
474 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
475 tmp
.adval
[_i
]=a
.adval
[_i
]*tmp2
;
477 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
482 const AutoDScalar
atan2(const AutoDScalar
&a
, const AutoDScalar
&b
) {
484 tmp
.val
=::atan2(a
.val
, b
.val
);
485 PetscScalar tmp2
=a
.val
*a
.val
;
486 PetscScalar tmp3
=b
.val
*b
.val
;
487 PetscScalar tmp4
=tmp3
/(tmp2
+tmp3
);
489 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
490 tmp
.adval
[_i
]=(a
.adval
[_i
]*b
.val
-a
.val
*b
.adval
[_i
])/tmp3
*tmp4
;
492 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
497 const AutoDScalar
pow(const AutoDScalar
&a
, PetscScalar v
) {
499 tmp
.val
=::pow(a
.val
, v
);
500 PetscScalar tmp2
=v
*::pow(a
.val
, v
-1);
501 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
502 tmp
.adval
[_i
]=tmp2
*a
.adval
[_i
];
506 const AutoDScalar
pow(const AutoDScalar
&a
, const AutoDScalar
&b
) {
508 tmp
.val
=::pow(a
.val
, b
.val
);
509 PetscScalar tmp2
=b
.val
*::pow(a
.val
, b
.val
-1);
510 PetscScalar tmp3
=::log(a
.val
)*tmp
.val
;
511 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
512 tmp
.adval
[_i
]=tmp2
*a
.adval
[_i
]+tmp3
*b
.adval
[_i
];
516 const AutoDScalar
pow(PetscScalar v
, const AutoDScalar
&a
) {
518 tmp
.val
=::pow(v
, a
.val
);
519 PetscScalar tmp2
=tmp
.val
*::log(v
);
520 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
521 tmp
.adval
[_i
]=tmp2
*a
.adval
[_i
];
525 const AutoDScalar
log10(const AutoDScalar
&a
) {
527 tmp
.val
=::log10(a
.val
);
528 PetscScalar tmp2
=::log((PetscScalar
)10)*a
.val
;
529 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
530 tmp
.adval
[_i
]=a
.adval
[_i
]/tmp2
;
534 const AutoDScalar
sinh (const AutoDScalar
&a
) {
536 tmp
.val
=::sinh(a
.val
);
537 PetscScalar tmp2
=::cosh(a
.val
);
538 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
539 tmp
.adval
[_i
]=a
.adval
[_i
]*tmp2
;
543 const AutoDScalar
cosh (const AutoDScalar
&a
) {
545 tmp
.val
=::cosh(a
.val
);
546 PetscScalar tmp2
=::sinh(a
.val
);
547 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
548 tmp
.adval
[_i
]=a
.adval
[_i
]*tmp2
;
552 const AutoDScalar
tanh (const AutoDScalar
&a
) {
554 tmp
.val
=::tanh(a
.val
);
555 PetscScalar tmp2
=::cosh(a
.val
);
557 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
558 tmp
.adval
[_i
]=a
.adval
[_i
]/tmp2
;
562 #if defined(ATRIG_ERF)
563 const AutoDScalar
asinh (const AutoDScalar
&a
) {
565 tmp
.val
=::asinh(a
.val
);
566 PetscScalar tmp2
=::sqrt(a
.val
*a
.val
+1);
567 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
568 tmp
.adval
[_i
]=a
.adval
[_i
]/tmp2
;
572 const AutoDScalar
acosh (const AutoDScalar
&a
) {
574 tmp
.val
=::acosh(a
.val
);
575 PetscScalar tmp2
=::sqrt(a
.val
*a
.val
-1);
576 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
577 tmp
.adval
[_i
]=a
.adval
[_i
]/tmp2
;
581 const AutoDScalar
atanh (const AutoDScalar
&a
) {
583 tmp
.val
=::atanh(a
.val
);
584 PetscScalar tmp2
=1-a
.val
*a
.val
;
585 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
586 tmp
.adval
[_i
]=a
.adval
[_i
]/tmp2
;
591 const AutoDScalar
fabs (const AutoDScalar
&a
) {
593 tmp
.val
=::fabs(a
.val
);
598 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
599 tmp
.adval
[_i
]=a
.adval
[_i
]*as
;
601 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
) {
603 if (a
.adval
[_i
]>0) as
=1;
604 if (a
.adval
[_i
]<0) as
=-1;
605 tmp
.adval
[_i
]=a
.adval
[_i
]*as
;
610 const AutoDScalar
ceil (const AutoDScalar
&a
) {
612 tmp
.val
=::ceil(a
.val
);
613 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
618 const AutoDScalar
floor (const AutoDScalar
&a
) {
620 tmp
.val
=::floor(a
.val
);
621 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
626 const AutoDScalar
fmax (const AutoDScalar
&a
, const AutoDScalar
&b
) {
628 PetscScalar tmp2
=a
.val
-b
.val
;
631 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
632 tmp
.adval
[_i
]=b
.adval
[_i
];
636 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
637 tmp
.adval
[_i
]=a
.adval
[_i
];
639 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
641 if (a
.adval
[_i
]<b
.adval
[_i
]) tmp
.adval
[_i
]=b
.adval
[_i
];
642 else tmp
.adval
[_i
]=a
.adval
[_i
];
649 const AutoDScalar
fmax (PetscScalar v
, const AutoDScalar
&a
) {
651 PetscScalar tmp2
=v
-a
.val
;
654 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
655 tmp
.adval
[_i
]=a
.adval
[_i
];
659 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
662 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
664 if (a
.adval
[_i
]>0) tmp
.adval
[_i
]=a
.adval
[_i
];
665 else tmp
.adval
[_i
]=0.0;
672 const AutoDScalar
fmax (const AutoDScalar
&a
, PetscScalar v
) {
674 PetscScalar tmp2
=a
.val
-v
;
677 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
682 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
683 tmp
.adval
[_i
]=a
.adval
[_i
];
685 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
687 if (a
.adval
[_i
]>0) tmp
.adval
[_i
]=a
.adval
[_i
];
688 else tmp
.adval
[_i
]=0.0;
695 const AutoDScalar
fmin (const AutoDScalar
&a
, const AutoDScalar
&b
) {
697 PetscScalar tmp2
=a
.val
-b
.val
;
700 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
701 tmp
.adval
[_i
]=a
.adval
[_i
];
705 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
706 tmp
.adval
[_i
]=b
.adval
[_i
];
708 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
710 if (a
.adval
[_i
]<b
.adval
[_i
]) tmp
.adval
[_i
]=a
.adval
[_i
];
711 else tmp
.adval
[_i
]=b
.adval
[_i
];
718 const AutoDScalar
fmin (PetscScalar v
, const AutoDScalar
&a
) {
720 PetscScalar tmp2
=v
-a
.val
;
723 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
728 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
729 tmp
.adval
[_i
]=a
.adval
[_i
];
731 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
733 if (a
.adval
[_i
]<0) tmp
.adval
[_i
]=a
.adval
[_i
];
734 else tmp
.adval
[_i
]=0.0;
741 const AutoDScalar
fmin (const AutoDScalar
&a
, PetscScalar v
) {
743 PetscScalar tmp2
=a
.val
-v
;
746 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
747 tmp
.adval
[_i
]=a
.adval
[_i
];
751 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
754 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
756 if (a
.adval
[_i
]<0) tmp
.adval
[_i
]=a
.adval
[_i
];
757 else tmp
.adval
[_i
]=0.0;
764 const AutoDScalar
ldexp (const AutoDScalar
&a
, const AutoDScalar
&b
) {
768 const AutoDScalar
ldexp (const AutoDScalar
&a
, const PetscScalar v
) {
769 return a
*::pow(2.,v
);
772 const AutoDScalar
ldexp (const PetscScalar v
, const AutoDScalar
&a
) {
776 PetscScalar
frexp (const AutoDScalar
&a
, int* v
) {
777 return ::frexp(a
.val
, v
);
780 #if defined(ATRIG_ERF)
781 const AutoDScalar
erf (const AutoDScalar
&a
) {
783 tmp
.val
=::erf(a
.val
);
784 PetscScalar tmp2
=2.0/::sqrt(::acos(-1.0))*::exp(-a
.val
*a
.val
);
785 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
786 tmp
.adval
[_i
]=tmp2
*a
.adval
[_i
];
792 /******************* nontemporary results *********************************/
793 void AutoDScalar::operator = (const PetscScalar v
) {
795 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
799 void AutoDScalar::operator = (const AutoDScalar
& a
) {
801 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
802 adval
[_i
]=a
.adval
[_i
];
805 void AutoDScalar::operator += (const PetscScalar v
) {
809 void AutoDScalar::operator += (const AutoDScalar
& a
) {
811 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
812 adval
[_i
]+=a
.adval
[_i
];
815 void AutoDScalar::operator -= (const PetscScalar v
) {
819 void AutoDScalar::operator -= (const AutoDScalar
& a
) {
821 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
822 adval
[_i
]-=a
.adval
[_i
];
825 void AutoDScalar::operator *= (const PetscScalar v
) {
827 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
831 void AutoDScalar::operator *= (const AutoDScalar
& a
) {
832 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
833 adval
[_i
]=adval
[_i
]*a
.val
+val
*a
.adval
[_i
];
837 void AutoDScalar::operator /= (const PetscScalar v
) {
839 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
843 void AutoDScalar::operator /= (const AutoDScalar
& a
) {
844 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
845 adval
[_i
]=(adval
[_i
]*a
.val
-val
*a
.adval
[_i
])/a
.val
/a
.val
;
850 int AutoDScalar::operator ! () const {
855 int AutoDScalar::operator != (const AutoDScalar
&a
) const {
859 int AutoDScalar::operator != (const PetscScalar v
) const {
863 int operator != (const PetscScalar v
, const AutoDScalar
&a
) {
867 int AutoDScalar::operator == (const AutoDScalar
&a
) const {
871 int AutoDScalar::operator == (const PetscScalar v
) const {
875 int operator == (const PetscScalar v
, const AutoDScalar
&a
) {
879 int AutoDScalar::operator <= (const AutoDScalar
&a
) const {
883 int AutoDScalar::operator <= (const PetscScalar v
) const {
887 int operator <= (const PetscScalar v
, const AutoDScalar
&a
) {
891 int AutoDScalar::operator >= (const AutoDScalar
&a
) const {
895 int AutoDScalar::operator >= (const PetscScalar v
) const {
899 int operator >= (const PetscScalar v
, const AutoDScalar
&a
) {
903 int AutoDScalar::operator > (const AutoDScalar
&a
) const {
907 int AutoDScalar::operator > (const PetscScalar v
) const {
911 int operator > (const PetscScalar v
, const AutoDScalar
&a
) {
915 int AutoDScalar::operator < (const AutoDScalar
&a
) const {
919 int AutoDScalar::operator < (const PetscScalar v
) const {
923 int operator < (const PetscScalar v
, const AutoDScalar
&a
) {
927 /******************* getter / setter **************************************/
928 PetscScalar
AutoDScalar::getValue() const {
932 void AutoDScalar::setValue(const PetscScalar v
) {
936 const PetscScalar
* AutoDScalar::getADValue() const {
940 void AutoDScalar::setADValue(const PetscScalar
* v
) {
941 for (unsigned int _i
=0; _i
<numdir
; ++_i
)
945 # if defined(NUMBER_DIRECTIONS)
946 PetscScalar
AutoDScalar::getADValue(const unsigned int p
) const {
947 if (p
>=NUMBER_DIRECTIONS
) {
948 fprintf(stdout
, "Derivative array accessed out of bounds"\
949 " while \"getADValue(...)\"!!!\n");
955 void AutoDScalar::setADValue(const unsigned int p
, const PetscScalar v
) {
956 if (p
>=NUMBER_DIRECTIONS
) {
957 fprintf(stdout
, "Derivative array accessed out of bounds"\
958 " while \"setADValue(...)\"!!!\n");
965 /******************* i/o operations ***************************************/
966 ostream
& operator << ( ostream
& out
, const AutoDScalar
& a
) {
967 out
<< "Value: " << a
.val
;
968 #if !defined(NUMBER_DIRECTIONS)
971 out
<< " ADValues (" << AutoDScalar::numdir
<< "): ";
973 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
974 out
<< a
.adval
[_i
] << " ";
979 istream
& operator >> ( istream
& in
, AutoDScalar
& a
) {
983 } while (c
!=':' && !in
.eof());
985 #if !defined(NUMBER_DIRECTIONS)
987 while (c
!=':' && !in
.eof());
991 while (c
!='(' && !in
.eof());
993 if (num
>NUMBER_DIRECTIONS
) {
994 cout
<< "ADOL-C error: to many directions in input\n";
998 while (c
!=')' && !in
.eof());
1000 for (unsigned int _i
=0; _i
<AutoDScalar::numdir
; ++_i
)
1003 while (c
!=')' && !in
.eof());