Stokhos 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_MP_Vector.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_MP_VECTOR_HPP
53 #define SACADO_FAD_OPS_MP_VECTOR_HPP
54 
55 #include "Sacado_Fad_Ops.hpp"
56 #include "Sacado_mpl_enable_if.hpp"
58 
59 #define FAD_UNARYOP_MACRO(OPNAME,OP,MPVALUE,VALUE,DX,FASTACCESSDX) \
60 namespace Sacado { \
61  namespace Fad { \
62  \
63  template <typename ExprT> \
64  class Expr< OP<ExprT>,ExprSpecMPVector > { \
65  public: \
66  \
67  typedef typename ExprT::value_type value_type; \
68  typedef typename ExprT::scalar_type scalar_type; \
69  typedef typename ExprT::base_expr_type base_expr_type; \
70  \
71  typedef typename value_type::value_type val_type; \
72  \
73  KOKKOS_INLINE_FUNCTION \
74  Expr(const ExprT& expr_) : expr(expr_) {} \
75  \
76  KOKKOS_INLINE_FUNCTION \
77  int size() const { return expr.size(); } \
78  \
79  KOKKOS_INLINE_FUNCTION \
80  bool hasFastAccess() const { return expr.hasFastAccess(); } \
81  \
82  KOKKOS_INLINE_FUNCTION \
83  bool isPassive() const { return expr.isPassive();} \
84  \
85  KOKKOS_INLINE_FUNCTION \
86  bool updateValue() const { return expr.updateValue(); } \
87  \
88  KOKKOS_INLINE_FUNCTION \
89  value_type val() const { \
90  return MPVALUE; \
91  } \
92  \
93  KOKKOS_INLINE_FUNCTION \
94  val_type val(int j) const { \
95  return VALUE; \
96  } \
97  \
98  KOKKOS_INLINE_FUNCTION \
99  val_type dx(int i, int j) const { \
100  return DX; \
101  } \
102  \
103  KOKKOS_INLINE_FUNCTION \
104  val_type fastAccessDx(int i, int j) const { \
105  return FASTACCESSDX; \
106  } \
107  \
108  protected: \
109  \
110  const ExprT& expr; \
111  }; \
112  \
113  } \
114 }
115 
116 FAD_UNARYOP_MACRO(operator+,
117  UnaryPlusOp,
118  expr.val(),
119  expr.val(j),
120  expr.dx(i,j),
121  expr.fastAccessDx(i,j))
122 FAD_UNARYOP_MACRO(operator-,
124  -expr.val(),
125  -expr.val(j),
126  -expr.dx(i,j),
127  -expr.fastAccessDx(i,j))
130  std::exp(expr.val()),
131  std::exp(expr.val(j)),
132  std::exp(expr.val(j))*expr.dx(i,j),
133  std::exp(expr.val(j))*expr.fastAccessDx(i,j))
135  LogOp,
136  std::log(expr.val()),
137  std::log(expr.val(j)),
138  expr.dx(i,j)/expr.val(j),
139  expr.fastAccessDx(i,j)/expr.val(j))
142  std::log10(expr.val()),
143  std::log10(expr.val(j)),
144  expr.dx(i,j)/( std::log(val_type(10))*expr.val(j)),
145  expr.fastAccessDx(i,j) / ( std::log(val_type(10))*expr.val(j)))
147  SqrtOp,
148  std::sqrt(expr.val()),
149  std::sqrt(expr.val(j)),
150  expr.dx(i,j)/(val_type(2)* std::sqrt(expr.val(j))),
151  expr.fastAccessDx(i,j)/(val_type(2)* std::sqrt(expr.val(j))))
153  CosOp,
154  std::cos(expr.val()),
155  std::cos(expr.val(j)),
156  -expr.dx(i,j)* std::sin(expr.val(j)),
157  -expr.fastAccessDx(i,j)* std::sin(expr.val(j)))
159  SinOp,
160  std::sin(expr.val()),
161  std::sin(expr.val(j)),
162  expr.dx(i,j)* std::cos(expr.val(j)),
163  expr.fastAccessDx(i,j)* std::cos(expr.val(j)))
165  TanOp,
166  std::tan(expr.val()),
167  std::tan(expr.val(j)),
168  expr.dx(i,j)*
169  (val_type(1)+ std::tan(expr.val(j))* std::tan(expr.val(j))),
170  expr.fastAccessDx(i,j)*
171  (val_type(1)+ std::tan(expr.val(j))* std::tan(expr.val(j))))
173  ACosOp,
174  std::acos(expr.val()),
175  std::acos(expr.val(j)),
176  -expr.dx(i,j)/ std::sqrt(val_type(1)-expr.val(j)*expr.val(j)),
177  -expr.fastAccessDx(i,j) /
178  std::sqrt(val_type(1)-expr.val(j)*expr.val(j)))
180  ASinOp,
181  std::asin(expr.val()),
182  std::asin(expr.val(j)),
183  expr.dx(i,j)/ std::sqrt(val_type(1)-expr.val(j)*expr.val(j)),
184  expr.fastAccessDx(i,j) /
185  std::sqrt(val_type(1)-expr.val(j)*expr.val(j)))
187  ATanOp,
188  std::atan(expr.val()),
189  std::atan(expr.val(j)),
190  expr.dx(i,j)/(val_type(1)+expr.val(j)*expr.val(j)),
191  expr.fastAccessDx(i,j)/(val_type(1)+expr.val(j)*expr.val(j)))
193  CoshOp,
194  std::cosh(expr.val()),
195  std::cosh(expr.val(j)),
196  expr.dx(i,j)* std::sinh(expr.val(j)),
197  expr.fastAccessDx(i,j)* std::sinh(expr.val(j)))
199  SinhOp,
200  std::sinh(expr.val()),
201  std::sinh(expr.val(j)),
202  expr.dx(i,j)* std::cosh(expr.val(j)),
203  expr.fastAccessDx(i,j)* std::cosh(expr.val(j)))
205  TanhOp,
206  std::tanh(expr.val()),
207  std::tanh(expr.val(j)),
208  expr.dx(i,j)/( std::cosh(expr.val(j))* std::cosh(expr.val(j))),
209  expr.fastAccessDx(i,j) /
210  ( std::cosh(expr.val(j))* std::cosh(expr.val(j))))
212  ACoshOp,
213  std::acosh(expr.val()),
214  std::acosh(expr.val(j)),
215  expr.dx(i,j)/ std::sqrt((expr.val(j)-val_type(1)) *
216  (expr.val(j)+val_type(1))),
217  expr.fastAccessDx(i,j)/ std::sqrt((expr.val(j)-val_type(1)) *
218  (expr.val(j)+val_type(1))))
220  ASinhOp,
221  std::asinh(expr.val()),
222  std::asinh(expr.val(j)),
223  expr.dx(i,j)/ std::sqrt(val_type(1)+expr.val(j)*expr.val(j)),
224  expr.fastAccessDx(i,j)/ std::sqrt(val_type(1)+
225  expr.val(j)*expr.val(j)))
227  ATanhOp,
228  std::atanh(expr.val()),
229  std::atanh(expr.val(j)),
230  expr.dx(i,j)/(val_type(1)-expr.val(j)*expr.val(j)),
231  expr.fastAccessDx(i,j)/(val_type(1)-
232  expr.val(j)*expr.val(j)))
234  AbsOp,
235  std::abs(expr.val()),
236  std::abs(expr.val(j)),
237  expr.val(j) >= 0 ? val_type(+expr.dx(i,j)) :
238  val_type(-expr.dx(i,j)),
239  expr.val(j) >= 0 ? val_type(+expr.fastAccessDx(i,j)) :
240  val_type(-expr.fastAccessDx(i,j)))
242  FAbsOp,
243  std::fabs(expr.val()),
244  std::fabs(expr.val(j)),
245  expr.val(j) >= 0 ? val_type(+expr.dx(i,j)) :
246  val_type(-expr.dx(i,j)),
247  expr.val(j) >= 0 ? val_type(+expr.fastAccessDx(i,j)) :
248  val_type(-expr.fastAccessDx(i,j)))
249 #ifdef HAVE_SACADO_CXX11
251  CbrtOp,
252  std::cbrt(expr.val()),
253  std::cbrt(expr.val(j)),
254  expr.dx(i,j)/(val_type(3)*std::cbrt(expr.val(j)*expr.val(j))),
255  expr.fastAccessDx(i,j)/(val_type(3)*std::cbrt(expr.val(j)*expr.val(j))))
256 #endif
257 
258 #undef FAD_UNARYOP_MACRO
259 
260 #define FAD_BINARYOP_MACRO(OPNAME,OP,MPVALUE,VALUE,DX,FASTACCESSDX,MPVAL_CONST_DX_1,MPVAL_CONST_DX_2,VAL_CONST_DX_1,VAL_CONST_DX_2,CONST_DX_1,CONST_DX_2,CONST_FASTACCESSDX_1,CONST_FASTACCESSDX_2) \
261 namespace Sacado { \
262  namespace Fad { \
263  \
264  template <typename ExprT1, typename ExprT2> \
265  class Expr< OP< ExprT1, ExprT2 >,ExprSpecMPVector > { \
266  \
267  public: \
268  \
269  typedef typename ExprT1::value_type value_type_1; \
270  typedef typename ExprT2::value_type value_type_2; \
271  typedef typename Sacado::Promote<value_type_1, \
272  value_type_2>::type value_type; \
273  \
274  typedef typename ExprT1::scalar_type scalar_type_1; \
275  typedef typename ExprT2::scalar_type scalar_type_2; \
276  typedef typename Sacado::Promote<scalar_type_1, \
277  scalar_type_2>::type scalar_type; \
278  \
279  typedef typename ExprT1::base_expr_type base_expr_type_1; \
280  typedef typename ExprT2::base_expr_type base_expr_type_2; \
281  typedef typename Sacado::Promote<base_expr_type_1, \
282  base_expr_type_2>::type base_expr_type; \
283  \
284  typedef typename value_type::value_type val_type; \
285  \
286  KOKKOS_INLINE_FUNCTION \
287  Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
288  expr1(expr1_), expr2(expr2_) {} \
289  \
291  int size() const { \
292  int sz1 = expr1.size(), sz2 = expr2.size(); \
293  return sz1 > sz2 ? sz1 : sz2; \
294  } \
295  \
296  KOKKOS_INLINE_FUNCTION \
297  bool hasFastAccess() const { \
298  return expr1.hasFastAccess() && expr2.hasFastAccess(); \
299  } \
300  \
301  KOKKOS_INLINE_FUNCTION \
302  bool isPassive() const { \
303  return expr1.isPassive() && expr2.isPassive(); \
304  } \
305  \
306  KOKKOS_INLINE_FUNCTION \
307  bool updateValue() const { \
308  return expr1.updateValue() && expr2.updateValue(); \
309  } \
310  \
311  KOKKOS_INLINE_FUNCTION \
312  const value_type val() const { \
313  return MPVALUE; \
314  } \
315  \
316  KOKKOS_INLINE_FUNCTION \
317  const val_type val(int j) const { \
318  return VALUE; \
319  } \
320  \
321  KOKKOS_INLINE_FUNCTION \
322  const val_type dx(int i, int j) const { \
323  return DX; \
324  } \
325  \
326  KOKKOS_INLINE_FUNCTION \
327  const val_type fastAccessDx(int i, int j) const { \
328  return FASTACCESSDX; \
329  } \
330  \
331  protected: \
332  \
333  const ExprT1& expr1; \
334  const ExprT2& expr2; \
335  \
336  }; \
337  \
338  template <typename ExprT1, typename T2> \
339  class Expr< OP< ExprT1, ConstExpr<T2> >,ExprSpecMPVector > { \
340  \
341  public: \
342  \
343  typedef ConstExpr<T2> ConstT; \
344  typedef ConstExpr<T2> ExprT2; \
345  typedef typename ExprT1::value_type value_type_1; \
346  typedef typename ExprT2::value_type value_type_2; \
347  typedef typename Sacado::Promote<value_type_1, \
348  value_type_2>::type value_type; \
349  \
350  typedef typename ExprT1::scalar_type scalar_type_1; \
351  typedef typename ExprT2::scalar_type scalar_type_2; \
352  typedef typename Sacado::Promote<scalar_type_1, \
353  scalar_type_2>::type scalar_type; \
354  \
355  typedef typename ExprT1::base_expr_type base_expr_type_1; \
356  typedef typename ExprT2::base_expr_type base_expr_type_2; \
357  typedef typename Sacado::Promote<base_expr_type_1, \
358  base_expr_type_2>::type base_expr_type; \
359  \
360  typedef typename value_type::value_type val_type; \
361  \
362  KOKKOS_INLINE_FUNCTION \
363  Expr(const ExprT1& expr1_, const ConstT& c_) : \
364  expr1(expr1_), c(c_) {} \
365  \
367  int size() const { \
368  return expr1.size(); \
369  } \
370  \
371  KOKKOS_INLINE_FUNCTION \
372  bool hasFastAccess() const { \
373  return expr1.hasFastAccess(); \
374  } \
375  \
376  KOKKOS_INLINE_FUNCTION \
377  bool isPassive() const { \
378  return expr1.isPassive(); \
379  } \
380  \
381  KOKKOS_INLINE_FUNCTION \
382  bool updateValue() const { return expr1.updateValue(); } \
383  \
384  KOKKOS_INLINE_FUNCTION \
385  const value_type val() const { \
386  return MPVAL_CONST_DX_2; \
387  } \
388  \
389  KOKKOS_INLINE_FUNCTION \
390  const val_type val(int j) const { \
391  return VAL_CONST_DX_2; \
392  } \
393  \
394  KOKKOS_INLINE_FUNCTION \
395  const val_type dx(int i, int j) const { \
396  return CONST_DX_2; \
397  } \
398  \
399  KOKKOS_INLINE_FUNCTION \
400  const val_type fastAccessDx(int i, int j) const { \
401  return CONST_FASTACCESSDX_2; \
402  } \
403  \
404  protected: \
405  \
406  const ExprT1& expr1; \
407  ConstT c; \
408  }; \
409  \
410  template <typename T1, typename ExprT2> \
411  class Expr< OP< ConstExpr<T1>, ExprT2 >,ExprSpecMPVector > { \
412  \
413  public: \
414  \
415  typedef ConstExpr<T1> ConstT; \
416  typedef ConstExpr<T1> ExprT1; \
417  typedef typename ExprT1::value_type value_type_1; \
418  typedef typename ExprT2::value_type value_type_2; \
419  typedef typename Sacado::Promote<value_type_1, \
420  value_type_2>::type value_type; \
421  \
422  typedef typename ExprT1::scalar_type scalar_type_1; \
423  typedef typename ExprT2::scalar_type scalar_type_2; \
424  typedef typename Sacado::Promote<scalar_type_1, \
425  scalar_type_2>::type scalar_type; \
426  \
427  typedef typename ExprT1::base_expr_type base_expr_type_1; \
428  typedef typename ExprT2::base_expr_type base_expr_type_2; \
429  typedef typename Sacado::Promote<base_expr_type_1, \
430  base_expr_type_2>::type base_expr_type; \
431  \
432  typedef typename value_type::value_type val_type; \
433  \
434  KOKKOS_INLINE_FUNCTION \
435  Expr(const ConstT& c_, const ExprT2& expr2_) : \
436  c(c_), expr2(expr2_) {} \
437  \
439  int size() const { \
440  return expr2.size(); \
441  } \
442  \
443  KOKKOS_INLINE_FUNCTION \
444  bool hasFastAccess() const { \
445  return expr2.hasFastAccess(); \
446  } \
447  \
448  KOKKOS_INLINE_FUNCTION \
449  bool isPassive() const { \
450  return expr2.isPassive(); \
451  } \
452  \
453  KOKKOS_INLINE_FUNCTION \
454  bool updateValue() const { return expr2.updateValue(); } \
455  \
456  KOKKOS_INLINE_FUNCTION \
457  const value_type val() const { \
458  return MPVAL_CONST_DX_1; \
459  } \
460  \
461  KOKKOS_INLINE_FUNCTION \
462  const val_type val(int j) const { \
463  return VAL_CONST_DX_1; \
464  } \
465  \
466  KOKKOS_INLINE_FUNCTION \
467  const val_type dx(int i, int j) const { \
468  return CONST_DX_1; \
469  } \
470  \
471  KOKKOS_INLINE_FUNCTION \
472  const val_type fastAccessDx(int i, int j) const { \
473  return CONST_FASTACCESSDX_1; \
474  } \
475  \
476  protected: \
477  \
478  ConstT c; \
479  const ExprT2& expr2; \
480  }; \
481  \
482  } \
483 }
484 
485 
486 FAD_BINARYOP_MACRO(operator+,
487  AdditionOp,
488  expr1.val() + expr2.val(),
489  expr1.val(j) + expr2.val(j),
490  expr1.dx(i,j) + expr2.dx(i,j),
491  expr1.fastAccessDx(i,j) + expr2.fastAccessDx(i,j),
492  c.val() + expr2.val(),
493  expr1.val() + c.val(),
494  c.val(j) + expr2.val(j),
495  expr1.val(j) + c.val(j),
496  expr2.dx(i,j),
497  expr1.dx(i,j),
498  expr2.fastAccessDx(i,j),
499  expr1.fastAccessDx(i,j))
500 FAD_BINARYOP_MACRO(operator-,
502  expr1.val() - expr2.val(),
503  expr1.val(j) - expr2.val(j),
504  expr1.dx(i,j) - expr2.dx(i,j),
505  expr1.fastAccessDx(i,j) - expr2.fastAccessDx(i,j),
506  c.val() - expr2.val(),
507  expr1.val() - c.val(),
508  c.val(j) - expr2.val(j),
509  expr1.val(j) - c.val(j),
510  -expr2.dx(i,j),
511  expr1.dx(i,j),
512  -expr2.fastAccessDx(i,j),
513  expr1.fastAccessDx(i,j))
514 // FAD_BINARYOP_MACRO(operator*,
515 // MultiplicationOp,
516 // expr1.val() * expr2.val(),
517 // expr1.val(j) * expr2.val(j),
518 // expr1.val(j)*expr2.dx(i,j) + expr1.dx(i,j)*expr2.val(j),
519 // expr1.val(j)*expr2.fastAccessDx(i,j) +
520 // expr1.fastAccessDx(i,j)*expr2.val(j),
521 // c.val() * expr2.val(),
522 // expr1.val() * c.val(),
523 // c.val(j) * expr2.val(j),
524 // expr1.val(j) * c.val(j),
525 // c.val(j)*expr2.dx(i,j),
526 // expr1.dx(i,j)*c.val(j),
527 // c.val(j)*expr2.fastAccessDx(i,j),
528 // expr1.fastAccessDx(i,j)*c.val(j))
529 FAD_BINARYOP_MACRO(operator/,
530  DivisionOp,
531  expr1.val() / expr2.val(),
532  expr1.val(j) / expr2.val(j),
533  (expr1.dx(i,j)*expr2.val(j) - expr2.dx(i,j)*expr1.val(j)) /
534  (expr2.val(j)*expr2.val(j)),
535  (expr1.fastAccessDx(i,j)*expr2.val(j) -
536  expr2.fastAccessDx(i,j)*expr1.val(j)) /
537  (expr2.val(j)*expr2.val(j)),
538  c.val() / expr2.val(),
539  expr1.val() / c.val(),
540  c.val(j) / expr2.val(j),
541  expr1.val(j) / c.val(j),
542  -expr2.dx(i,j)*c.val(j) / (expr2.val(j)*expr2.val(j)),
543  expr1.dx(i,j)/c.val(j),
544  -expr2.fastAccessDx(i,j)*c.val(j) / (expr2.val(j)*expr2.val(j)),
545  expr1.fastAccessDx(i,j)/c.val(j))
547  Atan2Op,
548  std::atan2(expr1.val(), expr2.val()),
549  std::atan2(expr1.val(j), expr2.val(j)),
550  (expr2.val(j)*expr1.dx(i,j) - expr1.val(j)*expr2.dx(i,j))/
551  (expr1.val(j)*expr1.val(j) + expr2.val(j)*expr2.val(j)),
552  (expr2.val(j)*expr1.fastAccessDx(i,j) - expr1.val(j)*expr2.fastAccessDx(i,j))/
553  (expr1.val(j)*expr1.val(j) + expr2.val(j)*expr2.val(j)),
554  std::atan2(c.val(), expr2.val()),
555  std::atan2(expr1.val(), c.val()),
556  std::atan2(c.val(j), expr2.val(j)),
557  std::atan2(expr1.val(j), c.val(j)),
558  (-c.val(j)*expr2.dx(i,j)) / (c.val(j)*c.val(j) + expr2.val(j)*expr2.val(j)),
559  (c.val(j)*expr1.dx(i,j))/ (expr1.val(j)*expr1.val(j) + c.val(j)*c.val(j)),
560  (-c.val(j)*expr2.fastAccessDx(i,j))/ (c.val(j)*c.val(j) + expr2.val(j)*expr2.val(j)),
561  (c.val(j)*expr1.fastAccessDx(i,j))/ (expr1.val(j)*expr1.val(j) + c.val(j)*c.val(j)))
563  PowerOp,
564  std::pow(expr1.val(), expr2.val()),
565  std::pow(expr1.val(j), expr2.val(j)),
566  expr1.val(j) == val_type(0) ? val_type(0) : val_type((expr2.dx(i,j)*std::log(expr1.val(j))+expr2.val(j)*expr1.dx(i,j)/expr1.val(j))*std::pow(expr1.val(j),expr2.val(j))),
567  expr1.val(j) == val_type(0) ? val_type(0.0) : val_type((expr2.fastAccessDx(i,j)*std::log(expr1.val(j))+expr2.val(j)*expr1.fastAccessDx(i,j)/expr1.val(j))*std::pow(expr1.val(j),expr2.val(j))),
568  std::pow(c.val(), expr2.val()),
569  std::pow(expr1.val(), c.val()),
570  std::pow(c.val(j), expr2.val(j)),
571  std::pow(expr1.val(j), c.val(j)),
572  c.val(j) == val_type(0) ? val_type(0) : val_type(expr2.dx(i,j)*std::log(c.val(j))*std::pow(c.val(j),expr2.val(j))),
573  expr1.val(j) == val_type(0) ? val_type(0.0) : val_type(c.val(j)*expr1.dx(i,j)/expr1.val(j)*std::pow(expr1.val(j),c.val(j))),
574  c.val(j) == val_type(0) ? val_type(0) : val_type(expr2.fastAccessDx(i,j)*std::log(c.val(j))*std::pow(c.val(j),expr2.val(j))),
575  expr1.val(j) == val_type(0) ? val_type(0.0) : val_type(c.val(j)*expr1.fastAccessDx(i,j)/expr1.val(j)*std::pow(expr1.val(j),c.val(j))))
577  MaxOp,
578  std::max(expr1.val(), expr2.val()),
579  std::max(expr1.val(j), expr2.val(j)),
580  expr1.val(j) >= expr2.val(j) ? expr1.dx(i,j) : expr2.dx(i,j),
581  expr1.val(j) >= expr2.val(j) ? expr1.fastAccessDx(i,j) :
582  expr2.fastAccessDx(i,j),
583  std::max(c.val(), expr2.val()),
584  std::max(expr1.val(), c.val()),
585  std::max(c.val(j), expr2.val(j)),
586  std::max(expr1.val(j), c.val(j)),
587  c.val(j) >= expr2.val(j) ? val_type(0) : expr2.dx(i,j),
588  expr1.val(j) >= c.val(j) ? expr1.dx(i,j) : val_type(0),
589  c.val(j) >= expr2.val(j) ? val_type(0) : expr2.fastAccessDx(i,j),
590  expr1.val(j) >= c.val(j) ? expr1.fastAccessDx(i,j) : val_type(0))
592  MinOp,
593  std::min(expr1.val(), expr2.val()),
594  std::min(expr1.val(j), expr2.val(j)),
595  expr1.val(j) <= expr2.val(j) ? expr1.dx(i,j) : expr2.dx(i,j),
596  expr1.val(j) <= expr2.val(j) ? expr1.fastAccessDx(i,j) :
597  expr2.fastAccessDx(i,j),
598  std::min(c.val(), expr2.val()),
599  std::min(expr1.val(), c.val()),
600  std::min(c.val(j), expr2.val(j)),
601  std::min(expr1.val(j), c.val(j)),
602  c.val(j) <= expr2.val(j) ? val_type(0) : expr2.dx(i,j),
603  expr1.val(j) <= c.val(j) ? expr1.dx(i,j) : val_type(0),
604  c.val(j) <= expr2.val(j) ? val_type(0) : expr2.fastAccessDx(i,j),
605  expr1.val(j) <= c.val(j) ? expr1.fastAccessDx(i,j) : val_type(0))
606 
607 
608 #undef FAD_BINARYOP_MACRO
609 
610 namespace Sacado {
611  namespace Fad {
612 
613  template <typename ExprT1, typename ExprT2>
614  class Expr< MultiplicationOp< ExprT1, ExprT2 >,ExprSpecMPVector > {
615 
616  public:
617 
618  typedef typename ExprT1::value_type value_type_1;
619  typedef typename ExprT2::value_type value_type_2;
620  typedef typename Sacado::Promote<value_type_1,
621  value_type_2>::type value_type;
622 
623  typedef typename ExprT1::scalar_type scalar_type_1;
624  typedef typename ExprT2::scalar_type scalar_type_2;
625  typedef typename Sacado::Promote<scalar_type_1,
626  scalar_type_2>::type scalar_type;
627 
628  typedef typename ExprT1::base_expr_type base_expr_type_1;
629  typedef typename ExprT2::base_expr_type base_expr_type_2;
630  typedef typename Sacado::Promote<base_expr_type_1,
631  base_expr_type_2>::type base_expr_type;
632 
633  typedef typename value_type::value_type val_type;
634 
635  KOKKOS_INLINE_FUNCTION
636  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
637  expr1(expr1_), expr2(expr2_) {}
638 
639  KOKKOS_INLINE_FUNCTION
640  int size() const {
641  int sz1 = expr1.size(), sz2 = expr2.size();
642  return sz1 > sz2 ? sz1 : sz2;
643  }
644 
645  KOKKOS_INLINE_FUNCTION
646  bool hasFastAccess() const {
647  return expr1.hasFastAccess() && expr2.hasFastAccess();
648  }
649 
650  KOKKOS_INLINE_FUNCTION
651  bool isPassive() const {
652  return expr1.isPassive() && expr2.isPassive();
653  }
654 
655  KOKKOS_INLINE_FUNCTION
656  bool updateValue() const {
657  return expr1.updateValue() && expr2.updateValue();
658  }
659 
660  KOKKOS_INLINE_FUNCTION
661  const value_type val() const {
662  return expr1.val()*expr2.val();
663  }
664 
665  KOKKOS_INLINE_FUNCTION
666  const val_type val(int j) const {
667  return expr1.val(j)*expr2.val(j);
668  }
669 
670  KOKKOS_INLINE_FUNCTION
671  const val_type dx(int i, int j) const {
672  if (expr1.size() > 0 && expr2.size() > 0)
673  return expr1.val(j)*expr2.dx(i,j) + expr1.dx(i,j)*expr2.val(j);
674  else if (expr1.size() > 0)
675  return expr1.dx(i,j)*expr2.val(j);
676  else
677  return expr1.val(j)*expr2.dx(i,j);
678  }
679 
680  KOKKOS_INLINE_FUNCTION
681  const val_type fastAccessDx(int i, int j) const {
682  return expr1.val(j)*expr2.fastAccessDx(i,j) +
683  expr1.fastAccessDx(i,j)*expr2.val(j);
684  }
685 
686  protected:
687 
688  const ExprT1& expr1;
689  const ExprT2& expr2;
690 
691  };
692 
693  template <typename ExprT1, typename T2>
694  class Expr< MultiplicationOp< ExprT1, ConstExpr<T2> >,ExprSpecMPVector > {
695 
696  public:
697 
698  typedef ConstExpr<T2> ConstT;
699  typedef ConstExpr<T2> ExprT2;
702  typedef typename Sacado::Promote<value_type_1,
704 
707  typedef typename Sacado::Promote<scalar_type_1,
709 
710  typedef typename ExprT1::base_expr_type base_expr_type_1;
711  typedef typename ExprT2::base_expr_type base_expr_type_2;
712  typedef typename Sacado::Promote<base_expr_type_1,
714 
716 
717  KOKKOS_INLINE_FUNCTION
718  Expr(const ExprT1& expr1_, const ConstT& c_) :
719  expr1(expr1_), c(c_) {}
720 
721  KOKKOS_INLINE_FUNCTION
722  int size() const {
723  return expr1.size();
724  }
725 
726  KOKKOS_INLINE_FUNCTION
727  bool hasFastAccess() const {
728  return expr1.hasFastAccess();
729  }
730 
731  KOKKOS_INLINE_FUNCTION
732  bool isPassive() const {
733  return expr1.isPassive();
734  }
735 
736  KOKKOS_INLINE_FUNCTION
737  bool updateValue() const { return expr1.updateValue(); }
738 
739  KOKKOS_INLINE_FUNCTION
740  const value_type val() const {
741  return expr1.val()*c.val();
742  }
743 
744  KOKKOS_INLINE_FUNCTION
745  const val_type val(int j) const {
746  return expr1.val(j)*c.val(j);
747  }
748 
749  KOKKOS_INLINE_FUNCTION
750  const val_type dx(int i, int j) const {
751  return expr1.dx(i,j)*c.val(j);
752  }
753 
754  KOKKOS_INLINE_FUNCTION
755  const val_type fastAccessDx(int i, int j) const {
756  return expr1.fastAccessDx(i,j)*c.val(j);
757  }
758 
759  protected:
760 
761  const ExprT1& expr1;
763  };
764 
765  template <typename T1, typename ExprT2>
766  class Expr< MultiplicationOp< ConstExpr<T1>, ExprT2 >,ExprSpecMPVector > {
767 
768  public:
769 
770  typedef ConstExpr<T1> ConstT;
771  typedef ConstExpr<T1> ExprT1;
774  typedef typename Sacado::Promote<value_type_1,
776 
779  typedef typename Sacado::Promote<scalar_type_1,
781 
782  typedef typename ExprT1::base_expr_type base_expr_type_1;
783  typedef typename ExprT2::base_expr_type base_expr_type_2;
784  typedef typename Sacado::Promote<base_expr_type_1,
786 
788 
789  KOKKOS_INLINE_FUNCTION
790  Expr(const ConstT& c_, const ExprT2& expr2_) :
791  c(c_), expr2(expr2_) {}
792 
793  KOKKOS_INLINE_FUNCTION
794  int size() const {
795  return expr2.size();
796  }
797 
798  KOKKOS_INLINE_FUNCTION
799  bool hasFastAccess() const {
800  return expr2.hasFastAccess();
801  }
802 
803  KOKKOS_INLINE_FUNCTION
804  bool isPassive() const {
805  return expr2.isPassive();
806  }
807 
808  KOKKOS_INLINE_FUNCTION
809  bool updateValue() const { return expr2.updateValue(); }
810 
811  KOKKOS_INLINE_FUNCTION
812  const value_type val() const {
813  return c.val()*expr2.val();
814  }
815 
816  KOKKOS_INLINE_FUNCTION
817  const val_type val(int j) const {
818  return c.val(j)*expr2.val(j);
819  }
820 
821  KOKKOS_INLINE_FUNCTION
822  const val_type dx(int i, int j) const {
823  return c.val(j)*expr2.dx(i,j);
824  }
825 
826  KOKKOS_INLINE_FUNCTION
827  const val_type fastAccessDx(int i, int j) const {
828  return c.val(j)*expr2.fastAccessDx(i,j);
829  }
830 
831  protected:
832 
834  const ExprT2& expr2;
835  };
836 
837  template <typename ExprT>
838  KOKKOS_INLINE_FUNCTION
839  bool toBool(const Expr<ExprT,ExprSpecMPVector>& x) {
840  bool is_zero = (x.val() == 0.0);
841  for (int i=0; i<x.size(); i++)
842  for (int j=0; j<x.val().size(); ++j)
843  is_zero = is_zero && (x.dx(i,j) == 0.0);
844  return !is_zero;
845  }
846 
847  template <typename ExprT>
848  std::ostream& operator << (std::ostream& os, const Expr<ExprT,ExprSpecMPVector>& x) {
849  os << x.val() << " [";
850 
851  for (int i=0; i< x.size(); i++) {
852  os << " [";
853  for (int j=0; j<x.val().size(); ++j) {
854  os << " " << x.dx(i,j);
855  }
856  os << " ]";
857  }
858 
859  os << " ]";
860  return os;
861  }
862  }
863 }
864 
865 #endif // SACADO_FAD_OPS_MP_VECTOR_HPP
expr expr ASinhOp
KOKKOS_INLINE_FUNCTION PCE< Storage > sqrt(const PCE< Storage > &a)
KOKKOS_INLINE_FUNCTION PCE< Storage > fabs(const PCE< Storage > &a)
KOKKOS_INLINE_FUNCTION PCE< Storage > tan(const PCE< Storage > &a)
expr expr TanhOp
#define OPNAME
KOKKOS_INLINE_FUNCTION Expr(const ExprT1 &expr1_, const ConstT &c_)
KOKKOS_INLINE_FUNCTION PCE< Storage > sinh(const PCE< Storage > &a)
expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 c expr1 expr2 expr1 expr2 expr1 MultiplicationOp
expr expr ATanhOp
atanh(expr.val())
expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 c expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 j expr1 expr1 expr1 expr1 j expr1 c *expr2 expr1 c expr1 c expr1 c expr1 DivisionOp
KOKKOS_INLINE_FUNCTION PCE< Storage > pow(const PCE< Storage > &a, const PCE< Storage > &b)
expr expr ASinOp
KOKKOS_INLINE_FUNCTION const val_type fastAccessDx(int i, int j) const
KOKKOS_INLINE_FUNCTION PCE< Storage > tanh(const PCE< Storage > &a)
#define FAD_BINARYOP_MACRO(OPNAME, OP, USING, MPVALUE, VALUE, DX, CDX1, CDX2, FASTACCESSDX, MPVAL_CONST_DX_1, MPVAL_CONST_DX_2, VAL_CONST_DX_1, VAL_CONST_DX_2, CONST_DX_1, CONST_DX_2, CONST_FASTACCESSDX_1, CONST_FASTACCESSDX_2)
KOKKOS_INLINE_FUNCTION PCE< Storage > cbrt(const PCE< Storage > &a)
expr expr TanOp
KOKKOS_INLINE_FUNCTION PCE< Storage > acos(const PCE< Storage > &a)
atan2(expr1.val(), expr2.val())
KOKKOS_INLINE_FUNCTION PCE< Storage > min(const typename PCE< Storage >::value_type &a, const PCE< Storage > &b)
asinh(expr.val())
KOKKOS_INLINE_FUNCTION bool toBool(const Expr< ExprT, ExprSpecMPVector > &x)
expr2 j expr1 expr1 expr2 expr2 j expr1 c c c c MaxOp
expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 c expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 j expr1 expr1 expr1 expr1 j expr1 c *expr2 expr1 c expr1 c expr1 c expr1 expr1 expr1 expr1 j *expr1 expr2 expr1 expr1 j *expr1 c expr2 expr1 c expr1 expr2 expr1 expr2 expr1 Atan2Op
KOKKOS_INLINE_FUNCTION const val_type dx(int i, int j) const
expr expr CoshOp
KOKKOS_INLINE_FUNCTION PCE< Storage > max(const typename PCE< Storage >::value_type &a, const PCE< Storage > &b)
expr expr expr expr fastAccessDx(i, j)) FAD_UNARYOP_MACRO(exp
KOKKOS_INLINE_FUNCTION PCE< Storage > cosh(const PCE< Storage > &a)
#define FAD_UNARYOP_MACRO(OPNAME, OP, USING, MPVALUE, VALUE, DX, FASTACCESSDX)
expr expr CosOp
KOKKOS_INLINE_FUNCTION PCE< Storage > abs(const PCE< Storage > &a)
expr expr expr dx(i, j)
Sacado::Promote< scalar_type_1, scalar_type_2 >::type scalar_type
KOKKOS_INLINE_FUNCTION PCE< Storage > atan(const PCE< Storage > &a)
KOKKOS_INLINE_FUNCTION PCE< Storage > exp(const PCE< Storage > &a)
KOKKOS_INLINE_FUNCTION Expr(const ConstT &c_, const ExprT2 &expr2_)
expr2 j expr1 expr1 expr2 expr2 j expr1 c c c c MinOp
expr expr SinhOp
expr val()
acosh(expr.val())
expr expr SinOp
expr expr expr expr ExpOp
expr expr SqrtOp
KOKKOS_INLINE_FUNCTION PCE< Storage > sin(const PCE< Storage > &a)
expr expr AbsOp
KOKKOS_INLINE_FUNCTION const val_type fastAccessDx(int i, int j) const
expr expr ACoshOp
Sacado::Promote< base_expr_type_1, base_expr_type_2 >::type base_expr_type
expr expr ATanOp
KOKKOS_INLINE_FUNCTION PCE< Storage > log(const PCE< Storage > &a)
KOKKOS_INLINE_FUNCTION PCE< Storage > log10(const PCE< Storage > &a)
Sacado::Promote< scalar_type_1, scalar_type_2 >::type scalar_type
Sacado::Promote< base_expr_type_1, base_expr_type_2 >::type base_expr_type
KOKKOS_INLINE_FUNCTION const val_type dx(int i, int j) const
KOKKOS_INLINE_FUNCTION PCE< Storage > asin(const PCE< Storage > &a)
KOKKOS_INLINE_FUNCTION PCE< Storage > cos(const PCE< Storage > &a)
expr expr ACosOp