Sacado Package Browser (Single Doxygen Collection)  Version of the Day
Sacado_ELRFad_Ops.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Sacado Package
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25 // (etphipp@sandia.gov).
26 //
27 // ***********************************************************************
28 //
29 // The forward-mode AD classes in Sacado are a derivative work of the
30 // expression template classes in the Fad package by Nicolas Di Cesare.
31 // The following banner is included in the original Fad source code:
32 //
33 // ************ DO NOT REMOVE THIS BANNER ****************
34 //
35 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
36 // http://www.ann.jussieu.fr/~dicesare
37 //
38 // CEMRACS 98 : C++ courses,
39 // templates : new C++ techniques
40 // for scientific computing
41 //
42 //********************************************************
43 //
44 // A short implementation ( not all operators and
45 // functions are overloaded ) of 1st order Automatic
46 // Differentiation in forward mode (FAD) using
47 // EXPRESSION TEMPLATES.
48 //
49 //********************************************************
50 // @HEADER
51 
52 #ifndef SACADO_ELRFAD_OPS_HPP
53 #define SACADO_ELRFAD_OPS_HPP
54 
56 #include "Sacado_cmath.hpp"
57 #include <ostream> // for std::ostream
58 
59 #define FAD_UNARYOP_MACRO(OPNAME,OP,VALUE,ADJOINT, \
60  LINEAR,DX,FASTACCESSDX) \
61 namespace Sacado { \
62  namespace ELRFad { \
63  \
64  template <typename ExprT> \
65  class OP {}; \
66  \
67  template <typename ExprT> \
68  class Expr< OP<ExprT> > { \
69  public: \
70  \
71  typedef typename ExprT::value_type value_type; \
72  typedef typename ExprT::scalar_type scalar_type; \
73  typedef typename ExprT::base_expr_type base_expr_type; \
74  \
75  static const int num_args = ExprT::num_args; \
76  \
77  static const bool is_linear = LINEAR; \
78  \
79  KOKKOS_INLINE_FUNCTION \
80  Expr(const ExprT& expr_) : expr(expr_) {} \
81  \
82  KOKKOS_INLINE_FUNCTION \
83  int size() const { return expr.size(); } \
84  \
85  template <int Arg> \
86  KOKKOS_INLINE_FUNCTION \
87  bool isActive() const { return expr.template isActive<Arg>(); } \
88  \
89  KOKKOS_INLINE_FUNCTION \
90  bool isActive2(int j) const { return expr.isActive2(j); } \
91  \
92  KOKKOS_INLINE_FUNCTION \
93  bool updateValue() const { return expr.updateValue(); } \
94  \
95  KOKKOS_INLINE_FUNCTION \
96  value_type val() const { \
97  return VALUE; \
98  } \
99  \
100  KOKKOS_INLINE_FUNCTION \
101  void computePartials(const value_type& bar, \
102  value_type partials[]) const { \
103  expr.computePartials(ADJOINT, partials); \
104  } \
105  \
106  KOKKOS_INLINE_FUNCTION \
107  void getTangents(int i, value_type dots[]) const { \
108  expr.getTangents(i, dots); } \
109  \
110  template <int Arg> \
111  KOKKOS_INLINE_FUNCTION \
112  const value_type& getTangent(int i) const { \
113  return expr.template getTangent<Arg>(i); \
114  } \
115  \
116  KOKKOS_INLINE_FUNCTION \
117  bool isLinear() const { \
118  return LINEAR; \
119  } \
120  \
121  KOKKOS_INLINE_FUNCTION \
122  bool hasFastAccess() const { \
123  return expr.hasFastAccess(); \
124  } \
125  \
126  KOKKOS_INLINE_FUNCTION \
127  const value_type dx(int i) const { \
128  return DX; \
129  } \
130  \
131  KOKKOS_INLINE_FUNCTION \
132  const value_type fastAccessDx(int i) const { \
133  return FASTACCESSDX; \
134  } \
135  \
136  KOKKOS_INLINE_FUNCTION \
137  const value_type* getDx(int j) const { \
138  return expr.getDx(j); \
139  } \
140  \
141  KOKKOS_INLINE_FUNCTION \
142  int numActiveArgs() const { \
143  return expr.numActiveArgs(); \
144  } \
145  \
146  KOKKOS_INLINE_FUNCTION \
147  void computeActivePartials(const value_type& bar, \
148  value_type *partials) const { \
149  expr.computePartials(ADJOINT, partials); \
150  } \
151  \
152  protected: \
153  \
154  const ExprT& expr; \
155  }; \
156  \
157  template <typename T> \
158  KOKKOS_INLINE_FUNCTION \
159  Expr< OP< Expr<T> > > \
160  OPNAME (const Expr<T>& expr) \
161  { \
162  typedef OP< Expr<T> > expr_t; \
163  \
164  return Expr<expr_t>(expr); \
165  } \
166  } \
167 }
168 
169 FAD_UNARYOP_MACRO(operator+,
170  UnaryPlusOp,
171  expr.val(),
172  bar,
173  true,
174  expr.dx(i),
175  expr.fastAccessDx(i))
176 FAD_UNARYOP_MACRO(operator-,
178  -expr.val(),
179  -bar,
180  true,
181  -expr.dx(i),
182  -expr.fastAccessDx(i))
185  std::exp(expr.val()),
186  bar*std::exp(expr.val()),
187  false,
188  std::exp(expr.val())*expr.dx(i),
189  std::exp(expr.val())*expr.fastAccessDx(i))
192  std::log(expr.val()),
193  bar/expr.val(),
194  false,
195  expr.dx(i)/expr.val(),
196  expr.fastAccessDx(i)/expr.val())
199  std::log10(expr.val()),
200  bar/( std::log(value_type(10.))*expr.val() ),
201  false,
202  expr.dx(i)/( std::log(value_type(10))*expr.val()),
203  expr.fastAccessDx(i) / ( std::log(value_type(10))*expr.val()))
205  SqrtOp,
206  std::sqrt(expr.val()),
207  value_type(0.5)*bar/std::sqrt(expr.val()),
208  false,
209  expr.dx(i)/(value_type(2)* std::sqrt(expr.val())),
210  expr.fastAccessDx(i)/(value_type(2)* std::sqrt(expr.val())))
212  CosOp,
213  std::cos(expr.val()),
214  -bar*std::sin(expr.val()),
215  false,
216  -expr.dx(i)* std::sin(expr.val()),
217  -expr.fastAccessDx(i)* std::sin(expr.val()))
219  SinOp,
220  std::sin(expr.val()),
221  bar*std::cos(expr.val()),
222  false,
223  expr.dx(i)* std::cos(expr.val()),
224  expr.fastAccessDx(i)* std::cos(expr.val()))
226  TanOp,
227  std::tan(expr.val()),
228  bar*(value_type(1.)+ std::tan(expr.val())*std::tan(expr.val())),
229  false,
230  expr.dx(i)*
231  (value_type(1)+ std::tan(expr.val())* std::tan(expr.val())),
232  expr.fastAccessDx(i)*
233  (value_type(1)+ std::tan(expr.val())* std::tan(expr.val())))
235  ACosOp,
236  std::acos(expr.val()),
237  -bar/std::sqrt(value_type(1.)-expr.val()*expr.val()),
238  false,
239  -expr.dx(i)/ std::sqrt(value_type(1)-expr.val()*expr.val()),
240  -expr.fastAccessDx(i) /
241  std::sqrt(value_type(1)-expr.val()*expr.val()))
243  ASinOp,
244  std::asin(expr.val()),
245  bar/std::sqrt(value_type(1.)-expr.val()*expr.val()),
246  false,
247  expr.dx(i)/ std::sqrt(value_type(1)-expr.val()*expr.val()),
248  expr.fastAccessDx(i) /
249  std::sqrt(value_type(1)-expr.val()*expr.val()))
251  ATanOp,
252  std::atan(expr.val()),
253  bar/(value_type(1.)+expr.val()*expr.val()),
254  false,
255  expr.dx(i)/(value_type(1)+expr.val()*expr.val()),
256  expr.fastAccessDx(i)/(value_type(1)+expr.val()*expr.val()))
258  CoshOp,
259  std::cosh(expr.val()),
260  bar*std::sinh(expr.val()),
261  false,
262  expr.dx(i)* std::sinh(expr.val()),
263  expr.fastAccessDx(i)* std::sinh(expr.val()))
265  SinhOp,
266  std::sinh(expr.val()),
267  bar*std::cosh(expr.val()),
268  false,
269  expr.dx(i)* std::cosh(expr.val()),
270  expr.fastAccessDx(i)* std::cosh(expr.val()))
272  TanhOp,
273  std::tanh(expr.val()),
274  bar/(std::cosh(expr.val())*std::cosh(expr.val())),
275  false,
276  expr.dx(i)/( std::cosh(expr.val())* std::cosh(expr.val())),
277  expr.fastAccessDx(i) /
278  ( std::cosh(expr.val())* std::cosh(expr.val())))
280  ACoshOp,
281  std::acosh(expr.val()),
282  bar/std::sqrt((expr.val()-value_type(1.)) *
283  (expr.val()+value_type(1.))),
284  false,
285  expr.dx(i)/ std::sqrt((expr.val()-value_type(1)) *
286  (expr.val()+value_type(1))),
287  expr.fastAccessDx(i)/ std::sqrt((expr.val()-value_type(1)) *
288  (expr.val()+value_type(1))))
290  ASinhOp,
291  std::asinh(expr.val()),
292  bar/std::sqrt(value_type(1.)+expr.val()*expr.val()),
293  false,
294  expr.dx(i)/ std::sqrt(value_type(1)+expr.val()*expr.val()),
295  expr.fastAccessDx(i)/ std::sqrt(value_type(1)+
296  expr.val()*expr.val()))
298  ATanhOp,
299  std::atanh(expr.val()),
300  bar/(value_type(1.)-expr.val()*expr.val()),
301  false,
302  expr.dx(i)/(value_type(1)-expr.val()*expr.val()),
303  expr.fastAccessDx(i)/(value_type(1)-
304  expr.val()*expr.val()))
306  AbsOp,
307  std::abs(expr.val()),
308  (expr.val() >= value_type(0.)) ? bar : value_type(-bar),
309  false,
310  expr.val() >= 0 ? value_type(+expr.dx(i)) :
311  value_type(-expr.dx(i)),
312  expr.val() >= 0 ? value_type(+expr.fastAccessDx(i)) :
313  value_type(-expr.fastAccessDx(i)))
315  FAbsOp,
316  std::fabs(expr.val()),
317  (expr.val() >= value_type(0.)) ? bar : value_type(-bar),
318  false,
319  expr.val() >= 0 ? value_type(+expr.dx(i)) :
320  value_type(-expr.dx(i)),
321  expr.val() >= 0 ? value_type(+expr.fastAccessDx(i)) :
322  value_type(-expr.fastAccessDx(i)))
323 #ifdef HAVE_SACADO_CXX11
324 FAD_UNARYOP_MACRO(cbrt,
325  CbrtOp,
326  std::cbrt(expr.val()),
327  bar/(value_type(3)*std::cbrt(expr.val()*expr.val())),
328  false,
329  expr.dx(i)/(value_type(3)*std::cbrt(expr.val()*expr.val())),
330  expr.fastAccessDx(i)/(value_type(3)*std::cbrt(expr.val()*expr.val())))
331 #endif
332 
333 #undef FAD_UNARYOP_MACRO
334 
335 #define FAD_BINARYOP_MACRO( \
336  OPNAME,OP,VALUE,LADJOINT,RADJOINT, \
337  LINEAR,CONST_LINEAR_1, CONST_LINEAR_2, \
338  LINEAR_2,CONST_LINEAR_1_2, CONST_LINEAR_2_2, \
339  DX,FASTACCESSDX,CONST_DX_1,CONST_DX_2, \
340  CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
341 namespace Sacado { \
342  namespace ELRFad { \
343  \
344  template <typename ExprT1, typename ExprT2> \
345  class OP {}; \
346  \
347  template <typename ExprT1, typename ExprT2> \
348  class Expr< OP<ExprT1,ExprT2> > { \
349  \
350  public: \
351  \
352  typedef typename ExprT1::value_type value_type_1; \
353  typedef typename ExprT2::value_type value_type_2; \
354  typedef typename Sacado::Promote<value_type_1, \
355  value_type_2>::type value_type; \
356  \
357  typedef typename ExprT1::scalar_type scalar_type_1; \
358  typedef typename ExprT2::scalar_type scalar_type_2; \
359  typedef typename Sacado::Promote<scalar_type_1, \
360  scalar_type_2>::type scalar_type; \
361  \
362  typedef typename ExprT1::base_expr_type base_expr_type_1; \
363  typedef typename ExprT2::base_expr_type base_expr_type_2; \
364  typedef typename Sacado::Promote<base_expr_type_1, \
365  base_expr_type_2>::type base_expr_type; \
366  \
367  static const int num_args1 = ExprT1::num_args; \
368  static const int num_args2 = ExprT2::num_args; \
369  static const int num_args = num_args1 + num_args2; \
370  \
371  static const bool is_linear = LINEAR_2; \
372  \
373  KOKKOS_INLINE_FUNCTION \
374  Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
375  expr1(expr1_), expr2(expr2_) {} \
376  \
377  KOKKOS_INLINE_FUNCTION \
378  int size() const { \
379  int sz1 = expr1.size(), sz2 = expr2.size(); \
380  return sz1 > sz2 ? sz1 : sz2; \
381  } \
382  \
383  template <int Arg> \
384  KOKKOS_INLINE_FUNCTION \
385  bool isActive() const { \
386  if (Arg < num_args1) \
387  return expr1.template isActive<Arg>(); \
388  else \
389  return expr2.template isActive<Arg-num_args1>(); \
390  } \
391  \
392  KOKKOS_INLINE_FUNCTION \
393  bool isActive2(int j) const { \
394  if (j < num_args1) \
395  return expr1.isActive2(j); \
396  else \
397  return expr2.isActive2(j); \
398  } \
399  \
400  KOKKOS_INLINE_FUNCTION \
401  bool updateValue() const { \
402  return expr1.updateValue() && expr2.updateValue(); \
403  } \
404  \
405  KOKKOS_INLINE_FUNCTION \
406  value_type val() const { \
407  return VALUE; \
408  } \
409  \
410  KOKKOS_INLINE_FUNCTION \
411  void computePartials(const value_type& bar, \
412  value_type partials[]) const { \
413  if (num_args1 > 0) \
414  expr1.computePartials(LADJOINT, partials); \
415  if (num_args2 > 0) \
416  expr2.computePartials(RADJOINT, partials+num_args1); \
417  } \
418  \
419  KOKKOS_INLINE_FUNCTION \
420  void getTangents(int i, value_type dots[]) const { \
421  expr1.getTangents(i, dots); \
422  expr2.getTangents(i, dots+num_args1); \
423  } \
424  \
425  template <int Arg> \
426  KOKKOS_INLINE_FUNCTION \
427  const value_type& getTangent(int i) const { \
428  if (Arg < num_args1) \
429  return expr1.template getTangent<Arg>(i); \
430  else \
431  return expr2.template getTangent<Arg-num_args1>(i); \
432  } \
433  \
434  KOKKOS_INLINE_FUNCTION \
435  bool isLinear() const { \
436  return LINEAR; \
437  } \
438  \
439  KOKKOS_INLINE_FUNCTION \
440  bool hasFastAccess() const { \
441  return expr1.hasFastAccess() && expr2.hasFastAccess(); \
442  } \
443  \
444  KOKKOS_INLINE_FUNCTION \
445  const value_type dx(int i) const { \
446  return DX; \
447  } \
448  \
449  KOKKOS_INLINE_FUNCTION \
450  const value_type fastAccessDx(int i) const { \
451  return FASTACCESSDX; \
452  } \
453  \
454  KOKKOS_INLINE_FUNCTION \
455  const value_type* getDx(int j) const { \
456  if (j < num_args1) \
457  return expr1.getDx(j); \
458  else \
459  return expr2.getDx(j-num_args1); \
460  } \
461  \
462  KOKKOS_INLINE_FUNCTION \
463  int numActiveArgs() const { \
464  return expr1.numActiveArgs() + expr2.numActiveArgs(); \
465  } \
466  \
467  KOKKOS_INLINE_FUNCTION \
468  void computeActivePartials(const value_type& bar, \
469  value_type *partials) const { \
470  if (expr1.numActiveArgs() > 0) \
471  expr1.computePartials(LADJOINT, partials); \
472  if (expr2.numActiveArgs() > 0) \
473  expr2.computePartials(RADJOINT, partials+expr2.numActiveArgs()); \
474  } \
475  protected: \
476  \
477  typename ExprConstRef<ExprT1>::type expr1; \
478  typename ExprConstRef<ExprT2>::type expr2; \
479  \
480  }; \
481  \
482  template <typename ExprT1, typename T2> \
483  class Expr< OP<ExprT1, ConstExpr<T2> > > { \
484  \
485  public: \
486  \
487  typedef ConstExpr<T2> ExprT2; \
488  typedef typename ExprT1::value_type value_type_1; \
489  typedef typename ExprT2::value_type value_type_2; \
490  typedef typename Sacado::Promote<value_type_1, \
491  value_type_2>::type value_type; \
492  \
493  typedef typename ExprT1::scalar_type scalar_type_1; \
494  typedef typename ExprT2::scalar_type scalar_type_2; \
495  typedef typename Sacado::Promote<scalar_type_1, \
496  scalar_type_2>::type scalar_type; \
497  \
498  typedef typename ExprT1::base_expr_type base_expr_type_1; \
499  typedef typename ExprT2::base_expr_type base_expr_type_2; \
500  typedef typename Sacado::Promote<base_expr_type_1, \
501  base_expr_type_2>::type base_expr_type; \
502  \
503  static const int num_args = ExprT1::num_args; \
504  \
505  static const bool is_linear = CONST_LINEAR_2_2; \
506  \
507  KOKKOS_INLINE_FUNCTION \
508  Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
509  expr1(expr1_), expr2(expr2_) {} \
510  \
511  KOKKOS_INLINE_FUNCTION \
512  int size() const { \
513  return expr1.size(); \
514  } \
515  \
516  template <int Arg> \
517  KOKKOS_INLINE_FUNCTION \
518  bool isActive() const { \
519  return expr1.template isActive<Arg>(); \
520  } \
521  \
522  KOKKOS_INLINE_FUNCTION \
523  bool isActive2(int j) const { return expr1.isActive2(j); } \
524  \
525  KOKKOS_INLINE_FUNCTION \
526  bool updateValue() const { \
527  return expr1.updateValue(); \
528  } \
529  \
530  KOKKOS_INLINE_FUNCTION \
531  value_type val() const { \
532  return VALUE; \
533  } \
534  \
535  KOKKOS_INLINE_FUNCTION \
536  void computePartials(const value_type& bar, \
537  value_type partials[]) const { \
538  expr1.computePartials(LADJOINT, partials); \
539  } \
540  \
541  KOKKOS_INLINE_FUNCTION \
542  void getTangents(int i, value_type dots[]) const { \
543  expr1.getTangents(i, dots); \
544  } \
545  \
546  template <int Arg> \
547  KOKKOS_INLINE_FUNCTION \
548  const value_type& getTangent(int i) const { \
549  return expr1.template getTangent<Arg>(i); \
550  } \
551  \
552  KOKKOS_INLINE_FUNCTION \
553  bool isLinear() const { \
554  return CONST_LINEAR_2; \
555  } \
556  \
557  KOKKOS_INLINE_FUNCTION \
558  bool hasFastAccess() const { \
559  return expr1.hasFastAccess(); \
560  } \
561  \
562  KOKKOS_INLINE_FUNCTION \
563  const value_type dx(int i) const { \
564  return CONST_DX_2; \
565  } \
566  \
567  KOKKOS_INLINE_FUNCTION \
568  const value_type fastAccessDx(int i) const { \
569  return CONST_FASTACCESSDX_2; \
570  } \
571  \
572  KOKKOS_INLINE_FUNCTION \
573  const value_type* getDx(int j) const { \
574  return expr1.getDx(j); \
575  } \
576  \
577  KOKKOS_INLINE_FUNCTION \
578  int numActiveArgs() const { \
579  return expr1.numActiveArgs(); \
580  } \
581  \
582  KOKKOS_INLINE_FUNCTION \
583  void computeActivePartials(const value_type& bar, \
584  value_type *partials) const { \
585  expr1.computePartials(LADJOINT, partials); \
586  } \
587  \
588  protected: \
589  \
590  typename ExprConstRef<ExprT1>::type expr1; \
591  typename ExprConstRef<ExprT2>::type expr2; \
592  \
593  }; \
594  \
595  template <typename T1, typename ExprT2> \
596  class Expr< OP<ConstExpr<T1>,ExprT2> > { \
597  \
598  public: \
599  \
600  typedef ConstExpr<T1> ExprT1; \
601  typedef typename ExprT1::value_type value_type_1; \
602  typedef typename ExprT2::value_type value_type_2; \
603  typedef typename Sacado::Promote<value_type_1, \
604  value_type_2>::type value_type; \
605  \
606  typedef typename ExprT1::scalar_type scalar_type_1; \
607  typedef typename ExprT2::scalar_type scalar_type_2; \
608  typedef typename Sacado::Promote<scalar_type_1, \
609  scalar_type_2>::type scalar_type; \
610  \
611  typedef typename ExprT1::base_expr_type base_expr_type_1; \
612  typedef typename ExprT2::base_expr_type base_expr_type_2; \
613  typedef typename Sacado::Promote<base_expr_type_1, \
614  base_expr_type_2>::type base_expr_type; \
615  \
616  static const int num_args = ExprT2::num_args; \
617  \
618  static const bool is_linear = CONST_LINEAR_1_2; \
619  \
620  KOKKOS_INLINE_FUNCTION \
621  Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
622  expr1(expr1_), expr2(expr2_) {} \
623  \
624  KOKKOS_INLINE_FUNCTION \
625  int size() const { \
626  return expr2.size(); \
627  } \
628  \
629  template <int Arg> \
630  KOKKOS_INLINE_FUNCTION \
631  bool isActive() const { \
632  return expr2.template isActive<Arg>(); \
633  } \
634  \
635  KOKKOS_INLINE_FUNCTION \
636  bool isActive2(int j) const { return expr2.isActive2(j); } \
637  \
638  KOKKOS_INLINE_FUNCTION \
639  bool updateValue() const { \
640  return expr2.updateValue(); \
641  } \
642  \
643  KOKKOS_INLINE_FUNCTION \
644  value_type val() const { \
645  return VALUE; \
646  } \
647  \
648  KOKKOS_INLINE_FUNCTION \
649  void computePartials(const value_type& bar, \
650  value_type partials[]) const { \
651  expr2.computePartials(RADJOINT, partials); \
652  } \
653  \
654  KOKKOS_INLINE_FUNCTION \
655  void getTangents(int i, value_type dots[]) const { \
656  expr2.getTangents(i, dots); \
657  } \
658  \
659  template <int Arg> \
660  KOKKOS_INLINE_FUNCTION \
661  const value_type& getTangent(int i) const { \
662  return expr2.template getTangent<Arg>(i); \
663  } \
664  \
665  KOKKOS_INLINE_FUNCTION \
666  bool isLinear() const { \
667  return CONST_LINEAR_1; \
668  } \
669  \
670  KOKKOS_INLINE_FUNCTION \
671  bool hasFastAccess() const { \
672  return expr2.hasFastAccess(); \
673  } \
674  \
675  KOKKOS_INLINE_FUNCTION \
676  const value_type dx(int i) const { \
677  return CONST_DX_1; \
678  } \
679  \
680  KOKKOS_INLINE_FUNCTION \
681  const value_type fastAccessDx(int i) const { \
682  return CONST_FASTACCESSDX_1; \
683  } \
684  \
685  KOKKOS_INLINE_FUNCTION \
686  const value_type* getDx(int j) const { \
687  return expr2.getDx(j); \
688  } \
689  \
690  KOKKOS_INLINE_FUNCTION \
691  int numActiveArgs() const { \
692  return expr2.numActiveArgs(); \
693  } \
694  \
695  KOKKOS_INLINE_FUNCTION \
696  void computeActivePartials(const value_type& bar, \
697  value_type *partials) const { \
698  expr2.computePartials(RADJOINT, partials); \
699  } \
700  protected: \
701  \
702  typename ExprConstRef<ExprT1>::type expr1; \
703  typename ExprConstRef<ExprT2>::type expr2; \
704  \
705  }; \
706  \
707  template <typename T1, typename T2> \
710  OPNAME (const T1& expr1, const T2& expr2) \
711  { \
712  typedef OP< T1, T2 > expr_t; \
713  \
714  return Expr<expr_t>(expr1, expr2); \
715  } \
716  \
717  template <typename T> \
718  KOKKOS_INLINE_FUNCTION \
719  Expr< OP< Expr<T>, Expr<T> > > \
720  OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
721  { \
722  typedef OP< Expr<T>, Expr<T> > expr_t; \
723  \
724  return Expr<expr_t>(expr1, expr2); \
725  } \
726  \
727  template <typename T> \
728  KOKKOS_INLINE_FUNCTION \
729  Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
730  Expr<T> > > \
731  OPNAME (const typename Expr<T>::value_type& c, \
732  const Expr<T>& expr) \
733  { \
734  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
735  typedef OP< ConstT, Expr<T> > expr_t; \
736  \
737  return Expr<expr_t>(ConstT(c), expr); \
738  } \
739  \
740  template <typename T> \
741  KOKKOS_INLINE_FUNCTION \
742  Expr< OP< Expr<T>, \
743  ConstExpr<typename Expr<T>::value_type> > > \
744  OPNAME (const Expr<T>& expr, \
745  const typename Expr<T>::value_type& c) \
746  { \
747  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
748  typedef OP< Expr<T>, ConstT > expr_t; \
749  \
750  return Expr<expr_t>(expr, ConstT(c)); \
751  } \
752  \
753  template <typename T> \
756  OPNAME (const typename Expr<T>::scalar_type& c, \
757  const Expr<T>& expr) \
758  { \
759  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
760  typedef OP< ConstT, Expr<T> > expr_t; \
761  \
762  return Expr<expr_t>(ConstT(c), expr); \
763  } \
764  \
765  template <typename T> \
768  OPNAME (const Expr<T>& expr, \
769  const typename Expr<T>::scalar_type& c) \
770  { \
771  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
772  typedef OP< Expr<T>, ConstT > expr_t; \
773  \
774  return Expr<expr_t>(expr, ConstT(c)); \
775  } \
776  } \
777 }
778 
779 
780 FAD_BINARYOP_MACRO(operator+,
781  AdditionOp,
782  expr1.val() + expr2.val(),
783  bar,
784  bar,
785  expr1.isLinear() && expr2.isLinear(),
786  expr2.isLinear(),
787  expr1.isLinear(),
788  ExprT1::is_linear && ExprT2::is_linear,
789  ExprT2::is_linear,
790  ExprT1::is_linear,
791  expr1.dx(i) + expr2.dx(i),
792  expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
793  expr2.dx(i),
794  expr1.dx(i),
795  expr2.fastAccessDx(i),
796  expr1.fastAccessDx(i))
797 FAD_BINARYOP_MACRO(operator-,
799  expr1.val() - expr2.val(),
800  bar,
801  -bar,
802  expr1.isLinear() && expr2.isLinear(),
803  expr2.isLinear(),
804  expr1.isLinear(),
805  ExprT1::is_linear && ExprT2::is_linear,
806  ExprT2::is_linear,
807  ExprT1::is_linear,
808  expr1.dx(i) - expr2.dx(i),
809  expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
810  -expr2.dx(i),
811  expr1.dx(i),
812  -expr2.fastAccessDx(i),
813  expr1.fastAccessDx(i))
814 FAD_BINARYOP_MACRO(operator*,
816  expr1.val() * expr2.val(),
817  bar*expr2.val(),
818  bar*expr1.val(),
819  false,
820  expr2.isLinear(),
821  expr1.isLinear(),
822  false,
823  ExprT2::is_linear,
824  ExprT1::is_linear,
825  expr1.val()*expr2.dx(i) + expr1.dx(i)*expr2.val(),
826  expr1.val()*expr2.fastAccessDx(i) +
827  expr1.fastAccessDx(i)*expr2.val(),
828  expr1.val()*expr2.dx(i),
829  expr1.dx(i)*expr2.val(),
830  expr1.val()*expr2.fastAccessDx(i),
831  expr1.fastAccessDx(i)*expr2.val())
832 FAD_BINARYOP_MACRO(operator/,
833  DivisionOp,
834  expr1.val() / expr2.val(),
835  bar/expr2.val(),
836  -bar*expr1.val()/(expr2.val()*expr2.val()),
837  false,
838  false,
839  expr1.isLinear(),
840  false,
841  false,
842  ExprT1::is_linear,
843  (expr1.dx(i)*expr2.val() - expr2.dx(i)*expr1.val()) /
844  (expr2.val()*expr2.val()),
845  (expr1.fastAccessDx(i)*expr2.val() -
846  expr2.fastAccessDx(i)*expr1.val()) /
847  (expr2.val()*expr2.val()),
848  -expr2.dx(i)*expr1.val() / (expr2.val()*expr2.val()),
849  expr1.dx(i)/expr2.val(),
850  -expr2.fastAccessDx(i)*expr1.val() / (expr2.val()*expr2.val()),
851  expr1.fastAccessDx(i)/expr2.val())
853  Atan2Op,
854  std::atan2(expr1.val(), expr2.val()),
855  bar*expr2.val()/
856  (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
857  -bar*expr1.val()/
858  (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
859  false,
860  false,
861  false,
862  false,
863  false,
864  false,
865  (expr2.val()*expr1.dx(i) - expr1.val()*expr2.dx(i))/ (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
866  (expr2.val()*expr1.fastAccessDx(i) - expr1.val()*expr2.fastAccessDx(i))/
867  (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
868  (-expr1.val()*expr2.dx(i)) / (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
869  (expr2.val()*expr1.dx(i))/ (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
870  (-expr1.val()*expr2.fastAccessDx(i))/ (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
871  (expr2.val()*expr1.fastAccessDx(i))/ (expr1.val()*expr1.val() + expr2.val()*expr2.val()))
873  PowerOp,
874  std::pow(expr1.val(), expr2.val()),
875  expr1.val() == value_type(0) ? value_type(0) : value_type(bar*std::pow(expr1.val(),expr2.val())*expr2.val()/expr1.val()),
876  expr1.val() == value_type(0) ? value_type(0) : value_type(bar*std::pow(expr1.val(),expr2.val())*std::log(expr1.val())),
877  false,
878  false,
879  false,
880  false,
881  false,
882  false,
883  expr1.val() == value_type(0) ? value_type(0) : value_type((expr2.dx(i)*std::log(expr1.val())+expr2.val()*expr1.dx(i)/expr1.val())*std::pow(expr1.val(),expr2.val())),
884  expr1.val() == value_type(0) ? value_type(0.0) : value_type((expr2.fastAccessDx(i)*std::log(expr1.val())+expr2.val()*expr1.fastAccessDx(i)/expr1.val())*std::pow(expr1.val(),expr2.val())),
885  expr1.val() == value_type(0) ? value_type(0) : value_type(expr2.dx(i)*std::log(expr1.val())*std::pow(expr1.val(),expr2.val())),
886  expr1.val() == value_type(0) ? value_type(0.0) : value_type(expr2.val()*expr1.dx(i)/expr1.val()*std::pow(expr1.val(),expr2.val())),
887  expr1.val() == value_type(0) ? value_type(0) : value_type(expr2.fastAccessDx(i)*std::log(expr1.val())*std::pow(expr1.val(),expr2.val())),
888  expr1.val() == value_type(0) ? value_type(0.0) : value_type(expr2.val()*expr1.fastAccessDx(i)/expr1.val()*std::pow(expr1.val(),expr2.val())))
890  MaxOp,
891  expr1.val() >= expr2.val() ? expr1.val() : expr2.val(),
892  expr1.val() >= expr2.val() ? bar : value_type(0.),
893  expr2.val() > expr1.val() ? bar : value_type(0.),
894  expr1.isLinear() && expr2.isLinear(),
895  expr2.isLinear(),
896  expr1.isLinear(),
897  ExprT1::is_linear && ExprT2::is_linear,
898  ExprT2::is_linear,
899  ExprT1::is_linear,
900  expr1.val() >= expr2.val() ? expr1.dx(i) : expr2.dx(i),
901  expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) :
902  expr2.fastAccessDx(i),
903  expr1.val() >= expr2.val() ? value_type(0) : expr2.dx(i),
904  expr1.val() >= expr2.val() ? expr1.dx(i) : value_type(0),
905  expr1.val() >= expr2.val() ? value_type(0) :
906  expr2.fastAccessDx(i),
907  expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) :
908  value_type(0))
910  MinOp,
911  expr1.val() <= expr2.val() ? expr1.val() : expr2.val(),
912  expr1.val() <= expr2.val() ? bar : value_type(0.),
913  expr2.val() < expr1.val() ? bar : value_type(0.),
914  expr1.isLinear() && expr2.isLinear(),
915  expr2.isLinear(),
916  expr1.isLinear(),
917  ExprT1::is_linear && ExprT2::is_linear,
918  ExprT2::is_linear,
919  ExprT1::is_linear,
920  expr1.val() <= expr2.val() ? expr1.dx(i) : expr2.dx(i),
921  expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) :
922  expr2.fastAccessDx(i),
923  expr1.val() <= expr2.val() ? value_type(0) : expr2.dx(i),
924  expr1.val() <= expr2.val() ? expr1.dx(i) : value_type(0),
925  expr1.val() <= expr2.val() ? value_type(0) :
926  expr2.fastAccessDx(i),
927  expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) :
928  value_type(0))
929 
930 #undef FAD_BINARYOP_MACRO
931 
932 //-------------------------- Relational Operators -----------------------
933 
934 #define FAD_RELOP_MACRO(OP) \
935 namespace Sacado { \
936  namespace ELRFad { \
937  template <typename ExprT1, typename ExprT2> \
938  KOKKOS_INLINE_FUNCTION \
939  bool \
940  operator OP (const Expr<ExprT1>& expr1, \
941  const Expr<ExprT2>& expr2) \
942  { \
943  return expr1.val() OP expr2.val(); \
944  } \
945  \
946  template <typename ExprT2> \
947  KOKKOS_INLINE_FUNCTION \
948  bool \
949  operator OP (const typename Expr<ExprT2>::value_type& a, \
950  const Expr<ExprT2>& expr2) \
951  { \
952  return a OP expr2.val(); \
953  } \
954  \
955  template <typename ExprT1> \
956  KOKKOS_INLINE_FUNCTION \
957  bool \
958  operator OP (const Expr<ExprT1>& expr1, \
959  const typename Expr<ExprT1>::value_type& b) \
960  { \
961  return expr1.val() OP b; \
962  } \
963  } \
964 }
965 
966 FAD_RELOP_MACRO(==)
967 FAD_RELOP_MACRO(!=)
970 FAD_RELOP_MACRO(<=)
971 FAD_RELOP_MACRO(>=)
972 FAD_RELOP_MACRO(<<=)
973 FAD_RELOP_MACRO(>>=)
976 
977 #undef FAD_RELOP_MACRO
978 
979 namespace Sacado {
980 
981  namespace ELRFad {
982 
983  template <typename ExprT>
985  bool operator ! (const Expr<ExprT>& expr)
986  {
987  return ! expr.val();
988  }
989 
990  } // namespace ELRFad
991 
992 } // namespace Sacado
993 
994 //-------------------------- Boolean Operators -----------------------
995 namespace Sacado {
996 
997  namespace ELRFad {
998 
999  template <typename ExprT>
1001  bool toBool(const Expr<ExprT>& x) {
1002  bool is_zero = (x.val() == 0.0);
1003  for (int i=0; i<x.size(); i++)
1004  is_zero = is_zero && (x.dx(i) == 0.0);
1005  return !is_zero;
1006  }
1007 
1008  } // namespace Fad
1009 
1010 } // namespace Sacado
1011 
1012 #define FAD_BOOL_MACRO(OP) \
1013 namespace Sacado { \
1014  namespace ELRFad { \
1015  template <typename ExprT1, typename ExprT2> \
1016  KOKKOS_INLINE_FUNCTION \
1017  bool \
1018  operator OP (const Expr<ExprT1>& expr1, \
1019  const Expr<ExprT2>& expr2) \
1020  { \
1021  return toBool(expr1) OP toBool(expr2); \
1022  } \
1023  \
1024  template <typename ExprT2> \
1025  KOKKOS_INLINE_FUNCTION \
1026  bool \
1027  operator OP (const typename Expr<ExprT2>::value_type& a, \
1028  const Expr<ExprT2>& expr2) \
1029  { \
1030  return a OP toBool(expr2); \
1031  } \
1032  \
1033  template <typename ExprT1> \
1034  KOKKOS_INLINE_FUNCTION \
1035  bool \
1036  operator OP (const Expr<ExprT1>& expr1, \
1037  const typename Expr<ExprT1>::value_type& b) \
1038  { \
1039  return toBool(expr1) OP b; \
1040  } \
1041  } \
1042 }
1043 
1044 FAD_BOOL_MACRO(&&)
1045 FAD_BOOL_MACRO(||)
1046 
1047 #undef FAD_BOOL_MACRO
1048 
1049 //-------------------------- I/O Operators -----------------------
1050 
1051 namespace Sacado {
1052 
1053  namespace ELRFad {
1054 
1055  template <typename ExprT>
1056  std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
1057  os << x.val() << " [";
1058 
1059  for (int i=0; i< x.size(); i++) {
1060  os << " " << x.dx(i);
1061  }
1062 
1063  os << " ]";
1064  return os;
1065  }
1066 
1067  } // namespace Fad
1068 
1069 } // namespace Sacado
1070 
1071 
1072 #endif // SACADO_FAD_OPS_HPP
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 SubtractionOp
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 Atan2Op
expr val()
#define FAD_BOOL_MACRO(OP)
#define SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP)
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 MaxOp
SimpleFad< ValueT > atan2(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
KOKKOS_INLINE_FUNCTION bool toBool(const Expr< ExprT > &x)
#define SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP)
SimpleFad< ValueT > sqrt(const SimpleFad< ValueT > &a)
#define FAD_BINARYOP_MACRO( OPNAME, OP, VALUE, LADJOINT, RADJOINT, LINEAR, CONST_LINEAR_1, CONST_LINEAR_2, LINEAR_2, CONST_LINEAR_1_2, CONST_LINEAR_2_2, DX, FASTACCESSDX, CONST_DX_1, CONST_DX_2, CONST_FASTACCESSDX_1, CONST_FASTACCESSDX_2)
SimpleFad< ValueT > asin(const SimpleFad< ValueT > &a)
expr bar
expr expr expr ExpOp
SimpleFad< ValueT > log(const SimpleFad< ValueT > &a)
#define KOKKOS_INLINE_FUNCTION
#define FAD_UNARYOP_MACRO(OPNAME, OP, VALUE, ADJOINT, LINEAR, DX, FASTACCESSDX)
SimpleFad< ValueT > exp(const SimpleFad< ValueT > &a)
SimpleFad< ValueT > atan(const SimpleFad< ValueT > &a)
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 c
KOKKOS_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
SimpleFad< ValueT > log10(const SimpleFad< ValueT > &a)
#define T2(r, f)
Definition: Sacado_rad.hpp:578
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
SimpleFad< ValueT > sin(const SimpleFad< ValueT > &a)
#define T1(r, f)
Definition: Sacado_rad.hpp:603
SimpleFad< ValueT > sinh(const SimpleFad< ValueT > &a)
#define FAD_RELOP_MACRO(OP)
SimpleFad< ValueT > pow(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
SimpleFad< ValueT > tan(const SimpleFad< ValueT > &a)
expr acosh(expr.val())) FAD_UNARYOP_MACRO(asinh
#define SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP)
expr asinh(expr.val())) FAD_UNARYOP_MACRO(atanh
SimpleFad< ValueT > cos(const SimpleFad< ValueT > &a)
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 DivisionOp
expr expr expr bar LogOp
SimpleFad< ValueT > cosh(const SimpleFad< ValueT > &a)
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
expr expr dx(i)
KOKKOS_INLINE_FUNCTION Expr< AbsOp< Expr< T > > > abs(const Expr< T > &expr)
KOKKOS_INLINE_FUNCTION Expr< FAbsOp< Expr< T > > > fabs(const Expr< T > &expr)
expr expr expr bar false
expr atanh(expr.val())) FAD_UNARYOP_MACRO(abs
SimpleFad< ValueT > acos(const SimpleFad< ValueT > &a)
SimpleFad< ValueT > tanh(const SimpleFad< ValueT > &a)
Base template specification for Promote.
expr expr expr bar bar expr expr expr Log10Op
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 PowerOp