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