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 // Sacado Package
4 //
5 // Copyright 2006 NTESS and the Sacado contributors.
6 // SPDX-License-Identifier: LGPL-2.1-or-later
7 // *****************************************************************************
8 //
9 // The forward-mode AD classes in Sacado are a derivative work of the
10 // expression template classes in the Fad package by Nicolas Di Cesare.
11 // The following banner is included in the original Fad source code:
12 //
13 // ************ DO NOT REMOVE THIS BANNER ****************
14 //
15 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
16 // http://www.ann.jussieu.fr/~dicesare
17 //
18 // CEMRACS 98 : C++ courses,
19 // templates : new C++ techniques
20 // for scientific computing
21 //
22 //********************************************************
23 //
24 // A short implementation ( not all operators and
25 // functions are overloaded ) of 1st order Automatic
26 // Differentiation in forward mode (FAD) using
27 // EXPRESSION TEMPLATES.
28 //
29 //********************************************************
30 // @HEADER
31 
32 #ifndef SACADO_FAD_OPS_MP_VECTOR_HPP
33 #define SACADO_FAD_OPS_MP_VECTOR_HPP
34 
35 #include "Sacado_Fad_Ops.hpp"
36 #include "Sacado_mpl_enable_if.hpp"
38 
39 #define FAD_UNARYOP_MACRO(OPNAME,OP,MPVALUE,VALUE,DX,FASTACCESSDX) \
40 namespace Sacado { \
41  namespace Fad { \
42  \
43  template <typename ExprT> \
44  class Expr< OP<ExprT>,ExprSpecMPVector > { \
45  public: \
46  \
47  typedef typename ExprT::value_type value_type; \
48  typedef typename ExprT::scalar_type scalar_type; \
49  typedef typename ExprT::base_expr_type base_expr_type; \
50  \
51  typedef typename value_type::value_type val_type; \
52  \
53  KOKKOS_INLINE_FUNCTION \
54  Expr(const ExprT& expr_) : expr(expr_) {} \
55  \
56  KOKKOS_INLINE_FUNCTION \
57  int size() const { return expr.size(); } \
58  \
59  KOKKOS_INLINE_FUNCTION \
60  bool hasFastAccess() const { return expr.hasFastAccess(); } \
61  \
62  KOKKOS_INLINE_FUNCTION \
63  bool isPassive() const { return expr.isPassive();} \
64  \
65  KOKKOS_INLINE_FUNCTION \
66  bool updateValue() const { return expr.updateValue(); } \
67  \
68  KOKKOS_INLINE_FUNCTION \
69  value_type val() const { \
70  return MPVALUE; \
71  } \
72  \
73  KOKKOS_INLINE_FUNCTION \
74  val_type val(int j) const { \
75  return VALUE; \
76  } \
77  \
78  KOKKOS_INLINE_FUNCTION \
79  val_type dx(int i, int j) const { \
80  return DX; \
81  } \
82  \
83  KOKKOS_INLINE_FUNCTION \
84  val_type fastAccessDx(int i, int j) const { \
85  return FASTACCESSDX; \
86  } \
87  \
88  protected: \
89  \
90  const ExprT& expr; \
91  }; \
92  \
93  } \
94 }
95 
96 FAD_UNARYOP_MACRO(operator+,
97  UnaryPlusOp,
98  expr.val(),
99  expr.val(j),
100  expr.dx(i,j),
101  expr.fastAccessDx(i,j))
102 FAD_UNARYOP_MACRO(operator-,
104  -expr.val(),
105  -expr.val(j),
106  -expr.dx(i,j),
107  -expr.fastAccessDx(i,j))
110  std::exp(expr.val()),
111  std::exp(expr.val(j)),
112  std::exp(expr.val(j))*expr.dx(i,j),
113  std::exp(expr.val(j))*expr.fastAccessDx(i,j))
115  LogOp,
116  std::log(expr.val()),
117  std::log(expr.val(j)),
118  expr.dx(i,j)/expr.val(j),
119  expr.fastAccessDx(i,j)/expr.val(j))
122  std::log10(expr.val()),
123  std::log10(expr.val(j)),
124  expr.dx(i,j)/( std::log(val_type(10))*expr.val(j)),
125  expr.fastAccessDx(i,j) / ( std::log(val_type(10))*expr.val(j)))
127  SqrtOp,
128  std::sqrt(expr.val()),
129  std::sqrt(expr.val(j)),
130  expr.dx(i,j)/(val_type(2)* std::sqrt(expr.val(j))),
131  expr.fastAccessDx(i,j)/(val_type(2)* std::sqrt(expr.val(j))))
133  CosOp,
134  std::cos(expr.val()),
135  std::cos(expr.val(j)),
136  -expr.dx(i,j)* std::sin(expr.val(j)),
137  -expr.fastAccessDx(i,j)* std::sin(expr.val(j)))
139  SinOp,
140  std::sin(expr.val()),
141  std::sin(expr.val(j)),
142  expr.dx(i,j)* std::cos(expr.val(j)),
143  expr.fastAccessDx(i,j)* std::cos(expr.val(j)))
145  TanOp,
146  std::tan(expr.val()),
147  std::tan(expr.val(j)),
148  expr.dx(i,j)*
149  (val_type(1)+ std::tan(expr.val(j))* std::tan(expr.val(j))),
150  expr.fastAccessDx(i,j)*
151  (val_type(1)+ std::tan(expr.val(j))* std::tan(expr.val(j))))
153  ACosOp,
154  std::acos(expr.val()),
155  std::acos(expr.val(j)),
156  -expr.dx(i,j)/ std::sqrt(val_type(1)-expr.val(j)*expr.val(j)),
157  -expr.fastAccessDx(i,j) /
158  std::sqrt(val_type(1)-expr.val(j)*expr.val(j)))
160  ASinOp,
161  std::asin(expr.val()),
162  std::asin(expr.val(j)),
163  expr.dx(i,j)/ std::sqrt(val_type(1)-expr.val(j)*expr.val(j)),
164  expr.fastAccessDx(i,j) /
165  std::sqrt(val_type(1)-expr.val(j)*expr.val(j)))
167  ATanOp,
168  std::atan(expr.val()),
169  std::atan(expr.val(j)),
170  expr.dx(i,j)/(val_type(1)+expr.val(j)*expr.val(j)),
171  expr.fastAccessDx(i,j)/(val_type(1)+expr.val(j)*expr.val(j)))
173  CoshOp,
174  std::cosh(expr.val()),
175  std::cosh(expr.val(j)),
176  expr.dx(i,j)* std::sinh(expr.val(j)),
177  expr.fastAccessDx(i,j)* std::sinh(expr.val(j)))
179  SinhOp,
180  std::sinh(expr.val()),
181  std::sinh(expr.val(j)),
182  expr.dx(i,j)* std::cosh(expr.val(j)),
183  expr.fastAccessDx(i,j)* std::cosh(expr.val(j)))
185  TanhOp,
186  std::tanh(expr.val()),
187  std::tanh(expr.val(j)),
188  expr.dx(i,j)/( std::cosh(expr.val(j))* std::cosh(expr.val(j))),
189  expr.fastAccessDx(i,j) /
190  ( std::cosh(expr.val(j))* std::cosh(expr.val(j))))
192  ACoshOp,
193  std::acosh(expr.val()),
194  std::acosh(expr.val(j)),
195  expr.dx(i,j)/ std::sqrt((expr.val(j)-val_type(1)) *
196  (expr.val(j)+val_type(1))),
197  expr.fastAccessDx(i,j)/ std::sqrt((expr.val(j)-val_type(1)) *
198  (expr.val(j)+val_type(1))))
200  ASinhOp,
201  std::asinh(expr.val()),
202  std::asinh(expr.val(j)),
203  expr.dx(i,j)/ std::sqrt(val_type(1)+expr.val(j)*expr.val(j)),
204  expr.fastAccessDx(i,j)/ std::sqrt(val_type(1)+
205  expr.val(j)*expr.val(j)))
207  ATanhOp,
208  std::atanh(expr.val()),
209  std::atanh(expr.val(j)),
210  expr.dx(i,j)/(val_type(1)-expr.val(j)*expr.val(j)),
211  expr.fastAccessDx(i,j)/(val_type(1)-
212  expr.val(j)*expr.val(j)))
214  AbsOp,
215  std::abs(expr.val()),
216  std::abs(expr.val(j)),
217  expr.val(j) >= 0 ? val_type(+expr.dx(i,j)) :
218  val_type(-expr.dx(i,j)),
219  expr.val(j) >= 0 ? val_type(+expr.fastAccessDx(i,j)) :
220  val_type(-expr.fastAccessDx(i,j)))
222  FAbsOp,
223  std::fabs(expr.val()),
224  std::fabs(expr.val(j)),
225  expr.val(j) >= 0 ? val_type(+expr.dx(i,j)) :
226  val_type(-expr.dx(i,j)),
227  expr.val(j) >= 0 ? val_type(+expr.fastAccessDx(i,j)) :
228  val_type(-expr.fastAccessDx(i,j)))
230  CbrtOp,
231  std::cbrt(expr.val()),
232  std::cbrt(expr.val(j)),
233  expr.dx(i,j)/(val_type(3)*std::cbrt(expr.val(j)*expr.val(j))),
234  expr.fastAccessDx(i,j)/(val_type(3)*std::cbrt(expr.val(j)*expr.val(j))))
235 
236 #undef FAD_UNARYOP_MACRO
237 
238 #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) \
239 namespace Sacado { \
240  namespace Fad { \
241  \
242  template <typename ExprT1, typename ExprT2> \
243  class Expr< OP< ExprT1, ExprT2 >,ExprSpecMPVector > { \
244  \
245  public: \
246  \
247  typedef typename ExprT1::value_type value_type_1; \
248  typedef typename ExprT2::value_type value_type_2; \
249  typedef typename Sacado::Promote<value_type_1, \
250  value_type_2>::type value_type; \
251  \
252  typedef typename ExprT1::scalar_type scalar_type_1; \
253  typedef typename ExprT2::scalar_type scalar_type_2; \
254  typedef typename Sacado::Promote<scalar_type_1, \
255  scalar_type_2>::type scalar_type; \
256  \
257  typedef typename ExprT1::base_expr_type base_expr_type_1; \
258  typedef typename ExprT2::base_expr_type base_expr_type_2; \
259  typedef typename Sacado::Promote<base_expr_type_1, \
260  base_expr_type_2>::type base_expr_type; \
261  \
262  typedef typename value_type::value_type val_type; \
263  \
264  KOKKOS_INLINE_FUNCTION \
265  Expr(const ExprT1& expr1_, const ExprT2& expr2_) : \
266  expr1(expr1_), expr2(expr2_) {} \
267  \
268  KOKKOS_INLINE_FUNCTION \
269  int size() const { \
270  int sz1 = expr1.size(), sz2 = expr2.size(); \
271  return sz1 > sz2 ? sz1 : sz2; \
272  } \
273  \
274  KOKKOS_INLINE_FUNCTION \
275  bool hasFastAccess() const { \
276  return expr1.hasFastAccess() && expr2.hasFastAccess(); \
277  } \
278  \
279  KOKKOS_INLINE_FUNCTION \
280  bool isPassive() const { \
281  return expr1.isPassive() && expr2.isPassive(); \
282  } \
283  \
284  KOKKOS_INLINE_FUNCTION \
285  bool updateValue() const { \
286  return expr1.updateValue() && expr2.updateValue(); \
287  } \
288  \
289  KOKKOS_INLINE_FUNCTION \
290  const value_type val() const { \
291  return MPVALUE; \
292  } \
293  \
294  KOKKOS_INLINE_FUNCTION \
295  const val_type val(int j) const { \
296  return VALUE; \
297  } \
298  \
299  KOKKOS_INLINE_FUNCTION \
300  const val_type dx(int i, int j) const { \
301  return DX; \
302  } \
303  \
304  KOKKOS_INLINE_FUNCTION \
305  const val_type fastAccessDx(int i, int j) const { \
306  return FASTACCESSDX; \
307  } \
308  \
309  protected: \
310  \
311  const ExprT1& expr1; \
312  const ExprT2& expr2; \
313  \
314  }; \
315  \
316  template <typename ExprT1, typename T2> \
317  class Expr< OP< ExprT1, ConstExpr<T2> >,ExprSpecMPVector > { \
318  \
319  public: \
320  \
321  typedef ConstExpr<T2> ConstT; \
322  typedef ConstExpr<T2> ExprT2; \
323  typedef typename ExprT1::value_type value_type_1; \
324  typedef typename ExprT2::value_type value_type_2; \
325  typedef typename Sacado::Promote<value_type_1, \
326  value_type_2>::type value_type; \
327  \
328  typedef typename ExprT1::scalar_type scalar_type_1; \
329  typedef typename ExprT2::scalar_type scalar_type_2; \
330  typedef typename Sacado::Promote<scalar_type_1, \
331  scalar_type_2>::type scalar_type; \
332  \
333  typedef typename ExprT1::base_expr_type base_expr_type_1; \
334  typedef typename ExprT2::base_expr_type base_expr_type_2; \
335  typedef typename Sacado::Promote<base_expr_type_1, \
336  base_expr_type_2>::type base_expr_type; \
337  \
338  typedef typename value_type::value_type val_type; \
339  \
340  KOKKOS_INLINE_FUNCTION \
341  Expr(const ExprT1& expr1_, const ConstT& c_) : \
342  expr1(expr1_), c(c_) {} \
343  \
344  KOKKOS_INLINE_FUNCTION \
345  int size() const { \
346  return expr1.size(); \
347  } \
348  \
349  KOKKOS_INLINE_FUNCTION \
350  bool hasFastAccess() const { \
351  return expr1.hasFastAccess(); \
352  } \
353  \
354  KOKKOS_INLINE_FUNCTION \
355  bool isPassive() const { \
356  return expr1.isPassive(); \
357  } \
358  \
359  KOKKOS_INLINE_FUNCTION \
360  bool updateValue() const { return expr1.updateValue(); } \
361  \
362  KOKKOS_INLINE_FUNCTION \
363  const value_type val() const { \
364  return MPVAL_CONST_DX_2; \
365  } \
366  \
367  KOKKOS_INLINE_FUNCTION \
368  const val_type val(int j) const { \
369  return VAL_CONST_DX_2; \
370  } \
371  \
372  KOKKOS_INLINE_FUNCTION \
373  const val_type dx(int i, int j) const { \
374  return CONST_DX_2; \
375  } \
376  \
377  KOKKOS_INLINE_FUNCTION \
378  const val_type fastAccessDx(int i, int j) const { \
379  return CONST_FASTACCESSDX_2; \
380  } \
381  \
382  protected: \
383  \
384  const ExprT1& expr1; \
385  ConstT c; \
386  }; \
387  \
388  template <typename T1, typename ExprT2> \
389  class Expr< OP< ConstExpr<T1>, ExprT2 >,ExprSpecMPVector > { \
390  \
391  public: \
392  \
393  typedef ConstExpr<T1> ConstT; \
394  typedef ConstExpr<T1> ExprT1; \
395  typedef typename ExprT1::value_type value_type_1; \
396  typedef typename ExprT2::value_type value_type_2; \
397  typedef typename Sacado::Promote<value_type_1, \
398  value_type_2>::type value_type; \
399  \
400  typedef typename ExprT1::scalar_type scalar_type_1; \
401  typedef typename ExprT2::scalar_type scalar_type_2; \
402  typedef typename Sacado::Promote<scalar_type_1, \
403  scalar_type_2>::type scalar_type; \
404  \
405  typedef typename ExprT1::base_expr_type base_expr_type_1; \
406  typedef typename ExprT2::base_expr_type base_expr_type_2; \
407  typedef typename Sacado::Promote<base_expr_type_1, \
408  base_expr_type_2>::type base_expr_type; \
409  \
410  typedef typename value_type::value_type val_type; \
411  \
412  KOKKOS_INLINE_FUNCTION \
413  Expr(const ConstT& c_, const ExprT2& expr2_) : \
414  c(c_), expr2(expr2_) {} \
415  \
416  KOKKOS_INLINE_FUNCTION \
417  int size() const { \
418  return expr2.size(); \
419  } \
420  \
421  KOKKOS_INLINE_FUNCTION \
422  bool hasFastAccess() const { \
423  return expr2.hasFastAccess(); \
424  } \
425  \
426  KOKKOS_INLINE_FUNCTION \
427  bool isPassive() const { \
428  return expr2.isPassive(); \
429  } \
430  \
431  KOKKOS_INLINE_FUNCTION \
432  bool updateValue() const { return expr2.updateValue(); } \
433  \
434  KOKKOS_INLINE_FUNCTION \
435  const value_type val() const { \
436  return MPVAL_CONST_DX_1; \
437  } \
438  \
439  KOKKOS_INLINE_FUNCTION \
440  const val_type val(int j) const { \
441  return VAL_CONST_DX_1; \
442  } \
443  \
444  KOKKOS_INLINE_FUNCTION \
445  const val_type dx(int i, int j) const { \
446  return CONST_DX_1; \
447  } \
448  \
449  KOKKOS_INLINE_FUNCTION \
450  const val_type fastAccessDx(int i, int j) const { \
451  return CONST_FASTACCESSDX_1; \
452  } \
453  \
454  protected: \
455  \
456  ConstT c; \
457  const ExprT2& expr2; \
458  }; \
459  \
460  } \
461 }
462 
463 
464 FAD_BINARYOP_MACRO(operator+,
465  AdditionOp,
466  expr1.val() + expr2.val(),
467  expr1.val(j) + expr2.val(j),
468  expr1.dx(i,j) + expr2.dx(i,j),
469  expr1.fastAccessDx(i,j) + expr2.fastAccessDx(i,j),
470  c.val() + expr2.val(),
471  expr1.val() + c.val(),
472  c.val(j) + expr2.val(j),
473  expr1.val(j) + c.val(j),
474  expr2.dx(i,j),
475  expr1.dx(i,j),
476  expr2.fastAccessDx(i,j),
477  expr1.fastAccessDx(i,j))
478 FAD_BINARYOP_MACRO(operator-,
480  expr1.val() - expr2.val(),
481  expr1.val(j) - expr2.val(j),
482  expr1.dx(i,j) - expr2.dx(i,j),
483  expr1.fastAccessDx(i,j) - expr2.fastAccessDx(i,j),
484  c.val() - expr2.val(),
485  expr1.val() - c.val(),
486  c.val(j) - expr2.val(j),
487  expr1.val(j) - c.val(j),
488  -expr2.dx(i,j),
489  expr1.dx(i,j),
490  -expr2.fastAccessDx(i,j),
491  expr1.fastAccessDx(i,j))
492 // FAD_BINARYOP_MACRO(operator*,
493 // MultiplicationOp,
494 // expr1.val() * expr2.val(),
495 // expr1.val(j) * expr2.val(j),
496 // expr1.val(j)*expr2.dx(i,j) + expr1.dx(i,j)*expr2.val(j),
497 // expr1.val(j)*expr2.fastAccessDx(i,j) +
498 // expr1.fastAccessDx(i,j)*expr2.val(j),
499 // c.val() * expr2.val(),
500 // expr1.val() * c.val(),
501 // c.val(j) * expr2.val(j),
502 // expr1.val(j) * c.val(j),
503 // c.val(j)*expr2.dx(i,j),
504 // expr1.dx(i,j)*c.val(j),
505 // c.val(j)*expr2.fastAccessDx(i,j),
506 // expr1.fastAccessDx(i,j)*c.val(j))
507 FAD_BINARYOP_MACRO(operator/,
508  DivisionOp,
509  expr1.val() / expr2.val(),
510  expr1.val(j) / expr2.val(j),
511  (expr1.dx(i,j)*expr2.val(j) - expr2.dx(i,j)*expr1.val(j)) /
512  (expr2.val(j)*expr2.val(j)),
513  (expr1.fastAccessDx(i,j)*expr2.val(j) -
514  expr2.fastAccessDx(i,j)*expr1.val(j)) /
515  (expr2.val(j)*expr2.val(j)),
516  c.val() / expr2.val(),
517  expr1.val() / c.val(),
518  c.val(j) / expr2.val(j),
519  expr1.val(j) / c.val(j),
520  -expr2.dx(i,j)*c.val(j) / (expr2.val(j)*expr2.val(j)),
521  expr1.dx(i,j)/c.val(j),
522  -expr2.fastAccessDx(i,j)*c.val(j) / (expr2.val(j)*expr2.val(j)),
523  expr1.fastAccessDx(i,j)/c.val(j))
525  Atan2Op,
526  std::atan2(expr1.val(), expr2.val()),
527  std::atan2(expr1.val(j), expr2.val(j)),
528  (expr2.val(j)*expr1.dx(i,j) - expr1.val(j)*expr2.dx(i,j))/
529  (expr1.val(j)*expr1.val(j) + expr2.val(j)*expr2.val(j)),
530  (expr2.val(j)*expr1.fastAccessDx(i,j) - expr1.val(j)*expr2.fastAccessDx(i,j))/
531  (expr1.val(j)*expr1.val(j) + expr2.val(j)*expr2.val(j)),
532  std::atan2(c.val(), expr2.val()),
533  std::atan2(expr1.val(), c.val()),
534  std::atan2(c.val(j), expr2.val(j)),
535  std::atan2(expr1.val(j), c.val(j)),
536  (-c.val(j)*expr2.dx(i,j)) / (c.val(j)*c.val(j) + expr2.val(j)*expr2.val(j)),
537  (c.val(j)*expr1.dx(i,j))/ (expr1.val(j)*expr1.val(j) + c.val(j)*c.val(j)),
538  (-c.val(j)*expr2.fastAccessDx(i,j))/ (c.val(j)*c.val(j) + expr2.val(j)*expr2.val(j)),
539  (c.val(j)*expr1.fastAccessDx(i,j))/ (expr1.val(j)*expr1.val(j) + c.val(j)*c.val(j)))
541  PowerOp,
542  std::pow(expr1.val(), expr2.val()),
543  std::pow(expr1.val(j), expr2.val(j)),
544  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))),
545  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))),
546  std::pow(c.val(), expr2.val()),
547  std::pow(expr1.val(), c.val()),
548  std::pow(c.val(j), expr2.val(j)),
549  std::pow(expr1.val(j), c.val(j)),
550  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))),
551  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))),
552  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))),
553  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))))
555  MaxOp,
556  std::max(expr1.val(), expr2.val()),
557  std::max(expr1.val(j), expr2.val(j)),
558  expr1.val(j) >= expr2.val(j) ? expr1.dx(i,j) : expr2.dx(i,j),
559  expr1.val(j) >= expr2.val(j) ? expr1.fastAccessDx(i,j) :
560  expr2.fastAccessDx(i,j),
561  std::max(c.val(), expr2.val()),
562  std::max(expr1.val(), c.val()),
563  std::max(c.val(j), expr2.val(j)),
564  std::max(expr1.val(j), c.val(j)),
565  c.val(j) >= expr2.val(j) ? val_type(0) : expr2.dx(i,j),
566  expr1.val(j) >= c.val(j) ? expr1.dx(i,j) : val_type(0),
567  c.val(j) >= expr2.val(j) ? val_type(0) : expr2.fastAccessDx(i,j),
568  expr1.val(j) >= c.val(j) ? expr1.fastAccessDx(i,j) : val_type(0))
570  MinOp,
571  std::min(expr1.val(), expr2.val()),
572  std::min(expr1.val(j), expr2.val(j)),
573  expr1.val(j) <= expr2.val(j) ? expr1.dx(i,j) : expr2.dx(i,j),
574  expr1.val(j) <= expr2.val(j) ? expr1.fastAccessDx(i,j) :
575  expr2.fastAccessDx(i,j),
576  std::min(c.val(), expr2.val()),
577  std::min(expr1.val(), c.val()),
578  std::min(c.val(j), expr2.val(j)),
579  std::min(expr1.val(j), c.val(j)),
580  c.val(j) <= expr2.val(j) ? val_type(0) : expr2.dx(i,j),
581  expr1.val(j) <= c.val(j) ? expr1.dx(i,j) : val_type(0),
582  c.val(j) <= expr2.val(j) ? val_type(0) : expr2.fastAccessDx(i,j),
583  expr1.val(j) <= c.val(j) ? expr1.fastAccessDx(i,j) : val_type(0))
584 
585 
586 #undef FAD_BINARYOP_MACRO
587 
588 namespace Sacado {
589  namespace Fad {
590 
591  template <typename ExprT1, typename ExprT2>
592  class Expr< MultiplicationOp< ExprT1, ExprT2 >,ExprSpecMPVector > {
593 
594  public:
595 
596  typedef typename ExprT1::value_type value_type_1;
597  typedef typename ExprT2::value_type value_type_2;
598  typedef typename Sacado::Promote<value_type_1,
599  value_type_2>::type value_type;
600 
601  typedef typename ExprT1::scalar_type scalar_type_1;
602  typedef typename ExprT2::scalar_type scalar_type_2;
603  typedef typename Sacado::Promote<scalar_type_1,
604  scalar_type_2>::type scalar_type;
605 
606  typedef typename ExprT1::base_expr_type base_expr_type_1;
607  typedef typename ExprT2::base_expr_type base_expr_type_2;
608  typedef typename Sacado::Promote<base_expr_type_1,
609  base_expr_type_2>::type base_expr_type;
610 
611  typedef typename value_type::value_type val_type;
612 
613  KOKKOS_INLINE_FUNCTION
614  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
615  expr1(expr1_), expr2(expr2_) {}
616 
617  KOKKOS_INLINE_FUNCTION
618  int size() const {
619  int sz1 = expr1.size(), sz2 = expr2.size();
620  return sz1 > sz2 ? sz1 : sz2;
621  }
622 
623  KOKKOS_INLINE_FUNCTION
624  bool hasFastAccess() const {
625  return expr1.hasFastAccess() && expr2.hasFastAccess();
626  }
627 
628  KOKKOS_INLINE_FUNCTION
629  bool isPassive() const {
630  return expr1.isPassive() && expr2.isPassive();
631  }
632 
633  KOKKOS_INLINE_FUNCTION
634  bool updateValue() const {
635  return expr1.updateValue() && expr2.updateValue();
636  }
637 
638  KOKKOS_INLINE_FUNCTION
639  const value_type val() const {
640  return expr1.val()*expr2.val();
641  }
642 
643  KOKKOS_INLINE_FUNCTION
644  const val_type val(int j) const {
645  return expr1.val(j)*expr2.val(j);
646  }
647 
648  KOKKOS_INLINE_FUNCTION
649  const val_type dx(int i, int j) const {
650  if (expr1.size() > 0 && expr2.size() > 0)
651  return expr1.val(j)*expr2.dx(i,j) + expr1.dx(i,j)*expr2.val(j);
652  else if (expr1.size() > 0)
653  return expr1.dx(i,j)*expr2.val(j);
654  else
655  return expr1.val(j)*expr2.dx(i,j);
656  }
657 
658  KOKKOS_INLINE_FUNCTION
659  const val_type fastAccessDx(int i, int j) const {
660  return expr1.val(j)*expr2.fastAccessDx(i,j) +
661  expr1.fastAccessDx(i,j)*expr2.val(j);
662  }
663 
664  protected:
665 
666  const ExprT1& expr1;
667  const ExprT2& expr2;
668 
669  };
670 
671  template <typename ExprT1, typename T2>
672  class Expr< MultiplicationOp< ExprT1, ConstExpr<T2> >,ExprSpecMPVector > {
673 
674  public:
675 
676  typedef ConstExpr<T2> ConstT;
677  typedef ConstExpr<T2> ExprT2;
680  typedef typename Sacado::Promote<value_type_1,
682 
685  typedef typename Sacado::Promote<scalar_type_1,
687 
688  typedef typename ExprT1::base_expr_type base_expr_type_1;
689  typedef typename ExprT2::base_expr_type base_expr_type_2;
690  typedef typename Sacado::Promote<base_expr_type_1,
692 
694 
695  KOKKOS_INLINE_FUNCTION
696  Expr(const ExprT1& expr1_, const ConstT& c_) :
697  expr1(expr1_), c(c_) {}
698 
699  KOKKOS_INLINE_FUNCTION
700  int size() const {
701  return expr1.size();
702  }
703 
704  KOKKOS_INLINE_FUNCTION
705  bool hasFastAccess() const {
706  return expr1.hasFastAccess();
707  }
708 
709  KOKKOS_INLINE_FUNCTION
710  bool isPassive() const {
711  return expr1.isPassive();
712  }
713 
714  KOKKOS_INLINE_FUNCTION
715  bool updateValue() const { return expr1.updateValue(); }
716 
717  KOKKOS_INLINE_FUNCTION
718  const value_type val() const {
719  return expr1.val()*c.val();
720  }
721 
722  KOKKOS_INLINE_FUNCTION
723  const val_type val(int j) const {
724  return expr1.val(j)*c.val(j);
725  }
726 
727  KOKKOS_INLINE_FUNCTION
728  const val_type dx(int i, int j) const {
729  return expr1.dx(i,j)*c.val(j);
730  }
731 
732  KOKKOS_INLINE_FUNCTION
733  const val_type fastAccessDx(int i, int j) const {
734  return expr1.fastAccessDx(i,j)*c.val(j);
735  }
736 
737  protected:
738 
739  const ExprT1& expr1;
741  };
742 
743  template <typename T1, typename ExprT2>
744  class Expr< MultiplicationOp< ConstExpr<T1>, ExprT2 >,ExprSpecMPVector > {
745 
746  public:
747 
748  typedef ConstExpr<T1> ConstT;
749  typedef ConstExpr<T1> ExprT1;
752  typedef typename Sacado::Promote<value_type_1,
754 
757  typedef typename Sacado::Promote<scalar_type_1,
759 
760  typedef typename ExprT1::base_expr_type base_expr_type_1;
761  typedef typename ExprT2::base_expr_type base_expr_type_2;
762  typedef typename Sacado::Promote<base_expr_type_1,
764 
766 
767  KOKKOS_INLINE_FUNCTION
768  Expr(const ConstT& c_, const ExprT2& expr2_) :
769  c(c_), expr2(expr2_) {}
770 
771  KOKKOS_INLINE_FUNCTION
772  int size() const {
773  return expr2.size();
774  }
775 
776  KOKKOS_INLINE_FUNCTION
777  bool hasFastAccess() const {
778  return expr2.hasFastAccess();
779  }
780 
781  KOKKOS_INLINE_FUNCTION
782  bool isPassive() const {
783  return expr2.isPassive();
784  }
785 
786  KOKKOS_INLINE_FUNCTION
787  bool updateValue() const { return expr2.updateValue(); }
788 
789  KOKKOS_INLINE_FUNCTION
790  const value_type val() const {
791  return c.val()*expr2.val();
792  }
793 
794  KOKKOS_INLINE_FUNCTION
795  const val_type val(int j) const {
796  return c.val(j)*expr2.val(j);
797  }
798 
799  KOKKOS_INLINE_FUNCTION
800  const val_type dx(int i, int j) const {
801  return c.val(j)*expr2.dx(i,j);
802  }
803 
804  KOKKOS_INLINE_FUNCTION
805  const val_type fastAccessDx(int i, int j) const {
806  return c.val(j)*expr2.fastAccessDx(i,j);
807  }
808 
809  protected:
810 
812  const ExprT2& expr2;
813  };
814 
815  template <typename ExprT>
816  KOKKOS_INLINE_FUNCTION
817  bool toBool(const Expr<ExprT,ExprSpecMPVector>& x) {
818  bool is_zero = (x.val() == 0.0);
819  for (int i=0; i<x.size(); i++)
820  for (int j=0; j<x.val().size(); ++j)
821  is_zero = is_zero && (x.dx(i,j) == 0.0);
822  return !is_zero;
823  }
824 
825  template <typename ExprT>
826  std::ostream& operator << (std::ostream& os, const Expr<ExprT,ExprSpecMPVector>& x) {
827  os << x.val() << " [";
828 
829  for (int i=0; i< x.size(); i++) {
830  os << " [";
831  for (int j=0; j<x.val().size(); ++j) {
832  os << " " << x.dx(i,j);
833  }
834  os << " ]";
835  }
836 
837  os << " ]";
838  return os;
839  }
840  }
841 }
842 
843 #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
KOKKOS_INLINE_FUNCTION Expr(const ExprT1 &expr1_, const ConstT &c_)
KOKKOS_INLINE_FUNCTION PCE< Storage > sinh(const PCE< Storage > &a)
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