Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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_Fad_Ops_Fwd.hpp"
57 #include "Sacado_cmath.hpp"
58 #include <ostream> // for std::ostream
59 
60 #define FAD_UNARYOP_MACRO(OPNAME,OP,USING,VALUE,DX,FASTACCESSDX) \
61 namespace Sacado { \
62  namespace Fad { \
63  \
64  template <typename ExprT> \
65  class OP {}; \
66  \
67  template <typename ExprT> \
68  struct ExprSpec< OP<ExprT> > { \
69  typedef typename ExprSpec<ExprT>::type type; \
70  }; \
71  \
72  template <typename ExprT> \
73  class Expr< OP<ExprT>,ExprSpecDefault > { \
74  public: \
75  \
76  typedef typename ExprT::value_type value_type; \
77  typedef typename ExprT::scalar_type scalar_type; \
78  typedef typename ExprT::base_expr_type base_expr_type; \
79  \
80  KOKKOS_INLINE_FUNCTION \
81  Expr(const ExprT& expr_) : expr(expr_) {} \
82  \
83  KOKKOS_INLINE_FUNCTION \
84  int size() const { return expr.size(); } \
85  \
86  KOKKOS_INLINE_FUNCTION \
87  bool hasFastAccess() const { return expr.hasFastAccess(); } \
88  \
89  KOKKOS_INLINE_FUNCTION \
90  bool isPassive() const { return expr.isPassive();} \
91  \
92  KOKKOS_INLINE_FUNCTION \
93  bool updateValue() const { return expr.updateValue(); } \
94  \
95  KOKKOS_INLINE_FUNCTION \
96  void cache() const {} \
97  \
98  KOKKOS_INLINE_FUNCTION \
99  value_type val() const { \
100  USING \
101  return VALUE; \
102  } \
103  \
104  KOKKOS_INLINE_FUNCTION \
105  value_type dx(int i) const { \
106  USING \
107  return DX; \
108  } \
109  \
110  KOKKOS_INLINE_FUNCTION \
111  value_type fastAccessDx(int i) const { \
112  USING \
113  return FASTACCESSDX; \
114  } \
115  \
116  protected: \
117  \
118  const ExprT& expr; \
119  }; \
120  \
121  template <typename T> \
122  KOKKOS_INLINE_FUNCTION \
123  Expr< OP< Expr<T> > > \
124  OPNAME (const Expr<T>& expr) \
125  { \
126  typedef OP< Expr<T> > expr_t; \
127  \
128  return Expr<expr_t>(expr); \
129  } \
130  } \
131  \
132 }
133 
134 FAD_UNARYOP_MACRO(operator+,
135  UnaryPlusOp,
136  ;,
137  expr.val(),
138  expr.dx(i),
139  expr.fastAccessDx(i))
140 FAD_UNARYOP_MACRO(operator-,
142  ;,
143  -expr.val(),
144  -expr.dx(i),
145  -expr.fastAccessDx(i))
148  using std::exp;,
149  exp(expr.val()),
150  exp(expr.val())*expr.dx(i),
151  exp(expr.val())*expr.fastAccessDx(i))
154  using std::log;,
155  log(expr.val()),
156  expr.dx(i)/expr.val(),
157  expr.fastAccessDx(i)/expr.val())
160  using std::log10; using std::log;,
161  log10(expr.val()),
162  expr.dx(i)/( log(value_type(10))*expr.val()),
163  expr.fastAccessDx(i) / ( log(value_type(10))*expr.val()))
166  using std::sqrt;,
167  sqrt(expr.val()),
168  expr.dx(i)/(value_type(2)* sqrt(expr.val())),
169  expr.fastAccessDx(i)/(value_type(2)* sqrt(expr.val())))
172  using std::cos; using std::sin;,
173  cos(expr.val()),
174  -expr.dx(i)* sin(expr.val()),
175  -expr.fastAccessDx(i)* sin(expr.val()))
178  using std::cos; using std::sin;,
179  sin(expr.val()),
180  expr.dx(i)* cos(expr.val()),
181  expr.fastAccessDx(i)* cos(expr.val()))
184  using std::tan;,
185  std::tan(expr.val()),
186  expr.dx(i)*
187  (value_type(1)+ tan(expr.val())* tan(expr.val())),
188  expr.fastAccessDx(i)*
189  (value_type(1)+ tan(expr.val())* tan(expr.val())))
192  using std::acos; using std::sqrt;,
193  acos(expr.val()),
194  -expr.dx(i)/ sqrt(value_type(1)-expr.val()*expr.val()),
195  -expr.fastAccessDx(i) /
196  sqrt(value_type(1)-expr.val()*expr.val()))
199  using std::asin; using std::sqrt;,
200  asin(expr.val()),
201  expr.dx(i)/ sqrt(value_type(1)-expr.val()*expr.val()),
202  expr.fastAccessDx(i) /
203  sqrt(value_type(1)-expr.val()*expr.val()))
206  using std::atan;,
207  atan(expr.val()),
208  expr.dx(i)/(value_type(1)+expr.val()*expr.val()),
209  expr.fastAccessDx(i)/(value_type(1)+expr.val()*expr.val()))
212  using std::cosh; using std::sinh;,
213  cosh(expr.val()),
214  expr.dx(i)* sinh(expr.val()),
215  expr.fastAccessDx(i)* sinh(expr.val()))
216 FAD_UNARYOP_MACRO(sinh,
218  using std::cosh; using std::sinh;,
219  sinh(expr.val()),
220  expr.dx(i)* cosh(expr.val()),
221  expr.fastAccessDx(i)* cosh(expr.val()))
224  using std::tanh; using std::cosh;,
225  tanh(expr.val()),
226  expr.dx(i)/( cosh(expr.val())* cosh(expr.val())),
227  expr.fastAccessDx(i) /
228  ( cosh(expr.val())* cosh(expr.val())))
231  using std::acosh; using std::sqrt;,
232  acosh(expr.val()),
233  expr.dx(i)/ sqrt((expr.val()-value_type(1)) *
234  (expr.val()+value_type(1))),
235  expr.fastAccessDx(i)/ sqrt((expr.val()-value_type(1)) *
236  (expr.val()+value_type(1))))
239  using std::asinh; using std::sqrt;,
240  asinh(expr.val()),
241  expr.dx(i)/ sqrt(value_type(1)+expr.val()*expr.val()),
242  expr.fastAccessDx(i)/ sqrt(value_type(1)+
243  expr.val()*expr.val()))
246  using std::atanh;,
247  atanh(expr.val()),
248  expr.dx(i)/(value_type(1)-expr.val()*expr.val()),
249  expr.fastAccessDx(i)/(value_type(1)-
250  expr.val()*expr.val()))
253  using std::abs; using Sacado::if_then_else;,
254  abs(expr.val()),
255  if_then_else( expr.val() >= 0, expr.dx(i), value_type(-expr.dx(i)) ),
256  if_then_else( expr.val() >= 0, expr.fastAccessDx(i), value_type(-expr.fastAccessDx(i)) ) )
259  using std::fabs; using Sacado::if_then_else;,
260  fabs(expr.val()),
261  if_then_else( expr.val() >= 0, expr.dx(i), value_type(-expr.dx(i)) ),
262  if_then_else( expr.val() >= 0, expr.fastAccessDx(i), value_type(-expr.fastAccessDx(i)) ) )
263 #ifdef HAVE_SACADO_CXX11
265  CbrtOp,
266  using std::cbrt;,
267  cbrt(expr.val()),
268  expr.dx(i)/(value_type(3)*cbrt(expr.val()*expr.val())),
269  expr.fastAccessDx(i)/(value_type(3)*cbrt(expr.val()*expr.val())))
270 #endif
271 
272 #undef FAD_UNARYOP_MACRO
273 
274 #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) \
275 namespace Sacado { \
276  namespace Fad { \
277  \
278  template <typename ExprT1, typename ExprT2> \
279  class OP {}; \
280  \
281  template <typename ExprT1, typename ExprT2> \
282  struct ExprSpec< OP< ExprT1, ExprT2 > > { \
283  typedef typename ExprSpec<ExprT1>::type type; \
284  }; \
285  \
286  template <typename ExprT1, typename ExprT2> \
287  class Expr< OP< ExprT1, ExprT2 >,ExprSpecDefault > { \
288  \
289  public: \
290  \
291  typedef typename ExprT1::value_type value_type_1; \
292  typedef typename ExprT2::value_type value_type_2; \
293  typedef typename Sacado::Promote<value_type_1, \
294  value_type_2>::type value_type; \
295  \
296  typedef typename ExprT1::scalar_type scalar_type_1; \
297  typedef typename ExprT2::scalar_type scalar_type_2; \
298  typedef typename Sacado::Promote<scalar_type_1, \
299  scalar_type_2>::type scalar_type; \
300  \
301  typedef typename ExprT1::base_expr_type base_expr_type_1; \
302  typedef typename ExprT2::base_expr_type base_expr_type_2; \
303  typedef typename Sacado::Promote<base_expr_type_1, \
304  base_expr_type_2>::type base_expr_type; \
305  \
306  KOKKOS_INLINE_FUNCTION \
307  Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
308  expr1(expr1_), expr2(expr2_) {} \
309  \
310  KOKKOS_INLINE_FUNCTION \
311  int size() const { \
312  int sz1 = expr1.size(), sz2 = expr2.size(); \
313  return sz1 > sz2 ? sz1 : sz2; \
314  } \
315  \
316  KOKKOS_INLINE_FUNCTION \
317  bool hasFastAccess() const { \
318  return expr1.hasFastAccess() && expr2.hasFastAccess(); \
319  } \
320  \
321  KOKKOS_INLINE_FUNCTION \
322  bool isPassive() const { \
323  return expr1.isPassive() && expr2.isPassive(); \
324  } \
325  \
326  KOKKOS_INLINE_FUNCTION \
327  bool updateValue() const { \
328  return expr1.updateValue() && expr2.updateValue(); \
329  } \
330  \
332  void cache() const {} \
333  \
334  KOKKOS_INLINE_FUNCTION \
335  const value_type val() const { \
336  USING \
337  return VALUE; \
338  } \
339  \
340  KOKKOS_INLINE_FUNCTION \
341  const value_type dx(int i) const { \
342  USING \
343  return DX; \
344  } \
345  \
346  KOKKOS_INLINE_FUNCTION \
347  const value_type fastAccessDx(int i) const { \
348  USING \
349  return FASTACCESSDX; \
350  } \
351  \
352  protected: \
353  \
354  const ExprT1& expr1; \
355  const ExprT2& expr2; \
356  \
357  }; \
358  \
359  template <typename ExprT1, typename T2> \
360  struct ExprSpec< OP< ExprT1, ConstExpr<T2> > > { \
361  typedef typename ExprSpec<ExprT1>::type type; \
362  }; \
363  \
364  template <typename ExprT1, typename T2> \
365  class Expr< OP< ExprT1, ConstExpr<T2> >,ExprSpecDefault > { \
366  \
367  public: \
368  \
369  typedef ConstExpr<T2> ConstT; \
370  typedef ConstExpr<T2> ExprT2; \
371  typedef typename ExprT1::value_type value_type_1; \
372  typedef typename ExprT2::value_type value_type_2; \
373  typedef typename Sacado::Promote<value_type_1, \
374  value_type_2>::type value_type; \
375  \
376  typedef typename ExprT1::scalar_type scalar_type_1; \
377  typedef typename ExprT2::scalar_type scalar_type_2; \
378  typedef typename Sacado::Promote<scalar_type_1, \
379  scalar_type_2>::type scalar_type; \
380  \
381  typedef typename ExprT1::base_expr_type base_expr_type_1; \
382  typedef typename ExprT2::base_expr_type base_expr_type_2; \
383  typedef typename Sacado::Promote<base_expr_type_1, \
384  base_expr_type_2>::type base_expr_type; \
385  \
386  KOKKOS_INLINE_FUNCTION \
387  Expr(const ExprT1& expr1_, const ConstT& c_) : \
388  expr1(expr1_), c(c_) {} \
389  \
390  KOKKOS_INLINE_FUNCTION \
391  int size() const { \
392  return expr1.size(); \
393  } \
394  \
395  KOKKOS_INLINE_FUNCTION \
396  bool hasFastAccess() const { \
397  return expr1.hasFastAccess(); \
398  } \
399  \
400  KOKKOS_INLINE_FUNCTION \
401  bool isPassive() const { \
402  return expr1.isPassive(); \
403  } \
404  \
405  KOKKOS_INLINE_FUNCTION \
406  bool updateValue() const { return expr1.updateValue(); } \
407  \
409  void cache() const {} \
410  \
411  KOKKOS_INLINE_FUNCTION \
412  const value_type val() const { \
413  USING \
414  return VAL_CONST_DX_2; \
415  } \
416  \
417  KOKKOS_INLINE_FUNCTION \
418  const value_type dx(int i) const { \
419  USING \
420  return CONST_DX_2; \
421  } \
422  \
423  KOKKOS_INLINE_FUNCTION \
424  const value_type fastAccessDx(int i) const { \
425  USING \
426  return CONST_FASTACCESSDX_2; \
427  } \
428  \
429  protected: \
430  \
431  const ExprT1& expr1; \
432  ConstT c; \
433  }; \
434  \
435  template <typename T1, typename ExprT2> \
436  struct ExprSpec< OP< ConstExpr<T1>, ExprT2 > > { \
437  typedef typename ExprSpec<ExprT2>::type type; \
438  }; \
439  \
440  template <typename T1, typename ExprT2> \
441  class Expr< OP< ConstExpr<T1>, ExprT2 >,ExprSpecDefault > { \
442  \
443  public: \
444  \
445  typedef ConstExpr<T1> ConstT; \
446  typedef ConstExpr<T1> ExprT1; \
447  typedef typename ExprT1::value_type value_type_1; \
448  typedef typename ExprT2::value_type value_type_2; \
449  typedef typename Sacado::Promote<value_type_1, \
450  value_type_2>::type value_type; \
451  \
452  typedef typename ExprT1::scalar_type scalar_type_1; \
453  typedef typename ExprT2::scalar_type scalar_type_2; \
454  typedef typename Sacado::Promote<scalar_type_1, \
455  scalar_type_2>::type scalar_type; \
456  \
457  typedef typename ExprT1::base_expr_type base_expr_type_1; \
458  typedef typename ExprT2::base_expr_type base_expr_type_2; \
459  typedef typename Sacado::Promote<base_expr_type_1, \
460  base_expr_type_2>::type base_expr_type; \
461  \
462  \
463  KOKKOS_INLINE_FUNCTION \
464  Expr(const ConstT& c_, const ExprT2& expr2_) : \
465  c(c_), expr2(expr2_) {} \
466  \
467  KOKKOS_INLINE_FUNCTION \
468  int size() const { \
469  return expr2.size(); \
470  } \
471  \
472  KOKKOS_INLINE_FUNCTION \
473  bool hasFastAccess() const { \
474  return expr2.hasFastAccess(); \
475  } \
476  \
477  KOKKOS_INLINE_FUNCTION \
478  bool isPassive() const { \
479  return expr2.isPassive(); \
480  } \
481  \
482  KOKKOS_INLINE_FUNCTION \
483  bool updateValue() const { return expr2.updateValue(); } \
484  \
486  void cache() const {} \
487  \
488  KOKKOS_INLINE_FUNCTION \
489  const value_type val() const { \
490  USING \
491  return VAL_CONST_DX_1; \
492  } \
493  \
494  KOKKOS_INLINE_FUNCTION \
495  const value_type dx(int i) const { \
496  USING \
497  return CONST_DX_1; \
498  } \
499  \
500  KOKKOS_INLINE_FUNCTION \
501  const value_type fastAccessDx(int i) const { \
502  USING \
503  return CONST_FASTACCESSDX_1; \
504  } \
505  \
506  protected: \
507  \
508  ConstT c; \
509  const ExprT2& expr2; \
510  }; \
511  \
512  template <typename T1, typename T2> \
513  KOKKOS_INLINE_FUNCTION \
514  typename mpl::enable_if_c< \
515  ExprLevel< Expr<T1> >::value == ExprLevel< Expr<T2> >::value, \
516  Expr< OP< Expr<T1>, Expr<T2> > > \
517  >::type \
518  /*SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP)*/ \
519  OPNAME (const Expr<T1>& expr1, const Expr<T2>& expr2) \
520  { \
521  typedef OP< Expr<T1>, Expr<T2> > expr_t; \
522  \
523  return Expr<expr_t>(expr1, expr2); \
524  } \
525  \
526  template <typename T> \
527  KOKKOS_INLINE_FUNCTION \
528  Expr< OP< Expr<T>, Expr<T> > > \
529  OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
530  { \
531  typedef OP< Expr<T>, Expr<T> > expr_t; \
532  \
533  return Expr<expr_t>(expr1, expr2); \
534  } \
535  \
536  template <typename T> \
537  KOKKOS_INLINE_FUNCTION \
538  Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
539  Expr<T> > > \
540  OPNAME (const typename Expr<T>::value_type& c, \
541  const Expr<T>& expr) \
542  { \
543  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
544  typedef OP< ConstT, Expr<T> > expr_t; \
545  \
546  return Expr<expr_t>(ConstT(c), expr); \
547  } \
548  \
549  template <typename T> \
550  KOKKOS_INLINE_FUNCTION \
551  Expr< OP< Expr<T>, \
552  ConstExpr<typename Expr<T>::value_type> > > \
553  OPNAME (const Expr<T>& expr, \
554  const typename Expr<T>::value_type& c) \
555  { \
556  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
557  typedef OP< Expr<T>, ConstT > expr_t; \
558  \
559  return Expr<expr_t>(expr, ConstT(c)); \
560  } \
561  \
562  template <typename T> \
565  OPNAME (const typename Expr<T>::scalar_type& c, \
566  const Expr<T>& expr) \
567  { \
568  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
569  typedef OP< ConstT, Expr<T> > expr_t; \
570  \
571  return Expr<expr_t>(ConstT(c), expr); \
572  } \
573  \
574  template <typename T> \
577  OPNAME (const Expr<T>& expr, \
578  const typename Expr<T>::scalar_type& c) \
579  { \
580  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
581  typedef OP< Expr<T>, ConstT > expr_t; \
582  \
583  return Expr<expr_t>(expr, ConstT(c)); \
584  } \
585  } \
586  \
587 }
588 
589 
590 FAD_BINARYOP_MACRO(operator+,
592  ;,
593  expr1.val() + expr2.val(),
594  expr1.dx(i) + expr2.dx(i),
595  expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
596  c.val() + expr2.val(),
597  expr1.val() + c.val(),
598  expr2.dx(i),
599  expr1.dx(i),
600  expr2.fastAccessDx(i),
601  expr1.fastAccessDx(i))
602 FAD_BINARYOP_MACRO(operator-,
604  ;,
605  expr1.val() - expr2.val(),
606  expr1.dx(i) - expr2.dx(i),
607  expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
608  c.val() - expr2.val(),
609  expr1.val() - c.val(),
610  -expr2.dx(i),
611  expr1.dx(i),
612  -expr2.fastAccessDx(i),
613  expr1.fastAccessDx(i))
614 // FAD_BINARYOP_MACRO(operator*,
615 // MultiplicationOp,
616 // ;,
617 // expr1.val() * expr2.val(),
618 // expr1.val()*expr2.dx(i) + expr1.dx(i)*expr2.val(),
619 // expr1.val()*expr2.fastAccessDx(i) +
620 // expr1.fastAccessDx(i)*expr2.val(),
621 // c.val() * expr2.val(),
622 // expr1.val() * c.val(),
623 // c.val()*expr2.dx(i),
624 // expr1.dx(i)*c.val(),
625 // c.val()*expr2.fastAccessDx(i),
626 // expr1.fastAccessDx(i)*c.val())
627 FAD_BINARYOP_MACRO(operator/,
629  ;,
630  expr1.val() / expr2.val(),
631  (expr1.dx(i)*expr2.val() - expr2.dx(i)*expr1.val()) /
632  (expr2.val()*expr2.val()),
633  (expr1.fastAccessDx(i)*expr2.val() -
634  expr2.fastAccessDx(i)*expr1.val()) /
635  (expr2.val()*expr2.val()),
636  c.val() / expr2.val(),
637  expr1.val() / c.val(),
638  -expr2.dx(i)*c.val() / (expr2.val()*expr2.val()),
639  expr1.dx(i)/c.val(),
640  -expr2.fastAccessDx(i)*c.val() / (expr2.val()*expr2.val()),
641  expr1.fastAccessDx(i)/c.val())
644  using std::atan2;,
645  atan2(expr1.val(), expr2.val()),
646  (expr2.val()*expr1.dx(i) - expr1.val()*expr2.dx(i))/
647  (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
648  (expr2.val()*expr1.fastAccessDx(i) - expr1.val()*expr2.fastAccessDx(i))/
649  (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
650  atan2(c.val(), expr2.val()),
651  atan2(expr1.val(), c.val()),
652  (-c.val()*expr2.dx(i)) / (c.val()*c.val() + expr2.val()*expr2.val()),
653  (c.val()*expr1.dx(i))/ (expr1.val()*expr1.val() + c.val()*c.val()),
654  (-c.val()*expr2.fastAccessDx(i))/ (c.val()*c.val() + expr2.val()*expr2.val()),
655  (c.val()*expr1.fastAccessDx(i))/ (expr1.val()*expr1.val() + c.val()*c.val()))
656 // FAD_BINARYOP_MACRO(pow,
657 // PowerOp,
658 // using std::pow; using std::log; using Sacado::if_then_else;,
659 // pow(expr1.val(), expr2.val()),
660 // 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())) ),
661 // 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())) ),
662 // pow(c.val(), expr2.val()),
663 // pow(expr1.val(), c.val()),
664 // 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())) ),
665 // 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())) ),
666 // 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())) ),
667 // 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()))) )
670  using Sacado::if_then_else;,
671  if_then_else( expr1.val() >= expr2.val(), expr1.val(), expr2.val() ),
672  if_then_else( expr1.val() >= expr2.val(), expr1.dx(i), expr2.dx(i) ),
673  if_then_else( expr1.val() >= expr2.val(), expr1.fastAccessDx(i), expr2.fastAccessDx(i) ),
674  if_then_else( c.val() >= expr2.val(), value_type(c.val()), expr2.val() ),
675  if_then_else( expr1.val() >= c.val(), expr1.val(), value_type(c.val()) ),
676  if_then_else( c.val() >= expr2.val(), value_type(0.0), expr2.dx(i) ),
677  if_then_else( expr1.val() >= c.val(), expr1.dx(i), value_type(0.0) ),
678  if_then_else( c.val() >= expr2.val(), value_type(0.0), expr2.fastAccessDx(i) ),
679  if_then_else( expr1.val() >= c.val(), expr1.fastAccessDx(i), value_type(0.0) ) )
682  using Sacado::if_then_else;,
683  if_then_else( expr1.val() <= expr2.val(), expr1.val(), expr2.val() ),
684  if_then_else( expr1.val() <= expr2.val(), expr1.dx(i), expr2.dx(i) ),
685  if_then_else( expr1.val() <= expr2.val(), expr1.fastAccessDx(i), expr2.fastAccessDx(i) ),
686  if_then_else( c.val() <= expr2.val(), value_type(c.val()), expr2.val() ),
687  if_then_else( expr1.val() <= c.val(), expr1.val(), value_type(c.val()) ),
688  if_then_else( c.val() <= expr2.val(), value_type(0), expr2.dx(i) ),
689  if_then_else( expr1.val() <= c.val(), expr1.dx(i), value_type(0) ),
690  if_then_else( c.val() <= expr2.val(), value_type(0), expr2.fastAccessDx(i) ),
691  if_then_else( expr1.val() <= c.val(), expr1.fastAccessDx(i), value_type(0) ) )
692 
693 
694 #undef FAD_BINARYOP_MACRO
695 
696 namespace Sacado {
697  namespace Fad {
698 
699  template <typename ExprT1, typename ExprT2>
700  class MultiplicationOp {};
701 
702  template <typename ExprT1, typename ExprT2>
703  struct ExprSpec< MultiplicationOp< ExprT1, ExprT2 > > {
704  typedef typename ExprSpec<ExprT1>::type type;
705  };
706 
707  template <typename ExprT1, typename ExprT2>
708  class Expr< MultiplicationOp< ExprT1, ExprT2 >,ExprSpecDefault > {
709 
710  public:
711 
712  typedef typename ExprT1::value_type value_type_1;
713  typedef typename ExprT2::value_type value_type_2;
714  typedef typename Sacado::Promote<value_type_1,
715  value_type_2>::type value_type;
716 
717  typedef typename ExprT1::scalar_type scalar_type_1;
718  typedef typename ExprT2::scalar_type scalar_type_2;
719  typedef typename Sacado::Promote<scalar_type_1,
720  scalar_type_2>::type scalar_type;
721 
722  typedef typename ExprT1::base_expr_type base_expr_type_1;
723  typedef typename ExprT2::base_expr_type base_expr_type_2;
724  typedef typename Sacado::Promote<base_expr_type_1,
725  base_expr_type_2>::type base_expr_type;
726 
728  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
729  expr1(expr1_), expr2(expr2_) {}
730 
732  int size() const {
733  int sz1 = expr1.size(), sz2 = expr2.size();
734  return sz1 > sz2 ? sz1 : sz2;
735  }
736 
738  bool hasFastAccess() const {
739  return expr1.hasFastAccess() && expr2.hasFastAccess();
740  }
741 
743  bool isPassive() const {
744  return expr1.isPassive() && expr2.isPassive();
745  }
746 
748  bool updateValue() const {
749  return expr1.updateValue() && expr2.updateValue();
750  }
751 
753  void cache() const {}
754 
756  const value_type val() const {
757  return expr1.val()*expr2.val();
758  }
759 
761  const value_type dx(int i) const {
762  if (expr1.size() > 0 && expr2.size() > 0)
763  return expr1.val()*expr2.dx(i) + expr1.dx(i)*expr2.val();
764  else if (expr1.size() > 0)
765  return expr1.dx(i)*expr2.val();
766  else
767  return expr1.val()*expr2.dx(i);
768  }
769 
771  const value_type fastAccessDx(int i) const {
772  return expr1.val()*expr2.fastAccessDx(i) +
773  expr1.fastAccessDx(i)*expr2.val();
774  }
775 
776  protected:
777 
778  const ExprT1& expr1;
779  const ExprT2& expr2;
780 
781  };
782 
783  template <typename ExprT1, typename T2>
784  struct ExprSpec< MultiplicationOp< ExprT1, ConstExpr<T2> > > {
785  typedef typename ExprSpec<ExprT1>::type type;
786  };
787 
788  template <typename ExprT1, typename T2>
789  class Expr< MultiplicationOp< ExprT1, ConstExpr<T2> >,ExprSpecDefault > {
790 
791  public:
792 
793  typedef ConstExpr<T2> ConstT;
794  typedef ConstExpr<T2> ExprT2;
795  typedef typename ExprT1::value_type value_type_1;
796  typedef typename ExprT2::value_type value_type_2;
797  typedef typename Sacado::Promote<value_type_1,
798  value_type_2>::type value_type;
799 
800  typedef typename ExprT1::scalar_type scalar_type_1;
801  typedef typename ExprT2::scalar_type scalar_type_2;
802  typedef typename Sacado::Promote<scalar_type_1,
803  scalar_type_2>::type scalar_type;
804 
805  typedef typename ExprT1::base_expr_type base_expr_type_1;
806  typedef typename ExprT2::base_expr_type base_expr_type_2;
807  typedef typename Sacado::Promote<base_expr_type_1,
808  base_expr_type_2>::type base_expr_type;
809 
811  Expr(const ExprT1& expr1_, const ConstT& c_) :
812  expr1(expr1_), c(c_) {}
813 
815  int size() const {
816  return expr1.size();
817  }
818 
820  bool hasFastAccess() const {
821  return expr1.hasFastAccess();
822  }
823 
825  bool isPassive() const {
826  return expr1.isPassive();
827  }
828 
830  bool updateValue() const { return expr1.updateValue(); }
831 
833  void cache() const {}
834 
836  const value_type val() const {
837  return expr1.val()*c.val();
838  }
839 
841  const value_type dx(int i) const {
842  return expr1.dx(i)*c.val();
843  }
844 
846  const value_type fastAccessDx(int i) const {
847  return expr1.fastAccessDx(i)*c.val();
848  }
849 
850  protected:
851 
852  const ExprT1& expr1;
853  ConstT c;
854  };
855 
856  template <typename T1, typename ExprT2>
857  struct ExprSpec< MultiplicationOp< ConstExpr<T1>, ExprT2 > > {
858  typedef typename ExprSpec<ExprT2>::type type;
859  };
860 
861  template <typename T1, typename ExprT2>
862  class Expr< MultiplicationOp< ConstExpr<T1>, ExprT2 >,ExprSpecDefault > {
863 
864  public:
865 
866  typedef ConstExpr<T1> ConstT;
867  typedef ConstExpr<T1> ExprT1;
868  typedef typename ExprT1::value_type value_type_1;
869  typedef typename ExprT2::value_type value_type_2;
870  typedef typename Sacado::Promote<value_type_1,
871  value_type_2>::type value_type;
872 
873  typedef typename ExprT1::scalar_type scalar_type_1;
874  typedef typename ExprT2::scalar_type scalar_type_2;
875  typedef typename Sacado::Promote<scalar_type_1,
876  scalar_type_2>::type scalar_type;
877 
878  typedef typename ExprT1::base_expr_type base_expr_type_1;
879  typedef typename ExprT2::base_expr_type base_expr_type_2;
880  typedef typename Sacado::Promote<base_expr_type_1,
881  base_expr_type_2>::type base_expr_type;
882 
884  Expr(const ConstT& c_, const ExprT2& expr2_) :
885  c(c_), expr2(expr2_) {}
886 
888  int size() const {
889  return expr2.size();
890  }
891 
893  bool hasFastAccess() const {
894  return expr2.hasFastAccess();
895  }
896 
898  bool isPassive() const {
899  return expr2.isPassive();
900  }
901 
903  bool updateValue() const { return expr2.updateValue(); }
904 
906  void cache() const {}
907 
909  const value_type val() const {
910  return c.val()*expr2.val();
911  }
912 
914  const value_type dx(int i) const {
915  return c.val()*expr2.dx(i);
916  }
917 
919  const value_type fastAccessDx(int i) const {
920  return c.val()*expr2.fastAccessDx(i);
921  }
922 
923  protected:
924 
925  ConstT c;
926  const ExprT2& expr2;
927  };
928 
929  template <typename T1, typename T2>
931  typename mpl::enable_if_c<
932  ExprLevel< Expr<T1> >::value == ExprLevel< Expr<T2> >::value,
933  Expr< MultiplicationOp< Expr<T1>, Expr<T2> > >
934  >::type
935  /*SACADO_FAD_OP_ENABLE_EXPR_EXPR(MultiplicationOp)*/
936  operator* (const Expr<T1>& expr1, const Expr<T2>& expr2)
937  {
938  typedef MultiplicationOp< Expr<T1>, Expr<T2> > expr_t;
939 
940  return Expr<expr_t>(expr1, expr2);
941  }
942 
943  template <typename T>
945  Expr< MultiplicationOp< Expr<T>, Expr<T> > >
946  operator* (const Expr<T>& expr1, const Expr<T>& expr2)
947  {
948  typedef MultiplicationOp< Expr<T>, Expr<T> > expr_t;
949 
950  return Expr<expr_t>(expr1, expr2);
951  }
952 
953  template <typename T>
955  Expr< MultiplicationOp< ConstExpr<typename Expr<T>::value_type>, Expr<T> > >
956  operator* (const typename Expr<T>::value_type& c,
957  const Expr<T>& expr)
958  {
959  typedef ConstExpr<typename Expr<T>::value_type> ConstT;
960  typedef MultiplicationOp< ConstT, Expr<T> > expr_t;
961 
962  return Expr<expr_t>(ConstT(c), expr);
963  }
964 
965  template <typename T>
967  Expr< MultiplicationOp< Expr<T>, ConstExpr<typename Expr<T>::value_type> > >
968  operator* (const Expr<T>& expr,
969  const typename Expr<T>::value_type& c)
970  {
971  typedef ConstExpr<typename Expr<T>::value_type> ConstT;
972  typedef MultiplicationOp< Expr<T>, ConstT > expr_t;
973 
974  return Expr<expr_t>(expr, ConstT(c));
975  }
976 
977  template <typename T>
979  SACADO_FAD_OP_ENABLE_SCALAR_EXPR(MultiplicationOp)
980  operator* (const typename Expr<T>::scalar_type& c,
981  const Expr<T>& expr)
982  {
983  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT;
984  typedef MultiplicationOp< ConstT, Expr<T> > expr_t;
985 
986  return Expr<expr_t>(ConstT(c), expr);
987  }
988 
989  template <typename T>
991  SACADO_FAD_OP_ENABLE_EXPR_SCALAR(MultiplicationOp)
992  operator* (const Expr<T>& expr,
993  const typename Expr<T>::scalar_type& c)
994  {
995  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT;
996  typedef MultiplicationOp< Expr<T>, ConstT > expr_t;
997 
998  return Expr<expr_t>(expr, ConstT(c));
999  }
1000  }
1001 }
1002 
1003 // Special handling for std::pow() to provide specializations of PowerOp for
1004 // "simd" value types that use if_then_else(). The only reason for not using
1005 // if_then_else() always is to avoid evaluating the derivative if the value is
1006 // zero to avoid throwing FPEs.
1007 namespace Sacado {
1008  namespace Fad {
1009 
1010  template <typename ExprT1, typename ExprT2, bool is_simd>
1011  class PowerOp {};
1012 
1013  template <typename ExprT1, typename ExprT2>
1014  struct ExprSpec< PowerOp< ExprT1, ExprT2 > > {
1015  typedef typename ExprSpec<ExprT1>::type type;
1016  };
1017 
1018  template <typename ExprT1, typename T2>
1019  struct ExprSpec<PowerOp< ExprT1, ConstExpr<T2> > > {
1020  typedef typename ExprSpec<ExprT1>::type type;
1021  };
1022 
1023  template <typename T1, typename ExprT2>
1024  struct ExprSpec< PowerOp< ConstExpr<T1>, ExprT2 > > {
1025  typedef typename ExprSpec<ExprT2>::type type;
1026  };
1027 
1028  //
1029  // Implementation for simd type using if_then_else()
1030  //
1031  template <typename ExprT1, typename ExprT2>
1032  class Expr< PowerOp< ExprT1, ExprT2, true >, ExprSpecDefault > {
1033 
1034  public:
1035 
1036  typedef typename ExprT1::value_type value_type_1;
1037  typedef typename ExprT2::value_type value_type_2;
1038  typedef typename Sacado::Promote<value_type_1,
1040 
1041  typedef typename ExprT1::scalar_type scalar_type_1;
1042  typedef typename ExprT2::scalar_type scalar_type_2;
1043  typedef typename Sacado::Promote<scalar_type_1,
1045 
1046  typedef typename ExprT1::base_expr_type base_expr_type_1;
1047  typedef typename ExprT2::base_expr_type base_expr_type_2;
1048  typedef typename Sacado::Promote<base_expr_type_1,
1050 
1052  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1053  expr1(expr1_), expr2(expr2_) {}
1054 
1056  int size() const {
1057  int sz1 = expr1.size(), sz2 = expr2.size();
1058  return sz1 > sz2 ? sz1 : sz2;
1059  }
1060 
1062  bool hasFastAccess() const {
1063  return expr1.hasFastAccess() && expr2.hasFastAccess();
1064  }
1065 
1067  bool isPassive() const {
1068  return expr1.isPassive() && expr2.isPassive();
1069  }
1070 
1072  bool updateValue() const {
1073  return expr1.updateValue() && expr2.updateValue();
1074  }
1075 
1077  void cache() const {}
1078 
1080  const value_type val() const {
1081  using std::pow;
1082  return pow(expr1.val(), expr2.val());
1083  }
1084 
1086  const value_type dx(int i) const {
1087  using std::pow; using std::log;
1088  return 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())) );
1089  }
1090 
1092  const value_type fastAccessDx(int i) const {
1093  using std::pow; using std::log;
1094  return 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())) );
1095  }
1096 
1097  protected:
1098 
1099  const ExprT1& expr1;
1100  const ExprT2& expr2;
1101 
1102  };
1103 
1104  template <typename ExprT1, typename T2>
1105  class Expr< PowerOp< ExprT1, ConstExpr<T2>, true >, ExprSpecDefault > {
1106 
1107  public:
1108 
1111  typedef typename ExprT1::value_type value_type_1;
1113  typedef typename Sacado::Promote<value_type_1,
1115 
1116  typedef typename ExprT1::scalar_type scalar_type_1;
1118  typedef typename Sacado::Promote<scalar_type_1,
1120 
1121  typedef typename ExprT1::base_expr_type base_expr_type_1;
1123  typedef typename Sacado::Promote<base_expr_type_1,
1125 
1127  Expr(const ExprT1& expr1_, const ConstT& c_) :
1128  expr1(expr1_), c(c_) {}
1129 
1131  int size() const {
1132  return expr1.size();
1133  }
1134 
1136  bool hasFastAccess() const {
1137  return expr1.hasFastAccess();
1138  }
1139 
1141  bool isPassive() const {
1142  return expr1.isPassive();
1143  }
1144 
1146  bool updateValue() const { return expr1.updateValue(); }
1147 
1149  void cache() const {}
1150 
1152  const value_type val() const {
1153  using std::pow;
1154  return pow(expr1.val(), c.val());
1155  }
1156 
1158  const value_type dx(int i) const {
1159  using std::pow;
1160  // Don't use formula (a(x)^b)' = b*a(x)^{b-1}*a'(x)
1161  // It seems less accurate and caused convergence problems in some codes
1162  return 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())) );
1163  }
1164 
1166  const value_type fastAccessDx(int i) const {
1167  using std::pow;
1168  // Don't use formula (a(x)^b)' = b*a(x)^{b-1}*a'(x)
1169  // It seems less accurate and caused convergence problems in some codes
1170  return 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())));
1171  }
1172 
1173  protected:
1174 
1175  const ExprT1& expr1;
1177  };
1178 
1179  template <typename T1, typename ExprT2>
1180  class Expr< PowerOp< ConstExpr<T1>, ExprT2, true >, ExprSpecDefault > {
1181 
1182  public:
1183 
1187  typedef typename ExprT2::value_type value_type_2;
1188  typedef typename Sacado::Promote<value_type_1,
1190 
1192  typedef typename ExprT2::scalar_type scalar_type_2;
1193  typedef typename Sacado::Promote<scalar_type_1,
1195 
1197  typedef typename ExprT2::base_expr_type base_expr_type_2;
1198  typedef typename Sacado::Promote<base_expr_type_1,
1200 
1201 
1203  Expr(const ConstT& c_, const ExprT2& expr2_) :
1204  c(c_), expr2(expr2_) {}
1205 
1207  int size() const {
1208  return expr2.size();
1209  }
1210 
1212  bool hasFastAccess() const {
1213  return expr2.hasFastAccess();
1214  }
1215 
1217  bool isPassive() const {
1218  return expr2.isPassive();
1219  }
1220 
1222  bool updateValue() const { return expr2.updateValue(); }
1223 
1225  void cache() const {}
1226 
1228  const value_type val() const {
1229  using std::pow;
1230  return pow(c.val(), expr2.val());
1231  }
1232 
1234  const value_type dx(int i) const {
1235  using std::pow; using std::log;
1236  return if_then_else( c.val() == scalar_type(0.0), value_type(0.0), value_type(expr2.dx(i)*log(c.val())*pow(c.val(),expr2.val())) );
1237  }
1238 
1240  const value_type fastAccessDx(int i) const {
1241  using std::pow; using std::log;
1242  return if_then_else( c.val() == scalar_type(0.0), value_type(0.0), value_type(expr2.fastAccessDx(i)*log(c.val())*pow(c.val(),expr2.val())) );
1243  }
1244 
1245  protected:
1246 
1248  const ExprT2& expr2;
1249  };
1250 
1251  //
1252  // Specialization for scalar types using ternary operator
1253  //
1254 
1255  template <typename ExprT1, typename ExprT2>
1256  class Expr< PowerOp< ExprT1, ExprT2, false >, ExprSpecDefault > {
1257 
1258  public:
1259 
1260  typedef typename ExprT1::value_type value_type_1;
1261  typedef typename ExprT2::value_type value_type_2;
1262  typedef typename Sacado::Promote<value_type_1,
1264 
1265  typedef typename ExprT1::scalar_type scalar_type_1;
1266  typedef typename ExprT2::scalar_type scalar_type_2;
1267  typedef typename Sacado::Promote<scalar_type_1,
1269 
1270  typedef typename ExprT1::base_expr_type base_expr_type_1;
1271  typedef typename ExprT2::base_expr_type base_expr_type_2;
1272  typedef typename Sacado::Promote<base_expr_type_1,
1274 
1276  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1277  expr1(expr1_), expr2(expr2_) {}
1278 
1280  int size() const {
1281  int sz1 = expr1.size(), sz2 = expr2.size();
1282  return sz1 > sz2 ? sz1 : sz2;
1283  }
1284 
1286  bool hasFastAccess() const {
1287  return expr1.hasFastAccess() && expr2.hasFastAccess();
1288  }
1289 
1291  bool isPassive() const {
1292  return expr1.isPassive() && expr2.isPassive();
1293  }
1294 
1296  bool updateValue() const {
1297  return expr1.updateValue() && expr2.updateValue();
1298  }
1299 
1301  void cache() const {}
1302 
1304  const value_type val() const {
1305  using std::pow;
1306  return pow(expr1.val(), expr2.val());
1307  }
1308 
1310  const value_type dx(int i) const {
1311  using std::pow; using std::log;
1312  return 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()));
1313  }
1314 
1316  const value_type fastAccessDx(int i) const {
1317  using std::pow; using std::log;
1318  return 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()));
1319  }
1320 
1321  protected:
1322 
1323  const ExprT1& expr1;
1324  const ExprT2& expr2;
1325 
1326  };
1327 
1328  template <typename ExprT1, typename T2>
1329  class Expr< PowerOp< ExprT1, ConstExpr<T2>, false >, ExprSpecDefault > {
1330 
1331  public:
1332 
1335  typedef typename ExprT1::value_type value_type_1;
1337  typedef typename Sacado::Promote<value_type_1,
1339 
1340  typedef typename ExprT1::scalar_type scalar_type_1;
1342  typedef typename Sacado::Promote<scalar_type_1,
1344 
1345  typedef typename ExprT1::base_expr_type base_expr_type_1;
1347  typedef typename Sacado::Promote<base_expr_type_1,
1349 
1351  Expr(const ExprT1& expr1_, const ConstT& c_) :
1352  expr1(expr1_), c(c_) {}
1353 
1355  int size() const {
1356  return expr1.size();
1357  }
1358 
1360  bool hasFastAccess() const {
1361  return expr1.hasFastAccess();
1362  }
1363 
1365  bool isPassive() const {
1366  return expr1.isPassive();
1367  }
1368 
1370  bool updateValue() const { return expr1.updateValue(); }
1371 
1373  void cache() const {}
1374 
1376  const value_type val() const {
1377  using std::pow;
1378  return pow(expr1.val(), c.val());
1379  }
1380 
1382  const value_type dx(int i) const {
1383  using std::pow;
1384  // Don't use formula (a(x)^b)' = b*a(x)^{b-1}*a'(x)
1385  // It seems less accurate and caused convergence problems in some codes
1386  return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type(c.val()*expr1.dx(i)/expr1.val()*pow(expr1.val(),c.val()));
1387  }
1388 
1390  const value_type fastAccessDx(int i) const {
1391  using std::pow;
1392  // Don't use formula (a(x)^b)' = b*a(x)^{b-1}*a'(x)
1393  // It seems less accurate and caused convergence problems in some codes
1394  return expr1.val() == value_type(0.0) ? value_type(0.0) : value_type(c.val()*expr1.fastAccessDx(i)/expr1.val()*pow(expr1.val(),c.val()));
1395  }
1396 
1397  protected:
1398 
1399  const ExprT1& expr1;
1401  };
1402 
1403  template <typename T1, typename ExprT2>
1404  class Expr< PowerOp< ConstExpr<T1>, ExprT2, false >, ExprSpecDefault > {
1405 
1406  public:
1407 
1411  typedef typename ExprT2::value_type value_type_2;
1412  typedef typename Sacado::Promote<value_type_1,
1414 
1416  typedef typename ExprT2::scalar_type scalar_type_2;
1417  typedef typename Sacado::Promote<scalar_type_1,
1419 
1421  typedef typename ExprT2::base_expr_type base_expr_type_2;
1422  typedef typename Sacado::Promote<base_expr_type_1,
1424 
1425 
1427  Expr(const ConstT& c_, const ExprT2& expr2_) :
1428  c(c_), expr2(expr2_) {}
1429 
1431  int size() const {
1432  return expr2.size();
1433  }
1434 
1436  bool hasFastAccess() const {
1437  return expr2.hasFastAccess();
1438  }
1439 
1441  bool isPassive() const {
1442  return expr2.isPassive();
1443  }
1444 
1446  bool updateValue() const { return expr2.updateValue(); }
1447 
1449  void cache() const {}
1450 
1452  const value_type val() const {
1453  using std::pow;
1454  return pow(c.val(), expr2.val());
1455  }
1456 
1458  const value_type dx(int i) const {
1459  using std::pow; using std::log;
1460  return c.val() == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.dx(i)*log(c.val())*pow(c.val(),expr2.val()));
1461  }
1462 
1464  const value_type fastAccessDx(int i) const {
1465  using std::pow; using std::log;
1466  return c.val() == scalar_type(0.0) ? value_type(0.0) : value_type(expr2.fastAccessDx(i)*log(c.val())*pow(c.val(),expr2.val()));
1467  }
1468 
1469  protected:
1470 
1472  const ExprT2& expr2;
1473  };
1474 
1475  template <typename T1, typename T2>
1477  typename mpl::enable_if_c<
1478  ExprLevel< Expr<T1> >::value == ExprLevel< Expr<T2> >::value,
1480  >::type
1481  /*SACADO_FAD_OP_ENABLE_EXPR_EXPR(PowerOp)*/
1482  pow (const Expr<T1>& expr1, const Expr<T2>& expr2)
1483  {
1484  typedef PowerOp< Expr<T1>, Expr<T2> > expr_t;
1485 
1486  return Expr<expr_t>(expr1, expr2);
1487  }
1488 
1489  template <typename T>
1491  Expr< PowerOp< Expr<T>, Expr<T> > >
1492  pow (const Expr<T>& expr1, const Expr<T>& expr2)
1493  {
1494  typedef PowerOp< Expr<T>, Expr<T> > expr_t;
1495 
1496  return Expr<expr_t>(expr1, expr2);
1497  }
1498 
1499  template <typename T>
1501  Expr< PowerOp< ConstExpr<typename Expr<T>::value_type>, Expr<T> > >
1502  pow (const typename Expr<T>::value_type& c,
1503  const Expr<T>& expr)
1504  {
1506  typedef PowerOp< ConstT, Expr<T> > expr_t;
1507 
1508  return Expr<expr_t>(ConstT(c), expr);
1509  }
1510 
1511  template <typename T>
1513  Expr< PowerOp< Expr<T>, ConstExpr<typename Expr<T>::value_type> > >
1514  pow (const Expr<T>& expr,
1515  const typename Expr<T>::value_type& c)
1516  {
1518  typedef PowerOp< Expr<T>, ConstT > expr_t;
1519 
1520  return Expr<expr_t>(expr, ConstT(c));
1521  }
1522 
1523  template <typename T>
1526  pow (const typename Expr<T>::scalar_type& c,
1527  const Expr<T>& expr)
1528  {
1530  typedef PowerOp< ConstT, Expr<T> > expr_t;
1531 
1532  return Expr<expr_t>(ConstT(c), expr);
1533  }
1534 
1535  template <typename T>
1538  pow (const Expr<T>& expr,
1539  const typename Expr<T>::scalar_type& c)
1540  {
1542  typedef PowerOp< Expr<T>, ConstT > expr_t;
1543 
1544  return Expr<expr_t>(expr, ConstT(c));
1545  }
1546  }
1547 }
1548 
1549 //--------------------------if_then_else operator -----------------------
1550 // Can't use the above macros because it is a ternary operator (sort of).
1551 // Also, relies on C++11
1552 
1553 #ifdef HAVE_SACADO_CXX11
1554 
1555 namespace Sacado {
1556  namespace Fad {
1557 
1558  template <typename CondT, typename ExprT1, typename ExprT2>
1559  class IfThenElseOp {};
1560 
1561  template <typename CondT, typename ExprT1, typename ExprT2>
1562  struct ExprSpec< IfThenElseOp< CondT, ExprT1, ExprT2 > > {
1563  typedef typename ExprSpec<ExprT1>::type type;
1564  };
1565 
1566  template <typename CondT, typename ExprT1, typename ExprT2>
1567  class Expr< IfThenElseOp< CondT, ExprT1, ExprT2 >,ExprSpecDefault > {
1568 
1569  public:
1570 
1571  typedef typename ExprT1::value_type value_type_1;
1572  typedef typename ExprT2::value_type value_type_2;
1573  typedef typename Sacado::Promote<value_type_1,
1574  value_type_2>::type value_type;
1575 
1576  typedef typename ExprT1::scalar_type scalar_type_1;
1577  typedef typename ExprT2::scalar_type scalar_type_2;
1578  typedef typename Sacado::Promote<scalar_type_1,
1579  scalar_type_2>::type scalar_type;
1580 
1581  typedef typename ExprT1::base_expr_type base_expr_type_1;
1582  typedef typename ExprT2::base_expr_type base_expr_type_2;
1583  typedef typename Sacado::Promote<base_expr_type_1,
1584  base_expr_type_2>::type base_expr_type;
1585 
1587  Expr(const CondT& cond_, const ExprT1& expr1_, const ExprT2& expr2_) :
1588  cond(cond_), expr1(expr1_), expr2(expr2_) {}
1589 
1591  int size() const {
1592  int sz1 = expr1.size(), sz2 = expr2.size();
1593  return sz1 > sz2 ? sz1 : sz2;
1594  }
1595 
1597  bool hasFastAccess() const {
1598  return expr1.hasFastAccess() && expr2.hasFastAccess();
1599  }
1600 
1602  bool isPassive() const {
1603  return expr1.isPassive() && expr2.isPassive();
1604  }
1605 
1607  bool updateValue() const {
1608  return expr1.updateValue() && expr2.updateValue();
1609  }
1610 
1612  void cache() const {}
1613 
1615  const value_type val() const {
1616  using Sacado::if_then_else;
1617  return if_then_else( cond, expr1.val(), expr2.val() );
1618  }
1619 
1621  const value_type dx(int i) const {
1622  using Sacado::if_then_else;
1623  return if_then_else( cond, expr1.dx(i), expr2.dx(i) );
1624  }
1625 
1627  const value_type fastAccessDx(int i) const {
1628  using Sacado::if_then_else;
1629  return if_then_else( cond, expr1.fastAccessDx(i), expr2.fastAccessDx(i) );
1630  }
1631 
1632  protected:
1633 
1634  const CondT& cond;
1635  const ExprT1& expr1;
1636  const ExprT2& expr2;
1637 
1638  };
1639 
1640  template <typename CondT, typename ExprT1, typename T2>
1641  struct ExprSpec< IfThenElseOp< CondT, ExprT1, ConstExpr<T2> > > {
1642  typedef typename ExprSpec<ExprT1>::type type;
1643  };
1644 
1645  template <typename CondT, typename ExprT1, typename T2>
1646  class Expr< IfThenElseOp< CondT, ExprT1, ConstExpr<T2> >,ExprSpecDefault > {
1647 
1648  public:
1649 
1650  typedef ConstExpr<T2> ConstT;
1651  typedef ConstExpr<T2> ExprT2;
1652  typedef typename ExprT1::value_type value_type_1;
1653  typedef typename ExprT2::value_type value_type_2;
1654  typedef typename Sacado::Promote<value_type_1,
1655  value_type_2>::type value_type;
1656 
1657  typedef typename ExprT1::scalar_type scalar_type_1;
1658  typedef typename ExprT2::scalar_type scalar_type_2;
1659  typedef typename Sacado::Promote<scalar_type_1,
1660  scalar_type_2>::type scalar_type;
1661 
1662  typedef typename ExprT1::base_expr_type base_expr_type_1;
1663  typedef typename ExprT2::base_expr_type base_expr_type_2;
1664  typedef typename Sacado::Promote<base_expr_type_1,
1665  base_expr_type_2>::type base_expr_type;
1666 
1668  Expr(const CondT& cond_, const ExprT1& expr1_, const ConstT& c_) :
1669  cond(cond_), expr1(expr1_), c(c_) {}
1670 
1672  int size() const {
1673  return expr1.size();
1674  }
1675 
1677  bool hasFastAccess() const {
1678  return expr1.hasFastAccess();
1679  }
1680 
1682  bool isPassive() const {
1683  return expr1.isPassive();
1684  }
1685 
1687  bool updateValue() const { return expr1.updateValue(); }
1688 
1690  void cache() const {}
1691 
1693  const value_type val() const {
1694  using Sacado::if_then_else;
1695  return if_then_else( cond, expr1.val(), c.val() );
1696  }
1697 
1699  const value_type dx(int i) const {
1700  using Sacado::if_then_else;
1701  return if_then_else( cond, expr1.dx(i), value_type(0.0) );
1702  }
1703 
1705  const value_type fastAccessDx(int i) const {
1706  using Sacado::if_then_else;
1707  return if_then_else( cond, expr1.fastAccessDx(i), value_type(0.0) );
1708  }
1709 
1710  protected:
1711 
1712  const CondT& cond;
1713  const ExprT1& expr1;
1714  ConstT c;
1715  };
1716 
1717  template <typename CondT, typename T1, typename ExprT2>
1718  struct ExprSpec< IfThenElseOp< CondT, ConstExpr<T1>, ExprT2 > > {
1719  typedef typename ExprSpec<ExprT2>::type type;
1720  };
1721 
1722  template <typename CondT, typename T1, typename ExprT2>
1723  class Expr< IfThenElseOp< CondT, ConstExpr<T1>, ExprT2 >,ExprSpecDefault > {
1724 
1725  public:
1726 
1727  typedef ConstExpr<T1> ConstT;
1728  typedef ConstExpr<T1> ExprT1;
1729  typedef typename ExprT1::value_type value_type_1;
1730  typedef typename ExprT2::value_type value_type_2;
1731  typedef typename Sacado::Promote<value_type_1,
1732  value_type_2>::type value_type;
1733 
1734  typedef typename ExprT1::scalar_type scalar_type_1;
1735  typedef typename ExprT2::scalar_type scalar_type_2;
1736  typedef typename Sacado::Promote<scalar_type_1,
1737  scalar_type_2>::type scalar_type;
1738 
1739  typedef typename ExprT1::base_expr_type base_expr_type_1;
1740  typedef typename ExprT2::base_expr_type base_expr_type_2;
1741  typedef typename Sacado::Promote<base_expr_type_1,
1742  base_expr_type_2>::type base_expr_type;
1743 
1745  Expr(const CondT& cond_, const ConstT& c_, const ExprT2& expr2_) :
1746  cond(cond_), c(c_), expr2(expr2_) {}
1747 
1749  int size() const {
1750  return expr2.size();
1751  }
1752 
1754  bool hasFastAccess() const {
1755  return expr2.hasFastAccess();
1756  }
1757 
1759  bool isPassive() const {
1760  return expr2.isPassive();
1761  }
1762 
1764  bool updateValue() const { return expr2.updateValue(); }
1765 
1767  void cache() const {}
1768 
1770  const value_type val() const {
1771  using Sacado::if_then_else;
1772  return if_then_else( cond, c.val(), expr2.val() );
1773  }
1774 
1776  const value_type dx(int i) const {
1777  using Sacado::if_then_else;
1778  return if_then_else( cond, value_type(0.0), expr2.dx(i) );
1779  }
1780 
1782  const value_type fastAccessDx(int i) const {
1783  using Sacado::if_then_else;
1784  return if_then_else( cond, value_type(0.0), expr2.fastAccessDx(i) );
1785  }
1786 
1787  protected:
1788 
1789  const CondT& cond;
1790  ConstT c;
1791  const ExprT2& expr2;
1792  };
1793 
1794  template <typename CondT, typename T1, typename T2>
1796  typename mpl::enable_if_c< IsFadExpr<T1>::value && IsFadExpr<T2>::value &&
1797  ExprLevel<T1>::value == ExprLevel<T2>::value,
1798  Expr< IfThenElseOp< CondT, T1, T2 > >
1799  >::type
1800  if_then_else (const CondT& cond, const T1& expr1, const T2& expr2)
1801  {
1802  typedef IfThenElseOp< CondT, T1, T2 > expr_t;
1803 
1804  return Expr<expr_t>(cond, expr1, expr2);
1805  }
1806 
1807  template <typename CondT, typename T>
1809  Expr< IfThenElseOp< CondT, Expr<T>, Expr<T> > >
1810  if_then_else (const CondT& cond, const Expr<T>& expr1, const Expr<T>& expr2)
1811  {
1812  typedef IfThenElseOp< CondT, Expr<T>, Expr<T> > expr_t;
1813 
1814  return Expr<expr_t>(cond, expr1, expr2);
1815  }
1816 
1817  template <typename CondT, typename T>
1819  Expr< IfThenElseOp< CondT, ConstExpr<typename Expr<T>::value_type>,
1820  Expr<T> > >
1821  if_then_else (const CondT& cond, const typename Expr<T>::value_type& c,
1822  const Expr<T>& expr)
1823  {
1824  typedef ConstExpr<typename Expr<T>::value_type> ConstT;
1825  typedef IfThenElseOp< CondT, ConstT, Expr<T> > expr_t;
1826 
1827  return Expr<expr_t>(cond, ConstT(c), expr);
1828  }
1829 
1830  template <typename CondT, typename T>
1832  Expr< IfThenElseOp< CondT, Expr<T>,
1833  ConstExpr<typename Expr<T>::value_type> > >
1834  if_then_else (const CondT& cond, const Expr<T>& expr,
1835  const typename Expr<T>::value_type& c)
1836  {
1837  typedef ConstExpr<typename Expr<T>::value_type> ConstT;
1838  typedef IfThenElseOp< CondT, Expr<T>, ConstT > expr_t;
1839 
1840  return Expr<expr_t>(cond, expr, ConstT(c));
1841  }
1842 
1843  template <typename CondT, typename T>
1845  typename mpl::disable_if<
1846  mpl::is_same< typename Expr<T>::value_type,
1847  typename Expr<T>::scalar_type>,
1848  Expr< IfThenElseOp< CondT, ConstExpr<typename Expr<T>::scalar_type>,
1849  Expr<T> > >
1850  >::type
1851  if_then_else (const CondT& cond, const typename Expr<T>::scalar_type& c,
1852  const Expr<T>& expr)
1853  {
1854  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT;
1855  typedef IfThenElseOp< CondT, ConstT, Expr<T> > expr_t;
1856 
1857  return Expr<expr_t>(cond, ConstT(c), expr);
1858  }
1859 
1860  template <typename CondT, typename T>
1862  typename mpl::disable_if<
1863  mpl::is_same< typename Expr<T>::value_type,
1864  typename Expr<T>::scalar_type>,
1865  Expr< IfThenElseOp< CondT, Expr<T>,
1866  ConstExpr<typename Expr<T>::scalar_type> > >
1867  >::type
1868  if_then_else (const CondT& cond, const Expr<T>& expr,
1869  const typename Expr<T>::scalar_type& c)
1870  {
1871  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT;
1872  typedef IfThenElseOp< CondT, Expr<T>, ConstT > expr_t;
1873 
1874  return Expr<expr_t>(cond, expr, ConstT(c));
1875  }
1876  }
1877 }
1878 
1879 #endif
1880 
1881 //-------------------------- Relational Operators -----------------------
1882 
1883 #ifdef HAVE_SACADO_CXX11
1884 
1885 namespace Sacado {
1886  namespace Fad {
1887  template <typename T1, typename T2 = T1>
1888  struct ConditionalReturnType {
1889  typedef decltype( std::declval<T1>() == std::declval<T2>() ) type;
1890  };
1891  }
1892 }
1893 
1894 #define FAD_RELOP_MACRO(OP) \
1895 namespace Sacado { \
1896  namespace Fad { \
1897  template <typename ExprT1, typename ExprT2> \
1898  KOKKOS_INLINE_FUNCTION \
1899  typename ConditionalReturnType<typename Expr<ExprT1>::value_type, \
1900  typename Expr<ExprT2>::value_type>::type \
1901  operator OP (const Expr<ExprT1>& expr1, \
1902  const Expr<ExprT2>& expr2) \
1903  { \
1904  return expr1.val() OP expr2.val(); \
1905  } \
1906  \
1907  template <typename ExprT2> \
1908  KOKKOS_INLINE_FUNCTION \
1909  typename ConditionalReturnType<typename Expr<ExprT2>::value_type>::type \
1910  operator OP (const typename Expr<ExprT2>::value_type& a, \
1911  const Expr<ExprT2>& expr2) \
1912  { \
1913  return a OP expr2.val(); \
1914  } \
1915  \
1916  template <typename ExprT1> \
1917  KOKKOS_INLINE_FUNCTION \
1918  typename ConditionalReturnType<typename Expr<ExprT1>::value_type>::type \
1919  operator OP (const Expr<ExprT1>& expr1, \
1920  const typename Expr<ExprT1>::value_type& b) \
1921  { \
1922  return expr1.val() OP b; \
1923  } \
1924  } \
1925 }
1926 
1927 #else
1928 
1929 #define FAD_RELOP_MACRO(OP) \
1930 namespace Sacado { \
1931  namespace Fad { \
1932  template <typename ExprT1, typename ExprT2> \
1933  KOKKOS_INLINE_FUNCTION \
1934  bool \
1935  operator OP (const Expr<ExprT1>& expr1, \
1936  const Expr<ExprT2>& expr2) \
1937  { \
1938  return expr1.val() OP expr2.val(); \
1939  } \
1940  \
1941  template <typename ExprT2> \
1942  KOKKOS_INLINE_FUNCTION \
1943  bool \
1944  operator OP (const typename Expr<ExprT2>::value_type& a, \
1945  const Expr<ExprT2>& expr2) \
1946  { \
1947  return a OP expr2.val(); \
1948  } \
1949  \
1950  template <typename ExprT1> \
1951  KOKKOS_INLINE_FUNCTION \
1952  bool \
1953  operator OP (const Expr<ExprT1>& expr1, \
1954  const typename Expr<ExprT1>::value_type& b) \
1955  { \
1956  return expr1.val() OP b; \
1957  } \
1958  } \
1959 }
1960 
1961 #endif
1962 
1963 FAD_RELOP_MACRO(==)
1964 FAD_RELOP_MACRO(!=)
1965 FAD_RELOP_MACRO(<)
1966 FAD_RELOP_MACRO(>)
1967 FAD_RELOP_MACRO(<=)
1968 FAD_RELOP_MACRO(>=)
1969 FAD_RELOP_MACRO(<<=)
1970 FAD_RELOP_MACRO(>>=)
1971 FAD_RELOP_MACRO(&)
1972 FAD_RELOP_MACRO(|)
1973 
1974 #undef FAD_RELOP_MACRO
1975 
1976 namespace Sacado {
1977 
1978  namespace Fad {
1979 
1980  template <typename ExprT>
1982  bool operator ! (const Expr<ExprT>& expr)
1983  {
1984  return ! expr.val();
1985  }
1986 
1987  } // namespace Fad
1988 
1989 } // namespace Sacado
1990 
1991 //-------------------------- Boolean Operators -----------------------
1992 namespace Sacado {
1993 
1994  namespace Fad {
1995 
1996  template <typename ExprT>
1998  bool toBool(const Expr<ExprT>& x) {
1999  bool is_zero = (x.val() == 0.0);
2000  for (int i=0; i<x.size(); i++)
2001  is_zero = is_zero && (x.dx(i) == 0.0);
2002  return !is_zero;
2003  }
2004 
2005  } // namespace Fad
2006 
2007 } // namespace Sacado
2008 
2009 #define FAD_BOOL_MACRO(OP) \
2010 namespace Sacado { \
2011  namespace Fad { \
2012  template <typename ExprT1, typename ExprT2> \
2013  KOKKOS_INLINE_FUNCTION \
2014  bool \
2015  operator OP (const Expr<ExprT1>& expr1, \
2016  const Expr<ExprT2>& expr2) \
2017  { \
2018  return toBool(expr1) OP toBool(expr2); \
2019  } \
2020  \
2021  template <typename ExprT2> \
2022  KOKKOS_INLINE_FUNCTION \
2023  bool \
2024  operator OP (const typename Expr<ExprT2>::value_type& a, \
2025  const Expr<ExprT2>& expr2) \
2026  { \
2027  return a OP toBool(expr2); \
2028  } \
2029  \
2030  template <typename ExprT1> \
2031  KOKKOS_INLINE_FUNCTION \
2032  bool \
2033  operator OP (const Expr<ExprT1>& expr1, \
2034  const typename Expr<ExprT1>::value_type& b) \
2035  { \
2036  return toBool(expr1) OP b; \
2037  } \
2038  } \
2039 }
2040 
2041 FAD_BOOL_MACRO(&&)
2042 FAD_BOOL_MACRO(||)
2043 
2044 #undef FAD_BOOL_MACRO
2045 
2046 //-------------------------- I/O Operators -----------------------
2047 
2048 namespace Sacado {
2049 
2050  namespace Fad {
2051 
2052  template <typename ExprT>
2053  std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
2054  os << x.val() << " [";
2055 
2056  for (int i=0; i< x.size(); i++) {
2057  os << " " << x.dx(i);
2058  }
2059 
2060  os << " ]";
2061  return os;
2062  }
2063 
2064  } // namespace Fad
2065 
2066 } // namespace Sacado
2067 
2068 #endif // SACADO_FAD_OPS_HPP
Wrapper for a generic expression template.
cbrt(expr.val())
KOKKOS_INLINE_FUNCTION Expr(const ConstT &c_, const ExprT2 &expr2_)
Sacado::Promote< scalar_type_1, scalar_type_2 >::type scalar_type
expr expr AdditionOp
expr expr SinOp
ScalarType< value_type >::type scalar_type
Typename of scalar&#39;s (which may be different from ConstT)
Constant expression template.
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
asinh(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
#define FAD_UNARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, FASTACCESSDX)
asin(expr.val())
cosh(expr.val())
#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)
Sacado::Promote< scalar_type_1, scalar_type_2 >::type scalar_type
expr expr dx(i)
abs(expr.val())
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
Sacado::Promote< base_expr_type_1, base_expr_type_2 >::type base_expr_type
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MinOp
atanh(expr.val())
KOKKOS_INLINE_FUNCTION Expr(const ExprT1 &expr1_, const ConstT &c_)
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 expr1 expr1 expr1 expr1 expr1 c *expr2 expr1 c *expr2 expr1 c *expr2 expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 Atan2Op
expr expr CoshOp
KOKKOS_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
expr expr ATanhOp
#define SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP)
expr expr TanhOp
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
KOKKOS_INLINE_FUNCTION Expr(const ExprT1 &expr1_, const ExprT2 &expr2_)
expr expr SqrtOp
expr expr ASinhOp
expr true
atan(expr.val())
Sacado::Promote< scalar_type_1, scalar_type_2 >::type scalar_type
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 expr1 expr1 expr1 expr1 expr1 c *expr2 expr1 c *expr2 expr1 c *expr2 expr1 DivisionOp
KOKKOS_INLINE_FUNCTION mpl::enable_if_c< ExprLevel< Expr< T1 > >::value==ExprLevel< Expr< T2 > >::value, Expr< PowerOp< Expr< T1 >, Expr< T2 > > > >::type pow(const Expr< T1 > &expr1, const Expr< T2 > &expr2)
SimpleFad< ValueT > log(const SimpleFad< ValueT > &a)
Sacado::Promote< base_expr_type_1, base_expr_type_2 >::type base_expr_type
expr val()
#define KOKKOS_INLINE_FUNCTION
Sacado::Promote< value_type_1, value_type_2 >::type value_type
#define T
Definition: Sacado_rad.hpp:573
KOKKOS_INLINE_FUNCTION Expr(const ConstT &c_, const ExprT2 &expr2_)
Sacado::Promote< base_expr_type_1, base_expr_type_2 >::type base_expr_type
tanh(expr.val())
expr expr CosOp
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
Sacado::Promote< scalar_type_1, scalar_type_2 >::type scalar_type
#define FAD_BOOL_MACRO(OP)
expr expr ATanOp
#define T2(r, f)
Definition: Sacado_rad.hpp:578
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
expr expr ACosOp
Sacado::Promote< base_expr_type_1, base_expr_type_2 >::type base_expr_type
sqrt(expr.val())
sinh(expr.val())
tan(expr.val())
T2 base_expr_type
Typename of base-expressions.
#define T1(r, f)
Definition: Sacado_rad.hpp:603
atan2(expr1.val(), expr2.val())
Meta-function for determining nesting with an expression.
Sacado::Promote< scalar_type_1, scalar_type_2 >::type scalar_type
void
Definition: uninit.c:96
KOKKOS_INLINE_FUNCTION Expr(const ExprT1 &expr1_, const ExprT2 &expr2_)
sin(expr.val())
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
KOKKOS_INLINE_FUNCTION Expr(const ExprT1 &expr1_, const ConstT &c_)
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
#define SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP)
log(expr.val())
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
Sacado::Promote< base_expr_type_1, base_expr_type_2 >::type base_expr_type
expr expr ACoshOp
expr expr Log10Op
expr expr SinhOp
acosh(expr.val())
SimpleFad< ValueT > operator*(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
Sacado::Promote< scalar_type_1, scalar_type_2 >::type scalar_type
if_then_else(expr.val() >=0, expr.dx(i), value_type(-expr.dx(i)))
acos(expr.val())
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
expr expr ASinOp
T2 value_type
Typename of argument values.
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
#define FAD_RELOP_MACRO(OP)
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
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)
Sacado::Promote< value_type_1, value_type_2 >::type value_type
expr expr expr bar false
exp(expr.val())
expr expr expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 SubtractionOp
expr expr expr ExpOp
fabs(expr.val())
expr expr AbsOp
expr expr TanOp
Sacado::Promote< base_expr_type_1, base_expr_type_2 >::type base_expr_type
log10(expr.val())
Base template specification for Promote.
cos(expr.val())
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