Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Sacado_MP_Vector_ops.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Stokhos Package
4 //
5 // Copyright 2009 NTESS and the Stokhos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #include "Sacado_cmath.hpp"
11 #include <ostream> // for std::ostream
12 
13 #ifdef __CUDACC__
14  #include <cuda_runtime_api.h>
15  // including math functions via math_functions.h is deprecated in cuda version >= 10.0
16  // the deprecation warning indicates to use cuda_runtime_api.h instead
17  #if CUDART_VERSION < 10000
18  #include <math_functions.h>
19  #endif
20 #endif
21 
22 /*
23 namespace Sacado {
24  namespace MP {
25 
26  template <typename T>
27  class LogOp :
28  public Expr< LogOp< T > > {
29  public:
30 
31  typedef typename T::value_type value_type;
32  typedef typename T::storage_type storage_type;
33 
34  KOKKOS_INLINE_FUNCTION
35  LogOp(const T& expr_) : expr(expr_) {}
36 
37  KOKKOS_INLINE_FUNCTION
38  std::string name() const {
39  return std::string("log") + expr.name();
40  }
41 
42  KOKKOS_INLINE_FUNCTION
43  int size() const {
44  return expr.size();
45  }
46 
47  KOKKOS_INLINE_FUNCTION
48  bool hasFastAccess(int sz) const {
49  return expr.hasFastAccess(sz);
50  }
51 
52  KOKKOS_INLINE_FUNCTION
53  value_type val() const {
54  return std::log(expr.val());
55  }
56 
57  KOKKOS_INLINE_FUNCTION
58  value_type coeff(int i) const {
59  return std::log(expr.coeff(i));
60  }
61 
62  KOKKOS_INLINE_FUNCTION
63  value_type fastAccessCoeff(int i) const {
64  return std::log(expr.fastAccessCoeff(i));
65  }
66 
67  protected:
68 
69  const T& expr;
70 
71  };
72 
73  template <typename T, typename N>
74  KOKKOS_INLINE_FUNCTION
75  LogOp< T >
76  log (const Expr<T>& expr)
77  {
78  typedef LogOp< typename Expr<T>::derived_type > expr_t;
79 
80  return expr_t(expr.derived());
81  }
82  }
83 }
84 */
85 
86 #define MP_UNARYOP_MACRO(OPNAME,OP,OPER,USING_OP) \
87 namespace Sacado { \
88  namespace MP { \
89  \
90  \
91  template <typename T> \
92  class OP : \
93  public Expr< OP< T > > { \
94  public: \
95  \
96  typedef typename remove_volatile<T>::type Tnv; \
97  typedef typename Tnv::value_type value_type; \
98  typedef typename Tnv::storage_type storage_type; \
99  typedef typename Tnv::base_expr_type base_expr_type; \
100  \
101  KOKKOS_INLINE_FUNCTION \
102  explicit OP(const T& expr_) : expr(expr_) {} \
103  \
104  KOKKOS_INLINE_FUNCTION \
105  std::string name() const { \
106  return std::string(#OPER) + expr.name(); \
107  } \
108  \
109  KOKKOS_INLINE_FUNCTION \
110  int size() const { \
111  return expr.size(); \
112  } \
113  \
114  KOKKOS_INLINE_FUNCTION \
115  bool hasFastAccess(int sz) const { \
116  return expr.hasFastAccess(sz); \
117  } \
118  \
119  KOKKOS_INLINE_FUNCTION \
120  value_type val() const { \
121  USING_OP \
122  return OPER(expr.val()); \
123  } \
124  \
125  KOKKOS_INLINE_FUNCTION \
126  value_type coeff(int i) const { \
127  USING_OP \
128  return OPER(expr.coeff(i)); \
129  } \
130  \
131  KOKKOS_INLINE_FUNCTION \
132  value_type fastAccessCoeff(int i) const { \
133  USING_OP \
134  return OPER(expr.fastAccessCoeff(i)); \
135  } \
136  \
137  template <int i> \
138  KOKKOS_INLINE_FUNCTION \
139  value_type getCoeff() const { \
140  USING_OP \
141  return OPER(expr.template getCoeff<i>()); \
142  } \
143  \
144  protected: \
145  \
146  typename const_expr_ref<T>::type expr; \
147  \
148  }; \
149  \
150  template <typename T> \
151  KOKKOS_INLINE_FUNCTION \
152  OP< T > \
153  OPNAME (const Expr<T>& expr) \
154  { \
155  typedef OP< typename Expr<T>::derived_type > expr_t; \
156  \
157  return expr_t(expr.derived()); \
158  } \
159  \
160  template <typename T> \
161  KOKKOS_INLINE_FUNCTION \
162  OP< volatile T > \
163  OPNAME (const volatile Expr<T>& expr) \
164  { \
165  typedef typename Expr<T>::derived_type derived; \
166  typedef OP< typename add_volatile<derived>::type > expr_t; \
167  \
168  return expr_t(expr.derived()); \
169  } \
170  \
171  template <typename T> \
172  KOKKOS_INLINE_FUNCTION \
173  OP< Vector<T> > \
174  OPNAME (const Vector<T>& vector) \
175  { \
176  return OP< Vector<T> >(vector); \
177  } \
178  } \
179  \
180  template <typename T> \
181  struct IsExpr< MP::OP<T> > { \
182  static const bool value = true; \
183  }; \
184  \
185  template <typename T> \
186  struct BaseExprType< MP::OP<T> > { \
187  typedef typename MP::OP<T>::base_expr_type type; \
188  }; \
189 }
190 
191 MP_UNARYOP_MACRO(operator+, UnaryPlusOp , + , )
192 MP_UNARYOP_MACRO(operator-, UnaryMinusOp, - , )
193 MP_UNARYOP_MACRO(exp , ExpOp , exp , using std::exp;)
194 MP_UNARYOP_MACRO(log , LogOp , log , using std::log;)
195 MP_UNARYOP_MACRO(log10 , Log10Op , log10, using std::log10;)
196 MP_UNARYOP_MACRO(sqrt , SqrtOp , sqrt , using std::sqrt;)
197 MP_UNARYOP_MACRO(cbrt , CbrtOp , cbrt , using std::cbrt;)
198 MP_UNARYOP_MACRO(cos , CosOp , cos , using std::cos;)
199 MP_UNARYOP_MACRO(sin , SinOp , sin , using std::sin;)
200 MP_UNARYOP_MACRO(tan , TanOp , tan , using std::tan;)
201 MP_UNARYOP_MACRO(acos , ACosOp , acos , using std::acos;)
202 MP_UNARYOP_MACRO(asin , ASinOp , asin , using std::asin;)
203 MP_UNARYOP_MACRO(atan , ATanOp , atan , using std::atan;)
204 MP_UNARYOP_MACRO(cosh , CoshOp , cosh , using std::cosh;)
205 MP_UNARYOP_MACRO(sinh , SinhOp , sinh , using std::sinh;)
206 MP_UNARYOP_MACRO(tanh , TanhOp , tanh , using std::tanh;)
207 MP_UNARYOP_MACRO(acosh , ACoshOp , acosh, using std::acosh;)
208 MP_UNARYOP_MACRO(asinh , ASinhOp , asinh, using std::asinh;)
209 MP_UNARYOP_MACRO(atanh , ATanhOp , atanh, using std::atanh;)
210 MP_UNARYOP_MACRO(abs , AbsOp , abs , using std::abs;)
211 MP_UNARYOP_MACRO(fabs , FAbsOp , fabs , using std::fabs;)
212 MP_UNARYOP_MACRO(ceil , CeilOp , ceil , using std::ceil;)
213 
214 #undef MP_UNARYOP_MACRO
215 
216 #define MP_BINARYOP_MACRO(OPNAME,OP,OPER) \
217 namespace Sacado { \
218  namespace MP { \
219  \
220  template <typename T1, typename T2> \
221  class OP : \
222  public Expr< OP< T1, T2> > { \
223  \
224  public: \
225  \
226  typedef typename remove_volatile<T1>::type Tnv1; \
227  typedef typename remove_volatile<T2>::type Tnv2; \
228  typedef typename Tnv1::value_type value_type_1; \
229  typedef typename Tnv2::value_type value_type_2; \
230  typedef typename Sacado::Promote<value_type_1, \
231  value_type_2>::type value_type; \
232  \
233  typedef typename Tnv1::storage_type storage_type; \
234  typedef typename Tnv1::base_expr_type base_expr_type; \
235  \
236  KOKKOS_INLINE_FUNCTION \
237  OP(const T1& expr1_, const T2& expr2_) : \
238  expr1(expr1_), expr2(expr2_) {} \
239  \
240  KOKKOS_INLINE_FUNCTION \
241  std::string name() const { \
242  return expr1.name() + std::string(#OPER) + expr2.name(); \
243  } \
244  \
245  KOKKOS_INLINE_FUNCTION \
246  int size() const { \
247  int sz1 = expr1.size(), sz2 = expr2.size(); \
248  return sz1 > sz2 ? sz1 : sz2; \
249  } \
250  \
251  KOKKOS_INLINE_FUNCTION \
252  bool hasFastAccess(int sz) const { \
253  return expr1.hasFastAccess(sz) && expr2.hasFastAccess(sz); \
254  } \
255  \
256  KOKKOS_INLINE_FUNCTION \
257  value_type val() const { \
258  return (expr1.val() OPER expr2.val()); \
259  } \
260  \
261  KOKKOS_INLINE_FUNCTION \
262  value_type coeff(int i) const { \
263  return (expr1.coeff(i) OPER expr2.coeff(i)); \
264  } \
265  \
266  KOKKOS_INLINE_FUNCTION \
267  value_type fastAccessCoeff(int i) const { \
268  return (expr1.fastAccessCoeff(i) OPER expr2.fastAccessCoeff(i)); \
269  } \
270  \
271  template <int i> \
272  KOKKOS_INLINE_FUNCTION \
273  value_type getCoeff() const { \
274  return expr1.template getCoeff<i>() OPER expr2.template getCoeff<i>(); \
275  } \
276  \
277  protected: \
278  \
279  typename const_expr_ref<T1>::type expr1; \
280  typename const_expr_ref<T2>::type expr2; \
281  \
282  }; \
283  \
284  template <typename T1> \
285  class OP< T1, typename T1::value_type > : \
286  public Expr< OP< T1, typename T1::value_type > > { \
287  \
288  public: \
289  \
290  typedef typename remove_volatile<T1>::type Tnv1; \
291  typedef typename Tnv1::value_type value_type; \
292  typedef typename Tnv1::value_type ConstT; \
293  \
294  typedef typename Tnv1::storage_type storage_type; \
295  typedef typename Tnv1::base_expr_type base_expr_type; \
296  \
297  KOKKOS_INLINE_FUNCTION \
298  OP(const T1& expr1_, const ConstT& c_) : \
299  expr1(expr1_), c(c_) {} \
300  \
301  KOKKOS_INLINE_FUNCTION \
302  std::string name() const { \
303  return expr1.name() + std::string(#OPER) + std::string("c"); \
304  } \
305  \
306  KOKKOS_INLINE_FUNCTION \
307  int size() const { \
308  return expr1.size(); \
309  } \
310  \
311  KOKKOS_INLINE_FUNCTION \
312  bool hasFastAccess(int sz) const { \
313  return expr1.hasFastAccess(sz); \
314  } \
315  \
316  KOKKOS_INLINE_FUNCTION \
317  value_type val() const { \
318  return (expr1.val() OPER c); \
319  } \
320  \
321  KOKKOS_INLINE_FUNCTION \
322  value_type coeff(int i) const { \
323  return (expr1.coeff(i) OPER c); \
324  } \
325  \
326  KOKKOS_INLINE_FUNCTION \
327  value_type fastAccessCoeff(int i) const { \
328  return (expr1.fastAccessCoeff(i) OPER c); \
329  } \
330  \
331  template <int i> \
332  KOKKOS_INLINE_FUNCTION \
333  value_type getCoeff() const { \
334  return expr1.template getCoeff<i>() OPER c; \
335  } \
336  \
337  protected: \
338  \
339  typename const_expr_ref<T1>::type expr1; \
340  const ConstT& c; \
341  }; \
342  \
343  template <typename T2> \
344  class OP< typename T2::value_type, T2 > : \
345  public Expr< OP< typename T2::value_type, T2 > > { \
346  \
347  public: \
348  \
349  typedef typename remove_volatile<T2>::type Tnv2; \
350  typedef typename Tnv2::value_type value_type; \
351  typedef typename Tnv2::value_type ConstT; \
352  \
353  typedef typename Tnv2::storage_type storage_type; \
354  typedef typename Tnv2::base_expr_type base_expr_type; \
355  \
356  KOKKOS_INLINE_FUNCTION \
357  OP(const ConstT& c_, const T2& expr2_) : \
358  c(c_), expr2(expr2_) {} \
359  \
360  KOKKOS_INLINE_FUNCTION \
361  std::string name() const { \
362  return std::string("c") + std::string(#OPER) + expr2.name(); \
363  } \
364  \
365  KOKKOS_INLINE_FUNCTION \
366  int size() const { return expr2.size(); } \
367  \
368  KOKKOS_INLINE_FUNCTION \
369  bool hasFastAccess(int sz) const { \
370  return expr2.hasFastAccess(sz); \
371  } \
372  \
373  KOKKOS_INLINE_FUNCTION \
374  value_type val() const { \
375  return (c OPER expr2.val()); \
376  } \
377  \
378  KOKKOS_INLINE_FUNCTION \
379  value_type coeff(int i) const { \
380  return (c OPER expr2.coeff(i)); \
381  } \
382  \
383  KOKKOS_INLINE_FUNCTION \
384  value_type fastAccessCoeff(int i) const { \
385  return (c OPER expr2.fastAccessCoeff(i)); \
386  } \
387  \
388  template <int i> \
389  KOKKOS_INLINE_FUNCTION \
390  value_type getCoeff() const { \
391  return c OPER expr2.template getCoeff<i>(); \
392  } \
393  \
394  protected: \
395  \
396  const ConstT& c; \
397  typename const_expr_ref<T2>::type expr2; \
398  }; \
399  \
400  template <typename T1, typename T2> \
401  KOKKOS_INLINE_FUNCTION \
402  OP< T1, T2 > \
403  OPNAME (const Expr<T1>& expr1, \
404  const Expr<T2>& expr2) \
405  { \
406  typedef OP< typename Expr<T1>::derived_type, \
407  typename Expr<T2>::derived_type > expr_t; \
408  \
409  return expr_t(expr1.derived(), expr2.derived()); \
410  } \
411  \
412  template <typename T1, typename T2> \
413  KOKKOS_INLINE_FUNCTION \
414  OP< volatile T1, volatile T2 > \
415  OPNAME (const volatile Expr<T1>& expr1, \
416  const volatile Expr<T2>& expr2) \
417  { \
418  typedef typename Expr<T1>::derived_type derived1; \
419  typedef typename Expr<T2>::derived_type derived2; \
420  typedef OP< typename add_volatile<derived1>::type, \
421  typename add_volatile<derived2>::type > expr_t; \
422  \
423  return expr_t(expr1.derived(), expr2.derived()); \
424  } \
425  \
426  template <typename T1, typename T2> \
427  KOKKOS_INLINE_FUNCTION \
428  OP< T1, volatile T2 > \
429  OPNAME (const Expr<T1>& expr1, \
430  const volatile Expr<T2>& expr2) \
431  { \
432  typedef typename Expr<T1>::derived_type derived1; \
433  typedef typename Expr<T2>::derived_type derived2; \
434  typedef OP< derived1, \
435  typename add_volatile<derived2>::type > expr_t; \
436  \
437  return expr_t(expr1.derived(), expr2.derived()); \
438  } \
439  \
440  template <typename T1, typename T2> \
441  KOKKOS_INLINE_FUNCTION \
442  OP< volatile T1, T2 > \
443  OPNAME (const volatile Expr<T1>& expr1, \
444  const Expr<T2>& expr2) \
445  { \
446  typedef typename Expr<T1>::derived_type derived1; \
447  typedef typename Expr<T2>::derived_type derived2; \
448  typedef OP< typename add_volatile<derived1>::type, \
449  derived2 > expr_t; \
450  \
451  return expr_t(expr1.derived(), expr2.derived()); \
452  } \
453  \
454  template <typename T> \
455  KOKKOS_INLINE_FUNCTION \
456  OP< typename T::value_type, T > \
457  OPNAME (const typename T::value_type& c, \
458  const Expr<T>& expr) \
459  { \
460  typedef typename T::value_type ConstT; \
461  typedef OP< ConstT, typename Expr<T>::derived_type > expr_t; \
462  \
463  return expr_t(c, expr.derived()); \
464  } \
465  \
466  template <typename T> \
467  KOKKOS_INLINE_FUNCTION \
468  OP< typename T::value_type, volatile T > \
469  OPNAME (const typename T::value_type& c, \
470  const volatile Expr<T>& expr) \
471  { \
472  typedef typename T::value_type ConstT; \
473  typedef typename Expr<T>::derived_type derived; \
474  typedef OP< ConstT, \
475  typename add_volatile<derived>::type > expr_t; \
476  \
477  return expr_t(c, expr.derived()); \
478  } \
479  \
480  template <typename T> \
481  KOKKOS_INLINE_FUNCTION \
482  OP< T, typename T::value_type > \
483  OPNAME (const Expr<T>& expr, \
484  const typename T::value_type& c) \
485  { \
486  typedef typename T::value_type ConstT; \
487  typedef OP< typename Expr<T>::derived_type, ConstT > expr_t; \
488  \
489  return expr_t(expr.derived(), c); \
490  } \
491  \
492  template <typename T> \
493  KOKKOS_INLINE_FUNCTION \
494  OP< volatile T, typename T::value_type > \
495  OPNAME (const volatile Expr<T>& expr, \
496  const typename T::value_type& c) \
497  { \
498  typedef typename T::value_type ConstT; \
499  typedef typename Expr<T>::derived_type derived; \
500  typedef OP< typename add_volatile<derived>::type, \
501  ConstT > expr_t; \
502  \
503  return expr_t(expr.derived(), c); \
504  } \
505  \
506  template <typename T> \
507  KOKKOS_INLINE_FUNCTION \
508  OP< Vector<T>, Vector<T> > \
509  OPNAME (const Vector<T>& vector1, \
510  const Vector<T>& vector2) \
511  { \
512  return {vector1, vector2}; \
513  } \
514  } \
515  \
516  template <typename T1, typename T2> \
517  struct IsExpr< MP::OP<T1,T2> > { \
518  static const bool value = true; \
519  }; \
520  \
521  template <typename T1, typename T2> \
522  struct BaseExprType< MP::OP<T1,T2> > { \
523  typedef typename MP::OP<T1,T2>::base_expr_type type; \
524  }; \
525 }
526 
527 MP_BINARYOP_MACRO(operator+, AdditionOp, +)
528 MP_BINARYOP_MACRO(operator-, SubtractionOp, -)
529 MP_BINARYOP_MACRO(operator*, MultiplicationOp, *)
530 MP_BINARYOP_MACRO(operator/, DivisionOp, /)
531 
532 #undef MP_BINARYOP_MACRO
533 
534 #define MP_BINARYOP_MACRO(OPNAME,OP,OPER,USING_OP) \
535 namespace Sacado { \
536  namespace MP { \
537  \
538  template <typename T1, typename T2> \
539  class OP : \
540  public Expr< OP< T1, T2 > > { \
541  \
542  public: \
543  \
544  typedef typename T1::value_type value_type_1; \
545  typedef typename T2::value_type value_type_2; \
546  typedef typename Sacado::Promote<value_type_1, \
547  value_type_2>::type value_type; \
548  \
549  typedef typename T1::storage_type storage_type; \
550  typedef typename T1::base_expr_type base_expr_type; \
551  \
552  \
553  KOKKOS_INLINE_FUNCTION \
554  OP(const T1& expr1_, const T2& expr2_) : \
555  expr1(expr1_), expr2(expr2_) {} \
556  \
557  KOKKOS_INLINE_FUNCTION \
558  std::string name() const { \
559  return expr1.name() + std::string(#OPER) + expr2.name(); \
560  } \
561  \
562  KOKKOS_INLINE_FUNCTION \
563  int size() const { \
564  int sz1 = expr1.size(), sz2 = expr2.size(); \
565  return sz1 > sz2 ? sz1 : sz2; \
566  } \
567  \
568  KOKKOS_INLINE_FUNCTION \
569  bool hasFastAccess(int sz) const { \
570  return expr1.hasFastAccess(sz) && expr2.hasFastAccess(sz); \
571  } \
572  \
573  KOKKOS_INLINE_FUNCTION \
574  value_type val() const { \
575  USING_OP \
576  return OPER(expr1.val(), expr2.val()); \
577  } \
578  \
579  KOKKOS_INLINE_FUNCTION \
580  value_type coeff(int i) const { \
581  USING_OP \
582  return OPER(expr1.coeff(i), expr2.coeff(i)); \
583  } \
584  \
585  KOKKOS_INLINE_FUNCTION \
586  value_type fastAccessCoeff(int i) const { \
587  USING_OP \
588  return OPER(expr1.fastAccessCoeff(i), expr2.fastAccessCoeff(i)); \
589  } \
590  \
591  template <int i> \
592  KOKKOS_INLINE_FUNCTION \
593  value_type getCoeff() const { \
594  USING_OP \
595  return OPER(expr1.template getCoeff<i>(), \
596  expr2.template getCoeff<i>()); \
597  } \
598  \
599  protected: \
600  \
601  typename const_expr_ref<T1>::type expr1; \
602  typename const_expr_ref<T2>::type expr2; \
603  \
604  }; \
605  \
606  template <typename T1> \
607  class OP< T1, typename T1::value_type > : \
608  public Expr< OP< T1, typename T1::value_type > > { \
609  \
610  public: \
611  \
612  typedef typename T1::value_type value_type; \
613  typedef typename T1::value_type ConstT; \
614  \
615  typedef typename T1::storage_type storage_type; \
616  typedef typename T1::base_expr_type base_expr_type; \
617  \
618  KOKKOS_INLINE_FUNCTION \
619  OP(const T1& expr1_, const ConstT& c_) : \
620  expr1(expr1_), c(c_) {} \
621  \
622  KOKKOS_INLINE_FUNCTION \
623  std::string name() const { \
624  return expr1.name() + std::string(#OPER) + std::string("c"); \
625  } \
626  \
627  KOKKOS_INLINE_FUNCTION \
628  int size() const { return expr1.size(); } \
629  \
630  KOKKOS_INLINE_FUNCTION \
631  bool hasFastAccess(int sz) const { \
632  return expr1.hasFastAccess(sz); \
633  } \
634  \
635  KOKKOS_INLINE_FUNCTION \
636  value_type val() const { \
637  USING_OP \
638  return OPER(expr1.val(), c); \
639  } \
640  \
641  KOKKOS_INLINE_FUNCTION \
642  value_type coeff(int i) const { \
643  USING_OP \
644  return OPER(expr1.coeff(i), c); \
645  } \
646  \
647  KOKKOS_INLINE_FUNCTION \
648  value_type fastAccessCoeff(int i) const { \
649  USING_OP \
650  return OPER(expr1.fastAccessCoeff(i), c); \
651  } \
652  \
653  template <int i> \
654  KOKKOS_INLINE_FUNCTION \
655  value_type getCoeff() const { \
656  USING_OP \
657  return OPER(expr1.template getCoeff<i>(), c); \
658  } \
659  \
660  protected: \
661  \
662  typename const_expr_ref<T1>::type expr1; \
663  const ConstT& c; \
664  }; \
665  \
666  template <typename T2> \
667  class OP< typename T2::value_type, T2 > : \
668  public Expr< OP< typename T2::value_type, T2 > > { \
669  \
670  public: \
671  \
672  typedef typename T2::value_type value_type; \
673  typedef typename T2::value_type ConstT; \
674  \
675  typedef typename T2::storage_type storage_type; \
676  typedef typename T2::base_expr_type base_expr_type; \
677  \
678  KOKKOS_INLINE_FUNCTION \
679  OP(const ConstT& c_, const T2& expr2_) : \
680  c(c_), expr2(expr2_) {} \
681  \
682  KOKKOS_INLINE_FUNCTION \
683  std::string name() const { \
684  return std::string("c") + std::string(#OPER) + expr2.name(); \
685  } \
686  \
687  KOKKOS_INLINE_FUNCTION \
688  int size() const { return expr2.size(); } \
689  \
690  KOKKOS_INLINE_FUNCTION \
691  bool hasFastAccess(int sz) const { \
692  return expr2.hasFastAccess(sz); \
693  } \
694  \
695  KOKKOS_INLINE_FUNCTION \
696  value_type val() const { \
697  USING_OP \
698  return OPER(c, expr2.val()); \
699  } \
700  \
701  KOKKOS_INLINE_FUNCTION \
702  value_type coeff(int i) const { \
703  USING_OP \
704  return OPER(c, expr2.coeff(i)); \
705  } \
706  \
707  KOKKOS_INLINE_FUNCTION \
708  value_type fastAccessCoeff(int i) const { \
709  USING_OP \
710  return OPER(c, expr2.fastAccessCoeff(i)); \
711  } \
712  \
713  template <int i> \
714  KOKKOS_INLINE_FUNCTION \
715  value_type getCoeff() const { \
716  USING_OP \
717  return OPER(c, expr2.template getCoeff<i>()); \
718  } \
719  \
720  protected: \
721  \
722  const ConstT& c; \
723  typename const_expr_ref<T2>::type expr2; \
724  }; \
725  \
726  template <typename T1, typename T2> \
727  KOKKOS_INLINE_FUNCTION \
728  OP< T1, T2 > \
729  OPNAME (const Expr<T1>& expr1, \
730  const Expr<T2>& expr2) \
731  { \
732  typedef OP< typename Expr<T1>::derived_type, \
733  typename Expr<T2>::derived_type > expr_t; \
734  \
735  return expr_t(expr1.derived(), expr2.derived()); \
736  } \
737  \
738  template <typename T> \
739  KOKKOS_INLINE_FUNCTION \
740  OP< typename T::value_type, T > \
741  OPNAME (const typename T::value_type& c, \
742  const Expr<T>& expr) \
743  { \
744  typedef typename T::value_type ConstT; \
745  typedef OP< ConstT, typename Expr<T>::derived_type > expr_t; \
746  \
747  return expr_t(c, expr.derived()); \
748  } \
749  \
750  template <typename T> \
751  KOKKOS_INLINE_FUNCTION \
752  OP< T, typename T::value_type > \
753  OPNAME (const Expr<T>& expr, \
754  const typename T::value_type& c) \
755  { \
756  typedef typename T::value_type ConstT; \
757  typedef OP< typename Expr<T>::derived_type, ConstT > expr_t; \
758  \
759  return expr_t(expr.derived(), c); \
760  } \
761  \
762  template <typename T> \
763  KOKKOS_INLINE_FUNCTION \
764  OP< Vector<T>, Vector<T> > \
765  OPNAME (const Vector<T>& vector1, \
766  const Vector<T>& vector2) \
767  { \
768  return {vector1, vector2}; \
769  } \
770  } \
771  \
772  template <typename T1, typename T2> \
773  struct IsExpr< MP::OP<T1,T2> > { \
774  static const bool value = true; \
775  }; \
776  \
777  template <typename T1, typename T2> \
778  struct BaseExprType< MP::OP<T1,T2> > { \
779  typedef typename MP::OP<T1,T2>::base_expr_type type; \
780  }; \
781 }
782 
784 MP_BINARYOP_MACRO(pow , PowerOp, pow , using std::pow; )
785 #ifdef __CUDACC__
788 #else
791 #endif
792 MP_BINARYOP_MACRO(fmax, FMaxOp, fmax, using std::fmax;)
793 MP_BINARYOP_MACRO(fmin, FMinOp, fmin, using std::fmin;)
794 
795 #undef MP_BINARYOP_MACRO
796 
797 namespace Sacado {
798 
799  namespace MP {
800 
801  template <typename T>
802  KOKKOS_INLINE_FUNCTION
803  bool operator ! (const Expr<T>& expr)
804  {
805  return ! expr.derived().val();
806  }
807 
808  } // namespace MP
809 
810 } // namespace Sacado
811 
812 
813 //-------------------------- Boolean Operators -----------------------
814 namespace Sacado {
815 
816  namespace MP {
817 
818  template <typename T>
819  KOKKOS_INLINE_FUNCTION
820  bool toBool(const Expr<T>& xx) {
821  const typename Expr<T>::derived_type& x =
822  xx.derived();
823  bool is_zero = true;
824  for (int i=0; i<x.size(); i++)
825  is_zero = is_zero && (x.coeff(i) == 0.0);
826  return !is_zero;
827  }
828 
829  } // namespace MP
830 
831 } // namespace Sacado
832 
833 #define PCE_BOOL_MACRO(OP) \
834 namespace Sacado { \
835  namespace MP { \
836  \
837  template <typename T1, typename T2> \
838  KOKKOS_INLINE_FUNCTION \
839  bool \
840  operator OP (const Expr<T1>& expr1, \
841  const Expr<T2>& expr2) \
842  { \
843  return toBool(expr1) OP toBool(expr2); \
844  } \
845  \
846  template <typename T2> \
847  KOKKOS_INLINE_FUNCTION \
848  bool \
849  operator OP (const typename T2::value_type& a, \
850  const Expr<T2>& expr2) \
851  { \
852  return a OP toBool(expr2); \
853  } \
854  \
855  template <typename T1> \
856  KOKKOS_INLINE_FUNCTION \
857  bool \
858  operator OP (const Expr<T1>& expr1, \
859  const typename T1::value_type& b) \
860  { \
861  return toBool(expr1) OP b; \
862  } \
863  } \
864 }
865 
866 PCE_BOOL_MACRO(&&)
867 PCE_BOOL_MACRO(||)
868 
869 #undef PCE_BOOL_MACRO
870 
871 
872 //-------------------------- I/O Operators -----------------------
873 
874 namespace Sacado {
875 
876  namespace MP {
877 
878  template <typename T>
879  std::ostream& operator << (std::ostream& os,
880  const Expr<T>& x) {
881  typedef typename T::storage_type storage_type;
883  os << a;
884  return os;
885  }
886 
887  } // namespace MP
888 
889 } // namespace Sacado
890 
891 //-------------------------- Standard library -----------------------
892 namespace std {
893  template <typename T>
894  bool isfinite(const Sacado::MP::Expr<T>& xx) {
895  using std::isfinite;
896  const typename Sacado::MP::Expr<T>::derived_type& x = xx.derived();
897  for (int i=0; i<x.size(); i++)
898  if (!isfinite(x.coeff(i)))
899  return false;
900  return true;
901  }
902 }
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
Stokhos::StandardStorage< int, double > storage_type
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())
#define MP_BINARYOP_MACRO(OPNAME, OP, OPER)
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 bool toBool(const Expr< T > &xx)
KOKKOS_INLINE_FUNCTION PCE< Storage > tanh(const PCE< Storage > &a)
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 operator!(const Expr< T > &expr)
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 PCE< Storage > ceil(const PCE< Storage > &a)
expr expr CoshOp
KOKKOS_INLINE_FUNCTION PCE< Storage > max(const typename PCE< Storage >::value_type &a, const PCE< Storage > &b)
KOKKOS_INLINE_FUNCTION PCE< Storage > cosh(const PCE< Storage > &a)
expr expr CosOp
KOKKOS_INLINE_FUNCTION PCE< Storage > abs(const PCE< Storage > &a)
KOKKOS_INLINE_FUNCTION PCE< Storage > atan(const PCE< Storage > &a)
KOKKOS_INLINE_FUNCTION PCE< Storage > exp(const PCE< Storage > &a)
expr2 j expr1 expr1 expr2 expr2 j expr1 c c c c MinOp
expr expr SinhOp
std::ostream & operator<<(std::ostream &os, const Expr< T > &x)
acosh(expr.val())
expr expr SinOp
expr expr expr expr ExpOp
expr expr SqrtOp
#define MP_UNARYOP_MACRO(OPNAME, OP, OPER, USING_OP)
KOKKOS_INLINE_FUNCTION PCE< Storage > sin(const PCE< Storage > &a)
expr expr AbsOp
expr expr ACoshOp
expr expr ATanOp
KOKKOS_INLINE_FUNCTION PCE< Storage > log(const PCE< Storage > &a)
KOKKOS_INLINE_FUNCTION PCE< Storage > log10(const PCE< Storage > &a)
KOKKOS_INLINE_FUNCTION PCE< Storage > asin(const PCE< Storage > &a)
KOKKOS_INLINE_FUNCTION PCE< Storage > cos(const PCE< Storage > &a)
#define PCE_BOOL_MACRO(OP)
expr expr ACosOp