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,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  value_type val() const { \
96  return VALUE; \
97  } \
98  \
99  KOKKOS_INLINE_FUNCTION \
100  value_type dx(int i) const { \
101  return DX; \
102  } \
103  \
104  KOKKOS_INLINE_FUNCTION \
105  value_type fastAccessDx(int i) const { \
106  return FASTACCESSDX; \
107  } \
108  \
109  protected: \
110  \
111  const ExprT& expr; \
112  }; \
113  \
114  template <typename T> \
115  KOKKOS_INLINE_FUNCTION \
116  Expr< OP< Expr<T> > > \
117  OPNAME (const Expr<T>& expr) \
118  { \
119  typedef OP< Expr<T> > expr_t; \
120  \
121  return Expr<expr_t>(expr); \
122  } \
123  } \
124  \
125 }
126 
127 FAD_UNARYOP_MACRO(operator+,
128  UnaryPlusOp,
129  expr.val(),
130  expr.dx(i),
131  expr.fastAccessDx(i))
132 FAD_UNARYOP_MACRO(operator-,
134  -expr.val(),
135  -expr.dx(i),
136  -expr.fastAccessDx(i))
139  std::exp(expr.val()),
140  std::exp(expr.val())*expr.dx(i),
141  std::exp(expr.val())*expr.fastAccessDx(i))
144  std::log(expr.val()),
145  expr.dx(i)/expr.val(),
146  expr.fastAccessDx(i)/expr.val())
149  std::log10(expr.val()),
150  expr.dx(i)/( std::log(value_type(10))*expr.val()),
151  expr.fastAccessDx(i) / ( std::log(value_type(10))*expr.val()))
153  SqrtOp,
154  std::sqrt(expr.val()),
155  expr.dx(i)/(value_type(2)* std::sqrt(expr.val())),
156  expr.fastAccessDx(i)/(value_type(2)* std::sqrt(expr.val())))
158  CosOp,
159  std::cos(expr.val()),
160  -expr.dx(i)* std::sin(expr.val()),
161  -expr.fastAccessDx(i)* std::sin(expr.val()))
163  SinOp,
164  std::sin(expr.val()),
165  expr.dx(i)* std::cos(expr.val()),
166  expr.fastAccessDx(i)* std::cos(expr.val()))
168  TanOp,
169  std::tan(expr.val()),
170  expr.dx(i)*
171  (value_type(1)+ std::tan(expr.val())* std::tan(expr.val())),
172  expr.fastAccessDx(i)*
173  (value_type(1)+ std::tan(expr.val())* std::tan(expr.val())))
175  ACosOp,
176  std::acos(expr.val()),
177  -expr.dx(i)/ std::sqrt(value_type(1)-expr.val()*expr.val()),
178  -expr.fastAccessDx(i) /
179  std::sqrt(value_type(1)-expr.val()*expr.val()))
181  ASinOp,
182  std::asin(expr.val()),
183  expr.dx(i)/ std::sqrt(value_type(1)-expr.val()*expr.val()),
184  expr.fastAccessDx(i) /
185  std::sqrt(value_type(1)-expr.val()*expr.val()))
187  ATanOp,
188  std::atan(expr.val()),
189  expr.dx(i)/(value_type(1)+expr.val()*expr.val()),
190  expr.fastAccessDx(i)/(value_type(1)+expr.val()*expr.val()))
192  CoshOp,
193  std::cosh(expr.val()),
194  expr.dx(i)* std::sinh(expr.val()),
195  expr.fastAccessDx(i)* std::sinh(expr.val()))
197  SinhOp,
198  std::sinh(expr.val()),
199  expr.dx(i)* std::cosh(expr.val()),
200  expr.fastAccessDx(i)* std::cosh(expr.val()))
202  TanhOp,
203  std::tanh(expr.val()),
204  expr.dx(i)/( std::cosh(expr.val())* std::cosh(expr.val())),
205  expr.fastAccessDx(i) /
206  ( std::cosh(expr.val())* std::cosh(expr.val())))
208  ACoshOp,
209  std::acosh(expr.val()),
210  expr.dx(i)/ std::sqrt((expr.val()-value_type(1)) *
211  (expr.val()+value_type(1))),
212  expr.fastAccessDx(i)/ std::sqrt((expr.val()-value_type(1)) *
213  (expr.val()+value_type(1))))
215  ASinhOp,
216  std::asinh(expr.val()),
217  expr.dx(i)/ std::sqrt(value_type(1)+expr.val()*expr.val()),
218  expr.fastAccessDx(i)/ std::sqrt(value_type(1)+
219  expr.val()*expr.val()))
221  ATanhOp,
222  std::atanh(expr.val()),
223  expr.dx(i)/(value_type(1)-expr.val()*expr.val()),
224  expr.fastAccessDx(i)/(value_type(1)-
225  expr.val()*expr.val()))
227  AbsOp,
228  std::abs(expr.val()),
229  expr.val() >= 0 ? value_type(+expr.dx(i)) :
230  value_type(-expr.dx(i)),
231  expr.val() >= 0 ? value_type(+expr.fastAccessDx(i)) :
232  value_type(-expr.fastAccessDx(i)))
234  FAbsOp,
235  std::fabs(expr.val()),
236  expr.val() >= 0 ? value_type(+expr.dx(i)) :
237  value_type(-expr.dx(i)),
238  expr.val() >= 0 ? value_type(+expr.fastAccessDx(i)) :
239  value_type(-expr.fastAccessDx(i)))
240 #ifdef HAVE_SACADO_CXX11
241 FAD_UNARYOP_MACRO(cbrt,
242  CbrtOp,
243  std::cbrt(expr.val()),
244  expr.dx(i)/(value_type(3)*std::cbrt(expr.val()*expr.val())),
245  expr.fastAccessDx(i)/(value_type(3)*std::cbrt(expr.val()*expr.val())))
246 #endif
247 
248 #undef FAD_UNARYOP_MACRO
249 
250 #define FAD_BINARYOP_MACRO(OPNAME,OP,VALUE,DX,FASTACCESSDX,VAL_CONST_DX_1,VAL_CONST_DX_2,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
251 namespace Sacado { \
252  namespace Fad { \
253  \
254  template <typename ExprT1, typename ExprT2> \
255  class OP {}; \
256  \
257  template <typename ExprT1, typename ExprT2> \
258  struct ExprSpec< OP< ExprT1, ExprT2 > > { \
259  typedef typename ExprSpec<ExprT1>::type type; \
260  }; \
261  \
262  template <typename ExprT1, typename ExprT2> \
263  class Expr< OP< ExprT1, ExprT2 >,ExprSpecDefault > { \
264  \
265  public: \
266  \
267  typedef typename ExprT1::value_type value_type_1; \
268  typedef typename ExprT2::value_type value_type_2; \
269  typedef typename Sacado::Promote<value_type_1, \
270  value_type_2>::type value_type; \
271  \
272  typedef typename ExprT1::scalar_type scalar_type_1; \
273  typedef typename ExprT2::scalar_type scalar_type_2; \
274  typedef typename Sacado::Promote<scalar_type_1, \
275  scalar_type_2>::type scalar_type; \
276  \
277  typedef typename ExprT1::base_expr_type base_expr_type_1; \
278  typedef typename ExprT2::base_expr_type base_expr_type_2; \
279  typedef typename Sacado::Promote<base_expr_type_1, \
280  base_expr_type_2>::type base_expr_type; \
281  \
282  KOKKOS_INLINE_FUNCTION \
283  Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
284  expr1(expr1_), expr2(expr2_) {} \
285  \
286  KOKKOS_INLINE_FUNCTION \
287  int size() const { \
288  int sz1 = expr1.size(), sz2 = expr2.size(); \
289  return sz1 > sz2 ? sz1 : sz2; \
290  } \
291  \
292  KOKKOS_INLINE_FUNCTION \
293  bool hasFastAccess() const { \
294  return expr1.hasFastAccess() && expr2.hasFastAccess(); \
295  } \
296  \
297  KOKKOS_INLINE_FUNCTION \
298  bool isPassive() const { \
299  return expr1.isPassive() && expr2.isPassive(); \
300  } \
301  \
302  KOKKOS_INLINE_FUNCTION \
303  bool updateValue() const { \
304  return expr1.updateValue() && expr2.updateValue(); \
305  } \
306  \
307  KOKKOS_INLINE_FUNCTION \
308  const value_type val() const { \
309  return VALUE; \
310  } \
311  \
312  KOKKOS_INLINE_FUNCTION \
313  const value_type dx(int i) const { \
314  return DX; \
315  } \
316  \
317  KOKKOS_INLINE_FUNCTION \
318  const value_type fastAccessDx(int i) const { \
319  return FASTACCESSDX; \
320  } \
321  \
322  protected: \
323  \
324  const ExprT1& expr1; \
325  const ExprT2& expr2; \
326  \
327  }; \
328  \
329  template <typename ExprT1, typename T2> \
330  struct ExprSpec< OP< ExprT1, ConstExpr<T2> > > { \
331  typedef typename ExprSpec<ExprT1>::type type; \
332  }; \
333  \
334  template <typename ExprT1, typename T2> \
335  class Expr< OP< ExprT1, ConstExpr<T2> >,ExprSpecDefault > { \
336  \
337  public: \
338  \
339  typedef ConstExpr<T2> ConstT; \
340  typedef ConstExpr<T2> ExprT2; \
341  typedef typename ExprT1::value_type value_type_1; \
342  typedef typename ExprT2::value_type value_type_2; \
343  typedef typename Sacado::Promote<value_type_1, \
344  value_type_2>::type value_type; \
345  \
346  typedef typename ExprT1::scalar_type scalar_type_1; \
347  typedef typename ExprT2::scalar_type scalar_type_2; \
348  typedef typename Sacado::Promote<scalar_type_1, \
349  scalar_type_2>::type scalar_type; \
350  \
351  typedef typename ExprT1::base_expr_type base_expr_type_1; \
352  typedef typename ExprT2::base_expr_type base_expr_type_2; \
353  typedef typename Sacado::Promote<base_expr_type_1, \
354  base_expr_type_2>::type base_expr_type; \
355  \
356  KOKKOS_INLINE_FUNCTION \
357  Expr(const ExprT1& expr1_, const ConstT& c_) : \
358  expr1(expr1_), c(c_) {} \
359  \
360  KOKKOS_INLINE_FUNCTION \
361  int size() const { \
362  return expr1.size(); \
363  } \
364  \
365  KOKKOS_INLINE_FUNCTION \
366  bool hasFastAccess() const { \
367  return expr1.hasFastAccess(); \
368  } \
369  \
370  KOKKOS_INLINE_FUNCTION \
371  bool isPassive() const { \
372  return expr1.isPassive(); \
373  } \
374  \
375  KOKKOS_INLINE_FUNCTION \
376  bool updateValue() const { return expr1.updateValue(); } \
377  \
378  KOKKOS_INLINE_FUNCTION \
379  const value_type val() const { \
380  return VAL_CONST_DX_2; \
381  } \
382  \
383  KOKKOS_INLINE_FUNCTION \
384  const value_type dx(int i) const { \
385  return CONST_DX_2; \
386  } \
387  \
388  KOKKOS_INLINE_FUNCTION \
389  const value_type fastAccessDx(int i) const { \
390  return CONST_FASTACCESSDX_2; \
391  } \
392  \
393  protected: \
394  \
395  const ExprT1& expr1; \
396  ConstT c; \
397  }; \
398  \
399  template <typename T1, typename ExprT2> \
400  struct ExprSpec< OP< ConstExpr<T1>, ExprT2 > > { \
401  typedef typename ExprSpec<ExprT2>::type type; \
402  }; \
403  \
404  template <typename T1, typename ExprT2> \
405  class Expr< OP< ConstExpr<T1>, ExprT2 >,ExprSpecDefault > { \
406  \
407  public: \
408  \
409  typedef ConstExpr<T1> ConstT; \
410  typedef ConstExpr<T1> ExprT1; \
411  typedef typename ExprT1::value_type value_type_1; \
412  typedef typename ExprT2::value_type value_type_2; \
413  typedef typename Sacado::Promote<value_type_1, \
414  value_type_2>::type value_type; \
415  \
416  typedef typename ExprT1::scalar_type scalar_type_1; \
417  typedef typename ExprT2::scalar_type scalar_type_2; \
418  typedef typename Sacado::Promote<scalar_type_1, \
419  scalar_type_2>::type scalar_type; \
420  \
421  typedef typename ExprT1::base_expr_type base_expr_type_1; \
422  typedef typename ExprT2::base_expr_type base_expr_type_2; \
423  typedef typename Sacado::Promote<base_expr_type_1, \
424  base_expr_type_2>::type base_expr_type; \
425  \
426  \
427  KOKKOS_INLINE_FUNCTION \
428  Expr(const ConstT& c_, const ExprT2& expr2_) : \
429  c(c_), expr2(expr2_) {} \
430  \
431  KOKKOS_INLINE_FUNCTION \
432  int size() const { \
433  return expr2.size(); \
434  } \
435  \
436  KOKKOS_INLINE_FUNCTION \
437  bool hasFastAccess() const { \
438  return expr2.hasFastAccess(); \
439  } \
440  \
441  KOKKOS_INLINE_FUNCTION \
442  bool isPassive() const { \
443  return expr2.isPassive(); \
444  } \
445  \
446  KOKKOS_INLINE_FUNCTION \
447  bool updateValue() const { return expr2.updateValue(); } \
448  \
449  KOKKOS_INLINE_FUNCTION \
450  const value_type val() const { \
451  return VAL_CONST_DX_1; \
452  } \
453  \
454  KOKKOS_INLINE_FUNCTION \
455  const value_type dx(int i) const { \
456  return CONST_DX_1; \
457  } \
458  \
459  KOKKOS_INLINE_FUNCTION \
460  const value_type fastAccessDx(int i) const { \
461  return CONST_FASTACCESSDX_1; \
462  } \
463  \
464  protected: \
465  \
466  ConstT c; \
467  const ExprT2& expr2; \
468  }; \
469  \
470  template <typename T1, typename T2> \
473  OPNAME (const T1& expr1, const T2& expr2) \
474  { \
475  typedef OP< T1, T2 > expr_t; \
476  \
477  return Expr<expr_t>(expr1, expr2); \
478  } \
479  \
480  template <typename T> \
481  KOKKOS_INLINE_FUNCTION \
482  Expr< OP< Expr<T>, Expr<T> > > \
483  OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
484  { \
485  typedef OP< Expr<T>, Expr<T> > expr_t; \
486  \
487  return Expr<expr_t>(expr1, expr2); \
488  } \
489  \
490  template <typename T> \
491  KOKKOS_INLINE_FUNCTION \
492  Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
493  Expr<T> > > \
494  OPNAME (const typename Expr<T>::value_type& c, \
495  const Expr<T>& expr) \
496  { \
497  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
498  typedef OP< ConstT, Expr<T> > expr_t; \
499  \
500  return Expr<expr_t>(ConstT(c), expr); \
501  } \
502  \
503  template <typename T> \
504  KOKKOS_INLINE_FUNCTION \
505  Expr< OP< Expr<T>, \
506  ConstExpr<typename Expr<T>::value_type> > > \
507  OPNAME (const Expr<T>& expr, \
508  const typename Expr<T>::value_type& c) \
509  { \
510  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
511  typedef OP< Expr<T>, ConstT > expr_t; \
512  \
513  return Expr<expr_t>(expr, ConstT(c)); \
514  } \
515  \
516  template <typename T> \
519  OPNAME (const typename Expr<T>::scalar_type& c, \
520  const Expr<T>& expr) \
521  { \
522  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
523  typedef OP< ConstT, Expr<T> > expr_t; \
524  \
525  return Expr<expr_t>(ConstT(c), expr); \
526  } \
527  \
528  template <typename T> \
531  OPNAME (const Expr<T>& expr, \
532  const typename Expr<T>::scalar_type& c) \
533  { \
534  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
535  typedef OP< Expr<T>, ConstT > expr_t; \
536  \
537  return Expr<expr_t>(expr, ConstT(c)); \
538  } \
539  } \
540  \
541 }
542 
543 
544 FAD_BINARYOP_MACRO(operator+,
545  AdditionOp,
546  expr1.val() + expr2.val(),
547  expr1.dx(i) + expr2.dx(i),
548  expr1.fastAccessDx(i) + expr2.fastAccessDx(i),
549  c.val() + expr2.val(),
550  expr1.val() + c.val(),
551  expr2.dx(i),
552  expr1.dx(i),
553  expr2.fastAccessDx(i),
554  expr1.fastAccessDx(i))
555 FAD_BINARYOP_MACRO(operator-,
557  expr1.val() - expr2.val(),
558  expr1.dx(i) - expr2.dx(i),
559  expr1.fastAccessDx(i) - expr2.fastAccessDx(i),
560  c.val() - expr2.val(),
561  expr1.val() - c.val(),
562  -expr2.dx(i),
563  expr1.dx(i),
564  -expr2.fastAccessDx(i),
565  expr1.fastAccessDx(i))
566 // FAD_BINARYOP_MACRO(operator*,
567 // MultiplicationOp,
568 // expr1.val() * expr2.val(),
569 // expr1.val()*expr2.dx(i) + expr1.dx(i)*expr2.val(),
570 // expr1.val()*expr2.fastAccessDx(i) +
571 // expr1.fastAccessDx(i)*expr2.val(),
572 // c.val() * expr2.val(),
573 // expr1.val() * c.val(),
574 // c.val()*expr2.dx(i),
575 // expr1.dx(i)*c.val(),
576 // c.val()*expr2.fastAccessDx(i),
577 // expr1.fastAccessDx(i)*c.val())
578 FAD_BINARYOP_MACRO(operator/,
579  DivisionOp,
580  expr1.val() / expr2.val(),
581  (expr1.dx(i)*expr2.val() - expr2.dx(i)*expr1.val()) /
582  (expr2.val()*expr2.val()),
583  (expr1.fastAccessDx(i)*expr2.val() -
584  expr2.fastAccessDx(i)*expr1.val()) /
585  (expr2.val()*expr2.val()),
586  c.val() / expr2.val(),
587  expr1.val() / c.val(),
588  -expr2.dx(i)*c.val() / (expr2.val()*expr2.val()),
589  expr1.dx(i)/c.val(),
590  -expr2.fastAccessDx(i)*c.val() / (expr2.val()*expr2.val()),
591  expr1.fastAccessDx(i)/c.val())
593  Atan2Op,
594  std::atan2(expr1.val(), expr2.val()),
595  (expr2.val()*expr1.dx(i) - expr1.val()*expr2.dx(i))/
596  (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
597  (expr2.val()*expr1.fastAccessDx(i) - expr1.val()*expr2.fastAccessDx(i))/
598  (expr1.val()*expr1.val() + expr2.val()*expr2.val()),
599  std::atan2(c.val(), expr2.val()),
600  std::atan2(expr1.val(), c.val()),
601  (-c.val()*expr2.dx(i)) / (c.val()*c.val() + expr2.val()*expr2.val()),
602  (c.val()*expr1.dx(i))/ (expr1.val()*expr1.val() + c.val()*c.val()),
603  (-c.val()*expr2.fastAccessDx(i))/ (c.val()*c.val() + expr2.val()*expr2.val()),
604  (c.val()*expr1.fastAccessDx(i))/ (expr1.val()*expr1.val() + c.val()*c.val()))
606  PowerOp,
607  std::pow(expr1.val(), expr2.val()),
608  expr1.val() == value_type(0) ? value_type(0) : value_type((expr2.dx(i)*std::log(expr1.val())+expr2.val()*expr1.dx(i)/expr1.val())*std::pow(expr1.val(),expr2.val())),
609  expr1.val() == value_type(0) ? value_type(0.0) : value_type((expr2.fastAccessDx(i)*std::log(expr1.val())+expr2.val()*expr1.fastAccessDx(i)/expr1.val())*std::pow(expr1.val(),expr2.val())),
610  std::pow(c.val(), expr2.val()),
611  std::pow(expr1.val(), c.val()),
612  c.val() == value_type(0) ? value_type(0) : value_type(expr2.dx(i)*std::log(c.val())*std::pow(c.val(),expr2.val())),
613  expr1.val() == value_type(0) ? value_type(0.0) : value_type(c.val()*expr1.dx(i)/expr1.val()*std::pow(expr1.val(),c.val())),
614  c.val() == value_type(0) ? value_type(0) : value_type(expr2.fastAccessDx(i)*std::log(c.val())*std::pow(c.val(),expr2.val())),
615  expr1.val() == value_type(0) ? value_type(0.0) : value_type(c.val()*expr1.fastAccessDx(i)/expr1.val()*std::pow(expr1.val(),c.val())))
617  MaxOp,
618  expr1.val() >= expr2.val() ? expr1.val() : expr2.val(),
619  expr1.val() >= expr2.val() ? expr1.dx(i) : expr2.dx(i),
620  expr1.val() >= expr2.val() ? expr1.fastAccessDx(i) :
621  expr2.fastAccessDx(i),
622  c.val() >= expr2.val() ? c.val() : expr2.val(),
623  expr1.val() >= c.val() ? expr1.val() : c.val(),
624  c.val() >= expr2.val() ? value_type(0) : expr2.dx(i),
625  expr1.val() >= c.val() ? expr1.dx(i) : value_type(0),
626  c.val() >= expr2.val() ? value_type(0) : expr2.fastAccessDx(i),
627  expr1.val() >= c.val() ? expr1.fastAccessDx(i) : value_type(0))
629  MinOp,
630  expr1.val() <= expr2.val() ? expr1.val() : expr2.val(),
631  expr1.val() <= expr2.val() ? expr1.dx(i) : expr2.dx(i),
632  expr1.val() <= expr2.val() ? expr1.fastAccessDx(i) :
633  expr2.fastAccessDx(i),
634  c.val() <= expr2.val() ? c.val() : expr2.val(),
635  expr1.val() <= c.val() ? expr1.val() : c.val(),
636  c.val() <= expr2.val() ? value_type(0) : expr2.dx(i),
637  expr1.val() <= c.val() ? expr1.dx(i) : value_type(0),
638  c.val() <= expr2.val() ? value_type(0) : expr2.fastAccessDx(i),
639  expr1.val() <= c.val() ? expr1.fastAccessDx(i) : value_type(0))
640 
641 
642 #undef FAD_BINARYOP_MACRO
643 
644 namespace Sacado {
645  namespace Fad {
646 
647  template <typename ExprT1, typename ExprT2>
648  class MultiplicationOp {};
649 
650  template <typename ExprT1, typename ExprT2>
651  struct ExprSpec< MultiplicationOp< ExprT1, ExprT2 > > {
652  typedef typename ExprSpec<ExprT1>::type type;
653  };
654 
655  template <typename ExprT1, typename ExprT2>
656  class Expr< MultiplicationOp< ExprT1, ExprT2 >,ExprSpecDefault > {
657 
658  public:
659 
660  typedef typename ExprT1::value_type value_type_1;
661  typedef typename ExprT2::value_type value_type_2;
662  typedef typename Sacado::Promote<value_type_1,
663  value_type_2>::type value_type;
664 
665  typedef typename ExprT1::scalar_type scalar_type_1;
666  typedef typename ExprT2::scalar_type scalar_type_2;
667  typedef typename Sacado::Promote<scalar_type_1,
668  scalar_type_2>::type scalar_type;
669 
670  typedef typename ExprT1::base_expr_type base_expr_type_1;
671  typedef typename ExprT2::base_expr_type base_expr_type_2;
672  typedef typename Sacado::Promote<base_expr_type_1,
673  base_expr_type_2>::type base_expr_type;
674 
676  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
677  expr1(expr1_), expr2(expr2_) {}
678 
680  int size() const {
681  int sz1 = expr1.size(), sz2 = expr2.size();
682  return sz1 > sz2 ? sz1 : sz2;
683  }
684 
686  bool hasFastAccess() const {
687  return expr1.hasFastAccess() && expr2.hasFastAccess();
688  }
689 
691  bool isPassive() const {
692  return expr1.isPassive() && expr2.isPassive();
693  }
694 
696  bool updateValue() const {
697  return expr1.updateValue() && expr2.updateValue();
698  }
699 
701  const value_type val() const {
702  return expr1.val()*expr2.val();
703  }
704 
706  const value_type dx(int i) const {
707  if (expr1.size() > 0 && expr2.size() > 0)
708  return expr1.val()*expr2.dx(i) + expr1.dx(i)*expr2.val();
709  else if (expr1.size() > 0)
710  return expr1.dx(i)*expr2.val();
711  else
712  return expr1.val()*expr2.dx(i);
713  }
714 
716  const value_type fastAccessDx(int i) const {
717  return expr1.val()*expr2.fastAccessDx(i) +
718  expr1.fastAccessDx(i)*expr2.val();
719  }
720 
721  protected:
722 
723  const ExprT1& expr1;
724  const ExprT2& expr2;
725 
726  };
727 
728  template <typename ExprT1, typename T2>
729  struct ExprSpec< MultiplicationOp< ExprT1, ConstExpr<T2> > > {
730  typedef typename ExprSpec<ExprT1>::type type;
731  };
732 
733  template <typename ExprT1, typename T2>
734  class Expr< MultiplicationOp< ExprT1, ConstExpr<T2> >,ExprSpecDefault > {
735 
736  public:
737 
738  typedef ConstExpr<T2> ConstT;
739  typedef ConstExpr<T2> ExprT2;
740  typedef typename ExprT1::value_type value_type_1;
741  typedef typename ExprT2::value_type value_type_2;
742  typedef typename Sacado::Promote<value_type_1,
743  value_type_2>::type value_type;
744 
745  typedef typename ExprT1::scalar_type scalar_type_1;
746  typedef typename ExprT2::scalar_type scalar_type_2;
747  typedef typename Sacado::Promote<scalar_type_1,
748  scalar_type_2>::type scalar_type;
749 
750  typedef typename ExprT1::base_expr_type base_expr_type_1;
751  typedef typename ExprT2::base_expr_type base_expr_type_2;
752  typedef typename Sacado::Promote<base_expr_type_1,
753  base_expr_type_2>::type base_expr_type;
754 
756  Expr(const ExprT1& expr1_, const ConstT& c_) :
757  expr1(expr1_), c(c_) {}
758 
760  int size() const {
761  return expr1.size();
762  }
763 
765  bool hasFastAccess() const {
766  return expr1.hasFastAccess();
767  }
768 
770  bool isPassive() const {
771  return expr1.isPassive();
772  }
773 
775  bool updateValue() const { return expr1.updateValue(); }
776 
778  const value_type val() const {
779  return expr1.val()*c.val();
780  }
781 
783  const value_type dx(int i) const {
784  return expr1.dx(i)*c.val();
785  }
786 
788  const value_type fastAccessDx(int i) const {
789  return expr1.fastAccessDx(i)*c.val();
790  }
791 
792  protected:
793 
794  const ExprT1& expr1;
795  ConstT c;
796  };
797 
798  template <typename T1, typename ExprT2>
799  struct ExprSpec< MultiplicationOp< ConstExpr<T1>, ExprT2 > > {
800  typedef typename ExprSpec<ExprT2>::type type;
801  };
802 
803  template <typename T1, typename ExprT2>
804  class Expr< MultiplicationOp< ConstExpr<T1>, ExprT2 >,ExprSpecDefault > {
805 
806  public:
807 
808  typedef ConstExpr<T1> ConstT;
809  typedef ConstExpr<T1> ExprT1;
810  typedef typename ExprT1::value_type value_type_1;
811  typedef typename ExprT2::value_type value_type_2;
812  typedef typename Sacado::Promote<value_type_1,
813  value_type_2>::type value_type;
814 
815  typedef typename ExprT1::scalar_type scalar_type_1;
816  typedef typename ExprT2::scalar_type scalar_type_2;
817  typedef typename Sacado::Promote<scalar_type_1,
818  scalar_type_2>::type scalar_type;
819 
820  typedef typename ExprT1::base_expr_type base_expr_type_1;
821  typedef typename ExprT2::base_expr_type base_expr_type_2;
822  typedef typename Sacado::Promote<base_expr_type_1,
823  base_expr_type_2>::type base_expr_type;
824 
826  Expr(const ConstT& c_, const ExprT2& expr2_) :
827  c(c_), expr2(expr2_) {}
828 
830  int size() const {
831  return expr2.size();
832  }
833 
835  bool hasFastAccess() const {
836  return expr2.hasFastAccess();
837  }
838 
840  bool isPassive() const {
841  return expr2.isPassive();
842  }
843 
845  bool updateValue() const { return expr2.updateValue(); }
846 
848  const value_type val() const {
849  return c.val()*expr2.val();
850  }
851 
853  const value_type dx(int i) const {
854  return c.val()*expr2.dx(i);
855  }
856 
858  const value_type fastAccessDx(int i) const {
859  return c.val()*expr2.fastAccessDx(i);
860  }
861 
862  protected:
863 
864  ConstT c;
865  const ExprT2& expr2;
866  };
867 
868  template <typename T1, typename T2>
871  operator* (const T1& expr1, const T2& expr2)
872  {
873  typedef MultiplicationOp< T1, T2 > expr_t;
874 
875  return Expr<expr_t>(expr1, expr2);
876  }
877 
878  template <typename T>
880  Expr< MultiplicationOp< Expr<T>, Expr<T> > >
881  operator* (const Expr<T>& expr1, const Expr<T>& expr2)
882  {
883  typedef MultiplicationOp< Expr<T>, Expr<T> > expr_t;
884 
885  return Expr<expr_t>(expr1, expr2);
886  }
887 
888  template <typename T>
890  Expr< MultiplicationOp< ConstExpr<typename Expr<T>::value_type>, Expr<T> > >
891  operator* (const typename Expr<T>::value_type& c,
892  const Expr<T>& expr)
893  {
895  typedef MultiplicationOp< ConstT, Expr<T> > expr_t;
896 
897  return Expr<expr_t>(ConstT(c), expr);
898  }
899 
900  template <typename T>
902  Expr< MultiplicationOp< Expr<T>, ConstExpr<typename Expr<T>::value_type> > >
903  operator* (const Expr<T>& expr,
904  const typename Expr<T>::value_type& c)
905  {
907  typedef MultiplicationOp< Expr<T>, ConstT > expr_t;
908 
909  return Expr<expr_t>(expr, ConstT(c));
910  }
911 
912  template <typename T>
915  operator* (const typename Expr<T>::scalar_type& c,
916  const Expr<T>& expr)
917  {
919  typedef MultiplicationOp< ConstT, Expr<T> > expr_t;
920 
921  return Expr<expr_t>(ConstT(c), expr);
922  }
923 
924  template <typename T>
927  operator* (const Expr<T>& expr,
928  const typename Expr<T>::scalar_type& c)
929  {
931  typedef MultiplicationOp< Expr<T>, ConstT > expr_t;
932 
933  return Expr<expr_t>(expr, ConstT(c));
934  }
935  }
936 }
937 
938 //-------------------------- Relational Operators -----------------------
939 
940 #define FAD_RELOP_MACRO(OP) \
941 namespace Sacado { \
942  namespace Fad { \
943  template <typename ExprT1, typename ExprT2> \
944  KOKKOS_INLINE_FUNCTION \
945  bool \
946  operator OP (const Expr<ExprT1>& expr1, \
947  const Expr<ExprT2>& expr2) \
948  { \
949  return expr1.val() OP expr2.val(); \
950  } \
951  \
952  template <typename ExprT2> \
953  KOKKOS_INLINE_FUNCTION \
954  bool \
955  operator OP (const typename Expr<ExprT2>::value_type& a, \
956  const Expr<ExprT2>& expr2) \
957  { \
958  return a OP expr2.val(); \
959  } \
960  \
961  template <typename ExprT1> \
962  KOKKOS_INLINE_FUNCTION \
963  bool \
964  operator OP (const Expr<ExprT1>& expr1, \
965  const typename Expr<ExprT1>::value_type& b) \
966  { \
967  return expr1.val() OP b; \
968  } \
969  } \
970 }
971 
972 FAD_RELOP_MACRO(==)
973 FAD_RELOP_MACRO(!=)
976 FAD_RELOP_MACRO(<=)
977 FAD_RELOP_MACRO(>=)
978 FAD_RELOP_MACRO(<<=)
979 FAD_RELOP_MACRO(>>=)
982 
983 #undef FAD_RELOP_MACRO
984 
985 namespace Sacado {
986 
987  namespace Fad {
988 
989  template <typename ExprT>
991  bool operator ! (const Expr<ExprT>& expr)
992  {
993  return ! expr.val();
994  }
995 
996  } // namespace Fad
997 
998 } // namespace Sacado
999 
1000 //-------------------------- Boolean Operators -----------------------
1001 namespace Sacado {
1002 
1003  namespace Fad {
1004 
1005  template <typename ExprT>
1007  bool toBool(const Expr<ExprT>& x) {
1008  bool is_zero = (x.val() == 0.0);
1009  for (int i=0; i<x.size(); i++)
1010  is_zero = is_zero && (x.dx(i) == 0.0);
1011  return !is_zero;
1012  }
1013 
1014  } // namespace Fad
1015 
1016 } // namespace Sacado
1017 
1018 #define FAD_BOOL_MACRO(OP) \
1019 namespace Sacado { \
1020  namespace Fad { \
1021  template <typename ExprT1, typename ExprT2> \
1022  KOKKOS_INLINE_FUNCTION \
1023  bool \
1024  operator OP (const Expr<ExprT1>& expr1, \
1025  const Expr<ExprT2>& expr2) \
1026  { \
1027  return toBool(expr1) OP toBool(expr2); \
1028  } \
1029  \
1030  template <typename ExprT2> \
1031  KOKKOS_INLINE_FUNCTION \
1032  bool \
1033  operator OP (const typename Expr<ExprT2>::value_type& a, \
1034  const Expr<ExprT2>& expr2) \
1035  { \
1036  return a OP toBool(expr2); \
1037  } \
1038  \
1039  template <typename ExprT1> \
1040  KOKKOS_INLINE_FUNCTION \
1041  bool \
1042  operator OP (const Expr<ExprT1>& expr1, \
1043  const typename Expr<ExprT1>::value_type& b) \
1044  { \
1045  return toBool(expr1) OP b; \
1046  } \
1047  } \
1048 }
1049 
1050 FAD_BOOL_MACRO(&&)
1051 FAD_BOOL_MACRO(||)
1052 
1053 #undef FAD_BOOL_MACRO
1054 
1055 //-------------------------- I/O Operators -----------------------
1056 
1057 namespace Sacado {
1058 
1059  namespace Fad {
1060 
1061  template <typename ExprT>
1062  std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
1063  os << x.val() << " [";
1064 
1065  for (int i=0; i< x.size(); i++) {
1066  os << " " << x.dx(i);
1067  }
1068 
1069  os << " ]";
1070  return os;
1071  }
1072 
1073  } // namespace Fad
1074 
1075 } // namespace Sacado
1076 
1077 
1078 #endif // SACADO_FAD_OPS_HPP
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 SubtractionOp
ScalarType< value_type >::type scalar_type
Typename of scalar&#39;s (which may be different from ConstT)
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 Atan2Op
expr val()
#define SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP)
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 MaxOp
SimpleFad< ValueT > atan2(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
#define SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP)
SimpleFad< ValueT > sqrt(const SimpleFad< ValueT > &a)
SimpleFad< ValueT > asin(const SimpleFad< ValueT > &a)
bool toBool(const SimpleFad< T > &x)
SimpleFad< ValueT > log(const SimpleFad< ValueT > &a)
#define KOKKOS_INLINE_FUNCTION
SimpleFad< ValueT > exp(const SimpleFad< ValueT > &a)
SimpleFad< ValueT > atan(const SimpleFad< ValueT > &a)
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 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
#define FAD_BOOL_MACRO(OP)
SimpleFad< ValueT > log10(const SimpleFad< ValueT > &a)
#define T2(r, f)
Definition: Sacado_rad.hpp:578
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
expr expr expr ExpOp
SimpleFad< ValueT > sin(const SimpleFad< ValueT > &a)
#define FAD_BINARYOP_MACRO(OPNAME, OP, VALUE, DX, FASTACCESSDX, VAL_CONST_DX_1, VAL_CONST_DX_2, CONST_DX_1, CONST_DX_2, CONST_FASTACCESSDX_1, CONST_FASTACCESSDX_2)
UnaryMinusOp
#define T1(r, f)
Definition: Sacado_rad.hpp:603
SimpleFad< ValueT > sinh(const SimpleFad< ValueT > &a)
SimpleFad< ValueT > pow(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
#define FAD_UNARYOP_MACRO(OPNAME, OP, VALUE, DX, FASTACCESSDX)
SimpleFad< ValueT > tan(const SimpleFad< ValueT > &a)
expr acosh(expr.val())) FAD_UNARYOP_MACRO(asinh
#define SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP)
expr expr dx(i)
expr asinh(expr.val())) FAD_UNARYOP_MACRO(atanh
SimpleFad< ValueT > cos(const SimpleFad< ValueT > &a)
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 DivisionOp
SimpleFad< ValueT > cosh(const SimpleFad< ValueT > &a)
SimpleFad< ValueT > operator*(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
ConstT value_type
Typename of argument values.
expr expr expr LogOp
#define FAD_RELOP_MACRO(OP)
KOKKOS_INLINE_FUNCTION Expr< AbsOp< Expr< T > > > abs(const Expr< T > &expr)
KOKKOS_INLINE_FUNCTION Expr< FAbsOp< Expr< T > > > fabs(const Expr< T > &expr)
expr expr expr expr expr Log10Op
expr atanh(expr.val())) FAD_UNARYOP_MACRO(abs
bool operator!(const SimpleFad< ValueT > &a)
SimpleFad< ValueT > acos(const SimpleFad< ValueT > &a)
SimpleFad< ValueT > tanh(const SimpleFad< ValueT > &a)
Base template specification for Promote.
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 PowerOp