1 #ifndef FILE_AUTODIFFDIFF 2 #define FILE_AUTODIFFDIFF 21 template <
int D,
typename SCAL =
double>
39 for (
int i = 0; i < D; i++)
40 dval[i] = ad2.dval[i];
41 for (
int i = 0; i < D*D; i++)
42 ddval[i] = ad2.ddval[i];
49 for (
int i = 0; i < D; i++)
51 for (
int i = 0; i < D*D; i++)
59 for (
int i = 0; i < D; i++)
60 dval[i] = ad2.DValue(i);
61 for (
int i = 0; i < D*D; i++)
69 for (
int i = 0; i < D; i++)
71 for (
int i = 0; i < D*D; i++)
80 for (
int i = 0; i < D*D; i++)
84 INLINE
AutoDiffDiff (SCAL aval,
const SCAL * grad,
const SCAL * hesse)
95 for (
int i = 0; i < D; i++)
97 for (
int i = 0; i < D*D; i++)
102 INLINE
void StoreGradient (SCAL * p)
const 104 for (
int i = 0; i < D; i++)
108 INLINE
void LoadGradient (
const SCAL * p)
110 for (
int i = 0; i < D; i++)
114 INLINE
void StoreHessian (SCAL * p)
const 116 for (
int i = 0; i < D*D; i++)
120 INLINE
void LoadHessian (
const SCAL * p)
122 for (
int i = 0; i < D*D; i++)
127 SCAL
Value()
const throw() {
return val; }
130 SCAL
DValue (
int i)
const throw() {
return dval[i]; }
135 for (
int j = 0; j < D; j++)
136 r.DValue(j) = ddval[i*D+j];
141 SCAL
DDValue (
int i)
const throw() {
return ddval[i]; }
144 SCAL
DDValue (
int i,
int j)
const throw() {
return ddval[i*D+j]; }
147 SCAL &
Value() throw() {
return val; }
150 SCAL &
DValue (
int i)
throw() {
return dval[i]; }
153 SCAL &
DDValue (
int i)
throw() {
return ddval[i]; }
156 SCAL &
DDValue (
int i,
int j)
throw() {
return ddval[i*D+j]; }
165 for (
int i = 0; i < D; i++)
166 dval[i] += y.dval[i];
167 for (
int i = 0; i < D*D; i++)
168 ddval[i] += y.ddval[i];
176 for (
int i = 0; i < D; i++)
177 dval[i] -= y.dval[i];
178 for (
int i = 0; i < D*D; i++)
179 ddval[i] -= y.ddval[i];
186 for (
int i = 0; i < D*D; i++)
187 ddval[i] = val * y.ddval[i] + y.val * ddval[i];
189 for (
int i = 0; i < D; i++)
190 for (
int j = 0; j < D; j++)
191 ddval[i*D+j] += dval[i] * y.dval[j] + dval[j] * y.dval[i];
193 for (
int i = 0; i < D; i++)
196 dval[i] += val * y.dval[i];
205 for (
int i = 0; i < D*D; i++ )
207 for (
int i = 0; i < D; i++)
217 for (
int i = 0; i < D*D; i++ )
219 for (
int i = 0; i < D; i++)
254 template<
int D,
typename SCAL>
257 ost << x.
Value() <<
", D = ";
258 for (
int i = 0; i < D; i++)
259 ost << x.
DValue(i) <<
" ";
261 for (
int i = 0; i < D*D; i++)
267 template<
int D,
typename SCAL>
268 inline AutoDiffDiff<D, SCAL> operator+ (
const AutoDiffDiff<D, SCAL> & x,
const AutoDiffDiff<D, SCAL> & y)
throw()
270 AutoDiffDiff<D, SCAL> res;
271 res.Value () = x.Value()+y.Value();
272 for (
int i = 0; i < D; i++)
273 res.DValue(i) = x.DValue(i) + y.DValue(i);
274 for (
int i = 0; i < D*D; i++)
275 res.DDValue(i) = x.DDValue(i) + y.DDValue(i);
281 template<
int D,
typename SCAL>
282 inline AutoDiffDiff<D, SCAL> operator- (
const AutoDiffDiff<D, SCAL> & x,
const AutoDiffDiff<D, SCAL> & y)
throw()
284 AutoDiffDiff<D, SCAL> res;
285 res.Value() = x.Value()-y.Value();
286 for (
int i = 0; i < D; i++)
287 res.DValue(i) = x.DValue(i) - y.DValue(i);
288 for (
int i = 0; i < D*D; i++)
289 res.DDValue(i) = x.DDValue(i) - y.DDValue(i);
295 template<
int D,
typename SCAL,
typename SCAL2,
296 typename std::enable_if<std::is_convertible<SCAL2,SCAL>::value,
int>::type = 0>
297 inline AutoDiffDiff<D, SCAL> operator+ (SCAL2 x,
const AutoDiffDiff<D, SCAL> & y)
throw()
299 AutoDiffDiff<D, SCAL> res;
300 res.Value() = x+y.Value();
301 for (
int i = 0; i < D; i++)
302 res.DValue(i) = y.DValue(i);
303 for (
int i = 0; i < D*D; i++)
304 res.DDValue(i) = y.DDValue(i);
309 template<
int D,
typename SCAL,
typename SCAL2,
310 typename std::enable_if<std::is_convertible<SCAL2,SCAL>::value,
int>::type = 0>
311 inline AutoDiffDiff<D, SCAL> operator+ (
const AutoDiffDiff<D, SCAL> & y, SCAL2 x)
throw()
313 AutoDiffDiff<D, SCAL> res;
314 res.Value() = x+y.Value();
315 for (
int i = 0; i < D; i++)
316 res.DValue(i) = y.DValue(i);
317 for (
int i = 0; i < D*D; i++)
318 res.DDValue(i) = y.DDValue(i);
324 template<
int D,
typename SCAL>
325 inline AutoDiffDiff<D, SCAL> operator- (
const AutoDiffDiff<D, SCAL> & x)
throw()
327 AutoDiffDiff<D, SCAL> res;
328 res.Value() = -x.Value();
329 for (
int i = 0; i < D; i++)
330 res.DValue(i) = -x.DValue(i);
331 for (
int i = 0; i < D*D; i++)
332 res.DDValue(i) = -x.DDValue(i);
337 template<
int D,
typename SCAL,
typename SCAL2,
338 typename std::enable_if<std::is_convertible<SCAL2,SCAL>::value,
int>::type = 0>
339 inline AutoDiffDiff<D, SCAL> operator- (
const AutoDiffDiff<D, SCAL> & x, SCAL2 y)
throw()
341 AutoDiffDiff<D, SCAL> res;
342 res.Value() = x.Value()-y;
343 for (
int i = 0; i < D; i++)
344 res.DValue(i) = x.DValue(i);
345 for (
int i = 0; i < D*D; i++)
346 res.DDValue(i) = x.DDValue(i);
351 template<
int D,
typename SCAL,
typename SCAL2,
352 typename std::enable_if<std::is_convertible<SCAL2,SCAL>::value,
int>::type = 0>
353 inline AutoDiffDiff<D, SCAL> operator- (SCAL2 x,
const AutoDiffDiff<D, SCAL> & y)
throw()
355 AutoDiffDiff<D, SCAL> res;
356 res.Value() = x-y.Value();
357 for (
int i = 0; i < D; i++)
358 res.DValue(i) = -y.DValue(i);
359 for (
int i = 0; i < D*D; i++)
360 res.DDValue(i) = -y.DDValue(i);
366 template<
int D,
typename SCAL,
typename SCAL2,
367 typename std::enable_if<std::is_convertible<SCAL2,SCAL>::value,
int>::type = 0>
368 inline AutoDiffDiff<D, SCAL> operator* (SCAL2 x,
const AutoDiffDiff<D, SCAL> & y)
throw()
370 AutoDiffDiff<D, SCAL> res;
371 res.Value() = x*y.Value();
372 for (
int i = 0; i < D; i++)
373 res.DValue(i) = x*y.DValue(i);
374 for (
int i = 0; i < D*D; i++)
375 res.DDValue(i) = x*y.DDValue(i);
380 template<
int D,
typename SCAL,
typename SCAL2,
381 typename std::enable_if<std::is_convertible<SCAL2,SCAL>::value,
int>::type = 0>
382 inline AutoDiffDiff<D, SCAL> operator* (
const AutoDiffDiff<D, SCAL> & y, SCAL2 x)
throw()
384 AutoDiffDiff<D, SCAL> res;
385 res.Value() = x*y.Value();
386 for (
int i = 0; i < D; i++)
387 res.DValue(i) = x*y.DValue(i);
388 for (
int i = 0; i < D*D; i++)
389 res.DDValue(i) = x*y.DDValue(i);
394 template<
int D,
typename SCAL>
395 inline AutoDiffDiff<D, SCAL> operator* (
const AutoDiffDiff<D, SCAL> & x,
const AutoDiffDiff<D, SCAL> & y)
throw()
397 AutoDiffDiff<D, SCAL> res;
402 for (
int i = 0; i < D; i++)
403 res.DValue(i) = hx*y.DValue(i) + hy*x.DValue(i);
405 for (
int i = 0; i < D; i++)
406 for (
int j = 0; j < D; j++)
407 res.DDValue(i,j) = hx * y.DDValue(i,j) + hy * x.DDValue(i,j)
408 + x.DValue(i) * y.DValue(j) + x.DValue(j) * y.DValue(i);
415 template<
int D,
typename SCAL>
416 inline AutoDiffDiff<D, SCAL> Inv (
const AutoDiffDiff<D, SCAL> & x)
418 AutoDiffDiff<D, SCAL> res(1.0 / x.Value());
419 for (
int i = 0; i < D; i++)
420 res.DValue(i) = -x.DValue(i) / (x.Value() * x.Value());
422 SCAL fac1 = 2/(x.Value()*x.Value()*x.Value());
423 SCAL fac2 = 1/
sqr(x.Value());
424 for (
int i = 0; i < D; i++)
425 for (
int j = 0; j < D; j++)
426 res.DDValue(i,j) = fac1*x.DValue(i)*x.DValue(j) - fac2*x.DDValue(i,j);
431 template<
int D,
typename SCAL>
432 inline AutoDiffDiff<D, SCAL> operator/ (
const AutoDiffDiff<D, SCAL> & x,
const AutoDiffDiff<D, SCAL> & y)
437 template<
int D,
typename SCAL,
typename SCAL2,
438 typename std::enable_if<std::is_convertible<SCAL2,SCAL>::value,
int>::type = 0>
439 inline AutoDiffDiff<D, SCAL> operator/ (
const AutoDiffDiff<D, SCAL> & x, SCAL2 y)
444 template<
int D,
typename SCAL,
typename SCAL2,
445 typename std::enable_if<std::is_convertible<SCAL2,SCAL>::value,
int>::type = 0>
446 inline AutoDiffDiff<D, SCAL> operator/ (SCAL2 x,
const AutoDiffDiff<D, SCAL> & y)
452 template<
int D,
typename SCAL>
453 inline AutoDiffDiff<D, SCAL> sqrt (
const AutoDiffDiff<D, SCAL> & x)
455 AutoDiffDiff<D, SCAL> res;
456 res.Value() = sqrt(x.Value());
457 for (
int j = 0; j < D; j++)
458 res.DValue(j) = IfZero(x.DValue(j),0.,0.5 / res.Value() * x.DValue(j));
461 for (
int i = 0; i < D; i++)
462 for (
int j = 0; j < D; j++)
463 res.DDValue(i,j) = IfZero(x.DDValue(i,j)+x.DValue(i) * x.DValue(j),0.,0.5/res.Value() * x.DDValue(i,j) - 0.25 / (x.Value()*res.Value()) * x.DValue(i) * x.DValue(j));
470 template <
int D,
typename SCAL>
471 INLINE AutoDiffDiff<D, SCAL> exp (AutoDiffDiff<D, SCAL> x)
473 AutoDiffDiff<D, SCAL> res;
474 res.Value() = exp(x.Value());
475 for (
int k = 0; k < D; k++)
476 res.DValue(k) = x.DValue(k) * res.Value();
477 for (
int k = 0; k < D; k++)
478 for (
int l = 0; l < D; l++)
479 res.DDValue(k,l) = (x.DValue(k) * x.DValue(l)+x.DDValue(k,l)) * res.Value();
484 template <
int D,
typename SCAL>
485 INLINE AutoDiffDiff<D,SCAL> pow (AutoDiffDiff<D,SCAL> x, AutoDiffDiff<D,SCAL> y )
487 return exp(log(x)*y);
490 template <
int D,
typename SCAL>
491 INLINE AutoDiffDiff<D, SCAL> log (AutoDiffDiff<D, SCAL> x)
493 AutoDiffDiff<D, SCAL> res;
494 res.Value() = log(x.Value());
495 SCAL xinv = 1.0/x.Value();
496 for (
int k = 0; k < D; k++)
497 res.DValue(k) = x.DValue(k) * xinv;
498 for (
int k = 0; k < D; k++)
499 for (
int l = 0; l < D; l++)
500 res.DDValue(k,l) = -xinv*xinv*x.DValue(k) * x.DValue(l) + xinv * x.DDValue(k,l);
506 template <
int D,
typename SCAL>
507 INLINE AutoDiffDiff<D, SCAL> sin (AutoDiffDiff<D, SCAL> x)
509 AutoDiffDiff<D, SCAL> res;
510 SCAL s = sin(x.Value());
511 SCAL c = cos(x.Value());
514 for (
int k = 0; k < D; k++)
515 res.DValue(k) = x.DValue(k) * c;
516 for (
int k = 0; k < D; k++)
517 for (
int l = 0; l < D; l++)
518 res.DDValue(k,l) = -s * x.DValue(k) * x.DValue(l) + c * x.DDValue(k,l);
523 template <
int D,
typename SCAL>
524 INLINE AutoDiffDiff<D, SCAL> cos (AutoDiffDiff<D, SCAL> x)
526 AutoDiffDiff<D, SCAL> res;
527 SCAL s = sin(x.Value());
528 SCAL c = cos(x.Value());
531 for (
int k = 0; k < D; k++)
532 res.DValue(k) = -s * x.DValue(k);
533 for (
int k = 0; k < D; k++)
534 for (
int l = 0; l < D; l++)
535 res.DDValue(k,l) = -c * x.DValue(k) * x.DValue(l) - s * x.DDValue(k,l);
539 template <
int D,
typename SCAL>
540 INLINE AutoDiffDiff<D, SCAL> tan (AutoDiffDiff<D, SCAL> x)
541 {
return sin(x) / cos(x); }
544 template <
int D,
typename SCAL>
545 INLINE AutoDiffDiff<D, SCAL> atan (AutoDiffDiff<D, SCAL> x)
547 AutoDiffDiff<D, SCAL> res;
548 SCAL a = atan(x.Value());
550 for (
int k = 0; k < D; k++)
551 res.DValue(k) = x.DValue(k)/(1+x.Value()*x.Value()) ;
552 for (
int k = 0; k < D; k++)
553 for (
int l = 0; l < D; l++)
554 res.DDValue(k,l) = -2*x.Value()/((1+x.Value()*x.Value())*(1+x.Value()*x.Value())) * x.DValue(k) * x.DValue(l) + x.DDValue(k,l)/(1+x.Value()*x.Value());
558 template <
int D,
typename SCAL>
559 INLINE AutoDiffDiff<D, SCAL> atan2 (AutoDiffDiff<D, SCAL> x,AutoDiffDiff<D, SCAL> y)
561 AutoDiffDiff<D, SCAL> res;
562 SCAL a = atan2(x.Value(), y.Value());
564 for (
int k = 0; k < D; k++)
565 res.DValue(k) = (x.Value()*y.DValue(k)-y.Value()*x.DValue(k))/(y.Value()*y.Value()+x.Value()*x.Value());
567 for (
int k = 0; k < D; k++)
568 for (
int l = 0; l < D; l++)
569 res.DDValue(k,l) = (x.DValue(k)*y.DValue(l)+x.Value()*y.DDValue(l,k) - y.DValue(k)*x.DValue(l) - y.Value()*x.DDValue(l,k))/(y.Value()*y.Value()+x.Value()*x.Value()) - 2 * (x.Value()*y.DValue(k)-y.Value()*x.DValue(k)) * (x.Value()*x.DValue(k) + y.Value()*y.DValue(k))/( (y.Value()*y.Value()+x.Value()*x.Value()) * (y.Value()*y.Value()+x.Value()*x.Value()) );
576 template <
int D,
typename SCAL>
577 INLINE AutoDiffDiff<D,SCAL> acos (AutoDiffDiff<D,SCAL> x)
579 AutoDiffDiff<D,SCAL> res;
580 SCAL a = acos(x.Value());
582 auto omaa = 1-x.Value()*x.Value();
585 SCAL dda = -x.Value() / (s*omaa);
586 for (
int k = 0; k < D; k++)
587 res.DValue(k) = x.DValue(k)*da;
588 for (
int k = 0; k < D; k++)
589 for (
int l = 0; l < D; l++)
590 res.DDValue(k,l) = dda * x.DValue(k) * x.DValue(l) + da * x.DDValue(k,l);
597 template <
int D,
typename SCAL>
598 INLINE AutoDiffDiff<D,SCAL> asin (AutoDiffDiff<D,SCAL> x)
600 AutoDiffDiff<D,SCAL> res;
601 SCAL a = asin(x.Value());
603 auto omaa = 1-x.Value()*x.Value();
606 SCAL dda = x.Value() / (s*omaa);
607 for (
int k = 0; k < D; k++)
608 res.DValue(k) = x.DValue(k)*da;
609 for (
int k = 0; k < D; k++)
610 for (
int l = 0; l < D; l++)
611 res.DDValue(k,l) = dda * x.DValue(k) * x.DValue(l) + da * x.DDValue(k,l);
617 template <
int D,
typename SCAL>
618 INLINE AutoDiffDiff<D, SCAL> sinh (AutoDiffDiff<D, SCAL> x)
620 AutoDiffDiff<D, SCAL> res;
621 SCAL sh = sinh(x.Value());
622 SCAL ch = cosh(x.Value());
625 for (
int k = 0; k < D; k++)
626 res.DValue(k) = x.DValue(k) * ch;
627 for (
int k = 0; k < D; k++)
628 for (
int l = 0; l < D; l++)
629 res.DDValue(k,l) = sh * x.DValue(k) * x.DValue(l) + ch * x.DDValue(k,l);
634 template <
int D,
typename SCAL>
635 INLINE AutoDiffDiff<D, SCAL> cosh (AutoDiffDiff<D, SCAL> x)
637 AutoDiffDiff<D, SCAL> res;
638 SCAL sh = sinh(x.Value());
639 SCAL ch = cosh(x.Value());
642 for (
int k = 0; k < D; k++)
643 res.DValue(k) = sh * x.DValue(k);
644 for (
int k = 0; k < D; k++)
645 for (
int l = 0; l < D; l++)
646 res.DDValue(k,l) = ch * x.DValue(k) * x.DValue(l) + sh * x.DDValue(k,l);
651 template<
int D,
typename SCAL>
652 INLINE AutoDiffDiff<D,SCAL> floor (
const AutoDiffDiff<D,SCAL> & x)
654 return floor(x.Value());
658 template<
int D,
typename SCAL>
659 INLINE AutoDiffDiff<D,SCAL> ceil (
const AutoDiffDiff<D,SCAL> & x)
661 return ceil(x.Value());
665 template <
int D,
typename SCAL,
typename TB,
typename TC>
666 auto IfPos (AutoDiffDiff<D,SCAL> a, TB b, TC c) -> decltype(IfPos (a.Value(), b, c))
668 return IfPos (a.Value(), b, c);
671 template <
int D,
typename SCAL>
672 INLINE AutoDiffDiff<D,SCAL> IfPos (SCAL a, AutoDiffDiff<D,SCAL> b, AutoDiffDiff<D,SCAL> c)
674 AutoDiffDiff<D,SCAL> res;
675 res.Value() = IfPos (a, b.Value(), c.Value());
676 for (
int j = 0; j < D; j++)
678 res.DValue(j) = IfPos (a, b.DValue(j), c.DValue(j));
679 res.DDValue(j) = IfPos (a, b.DDValue(j), c.DDValue(j));
684 template <
int D,
typename SCAL,
typename TC>
685 INLINE AutoDiffDiff<D,SCAL> IfPos (SCAL a, AutoDiffDiff<D,SCAL> b, TC c)
687 return IfPos (a, b, AutoDiffDiff<D,SCAL> (c));
SCAL & DDValue(int i)
accesses partial derivative
Definition: autodiffdiff.hpp:153
AutoDiffDiff< D, SCAL > & operator+=(const AutoDiffDiff< D, SCAL > &y)
add autodiffdiff object
Definition: autodiffdiff.hpp:162
SCAL DDValue(int i) const
returns partial derivative
Definition: autodiffdiff.hpp:141
SCAL & Value()
access value
Definition: autodiffdiff.hpp:147
SCAL DValue(int i) const
returns partial derivative
Definition: autodiffdiff.hpp:130
bool operator>(SCAL val2)
greater
Definition: autodiffdiff.hpp:244
SCAL DDValue(int i, int j) const
returns partial derivative
Definition: autodiffdiff.hpp:144
AutoDiffDiff(SCAL aval, int diffindex)
init object with (val, e_diffindex)
Definition: autodiffdiff.hpp:66
ostream & operator<<(ostream &ost, const AutoDiffDiff< D, SCAL > &x)
Prints AudoDiffDiff.
Definition: autodiffdiff.hpp:255
SCAL & DDValue(int i, int j)
accesses partial derivative
Definition: autodiffdiff.hpp:156
AutoDiffDiff()
elements are undefined
Definition: autodiffdiff.hpp:33
AutoDiffDiff< D, SCAL > & operator/=(const SCAL &y)
divide by scalar
Definition: autodiffdiff.hpp:214
INLINE AutoDiffVec< D, SCAL > sqr(const AutoDiffVec< D, SCAL > &x)
AutoDiffVec times AutoDiffVec.
Definition: autodiff.hpp:250
bool operator<(SCAL val2)
less
Definition: autodiffdiff.hpp:238
AutoDiffDiff(const AutoDiff< D, SCAL > &ad2)
initial object with value and derivative
Definition: autodiffdiff.hpp:56
AutoDiffDiff & operator=(SCAL aval)
assign constant value
Definition: autodiffdiff.hpp:92
SCAL Value() const
returns value
Definition: autodiffdiff.hpp:127
AutoDiffDiff(const AutoDiffDiff &ad2)
copy constructor
Definition: autodiffdiff.hpp:36
SCAL & DValue(int i)
accesses partial derivative
Definition: autodiffdiff.hpp:150
AutoDiffDiff< D, SCAL > & operator *=(const AutoDiffDiff< D, SCAL > &y)
multiply with autodiffdiff object
Definition: autodiffdiff.hpp:184
namespace for standard data types and algorithms.
Definition: ngstd.hpp:81
Definition: autodiff.hpp:15
AutoDiffDiff(SCAL aval)
initial object with constant value
Definition: autodiffdiff.hpp:46
AutoDiffDiff< D, SCAL > & operator-=(const AutoDiffDiff< D, SCAL > &y)
subtract autodiffdiff object
Definition: autodiffdiff.hpp:173
bool operator!=(SCAL val2)
different values
Definition: autodiffdiff.hpp:232
Datatype for automatic differentiation.
Definition: autodiffdiff.hpp:22
bool operator==(SCAL val2)
same value
Definition: autodiffdiff.hpp:226