Sacado Package Browser (Single Doxygen Collection)  Version of the Day
Sacado_Fad_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_FAD_OPS_HPP
53 #define SACADO_FAD_OPS_HPP
54 
56 #include "Sacado_cmath.hpp"
57 #include <ostream> // for std::ostream
58 
59 #define FAD_UNARYOP_MACRO(OPNAME,OP,USING,VALUE,DX,FASTACCESSDX) \
60 namespace Sacado { \
61  namespace Fad { \
62  \
63  template <typename ExprT> \
64  class OP {}; \
65  \
66  template <typename ExprT> \
67  struct ExprSpec< OP<ExprT> > { \
68  typedef typename ExprSpec<ExprT>::type type; \
69  }; \
70  \
71  template <typename ExprT> \
72  class Expr< OP<ExprT>,ExprSpecDefault > { \
73  public: \
74  \
75  typedef typename ExprT::value_type value_type; \
76  typedef typename ExprT::scalar_type scalar_type; \
77  typedef typename ExprT::base_expr_type base_expr_type; \
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  KOKKOS_INLINE_FUNCTION \
86  bool hasFastAccess() const { return expr.hasFastAccess(); } \
87  \
88  KOKKOS_INLINE_FUNCTION \
89  bool isPassive() const { return expr.isPassive();} \
90  \
91  KOKKOS_INLINE_FUNCTION \
92  bool updateValue() const { return expr.updateValue(); } \
93  \
94  KOKKOS_INLINE_FUNCTION \
95  void cache() const {} \
96  \
97  KOKKOS_INLINE_FUNCTION \
98  value_type val() const { \
99  USING \
100  return VALUE; \
101  } \
102  \
103  KOKKOS_INLINE_FUNCTION \
104  value_type dx(int i) const { \
105  USING \
106  return DX; \
107  } \
108  \
109  KOKKOS_INLINE_FUNCTION \
110  value_type fastAccessDx(int i) const { \
111  USING \
112  return FASTACCESSDX; \
113  } \
114  \
115  protected: \
116  \
117  const ExprT& expr; \
118  }; \
119  \
120  template <typename T> \
121  KOKKOS_INLINE_FUNCTION \
122  Expr< OP< Expr<T> > > \
123  OPNAME (const Expr<T>& expr) \
124  { \
125  typedef OP< Expr<T> > expr_t; \
126  \
127  return Expr<expr_t>(expr); \
128  } \
129  } \
130  \
131 }
132 
133 FAD_UNARYOP_MACRO(operator+,
134  UnaryPlusOp,
135  ;,
136  expr.val(),
137  expr.dx(i),
138  expr.fastAccessDx(i))
139 FAD_UNARYOP_MACRO(operator-,
141  ;,
142  -expr.val(),
143  -expr.dx(i),
144  -expr.fastAccessDx(i))
147  using std::exp;,
148  exp(expr.val()),
149  exp(expr.val())*expr.dx(i),
150  exp(expr.val())*expr.fastAccessDx(i))
153  using std::log;,
154  log(expr.val()),
155  expr.dx(i)/expr.val(),
156  expr.fastAccessDx(i)/expr.val())
159  using std::log10; using std::log;,
160  log10(expr.val()),
161  expr.dx(i)/( log(value_type(10))*expr.val()),
162  expr.fastAccessDx(i) / ( log(value_type(10))*expr.val()))
165  using std::sqrt;,
166  sqrt(expr.val()),
167  expr.dx(i)/(value_type(2)* sqrt(expr.val())),
168  expr.fastAccessDx(i)/(value_type(2)* sqrt(expr.val())))
171  using std::cos; using std::sin;,
172  cos(expr.val()),
173  -expr.dx(i)* sin(expr.val()),
174  -expr.fastAccessDx(i)* sin(expr.val()))
177  using std::cos; using std::sin;,
178  sin(expr.val()),
179  expr.dx(i)* cos(expr.val()),
180  expr.fastAccessDx(i)* cos(expr.val()))
183  using std::tan;,
184  std::tan(expr.val()),
185  expr.dx(i)*
186  (value_type(1)+ tan(expr.val())* tan(expr.val())),
187  expr.fastAccessDx(i)*
188  (value_type(1)+ tan(expr.val())* tan(expr.val())))
191  using std::acos; using std::sqrt;,
192  acos(expr.val()),
193  -expr.dx(i)/ sqrt(value_type(1)-expr.val()*expr.val()),
194  -expr.fastAccessDx(i) /
195  sqrt(value_type(1)-expr.val()*expr.val()))
198  using std::asin; using std::sqrt;,
199  asin(expr.val()),
200  expr.dx(i)/ sqrt(value_type(1)-expr.val()*expr.val()),
201  expr.fastAccessDx(i) /
202  sqrt(value_type(1)-expr.val()*expr.val()))
205  using std::atan;,
206  atan(expr.val()),
207  expr.dx(i)/(value_type(1)+expr.val()*expr.val()),
208  expr.fastAccessDx(i)/(value_type(1)+expr.val()*expr.val()))
211  using std::cosh; using std::sinh;,
212  cosh(expr.val()),
213  expr.dx(i)* sinh(expr.val()),
214  expr.fastAccessDx(i)* sinh(expr.val()))
217  using std::cosh; using std::sinh;,
218  sinh(expr.val()),
219  expr.dx(i)* cosh(expr.val()),
220  expr.fastAccessDx(i)* cosh(expr.val()))
223  using std::tanh; using std::cosh;,
224  tanh(expr.val()),
225  expr.dx(i)/( cosh(expr.val())* cosh(expr.val())),
226  expr.fastAccessDx(i) /
227  ( cosh(expr.val())* cosh(expr.val())))
230  using std::acosh; using std::sqrt;,
231  acosh(expr.val()),
232  expr.dx(i)/ sqrt((expr.val()-value_type(1)) *
233  (expr.val()+value_type(1))),
234  expr.fastAccessDx(i)/ sqrt((expr.val()-value_type(1)) *
235  (expr.val()+value_type(1))))
238  using std::asinh; using std::sqrt;,
239  asinh(expr.val()),
240  expr.dx(i)/ sqrt(value_type(1)+expr.val()*expr.val()),
241  expr.fastAccessDx(i)/ sqrt(value_type(1)+
242  expr.val()*expr.val()))
245  using std::atanh;,
246  atanh(expr.val()),
247  expr.dx(i)/(value_type(1)-expr.val()*expr.val()),
248  expr.fastAccessDx(i)/(value_type(1)-
249  expr.val()*expr.val()))
252  using std::abs; using Sacado::if_then_else;,
253  abs(expr.val()),
254  if_then_else( expr.val() >= 0, expr.dx(i), value_type(-expr.dx(i)) ),
255  if_then_else( expr.val() >= 0, expr.fastAccessDx(i), value_type(-expr.fastAccessDx(i)) ) )
258  using std::fabs; using Sacado::if_then_else;,
259  fabs(expr.val()),
260  if_then_else( expr.val() >= 0, expr.dx(i), value_type(-expr.dx(i)) ),
261  if_then_else( expr.val() >= 0, expr.fastAccessDx(i), value_type(-expr.fastAccessDx(i)) ) )
262 #ifdef HAVE_SACADO_CXX11
264  CbrtOp,
265  using std::cbrt;,
266  cbrt(expr.val()),
267  expr.dx(i)/(value_type(3)*cbrt(expr.val()*expr.val())),
268  expr.fastAccessDx(i)/(value_type(3)*cbrt(expr.val()*expr.val())))
269 #endif
270 
271 #undef FAD_UNARYOP_MACRO
272 
273 #define FAD_BINARYOP_MACRO(OPNAME,OP,USING,VALUE,DX,FASTACCESSDX,VAL_CONST_DX_1,VAL_CONST_DX_2,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
274 namespace Sacado { \
275  namespace Fad { \
276  \
277  template <typename ExprT1, typename ExprT2> \
278  class OP {}; \
279  \
280  template <typename ExprT1, typename ExprT2> \
281  struct ExprSpec< OP< ExprT1, ExprT2 > > { \
282  typedef typename ExprSpec<ExprT1>::type type; \
283  }; \
284  \
285  template <typename ExprT1, typename ExprT2> \
286  class Expr< OP< ExprT1, ExprT2 >,ExprSpecDefault > { \
287  \
288  public: \
289  \
290  typedef typename ExprT1::value_type value_type_1; \
291  typedef typename ExprT2::value_type value_type_2; \
292  typedef typename Sacado::Promote<value_type_1, \
293  value_type_2>::type value_type; \
294  \
295  typedef typename ExprT1::scalar_type scalar_type_1; \
296  typedef typename ExprT2::scalar_type scalar_type_2; \
297  typedef typename Sacado::Promote<scalar_type_1, \
298  scalar_type_2>::type scalar_type; \
299  \
300  typedef typename ExprT1::base_expr_type base_expr_type_1; \
301  typedef typename ExprT2::base_expr_type base_expr_type_2; \
302  typedef typename Sacado::Promote<base_expr_type_1, \
303  base_expr_type_2>::type base_expr_type; \
304  \
305  KOKKOS_INLINE_FUNCTION \
306  Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
307  expr1(expr1_), expr2(expr2_) {} \
308  \
309  KOKKOS_INLINE_FUNCTION \
310  int size() const { \
311  int sz1 = expr1.size(), sz2 = expr2.size(); \
312  return sz1 > sz2 ? sz1 : sz2; \
313  } \
314  \
315  KOKKOS_INLINE_FUNCTION \
316  bool hasFastAccess() const { \
317  return expr1.hasFastAccess() && expr2.hasFastAccess(); \
318  } \
319  \
320  KOKKOS_INLINE_FUNCTION \
321  bool isPassive() const { \
322  return expr1.isPassive() && expr2.isPassive(); \
323  } \
324  \
325  KOKKOS_INLINE_FUNCTION \
326  bool updateValue() const { \
327  return expr1.updateValue() && expr2.updateValue(); \
328  } \
329  \
330  KOKKOS_INLINE_FUNCTION \
331  void cache() const {} \
332  \
333  KOKKOS_INLINE_FUNCTION \
334  const value_type val() const { \
335  USING \
336  return VALUE; \
337  } \
338  \
339  KOKKOS_INLINE_FUNCTION \
340  const value_type dx(int i) const { \
341  USING \
342  return DX; \
343  } \
344  \
345  KOKKOS_INLINE_FUNCTION \
346  const value_type fastAccessDx(int i) const { \
347  USING \
348  return FASTACCESSDX; \
349  } \
350  \
351  protected: \
352  \
353  const ExprT1& expr1; \
354  const ExprT2& expr2; \
355  \
356  }; \
357  \
358  template <typename ExprT1, typename T2> \
359  struct ExprSpec< OP< ExprT1, ConstExpr<T2> > > { \
360  typedef typename ExprSpec<ExprT1>::type type; \
361  }; \
362  \
363  template <typename ExprT1, typename T2> \
364  class Expr< OP< ExprT1, ConstExpr<T2> >,ExprSpecDefault > { \
365  \
366  public: \
367  \
368  typedef ConstExpr<T2> ConstT; \
369  typedef ConstExpr<T2> ExprT2; \
370  typedef typename ExprT1::value_type value_type_1; \
371  typedef typename ExprT2::value_type value_type_2; \
372  typedef typename Sacado::Promote<value_type_1, \
373  value_type_2>::type value_type; \
374  \
375  typedef typename ExprT1::scalar_type scalar_type_1; \
376  typedef typename ExprT2::scalar_type scalar_type_2; \
377  typedef typename Sacado::Promote<scalar_type_1, \
378  scalar_type_2>::type scalar_type; \
379  \
380  typedef typename ExprT1::base_expr_type base_expr_type_1; \
381  typedef typename ExprT2::base_expr_type base_expr_type_2; \
382  typedef typename Sacado::Promote<base_expr_type_1, \
383  base_expr_type_2>::type base_expr_type; \
384  \
385  KOKKOS_INLINE_FUNCTION \
386  Expr(const ExprT1& expr1_, const ConstT& c_) : \
387  expr1(expr1_), c(c_) {} \
388  \
389  KOKKOS_INLINE_FUNCTION \
390  int size() const { \
391  return expr1.size(); \
392  } \
393  \
394  KOKKOS_INLINE_FUNCTION \
395  bool hasFastAccess() const { \
396  return expr1.hasFastAccess(); \
397  } \
398  \
399  KOKKOS_INLINE_FUNCTION \
400  bool isPassive() const { \
401  return expr1.isPassive(); \
402  } \
403  \
404  KOKKOS_INLINE_FUNCTION \
405  bool updateValue() const { return expr1.updateValue(); } \
406  \
407  KOKKOS_INLINE_FUNCTION \
408  void cache() const {} \
409  \
410  KOKKOS_INLINE_FUNCTION \
411  const value_type val() const { \
412  USING \
413  return VAL_CONST_DX_2; \
414  } \
415  \
416  KOKKOS_INLINE_FUNCTION \
417  const value_type dx(int i) const { \
418  USING \
419  return CONST_DX_2; \
420  } \
421  \
422  KOKKOS_INLINE_FUNCTION \
423  const value_type fastAccessDx(int i) const { \
424  USING \
425  return CONST_FASTACCESSDX_2; \
426  } \
427  \
428  protected: \
429  \
430  const ExprT1& expr1; \
431  ConstT c; \
432  }; \
433  \
434  template <typename T1, typename ExprT2> \
435  struct ExprSpec< OP< ConstExpr<T1>, ExprT2 > > { \
436  typedef typename ExprSpec<ExprT2>::type type; \
437  }; \
438  \
439  template <typename T1, typename ExprT2> \
440  class Expr< OP< ConstExpr<T1>, ExprT2 >,ExprSpecDefault > { \
441  \
442  public: \
443  \
444  typedef ConstExpr<T1> ConstT; \
445  typedef ConstExpr<T1> ExprT1; \
446  typedef typename ExprT1::value_type value_type_1; \
447  typedef typename ExprT2::value_type value_type_2; \
448  typedef typename Sacado::Promote<value_type_1, \
449  value_type_2>::type value_type; \
450  \
451  typedef typename ExprT1::scalar_type scalar_type_1; \
452  typedef typename ExprT2::scalar_type scalar_type_2; \
453  typedef typename Sacado::Promote<scalar_type_1, \
454  scalar_type_2>::type scalar_type; \
455  \
456  typedef typename ExprT1::base_expr_type base_expr_type_1; \
457  typedef typename ExprT2::base_expr_type base_expr_type_2; \
458  typedef typename Sacado::Promote<base_expr_type_1, \
459  base_expr_type_2>::type base_expr_type; \
460  \
461  \
462  KOKKOS_INLINE_FUNCTION \
463  Expr(const ConstT& c_, const ExprT2& expr2_) : \
464  c(c_), expr2(expr2_) {} \
465  \
466  KOKKOS_INLINE_FUNCTION \
467  int size() const { \
468  return expr2.size(); \
469  } \
470  \
471  KOKKOS_INLINE_FUNCTION \
472  bool hasFastAccess() const { \
473  return expr2.hasFastAccess(); \
474  } \
475  \
476  KOKKOS_INLINE_FUNCTION \
477  bool isPassive() const { \
478  return expr2.isPassive(); \
479  } \
480  \
481  KOKKOS_INLINE_FUNCTION \
482  bool updateValue() const { return expr2.updateValue(); } \
483  \
484  KOKKOS_INLINE_FUNCTION \
485  void cache() const {} \
486  \
487  KOKKOS_INLINE_FUNCTION \
488  const value_type val() const { \
489  USING \
490  return VAL_CONST_DX_1; \
491  } \
492  \
493  KOKKOS_INLINE_FUNCTION \
494  const value_type dx(int i) const { \
495  USING \
496  return CONST_DX_1; \
497  } \
498  \
499  KOKKOS_INLINE_FUNCTION \
500  const value_type fastAccessDx(int i) const { \
501  USING \
502  return CONST_FASTACCESSDX_1; \
503  } \
504  \
505  protected: \
506  \
507  ConstT c; \
508  const ExprT2& expr2; \
509  }; \
510  \
511  template <typename T1, typename T2> \
512  KOKKOS_INLINE_FUNCTION \
513  typename mpl::enable_if_c< \
514  ExprLevel< Expr<T1> >::value == ExprLevel< Expr<T2> >::value, \
515  Expr< OP< Expr<T1>, Expr<T2> > > \
516  >::type \
517  /*SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP)*/ \
518  OPNAME (const Expr<T1>& expr1, const Expr<T2>& expr2) \
519  { \
520  typedef OP< Expr<T1>, Expr<T2> > expr_t; \
521  \
522  return Expr<expr_t>(expr1, expr2); \
523  } \
524  \
525  template <typename T> \
526  KOKKOS_INLINE_FUNCTION \
527  Expr< OP< Expr<T>, Expr<T> > > \
528  OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
529  { \
530  typedef OP< Expr<T>, Expr<T> > expr_t; \
531  \
532  return Expr<expr_t>(expr1, expr2); \
533  } \
534  \
535  template <typename T> \
536  KOKKOS_INLINE_FUNCTION \
537  Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
538  Expr<T> > > \
539  OPNAME (const typename Expr<T>::value_type& c, \
540  const Expr<T>& expr) \
541  { \
542  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
543  typedef OP< ConstT, Expr<T> > expr_t; \
544  \
545  return Expr<expr_t>(ConstT(c), expr); \
546  } \
547  \
548  template <typename T> \
549  KOKKOS_INLINE_FUNCTION \
550  Expr< OP< Expr<T>, \
551  ConstExpr<typename Expr<T>::value_type> > > \
552  OPNAME (const Expr<T>& expr, \
553  const typename Expr<T>::value_type& c) \
554  { \
555  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
556  typedef OP< Expr<T>, ConstT > expr_t; \
557  \
558  return Expr<expr_t>(expr, ConstT(c)); \
559  } \
560  \
561  template <typename T> \
564  OPNAME (const typename Expr<T>::scalar_type& c, \
565  const Expr<T>& expr) \
566  { \
567  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
568  typedef OP< ConstT, Expr<T> > expr_t; \
569  \
570  return Expr<expr_t>(ConstT(c), expr); \
571  } \
572  \
573  template <typename T> \
576  OPNAME (const Expr<T>& expr, \
577  const typename Expr<T>::scalar_type& c) \
578  { \
579  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
580  typedef OP< Expr<T>, ConstT > expr_t; \
581  \
582  return Expr<expr_t>(expr, ConstT(c)); \
583  } \
584  } \
585  \
586 }
587 
588 
589 FAD_BINARYOP_MACRO(operator+,
591  ;,
592  expr1.val() + expr2.val(),
593  expr1.dx(i) + expr2.dx(i),
594  expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
595  c.val() + expr2.val(),
596  expr1.val() + c.val(),
597  expr2.dx(i),
598  expr1.dx(i),
599  expr2.fastAccessDx(i),
600  expr1.fastAccessDx(i))
601 FAD_BINARYOP_MACRO(operator-,
603  ;,
604  expr1.val() - expr2.val(),
605  expr1.dx(i) - expr2.dx(i),
606  expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
607  c.val() - expr2.val(),
608  expr1.val() - c.val(),
609  -expr2.dx(i),
610  expr1.dx(i),
611  -expr2.fastAccessDx(i),
612  expr1.fastAccessDx(i))
613 // FAD_BINARYOP_MACRO(operator*,
614 // MultiplicationOp,
615 // ;,
616 // expr1.val() * expr2.val(),
617 // expr1.val()*expr2.dx(i) + expr1.dx(i)*expr2.val(),
618 // expr1.val()*expr2.fastAccessDx(i) +
619 // expr1.fastAccessDx(i)*expr2.val(),
620 // c.val() * expr2.val(),
621 // expr1.val() * c.val(),
622 // c.val()*expr2.dx(i),
623 // expr1.dx(i)*c.val(),
624 // c.val()*expr2.fastAccessDx(i),
625 // expr1.fastAccessDx(i)*c.val())
626 FAD_BINARYOP_MACRO(operator/,
628  ;,
629  expr1.val() / expr2.val(),
630  (expr1.dx(i)*expr2.val() - expr2.dx(i)*expr1.val()) /
631  (expr2.val()*expr2.val()),
632  (expr1.fastAccessDx(i)*expr2.val() -
633  expr2.fastAccessDx(i)*expr1.val()) /
634  (expr2.val()*expr2.val()),
635  c.val() / expr2.val(),
636  expr1.val() / c.val(),
637  -expr2.dx(i)*c.val() / (expr2.val()*expr2.val()),
638  expr1.dx(i)/c.val(),
639  -expr2.fastAccessDx(i)*c.val() / (expr2.val()*expr2.val()),
640  expr1.fastAccessDx(i)/c.val())
643  using std::atan2;,
644  atan2(expr1.val(), expr2.val()),
645  (expr2.val()*expr1.dx(i) - expr1.val()*expr2.dx(i))/
646  (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
647  (expr2.val()*expr1.fastAccessDx(i) - expr1.val()*expr2.fastAccessDx(i))/
648  (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
649  atan2(c.val(), expr2.val()),
650  atan2(expr1.val(), c.val()),
651  (-c.val()*expr2.dx(i)) / (c.val()*c.val() + expr2.val()*expr2.val()),
652  (c.val()*expr1.dx(i))/ (expr1.val()*expr1.val() + c.val()*c.val()),
653  (-c.val()*expr2.fastAccessDx(i))/ (c.val()*c.val() + expr2.val()*expr2.val()),
654  (c.val()*expr1.fastAccessDx(i))/ (expr1.val()*expr1.val() + c.val()*c.val()))
657  using std::pow; using std::log; using Sacado::if_then_else;,
658  pow(expr1.val(), expr2.val()),
659  if_then_else( expr1.val() == value_type(0.0), value_type(0.0), value_type((expr2.dx(i)*log(expr1.val())+expr2.val()*expr1.dx(i)/expr1.val())*pow(expr1.val(),expr2.val())) ),
660  if_then_else( expr1.val() == value_type(0.0), value_type(0.0), value_type((expr2.fastAccessDx(i)*log(expr1.val())+expr2.val()*expr1.fastAccessDx(i)/expr1.val())*pow(expr1.val(),expr2.val())) ),
661  pow(c.val(), expr2.val()),
662  pow(expr1.val(), c.val()),
663  if_then_else( c.val() == value_type(0.0), value_type(0.0), value_type(expr2.dx(i)*log(c.val())*pow(c.val(),expr2.val())) ),
664  if_then_else( expr1.val() == value_type(0.0), value_type(0.0), value_type(c.val()*expr1.dx(i)/expr1.val()*pow(expr1.val(),c.val())) ),
665  if_then_else( c.val() == value_type(0.0), value_type(0.0), value_type(expr2.fastAccessDx(i)*log(c.val())*pow(c.val(),expr2.val())) ),
666  if_then_else( expr1.val() == value_type(0.0), value_type(0.0), value_type(c.val()*expr1.fastAccessDx(i)/expr1.val()*pow(expr1.val(),c.val()))) )
669  using Sacado::if_then_else;,
670  if_then_else( expr1.val() >= expr2.val(), expr1.val(), expr2.val() ),
671  if_then_else( expr1.val() >= expr2.val(), expr1.dx(i), expr2.dx(i) ),
672  if_then_else( expr1.val() >= expr2.val(), expr1.fastAccessDx(i), expr2.fastAccessDx(i) ),
673  if_then_else( c.val() >= expr2.val(), value_type(c.val()), expr2.val() ),
674  if_then_else( expr1.val() >= c.val(), expr1.val(), value_type(c.val()) ),
675  if_then_else( c.val() >= expr2.val(), value_type(0.0), expr2.dx(i) ),
676  if_then_else( expr1.val() >= c.val(), expr1.dx(i), value_type(0.0) ),
677  if_then_else( c.val() >= expr2.val(), value_type(0.0), expr2.fastAccessDx(i) ),
678  if_then_else( expr1.val() >= c.val(), expr1.fastAccessDx(i), value_type(0.0) ) )
681  using Sacado::if_then_else;,
682  if_then_else( expr1.val() <= expr2.val(), expr1.val(), expr2.val() ),
683  if_then_else( expr1.val() <= expr2.val(), expr1.dx(i), expr2.dx(i) ),
684  if_then_else( expr1.val() <= expr2.val(), expr1.fastAccessDx(i), expr2.fastAccessDx(i) ),
685  if_then_else( c.val() <= expr2.val(), value_type(c.val()), expr2.val() ),
686  if_then_else( expr1.val() <= c.val(), expr1.val(), value_type(c.val()) ),
687  if_then_else( c.val() <= expr2.val(), value_type(0), expr2.dx(i) ),
688  if_then_else( expr1.val() <= c.val(), expr1.dx(i), value_type(0) ),
689  if_then_else( c.val() <= expr2.val(), value_type(0), expr2.fastAccessDx(i) ),
690  if_then_else( expr1.val() <= c.val(), expr1.fastAccessDx(i), value_type(0) ) )
691 
692 
693 #undef FAD_BINARYOP_MACRO
694 
695 namespace Sacado {
696  namespace Fad {
697 
698  template <typename ExprT1, typename ExprT2>
699  class MultiplicationOp {};
700 
701  template <typename ExprT1, typename ExprT2>
702  struct ExprSpec< MultiplicationOp< ExprT1, ExprT2 > > {
703  typedef typename ExprSpec<ExprT1>::type type;
704  };
705 
706  template <typename ExprT1, typename ExprT2>
707  class Expr< MultiplicationOp< ExprT1, ExprT2 >,ExprSpecDefault > {
708 
709  public:
710 
711  typedef typename ExprT1::value_type value_type_1;
712  typedef typename ExprT2::value_type value_type_2;
713  typedef typename Sacado::Promote<value_type_1,
714  value_type_2>::type value_type;
715 
716  typedef typename ExprT1::scalar_type scalar_type_1;
717  typedef typename ExprT2::scalar_type scalar_type_2;
718  typedef typename Sacado::Promote<scalar_type_1,
719  scalar_type_2>::type scalar_type;
720 
721  typedef typename ExprT1::base_expr_type base_expr_type_1;
722  typedef typename ExprT2::base_expr_type base_expr_type_2;
723  typedef typename Sacado::Promote<base_expr_type_1,
724  base_expr_type_2>::type base_expr_type;
725 
727  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
728  expr1(expr1_), expr2(expr2_) {}
729 
731  int size() const {
732  int sz1 = expr1.size(), sz2 = expr2.size();
733  return sz1 > sz2 ? sz1 : sz2;
734  }
735 
737  bool hasFastAccess() const {
738  return expr1.hasFastAccess() && expr2.hasFastAccess();
739  }
740 
742  bool isPassive() const {
743  return expr1.isPassive() && expr2.isPassive();
744  }
745 
747  bool updateValue() const {
748  return expr1.updateValue() && expr2.updateValue();
749  }
750 
752  void cache() const {}
753 
755  const value_type val() const {
756  return expr1.val()*expr2.val();
757  }
758 
760  const value_type dx(int i) const {
761  if (expr1.size() > 0 && expr2.size() > 0)
762  return expr1.val()*expr2.dx(i) + expr1.dx(i)*expr2.val();
763  else if (expr1.size() > 0)
764  return expr1.dx(i)*expr2.val();
765  else
766  return expr1.val()*expr2.dx(i);
767  }
768 
770  const value_type fastAccessDx(int i) const {
771  return expr1.val()*expr2.fastAccessDx(i) +
772  expr1.fastAccessDx(i)*expr2.val();
773  }
774 
775  protected:
776 
777  const ExprT1& expr1;
778  const ExprT2& expr2;
779 
780  };
781 
782  template <typename ExprT1, typename T2>
783  struct ExprSpec< MultiplicationOp< ExprT1, ConstExpr<T2> > > {
784  typedef typename ExprSpec<ExprT1>::type type;
785  };
786 
787  template <typename ExprT1, typename T2>
788  class Expr< MultiplicationOp< ExprT1, ConstExpr<T2> >,ExprSpecDefault > {
789 
790  public:
791 
792  typedef ConstExpr<T2> ConstT;
793  typedef ConstExpr<T2> ExprT2;
794  typedef typename ExprT1::value_type value_type_1;
795  typedef typename ExprT2::value_type value_type_2;
796  typedef typename Sacado::Promote<value_type_1,
797  value_type_2>::type value_type;
798 
799  typedef typename ExprT1::scalar_type scalar_type_1;
800  typedef typename ExprT2::scalar_type scalar_type_2;
801  typedef typename Sacado::Promote<scalar_type_1,
802  scalar_type_2>::type scalar_type;
803 
804  typedef typename ExprT1::base_expr_type base_expr_type_1;
805  typedef typename ExprT2::base_expr_type base_expr_type_2;
806  typedef typename Sacado::Promote<base_expr_type_1,
807  base_expr_type_2>::type base_expr_type;
808 
810  Expr(const ExprT1& expr1_, const ConstT& c_) :
811  expr1(expr1_), c(c_) {}
812 
814  int size() const {
815  return expr1.size();
816  }
817 
819  bool hasFastAccess() const {
820  return expr1.hasFastAccess();
821  }
822 
824  bool isPassive() const {
825  return expr1.isPassive();
826  }
827 
829  bool updateValue() const { return expr1.updateValue(); }
830 
832  void cache() const {}
833 
835  const value_type val() const {
836  return expr1.val()*c.val();
837  }
838 
840  const value_type dx(int i) const {
841  return expr1.dx(i)*c.val();
842  }
843 
845  const value_type fastAccessDx(int i) const {
846  return expr1.fastAccessDx(i)*c.val();
847  }
848 
849  protected:
850 
851  const ExprT1& expr1;
852  ConstT c;
853  };
854 
855  template <typename T1, typename ExprT2>
856  struct ExprSpec< MultiplicationOp< ConstExpr<T1>, ExprT2 > > {
857  typedef typename ExprSpec<ExprT2>::type type;
858  };
859 
860  template <typename T1, typename ExprT2>
861  class Expr< MultiplicationOp< ConstExpr<T1>, ExprT2 >,ExprSpecDefault > {
862 
863  public:
864 
865  typedef ConstExpr<T1> ConstT;
866  typedef ConstExpr<T1> ExprT1;
867  typedef typename ExprT1::value_type value_type_1;
868  typedef typename ExprT2::value_type value_type_2;
869  typedef typename Sacado::Promote<value_type_1,
870  value_type_2>::type value_type;
871 
872  typedef typename ExprT1::scalar_type scalar_type_1;
873  typedef typename ExprT2::scalar_type scalar_type_2;
874  typedef typename Sacado::Promote<scalar_type_1,
875  scalar_type_2>::type scalar_type;
876 
877  typedef typename ExprT1::base_expr_type base_expr_type_1;
878  typedef typename ExprT2::base_expr_type base_expr_type_2;
879  typedef typename Sacado::Promote<base_expr_type_1,
880  base_expr_type_2>::type base_expr_type;
881 
883  Expr(const ConstT& c_, const ExprT2& expr2_) :
884  c(c_), expr2(expr2_) {}
885 
887  int size() const {
888  return expr2.size();
889  }
890 
892  bool hasFastAccess() const {
893  return expr2.hasFastAccess();
894  }
895 
897  bool isPassive() const {
898  return expr2.isPassive();
899  }
900 
902  bool updateValue() const { return expr2.updateValue(); }
903 
905  void cache() const {}
906 
908  const value_type val() const {
909  return c.val()*expr2.val();
910  }
911 
913  const value_type dx(int i) const {
914  return c.val()*expr2.dx(i);
915  }
916 
918  const value_type fastAccessDx(int i) const {
919  return c.val()*expr2.fastAccessDx(i);
920  }
921 
922  protected:
923 
924  ConstT c;
925  const ExprT2& expr2;
926  };
927 
928  template <typename T1, typename T2>
931  operator* (const T1& expr1, const T2& expr2)
932  {
933  typedef MultiplicationOp< T1, T2 > expr_t;
934 
935  return Expr<expr_t>(expr1, expr2);
936  }
937 
938  template <typename T>
940  Expr< MultiplicationOp< Expr<T>, Expr<T> > >
941  operator* (const Expr<T>& expr1, const Expr<T>& expr2)
942  {
943  typedef MultiplicationOp< Expr<T>, Expr<T> > expr_t;
944 
945  return Expr<expr_t>(expr1, expr2);
946  }
947 
948  template <typename T>
951  operator* (const typename Expr<T>::value_type& c,
952  const Expr<T>& expr)
953  {
955  typedef MultiplicationOp< ConstT, Expr<T> > expr_t;
956 
957  return Expr<expr_t>(ConstT(c), expr);
958  }
959 
960  template <typename T>
962  Expr< MultiplicationOp< Expr<T>, ConstExpr<typename Expr<T>::value_type> > >
963  operator* (const Expr<T>& expr,
964  const typename Expr<T>::value_type& c)
965  {
967  typedef MultiplicationOp< Expr<T>, ConstT > expr_t;
968 
969  return Expr<expr_t>(expr, ConstT(c));
970  }
971 
972  template <typename T>
975  operator* (const typename Expr<T>::scalar_type& c,
976  const Expr<T>& expr)
977  {
979  typedef MultiplicationOp< ConstT, Expr<T> > expr_t;
980 
981  return Expr<expr_t>(ConstT(c), expr);
982  }
983 
984  template <typename T>
987  operator* (const Expr<T>& expr,
988  const typename Expr<T>::scalar_type& c)
989  {
991  typedef MultiplicationOp< Expr<T>, ConstT > expr_t;
992 
993  return Expr<expr_t>(expr, ConstT(c));
994  }
995  }
996 }
997 
998 //--------------------------if_then_else operator -----------------------
999 // Can't use the above macros because it is a ternary operator (sort of).
1000 // Also, relies on C++11
1001 
1002 #ifdef HAVE_SACADO_CXX11
1003 
1004 namespace Sacado {
1005  namespace Fad {
1006 
1007  template <typename CondT, typename ExprT1, typename ExprT2>
1008  class IfThenElseOp {};
1009 
1010  template <typename CondT, typename ExprT1, typename ExprT2>
1011  struct ExprSpec< IfThenElseOp< CondT, ExprT1, ExprT2 > > {
1012  typedef typename ExprSpec<ExprT1>::type type;
1013  };
1014 
1015  template <typename CondT, typename ExprT1, typename ExprT2>
1016  class Expr< IfThenElseOp< CondT, ExprT1, ExprT2 >,ExprSpecDefault > {
1017 
1018  public:
1019 
1020  typedef typename ExprT1::value_type value_type_1;
1021  typedef typename ExprT2::value_type value_type_2;
1022  typedef typename Sacado::Promote<value_type_1,
1023  value_type_2>::type value_type;
1024 
1025  typedef typename ExprT1::scalar_type scalar_type_1;
1026  typedef typename ExprT2::scalar_type scalar_type_2;
1027  typedef typename Sacado::Promote<scalar_type_1,
1028  scalar_type_2>::type scalar_type;
1029 
1030  typedef typename ExprT1::base_expr_type base_expr_type_1;
1031  typedef typename ExprT2::base_expr_type base_expr_type_2;
1032  typedef typename Sacado::Promote<base_expr_type_1,
1033  base_expr_type_2>::type base_expr_type;
1034 
1036  Expr(const CondT& cond_, const ExprT1& expr1_, const ExprT2& expr2_) :
1037  cond(cond_), expr1(expr1_), expr2(expr2_) {}
1038 
1040  int size() const {
1041  int sz1 = expr1.size(), sz2 = expr2.size();
1042  return sz1 > sz2 ? sz1 : sz2;
1043  }
1044 
1046  bool hasFastAccess() const {
1047  return expr1.hasFastAccess() && expr2.hasFastAccess();
1048  }
1049 
1051  bool isPassive() const {
1052  return expr1.isPassive() && expr2.isPassive();
1053  }
1054 
1056  bool updateValue() const {
1057  return expr1.updateValue() && expr2.updateValue();
1058  }
1059 
1061  void cache() const {}
1062 
1064  const value_type val() const {
1065  using Sacado::if_then_else;
1066  return if_then_else( cond, expr1.val(), expr2.val() );
1067  }
1068 
1070  const value_type dx(int i) const {
1071  using Sacado::if_then_else;
1072  return if_then_else( cond, expr1.dx(i), expr2.dx(i) );
1073  }
1074 
1076  const value_type fastAccessDx(int i) const {
1077  using Sacado::if_then_else;
1078  return if_then_else( cond, expr1.fastAccessDx(i), expr2.fastAccessDx(i) );
1079  }
1080 
1081  protected:
1082 
1083  const CondT& cond;
1084  const ExprT1& expr1;
1085  const ExprT2& expr2;
1086 
1087  };
1088 
1089  template <typename CondT, typename ExprT1, typename T2>
1090  struct ExprSpec< IfThenElseOp< CondT, ExprT1, ConstExpr<T2> > > {
1091  typedef typename ExprSpec<ExprT1>::type type;
1092  };
1093 
1094  template <typename CondT, typename ExprT1, typename T2>
1095  class Expr< IfThenElseOp< CondT, ExprT1, ConstExpr<T2> >,ExprSpecDefault > {
1096 
1097  public:
1098 
1099  typedef ConstExpr<T2> ConstT;
1100  typedef ConstExpr<T2> ExprT2;
1101  typedef typename ExprT1::value_type value_type_1;
1102  typedef typename ExprT2::value_type value_type_2;
1103  typedef typename Sacado::Promote<value_type_1,
1104  value_type_2>::type value_type;
1105 
1106  typedef typename ExprT1::scalar_type scalar_type_1;
1107  typedef typename ExprT2::scalar_type scalar_type_2;
1108  typedef typename Sacado::Promote<scalar_type_1,
1109  scalar_type_2>::type scalar_type;
1110 
1111  typedef typename ExprT1::base_expr_type base_expr_type_1;
1112  typedef typename ExprT2::base_expr_type base_expr_type_2;
1113  typedef typename Sacado::Promote<base_expr_type_1,
1114  base_expr_type_2>::type base_expr_type;
1115 
1117  Expr(const CondT& cond_, const ExprT1& expr1_, const ConstT& c_) :
1118  cond(cond_), expr1(expr1_), c(c_) {}
1119 
1121  int size() const {
1122  return expr1.size();
1123  }
1124 
1126  bool hasFastAccess() const {
1127  return expr1.hasFastAccess();
1128  }
1129 
1131  bool isPassive() const {
1132  return expr1.isPassive();
1133  }
1134 
1136  bool updateValue() const { return expr1.updateValue(); }
1137 
1139  void cache() const {}
1140 
1142  const value_type val() const {
1143  using Sacado::if_then_else;
1144  return if_then_else( cond, expr1.val(), c.val() );
1145  }
1146 
1148  const value_type dx(int i) const {
1149  using Sacado::if_then_else;
1150  return if_then_else( cond, expr1.dx(i), value_type(0.0) );
1151  }
1152 
1154  const value_type fastAccessDx(int i) const {
1155  using Sacado::if_then_else;
1156  return if_then_else( cond, expr1.fastAccessDx(i), value_type(0.0) );
1157  }
1158 
1159  protected:
1160 
1161  const CondT& cond;
1162  const ExprT1& expr1;
1163  ConstT c;
1164  };
1165 
1166  template <typename CondT, typename T1, typename ExprT2>
1167  struct ExprSpec< IfThenElseOp< CondT, ConstExpr<T1>, ExprT2 > > {
1168  typedef typename ExprSpec<ExprT2>::type type;
1169  };
1170 
1171  template <typename CondT, typename T1, typename ExprT2>
1172  class Expr< IfThenElseOp< CondT, ConstExpr<T1>, ExprT2 >,ExprSpecDefault > {
1173 
1174  public:
1175 
1176  typedef ConstExpr<T1> ConstT;
1177  typedef ConstExpr<T1> ExprT1;
1178  typedef typename ExprT1::value_type value_type_1;
1179  typedef typename ExprT2::value_type value_type_2;
1180  typedef typename Sacado::Promote<value_type_1,
1181  value_type_2>::type value_type;
1182 
1183  typedef typename ExprT1::scalar_type scalar_type_1;
1184  typedef typename ExprT2::scalar_type scalar_type_2;
1185  typedef typename Sacado::Promote<scalar_type_1,
1186  scalar_type_2>::type scalar_type;
1187 
1188  typedef typename ExprT1::base_expr_type base_expr_type_1;
1189  typedef typename ExprT2::base_expr_type base_expr_type_2;
1190  typedef typename Sacado::Promote<base_expr_type_1,
1191  base_expr_type_2>::type base_expr_type;
1192 
1194  Expr(const CondT& cond_, const ConstT& c_, const ExprT2& expr2_) :
1195  cond(cond_), c(c_), expr2(expr2_) {}
1196 
1198  int size() const {
1199  return expr2.size();
1200  }
1201 
1203  bool hasFastAccess() const {
1204  return expr2.hasFastAccess();
1205  }
1206 
1208  bool isPassive() const {
1209  return expr2.isPassive();
1210  }
1211 
1213  bool updateValue() const { return expr2.updateValue(); }
1214 
1216  void cache() const {}
1217 
1219  const value_type val() const {
1220  using Sacado::if_then_else;
1221  return if_then_else( cond, c.val(), expr2.val() );
1222  }
1223 
1225  const value_type dx(int i) const {
1226  using Sacado::if_then_else;
1227  return if_then_else( cond, value_type(0.0), expr2.dx(i) );
1228  }
1229 
1231  const value_type fastAccessDx(int i) const {
1232  using Sacado::if_then_else;
1233  return if_then_else( cond, value_type(0.0), expr2.fastAccessDx(i) );
1234  }
1235 
1236  protected:
1237 
1238  const CondT& cond;
1239  ConstT c;
1240  const ExprT2& expr2;
1241  };
1242 
1243  template <typename CondT, typename T1, typename T2>
1245  typename mpl::enable_if_c< IsFadExpr<T1>::value && IsFadExpr<T2>::value &&
1247  Expr< IfThenElseOp< CondT, T1, T2 > >
1248  >::type
1249  if_then_else (const CondT& cond, const T1& expr1, const T2& expr2)
1250  {
1251  typedef IfThenElseOp< CondT, T1, T2 > expr_t;
1252 
1253  return Expr<expr_t>(cond, expr1, expr2);
1254  }
1255 
1256  template <typename CondT, typename T>
1258  Expr< IfThenElseOp< CondT, Expr<T>, Expr<T> > >
1259  if_then_else (const CondT& cond, const Expr<T>& expr1, const Expr<T>& expr2)
1260  {
1261  typedef IfThenElseOp< CondT, Expr<T>, Expr<T> > expr_t;
1262 
1263  return Expr<expr_t>(cond, expr1, expr2);
1264  }
1265 
1266  template <typename CondT, typename T>
1269  Expr<T> > >
1270  if_then_else (const CondT& cond, const typename Expr<T>::value_type& c,
1271  const Expr<T>& expr)
1272  {
1274  typedef IfThenElseOp< CondT, ConstT, Expr<T> > expr_t;
1275 
1276  return Expr<expr_t>(cond, ConstT(c), expr);
1277  }
1278 
1279  template <typename CondT, typename T>
1281  Expr< IfThenElseOp< CondT, Expr<T>,
1283  if_then_else (const CondT& cond, const Expr<T>& expr,
1284  const typename Expr<T>::value_type& c)
1285  {
1287  typedef IfThenElseOp< CondT, Expr<T>, ConstT > expr_t;
1288 
1289  return Expr<expr_t>(cond, expr, ConstT(c));
1290  }
1291 
1292  template <typename CondT, typename T>
1294  typename mpl::disable_if<
1295  mpl::is_same< typename Expr<T>::value_type,
1296  typename Expr<T>::scalar_type>,
1297  Expr< IfThenElseOp< CondT, ConstExpr<typename Expr<T>::scalar_type>,
1298  Expr<T> > >
1299  >::type
1300  if_then_else (const CondT& cond, const typename Expr<T>::scalar_type& c,
1301  const Expr<T>& expr)
1302  {
1304  typedef IfThenElseOp< CondT, ConstT, Expr<T> > expr_t;
1305 
1306  return Expr<expr_t>(cond, ConstT(c), expr);
1307  }
1308 
1309  template <typename CondT, typename T>
1311  typename mpl::disable_if<
1312  mpl::is_same< typename Expr<T>::value_type,
1313  typename Expr<T>::scalar_type>,
1314  Expr< IfThenElseOp< CondT, Expr<T>,
1316  >::type
1317  if_then_else (const CondT& cond, const Expr<T>& expr,
1318  const typename Expr<T>::scalar_type& c)
1319  {
1321  typedef IfThenElseOp< CondT, Expr<T>, ConstT > expr_t;
1322 
1323  return Expr<expr_t>(cond, expr, ConstT(c));
1324  }
1325  }
1326 }
1327 
1328 #endif
1329 
1330 //-------------------------- Relational Operators -----------------------
1331 
1332 #ifdef HAVE_SACADO_CXX11
1333 
1334 namespace Sacado {
1335  namespace Fad {
1336  template <typename T1, typename T2 = T1>
1337  struct ConditionalReturnType {
1338  typedef decltype( std::declval<T1>() == std::declval<T2>() ) type;
1339  };
1340  }
1341 }
1342 
1343 #define FAD_RELOP_MACRO(OP) \
1344 namespace Sacado { \
1345  namespace Fad { \
1346  template <typename ExprT1, typename ExprT2> \
1347  KOKKOS_INLINE_FUNCTION \
1348  typename ConditionalReturnType<typename Expr<ExprT1>::value_type, \
1349  typename Expr<ExprT2>::value_type>::type \
1350  operator OP (const Expr<ExprT1>& expr1, \
1351  const Expr<ExprT2>& expr2) \
1352  { \
1353  return expr1.val() OP expr2.val(); \
1354  } \
1355  \
1356  template <typename ExprT2> \
1357  KOKKOS_INLINE_FUNCTION \
1358  typename ConditionalReturnType<typename Expr<ExprT2>::value_type>::type \
1359  operator OP (const typename Expr<ExprT2>::value_type& a, \
1360  const Expr<ExprT2>& expr2) \
1361  { \
1362  return a OP expr2.val(); \
1363  } \
1364  \
1365  template <typename ExprT1> \
1366  KOKKOS_INLINE_FUNCTION \
1367  typename ConditionalReturnType<typename Expr<ExprT1>::value_type>::type \
1368  operator OP (const Expr<ExprT1>& expr1, \
1369  const typename Expr<ExprT1>::value_type& b) \
1370  { \
1371  return expr1.val() OP b; \
1372  } \
1373  } \
1374 }
1375 
1376 #else
1377 
1378 #define FAD_RELOP_MACRO(OP) \
1379 namespace Sacado { \
1380  namespace Fad { \
1381  template <typename ExprT1, typename ExprT2> \
1382  KOKKOS_INLINE_FUNCTION \
1383  bool \
1384  operator OP (const Expr<ExprT1>& expr1, \
1385  const Expr<ExprT2>& expr2) \
1386  { \
1387  return expr1.val() OP expr2.val(); \
1388  } \
1389  \
1390  template <typename ExprT2> \
1391  KOKKOS_INLINE_FUNCTION \
1392  bool \
1393  operator OP (const typename Expr<ExprT2>::value_type& a, \
1394  const Expr<ExprT2>& expr2) \
1395  { \
1396  return a OP expr2.val(); \
1397  } \
1398  \
1399  template <typename ExprT1> \
1400  KOKKOS_INLINE_FUNCTION \
1401  bool \
1402  operator OP (const Expr<ExprT1>& expr1, \
1403  const typename Expr<ExprT1>::value_type& b) \
1404  { \
1405  return expr1.val() OP b; \
1406  } \
1407  } \
1408 }
1409 
1410 #endif
1411 
1412 FAD_RELOP_MACRO(==)
1413 FAD_RELOP_MACRO(!=)
1414 FAD_RELOP_MACRO(<)
1415 FAD_RELOP_MACRO(>)
1416 FAD_RELOP_MACRO(<=)
1417 FAD_RELOP_MACRO(>=)
1418 FAD_RELOP_MACRO(<<=)
1419 FAD_RELOP_MACRO(>>=)
1420 FAD_RELOP_MACRO(&)
1421 FAD_RELOP_MACRO(|)
1422 
1423 #undef FAD_RELOP_MACRO
1424 
1425 namespace Sacado {
1426 
1427  namespace Fad {
1428 
1429  template <typename ExprT>
1431  bool operator ! (const Expr<ExprT>& expr)
1432  {
1433  return ! expr.val();
1434  }
1435 
1436  } // namespace Fad
1437 
1438 } // namespace Sacado
1439 
1440 //-------------------------- Boolean Operators -----------------------
1441 namespace Sacado {
1442 
1443  namespace Fad {
1444 
1445  template <typename ExprT>
1447  bool toBool(const Expr<ExprT>& x) {
1448  bool is_zero = (x.val() == 0.0);
1449  for (int i=0; i<x.size(); i++)
1450  is_zero = is_zero && (x.dx(i) == 0.0);
1451  return !is_zero;
1452  }
1453 
1454  } // namespace Fad
1455 
1456 } // namespace Sacado
1457 
1458 #define FAD_BOOL_MACRO(OP) \
1459 namespace Sacado { \
1460  namespace Fad { \
1461  template <typename ExprT1, typename ExprT2> \
1462  KOKKOS_INLINE_FUNCTION \
1463  bool \
1464  operator OP (const Expr<ExprT1>& expr1, \
1465  const Expr<ExprT2>& expr2) \
1466  { \
1467  return toBool(expr1) OP toBool(expr2); \
1468  } \
1469  \
1470  template <typename ExprT2> \
1471  KOKKOS_INLINE_FUNCTION \
1472  bool \
1473  operator OP (const typename Expr<ExprT2>::value_type& a, \
1474  const Expr<ExprT2>& expr2) \
1475  { \
1476  return a OP toBool(expr2); \
1477  } \
1478  \
1479  template <typename ExprT1> \
1480  KOKKOS_INLINE_FUNCTION \
1481  bool \
1482  operator OP (const Expr<ExprT1>& expr1, \
1483  const typename Expr<ExprT1>::value_type& b) \
1484  { \
1485  return toBool(expr1) OP b; \
1486  } \
1487  } \
1488 }
1489 
1490 FAD_BOOL_MACRO(&&)
1491 FAD_BOOL_MACRO(||)
1492 
1493 #undef FAD_BOOL_MACRO
1494 
1495 //-------------------------- I/O Operators -----------------------
1496 
1497 namespace Sacado {
1498 
1499  namespace Fad {
1500 
1501  template <typename ExprT>
1502  std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
1503  os << x.val() << " [";
1504 
1505  for (int i=0; i< x.size(); i++) {
1506  os << " " << x.dx(i);
1507  }
1508 
1509  os << " ]";
1510  return os;
1511  }
1512 
1513  } // namespace Fad
1514 
1515 } // namespace Sacado
1516 
1517 #endif // SACADO_FAD_OPS_HPP
Wrapper for a generic expression template.
cbrt(expr.val())
expr expr ASinhOp
ScalarType< value_type >::type scalar_type
Typename of scalar&#39;s (which may be different from ConstT)
atan2(expr1.val(), expr2.val())
expr val()
expr expr expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
expr1 expr1 expr1 c expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr1 expr2 expr1 expr2 expr1 Atan2Op
expr expr TanOp
#define FAD_BINARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, FASTACCESSDX, VAL_CONST_DX_1, VAL_CONST_DX_2, CONST_DX_1, CONST_DX_2, CONST_FASTACCESSDX_1, CONST_FASTACCESSDX_2)
tanh(expr.val())
#define SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP)
sqrt(expr.val())
abs(expr.val())
KOKKOS_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
expr expr SinOp
expr expr ASinOp
expr expr SinhOp
#define SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP)
fabs(expr.val())
expr expr Log10Op
expr expr SqrtOp
exp(expr.val())
expr expr CosOp
log(expr.val())
#define KOKKOS_INLINE_FUNCTION
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
expr expr AbsOp
#define FAD_BOOL_MACRO(OP)
#define T2(r, f)
Definition: Sacado_rad.hpp:578
atan(expr.val())
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
expr expr expr ExpOp
atanh(expr.val())
asin(expr.val())
expr2 expr2 c c c c PowerOp
expr1 expr1 expr1 c expr1 expr2 expr1 expr2 expr1 SubtractionOp
log10(expr.val())
tan(expr.val())
expr expr ACosOp
sin(expr.val())
UnaryMinusOp
#define T1(r, f)
Definition: Sacado_rad.hpp:603
cosh(expr.val())
expr expr ATanOp
cos(expr.val())
#define SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP)
static const unsigned value
expr expr dx(i)
#define FAD_UNARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, FASTACCESSDX)
sinh(expr.val())
acosh(expr.val())
expr expr ATanhOp
SimpleFad< ValueT > operator*(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
acos(expr.val())
pow(expr1.val(), expr2.val())
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
ConstT value_type
Typename of argument values.
#define FAD_RELOP_MACRO(OP)
KOKKOS_INLINE_FUNCTION bool toBool(const Expr< ExprT > &x)
KOKKOS_INLINE_FUNCTION T if_then_else(const Cond cond, const T &a, const T &b)
if_then_else(expr.val() >=0, expr.dx(i), value_type(-expr.dx(i)))
asinh(expr.val())
expr expr ACoshOp
AdditionOp
expr1 expr1 expr1 c expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr1 expr2 expr1 expr2 expr1 DivisionOp
Base template specification for Promote.
expr expr CoshOp
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
expr expr TanhOp