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 //
4 // Stokhos Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Eric T. Phipps (etphipp@sandia.gov).
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #include "Sacado_cmath.hpp"
43 #include <ostream> // for std::ostream
44 
45 #ifdef __CUDACC__
46 #include <math_functions.h>
47 #endif
48 
49 /*
50 namespace Sacado {
51  namespace MP {
52 
53  template <typename T>
54  class LogOp :
55  public Expr< LogOp< T > > {
56  public:
57 
58  typedef typename T::value_type value_type;
59  typedef typename T::storage_type storage_type;
60 
61  KOKKOS_INLINE_FUNCTION
62  LogOp(const T& expr_) : expr(expr_) {}
63 
64  KOKKOS_INLINE_FUNCTION
65  std::string name() const {
66  return std::string("log") + expr.name();
67  }
68 
69  KOKKOS_INLINE_FUNCTION
70  int size() const {
71  return expr.size();
72  }
73 
74  KOKKOS_INLINE_FUNCTION
75  bool hasFastAccess(int sz) const {
76  return expr.hasFastAccess(sz);
77  }
78 
79  KOKKOS_INLINE_FUNCTION
80  value_type val() const {
81  return std::log(expr.val());
82  }
83 
84  KOKKOS_INLINE_FUNCTION
85  value_type coeff(int i) const {
86  return std::log(expr.coeff(i));
87  }
88 
89  KOKKOS_INLINE_FUNCTION
90  value_type fastAccessCoeff(int i) const {
91  return std::log(expr.fastAccessCoeff(i));
92  }
93 
94  protected:
95 
96  const T& expr;
97 
98  };
99 
100  template <typename T, typename N>
101  KOKKOS_INLINE_FUNCTION
102  LogOp< T >
103  log (const Expr<T>& expr)
104  {
105  typedef LogOp< typename Expr<T>::derived_type > expr_t;
106 
107  return expr_t(expr.derived());
108  }
109  }
110 }
111 */
112 
113 #define MP_UNARYOP_MACRO(OPNAME,OP,OPER) \
114 namespace Sacado { \
115  namespace MP { \
116  \
117  \
118  template <typename T> \
119  class OP : \
120  public Expr< OP< T > > { \
121  public: \
122  \
123  typedef typename remove_volatile<T>::type Tnv; \
124  typedef typename Tnv::value_type value_type; \
125  typedef typename Tnv::storage_type storage_type; \
126  typedef typename Tnv::base_expr_type base_expr_type; \
127  \
128  KOKKOS_INLINE_FUNCTION \
129  OP(const T& expr_) : expr(expr_) {} \
130  \
131  KOKKOS_INLINE_FUNCTION \
132  std::string name() const { \
133  return std::string(#OPER) + expr.name(); \
134  } \
135  \
136  KOKKOS_INLINE_FUNCTION \
137  int size() const { \
138  return expr.size(); \
139  } \
140  \
141  KOKKOS_INLINE_FUNCTION \
142  bool hasFastAccess(int sz) const { \
143  return expr.hasFastAccess(sz); \
144  } \
145  \
146  KOKKOS_INLINE_FUNCTION \
147  value_type val() const { \
148  return OPER(expr.val()); \
149  } \
150  \
151  KOKKOS_INLINE_FUNCTION \
152  value_type coeff(int i) const { \
153  return OPER(expr.coeff(i)); \
154  } \
155  \
156  KOKKOS_INLINE_FUNCTION \
157  value_type fastAccessCoeff(int i) const { \
158  return OPER(expr.fastAccessCoeff(i)); \
159  } \
160  \
161  template <int i> \
162  KOKKOS_INLINE_FUNCTION \
163  value_type getCoeff() const { \
164  return OPER(expr.template getCoeff<i>()); \
165  } \
166  \
167  protected: \
168  \
169  typename const_expr_ref<T>::type expr; \
170  \
171  }; \
172  \
173  template <typename T> \
174  KOKKOS_INLINE_FUNCTION \
175  OP< T > \
176  OPNAME (const Expr<T>& expr) \
177  { \
178  typedef OP< typename Expr<T>::derived_type > expr_t; \
179  \
180  return expr_t(expr.derived()); \
181  } \
182  \
183  template <typename T> \
184  KOKKOS_INLINE_FUNCTION \
185  OP< volatile T > \
186  OPNAME (const volatile Expr<T>& expr) \
187  { \
188  typedef typename Expr<T>::derived_type derived; \
189  typedef OP< typename add_volatile<derived>::type > expr_t; \
190  \
191  return expr_t(expr.derived()); \
192  } \
193  } \
194  \
195  template <typename T> \
196  struct IsExpr< MP::OP<T> > { \
197  static const bool value = true; \
198  }; \
199  \
200  template <typename T> \
201  struct BaseExprType< MP::OP<T> > { \
202  typedef typename MP::OP<T>::base_expr_type type; \
203  }; \
204 }
205 
206 MP_UNARYOP_MACRO(operator+, UnaryPlusOp, +)
207 MP_UNARYOP_MACRO(operator-, UnaryMinusOp, -)
208 MP_UNARYOP_MACRO(exp, ExpOp, std::exp)
209 MP_UNARYOP_MACRO(log, LogOp, std::log)
210 MP_UNARYOP_MACRO(log10, Log10Op, std::log10)
211 MP_UNARYOP_MACRO(sqrt, SqrtOp, std::sqrt)
212 MP_UNARYOP_MACRO(cbrt, CbrtOp, std::cbrt)
213 MP_UNARYOP_MACRO(cos, CosOp, std::cos)
214 MP_UNARYOP_MACRO(sin, SinOp, std::sin)
215 MP_UNARYOP_MACRO(tan, TanOp, std::tan)
216 MP_UNARYOP_MACRO(acos, ACosOp, std::acos)
217 MP_UNARYOP_MACRO(asin, ASinOp, std::asin)
218 MP_UNARYOP_MACRO(atan, ATanOp, std::atan)
219 MP_UNARYOP_MACRO(cosh, CoshOp, std::cosh)
220 MP_UNARYOP_MACRO(sinh, SinhOp, std::sinh)
221 MP_UNARYOP_MACRO(tanh, TanhOp, std::tanh)
222 MP_UNARYOP_MACRO(acosh, ACoshOp, std::acosh)
223 MP_UNARYOP_MACRO(asinh, ASinhOp, std::asinh)
224 MP_UNARYOP_MACRO(atanh, ATanhOp, std::atanh)
225 MP_UNARYOP_MACRO(abs, AbsOp, std::abs)
226 MP_UNARYOP_MACRO(fabs, FAbsOp, std::fabs)
227 MP_UNARYOP_MACRO(ceil, CeilOp, std::ceil)
228 
229 #undef MP_UNARYOP_MACRO
230 
231 #define MP_BINARYOP_MACRO(OPNAME,OP,OPER) \
232 namespace Sacado { \
233  namespace MP { \
234  \
235  template <typename T1, typename T2> \
236  class OP : \
237  public Expr< OP< T1, T2> > { \
238  \
239  public: \
240  \
241  typedef typename remove_volatile<T1>::type Tnv1; \
242  typedef typename remove_volatile<T2>::type Tnv2; \
243  typedef typename Tnv1::value_type value_type_1; \
244  typedef typename Tnv2::value_type value_type_2; \
245  typedef typename Sacado::Promote<value_type_1, \
246  value_type_2>::type value_type; \
247  \
248  typedef typename Tnv1::storage_type storage_type; \
249  typedef typename Tnv1::base_expr_type base_expr_type; \
250  \
251  KOKKOS_INLINE_FUNCTION \
252  OP(const T1& expr1_, const T2& expr2_) : \
253  expr1(expr1_), expr2(expr2_) {} \
254  \
255  KOKKOS_INLINE_FUNCTION \
256  std::string name() const { \
257  return expr1.name() + std::string(#OPER) + expr2.name(); \
258  } \
259  \
260  KOKKOS_INLINE_FUNCTION \
261  int size() const { \
262  int sz1 = expr1.size(), sz2 = expr2.size(); \
263  return sz1 > sz2 ? sz1 : sz2; \
264  } \
265  \
266  KOKKOS_INLINE_FUNCTION \
267  bool hasFastAccess(int sz) const { \
268  return expr1.hasFastAccess(sz) && expr2.hasFastAccess(sz); \
269  } \
270  \
271  KOKKOS_INLINE_FUNCTION \
272  value_type val() const { \
273  return (expr1.val() OPER expr2.val()); \
274  } \
275  \
276  KOKKOS_INLINE_FUNCTION \
277  value_type coeff(int i) const { \
278  return (expr1.coeff(i) OPER expr2.coeff(i)); \
279  } \
280  \
281  KOKKOS_INLINE_FUNCTION \
282  value_type fastAccessCoeff(int i) const { \
283  return (expr1.fastAccessCoeff(i) OPER expr2.fastAccessCoeff(i)); \
284  } \
285  \
286  template <int i> \
287  KOKKOS_INLINE_FUNCTION \
288  value_type getCoeff() const { \
289  return expr1.template getCoeff<i>() OPER expr2.template getCoeff<i>(); \
290  } \
291  \
292  protected: \
293  \
294  typename const_expr_ref<T1>::type expr1; \
295  typename const_expr_ref<T2>::type expr2; \
296  \
297  }; \
298  \
299  template <typename T1> \
300  class OP< T1, typename T1::value_type > : \
301  public Expr< OP< T1, typename T1::value_type > > { \
302  \
303  public: \
304  \
305  typedef typename remove_volatile<T1>::type Tnv1; \
306  typedef typename Tnv1::value_type value_type; \
307  typedef typename Tnv1::value_type ConstT; \
308  \
309  typedef typename Tnv1::storage_type storage_type; \
310  typedef typename Tnv1::base_expr_type base_expr_type; \
311  \
312  KOKKOS_INLINE_FUNCTION \
313  OP(const T1& expr1_, const ConstT& c_) : \
314  expr1(expr1_), c(c_) {} \
315  \
316  KOKKOS_INLINE_FUNCTION \
317  std::string name() const { \
318  return expr1.name() + std::string(#OPER) + std::string("c"); \
319  } \
320  \
321  KOKKOS_INLINE_FUNCTION \
322  int size() const { \
323  return expr1.size(); \
324  } \
325  \
326  KOKKOS_INLINE_FUNCTION \
327  bool hasFastAccess(int sz) const { \
328  return expr1.hasFastAccess(sz); \
329  } \
330  \
331  KOKKOS_INLINE_FUNCTION \
332  value_type val() const { \
333  return (expr1.val() OPER c); \
334  } \
335  \
336  KOKKOS_INLINE_FUNCTION \
337  value_type coeff(int i) const { \
338  return (expr1.coeff(i) OPER c); \
339  } \
340  \
341  KOKKOS_INLINE_FUNCTION \
342  value_type fastAccessCoeff(int i) const { \
343  return (expr1.fastAccessCoeff(i) OPER c); \
344  } \
345  \
346  template <int i> \
347  KOKKOS_INLINE_FUNCTION \
348  value_type getCoeff() const { \
349  return expr1.template getCoeff<i>() OPER c; \
350  } \
351  \
352  protected: \
353  \
354  typename const_expr_ref<T1>::type expr1; \
355  const ConstT& c; \
356  }; \
357  \
358  template <typename T2> \
359  class OP< typename T2::value_type, T2 > : \
360  public Expr< OP< typename T2::value_type, T2 > > { \
361  \
362  public: \
363  \
364  typedef typename remove_volatile<T2>::type Tnv2; \
365  typedef typename Tnv2::value_type value_type; \
366  typedef typename Tnv2::value_type ConstT; \
367  \
368  typedef typename Tnv2::storage_type storage_type; \
369  typedef typename Tnv2::base_expr_type base_expr_type; \
370  \
371  KOKKOS_INLINE_FUNCTION \
372  OP(const ConstT& c_, const T2& expr2_) : \
373  c(c_), expr2(expr2_) {} \
374  \
375  KOKKOS_INLINE_FUNCTION \
376  std::string name() const { \
377  return std::string("c") + std::string(#OPER) + expr2.name(); \
378  } \
379  \
380  KOKKOS_INLINE_FUNCTION \
381  int size() const { return expr2.size(); } \
382  \
383  KOKKOS_INLINE_FUNCTION \
384  bool hasFastAccess(int sz) const { \
385  return expr2.hasFastAccess(sz); \
386  } \
387  \
388  KOKKOS_INLINE_FUNCTION \
389  value_type val() const { \
390  return (c OPER expr2.val()); \
391  } \
392  \
393  KOKKOS_INLINE_FUNCTION \
394  value_type coeff(int i) const { \
395  return (c OPER expr2.coeff(i)); \
396  } \
397  \
398  KOKKOS_INLINE_FUNCTION \
399  value_type fastAccessCoeff(int i) const { \
400  return (c OPER expr2.fastAccessCoeff(i)); \
401  } \
402  \
403  template <int i> \
404  KOKKOS_INLINE_FUNCTION \
405  value_type getCoeff() const { \
406  return c OPER expr2.template getCoeff<i>(); \
407  } \
408  \
409  protected: \
410  \
411  const ConstT& c; \
412  typename const_expr_ref<T2>::type expr2; \
413  }; \
414  \
415  template <typename T1, typename T2> \
416  KOKKOS_INLINE_FUNCTION \
417  OP< T1, T2 > \
418  OPNAME (const Expr<T1>& expr1, \
419  const Expr<T2>& expr2) \
420  { \
421  typedef OP< typename Expr<T1>::derived_type, \
422  typename Expr<T2>::derived_type > expr_t; \
423  \
424  return expr_t(expr1.derived(), expr2.derived()); \
425  } \
426  \
427  template <typename T1, typename T2> \
428  KOKKOS_INLINE_FUNCTION \
429  OP< volatile T1, volatile T2 > \
430  OPNAME (const volatile Expr<T1>& expr1, \
431  const volatile Expr<T2>& expr2) \
432  { \
433  typedef typename Expr<T1>::derived_type derived1; \
434  typedef typename Expr<T2>::derived_type derived2; \
435  typedef OP< typename add_volatile<derived1>::type, \
436  typename add_volatile<derived2>::type > expr_t; \
437  \
438  return expr_t(expr1.derived(), expr2.derived()); \
439  } \
440  \
441  template <typename T1, typename T2> \
442  KOKKOS_INLINE_FUNCTION \
443  OP< T1, volatile T2 > \
444  OPNAME (const Expr<T1>& expr1, \
445  const volatile Expr<T2>& expr2) \
446  { \
447  typedef typename Expr<T1>::derived_type derived1; \
448  typedef typename Expr<T2>::derived_type derived2; \
449  typedef OP< derived1, \
450  typename add_volatile<derived2>::type > expr_t; \
451  \
452  return expr_t(expr1.derived(), expr2.derived()); \
453  } \
454  \
455  template <typename T1, typename T2> \
456  KOKKOS_INLINE_FUNCTION \
457  OP< volatile T1, T2 > \
458  OPNAME (const volatile Expr<T1>& expr1, \
459  const Expr<T2>& expr2) \
460  { \
461  typedef typename Expr<T1>::derived_type derived1; \
462  typedef typename Expr<T2>::derived_type derived2; \
463  typedef OP< typename add_volatile<derived1>::type, \
464  derived2 > expr_t; \
465  \
466  return expr_t(expr1.derived(), expr2.derived()); \
467  } \
468  \
469  template <typename T> \
470  KOKKOS_INLINE_FUNCTION \
471  OP< typename T::value_type, T > \
472  OPNAME (const typename T::value_type& c, \
473  const Expr<T>& expr) \
474  { \
475  typedef typename T::value_type ConstT; \
476  typedef OP< ConstT, typename Expr<T>::derived_type > expr_t; \
477  \
478  return expr_t(c, expr.derived()); \
479  } \
480  \
481  template <typename T> \
482  KOKKOS_INLINE_FUNCTION \
483  OP< typename T::value_type, volatile T > \
484  OPNAME (const typename T::value_type& c, \
485  const volatile Expr<T>& expr) \
486  { \
487  typedef typename T::value_type ConstT; \
488  typedef typename Expr<T>::derived_type derived; \
489  typedef OP< ConstT, \
490  typename add_volatile<derived>::type > expr_t; \
491  \
492  return expr_t(c, expr.derived()); \
493  } \
494  \
495  template <typename T> \
496  KOKKOS_INLINE_FUNCTION \
497  OP< T, typename T::value_type > \
498  OPNAME (const Expr<T>& expr, \
499  const typename T::value_type& c) \
500  { \
501  typedef typename T::value_type ConstT; \
502  typedef OP< typename Expr<T>::derived_type, ConstT > expr_t; \
503  \
504  return expr_t(expr.derived(), c); \
505  } \
506  \
507  template <typename T> \
508  KOKKOS_INLINE_FUNCTION \
509  OP< volatile T, typename T::value_type > \
510  OPNAME (const volatile Expr<T>& expr, \
511  const typename T::value_type& c) \
512  { \
513  typedef typename T::value_type ConstT; \
514  typedef typename Expr<T>::derived_type derived; \
515  typedef OP< typename add_volatile<derived>::type, \
516  ConstT > expr_t; \
517  \
518  return expr_t(expr.derived(), c); \
519  } \
520  } \
521  \
522  template <typename T1, typename T2> \
523  struct IsExpr< MP::OP<T1,T2> > { \
524  static const bool value = true; \
525  }; \
526  \
527  template <typename T1, typename T2> \
528  struct BaseExprType< MP::OP<T1,T2> > { \
529  typedef typename MP::OP<T1,T2>::base_expr_type type; \
530  }; \
531 }
532 
533 MP_BINARYOP_MACRO(operator+, AdditionOp, +)
534 MP_BINARYOP_MACRO(operator-, SubtractionOp, -)
535 MP_BINARYOP_MACRO(operator*, MultiplicationOp, *)
536 MP_BINARYOP_MACRO(operator/, DivisionOp, /)
537 
538 #undef MP_BINARYOP_MACRO
539 
540 #define MP_BINARYOP_MACRO(OPNAME,OP,OPER) \
541 namespace Sacado { \
542  namespace MP { \
543  \
544  template <typename T1, typename T2> \
545  class OP : \
546  public Expr< OP< T1, T2 > > { \
547  \
548  public: \
549  \
550  typedef typename T1::value_type value_type_1; \
551  typedef typename T2::value_type value_type_2; \
552  typedef typename Sacado::Promote<value_type_1, \
553  value_type_2>::type value_type; \
554  \
555  typedef typename T1::storage_type storage_type; \
556  typedef typename T1::base_expr_type base_expr_type; \
557  \
558  \
559  KOKKOS_INLINE_FUNCTION \
560  OP(const T1& expr1_, const T2& expr2_) : \
561  expr1(expr1_), expr2(expr2_) {} \
562  \
563  KOKKOS_INLINE_FUNCTION \
564  std::string name() const { \
565  return expr1.name() + std::string(#OPER) + expr2.name(); \
566  } \
567  \
568  KOKKOS_INLINE_FUNCTION \
569  int size() const { \
570  int sz1 = expr1.size(), sz2 = expr2.size(); \
571  return sz1 > sz2 ? sz1 : sz2; \
572  } \
573  \
574  KOKKOS_INLINE_FUNCTION \
575  bool hasFastAccess(int sz) const { \
576  return expr1.hasFastAccess(sz) && expr2.hasFastAccess(sz); \
577  } \
578  \
579  KOKKOS_INLINE_FUNCTION \
580  value_type val() const { \
581  return OPER(expr1.val(), expr2.val()); \
582  } \
583  \
584  KOKKOS_INLINE_FUNCTION \
585  value_type coeff(int i) const { \
586  return OPER(expr1.coeff(i), expr2.coeff(i)); \
587  } \
588  \
589  KOKKOS_INLINE_FUNCTION \
590  value_type fastAccessCoeff(int i) const { \
591  return OPER(expr1.fastAccessCoeff(i), expr2.fastAccessCoeff(i)); \
592  } \
593  \
594  template <int i> \
595  KOKKOS_INLINE_FUNCTION \
596  value_type getCoeff() const { \
597  return OPER(expr1.template getCoeff<i>(), \
598  expr2.template getCoeff<i>()); \
599  } \
600  \
601  protected: \
602  \
603  typename const_expr_ref<T1>::type expr1; \
604  typename const_expr_ref<T2>::type expr2; \
605  \
606  }; \
607  \
608  template <typename T1> \
609  class OP< T1, typename T1::value_type > : \
610  public Expr< OP< T1, typename T1::value_type > > { \
611  \
612  public: \
613  \
614  typedef typename T1::value_type value_type; \
615  typedef typename T1::value_type ConstT; \
616  \
617  typedef typename T1::storage_type storage_type; \
618  typedef typename T1::base_expr_type base_expr_type; \
619  \
620  KOKKOS_INLINE_FUNCTION \
621  OP(const T1& expr1_, const ConstT& c_) : \
622  expr1(expr1_), c(c_) {} \
623  \
624  KOKKOS_INLINE_FUNCTION \
625  std::string name() const { \
626  return expr1.name() + std::string(#OPER) + std::string("c"); \
627  } \
628  \
629  KOKKOS_INLINE_FUNCTION \
630  int size() const { return expr1.size(); } \
631  \
632  KOKKOS_INLINE_FUNCTION \
633  bool hasFastAccess(int sz) const { \
634  return expr1.hasFastAccess(sz); \
635  } \
636  \
637  KOKKOS_INLINE_FUNCTION \
638  value_type val() const { \
639  return OPER(expr1.val(), c); \
640  } \
641  \
642  KOKKOS_INLINE_FUNCTION \
643  value_type coeff(int i) const { \
644  return OPER(expr1.coeff(i), c); \
645  } \
646  \
647  KOKKOS_INLINE_FUNCTION \
648  value_type fastAccessCoeff(int i) const { \
649  return OPER(expr1.fastAccessCoeff(i), c); \
650  } \
651  \
652  template <int i> \
653  KOKKOS_INLINE_FUNCTION \
654  value_type getCoeff() const { \
655  return OPER(expr1.template getCoeff<i>(), c); \
656  } \
657  \
658  protected: \
659  \
660  typename const_expr_ref<T1>::type expr1; \
661  const ConstT& c; \
662  }; \
663  \
664  template <typename T2> \
665  class OP< typename T2::value_type, T2 > : \
666  public Expr< OP< typename T2::value_type, T2 > > { \
667  \
668  public: \
669  \
670  typedef typename T2::value_type value_type; \
671  typedef typename T2::value_type ConstT; \
672  \
673  typedef typename T2::storage_type storage_type; \
674  typedef typename T2::base_expr_type base_expr_type; \
675  \
676  KOKKOS_INLINE_FUNCTION \
677  OP(const ConstT& c_, const T2& expr2_) : \
678  c(c_), expr2(expr2_) {} \
679  \
680  KOKKOS_INLINE_FUNCTION \
681  std::string name() const { \
682  return std::string("c") + std::string(#OPER) + expr2.name(); \
683  } \
684  \
685  KOKKOS_INLINE_FUNCTION \
686  int size() const { return expr2.size(); } \
687  \
688  KOKKOS_INLINE_FUNCTION \
689  bool hasFastAccess(int sz) const { \
690  return expr2.hasFastAccess(sz); \
691  } \
692  \
693  KOKKOS_INLINE_FUNCTION \
694  value_type val() const { \
695  return OPER(c, expr2.val()); \
696  } \
697  \
698  KOKKOS_INLINE_FUNCTION \
699  value_type coeff(int i) const { \
700  return OPER(c, expr2.coeff(i)); \
701  } \
702  \
703  KOKKOS_INLINE_FUNCTION \
704  value_type fastAccessCoeff(int i) const { \
705  return OPER(c, expr2.fastAccessCoeff(i)); \
706  } \
707  \
708  template <int i> \
709  KOKKOS_INLINE_FUNCTION \
710  value_type getCoeff() const { \
711  return OPER(c, expr2.template getCoeff<i>()); \
712  } \
713  \
714  protected: \
715  \
716  const ConstT& c; \
717  typename const_expr_ref<T2>::type expr2; \
718  }; \
719  \
720  template <typename T1, typename T2> \
721  KOKKOS_INLINE_FUNCTION \
722  OP< T1, T2 > \
723  OPNAME (const Expr<T1>& expr1, \
724  const Expr<T2>& expr2) \
725  { \
726  typedef OP< typename Expr<T1>::derived_type, \
727  typename Expr<T2>::derived_type > expr_t; \
728  \
729  return expr_t(expr1.derived(), expr2.derived()); \
730  } \
731  \
732  template <typename T> \
733  KOKKOS_INLINE_FUNCTION \
734  OP< typename T::value_type, T > \
735  OPNAME (const typename T::value_type& c, \
736  const Expr<T>& expr) \
737  { \
738  typedef typename T::value_type ConstT; \
739  typedef OP< ConstT, typename Expr<T>::derived_type > expr_t; \
740  \
741  return expr_t(c, expr.derived()); \
742  } \
743  \
744  template <typename T> \
745  KOKKOS_INLINE_FUNCTION \
746  OP< T, typename T::value_type > \
747  OPNAME (const Expr<T>& expr, \
748  const typename T::value_type& c) \
749  { \
750  typedef typename T::value_type ConstT; \
751  typedef OP< typename Expr<T>::derived_type, ConstT > expr_t; \
752  \
753  return expr_t(expr.derived(), c); \
754  } \
755  } \
756  \
757  template <typename T1, typename T2> \
758  struct IsExpr< MP::OP<T1,T2> > { \
759  static const bool value = true; \
760  }; \
761  \
762  template <typename T1, typename T2> \
763  struct BaseExprType< MP::OP<T1,T2> > { \
764  typedef typename MP::OP<T1,T2>::base_expr_type type; \
765  }; \
766 }
767 
769 MP_BINARYOP_MACRO(pow, PowerOp, std::pow)
770 #ifdef __CUDACC__
772 MP_BINARYOP_MACRO(min, MinOp, ::min)
773 #else
775 MP_BINARYOP_MACRO(min, MinOp, std::min)
776 #endif
777 
778 #undef MP_BINARYOP_MACRO
779 
780 //-------------------------- Relational Operators -----------------------
781 
782 #define MP_RELOP_MACRO(OP) \
783 namespace Sacado { \
784  namespace MP { \
785  \
786  template <typename T1, typename T2> \
787  KOKKOS_INLINE_FUNCTION \
788  bool \
789  operator OP (const Expr<T1>& expr1, \
790  const Expr<T2>& expr2) \
791  { \
792  return expr1.derived().val() OP expr2.derived().val(); \
793  } \
794  \
795  template <typename T1, typename T2> \
796  KOKKOS_INLINE_FUNCTION \
797  bool \
798  operator OP (const volatile Expr<T1>& expr1, \
799  const volatile Expr<T2>& expr2) \
800  { \
801  return expr1.derived().val() OP expr2.derived().val(); \
802  } \
803  \
804  template <typename T1, typename T2> \
805  KOKKOS_INLINE_FUNCTION \
806  bool \
807  operator OP (const volatile Expr<T1>& expr1, \
808  const Expr<T2>& expr2) \
809  { \
810  return expr1.derived().val() OP expr2.derived().val(); \
811  } \
812  \
813  template <typename T1, typename T2> \
814  KOKKOS_INLINE_FUNCTION \
815  bool \
816  operator OP (const Expr<T1>& expr1, \
817  const volatile Expr<T2>& expr2) \
818  { \
819  return expr1.derived().val() OP expr2.derived().val(); \
820  } \
821  \
822  template <typename T2> \
823  KOKKOS_INLINE_FUNCTION \
824  bool \
825  operator OP (const typename T2::value_type& a, \
826  const Expr<T2>& expr2) \
827  { \
828  return a OP expr2.derived().val(); \
829  } \
830  \
831  template <typename T2> \
832  KOKKOS_INLINE_FUNCTION \
833  bool \
834  operator OP (const typename T2::value_type& a, \
835  const volatile Expr<T2>& expr2) \
836  { \
837  return a OP expr2.derived().val(); \
838  } \
839  \
840  template <typename T1> \
841  KOKKOS_INLINE_FUNCTION \
842  bool \
843  operator OP (const Expr<T1>& expr1, \
844  const typename T1::value_type& b) \
845  { \
846  return expr1.derived().val() OP b; \
847  } \
848  \
849  template <typename T1> \
850  KOKKOS_INLINE_FUNCTION \
851  bool \
852  operator OP (const volatile Expr<T1>& expr1, \
853  const typename T1::value_type& b) \
854  { \
855  return expr1.derived().val() OP b; \
856  } \
857  } \
858 }
859 
860 MP_RELOP_MACRO(==)
861 MP_RELOP_MACRO(!=)
864 MP_RELOP_MACRO(<=)
865 MP_RELOP_MACRO(>=)
866 MP_RELOP_MACRO(<<=)
867 MP_RELOP_MACRO(>>=)
870 
871 #undef MP_RELOP_MACRO
872 
873 namespace Sacado {
874 
875  namespace MP {
876 
877  template <typename T>
878  KOKKOS_INLINE_FUNCTION
879  bool operator ! (const Expr<T>& expr)
880  {
881  return ! expr.derived().val();
882  }
883 
884  } // namespace MP
885 
886 } // namespace Sacado
887 
888 
889 //-------------------------- Boolean Operators -----------------------
890 namespace Sacado {
891 
892  namespace MP {
893 
894  template <typename T>
895  KOKKOS_INLINE_FUNCTION
896  bool toBool(const Expr<T>& xx) {
897  const typename Expr<T>::derived_type& x =
898  xx.derived();
899  bool is_zero = true;
900  for (int i=0; i<x.size(); i++)
901  is_zero = is_zero && (x.coeff(i) == 0.0);
902  return !is_zero;
903  }
904 
905  } // namespace MP
906 
907 } // namespace Sacado
908 
909 #define PCE_BOOL_MACRO(OP) \
910 namespace Sacado { \
911  namespace MP { \
912  \
913  template <typename T1, typename T2> \
914  KOKKOS_INLINE_FUNCTION \
915  bool \
916  operator OP (const Expr<T1>& expr1, \
917  const Expr<T2>& expr2) \
918  { \
919  return toBool(expr1) OP toBool(expr2); \
920  } \
921  \
922  template <typename T2> \
923  KOKKOS_INLINE_FUNCTION \
924  bool \
925  operator OP (const typename T2::value_type& a, \
926  const Expr<T2>& expr2) \
927  { \
928  return a OP toBool(expr2); \
929  } \
930  \
931  template <typename T1> \
932  KOKKOS_INLINE_FUNCTION \
933  bool \
934  operator OP (const Expr<T1>& expr1, \
935  const typename T1::value_type& b) \
936  { \
937  return toBool(expr1) OP b; \
938  } \
939  } \
940 }
941 
942 PCE_BOOL_MACRO(&&)
943 PCE_BOOL_MACRO(||)
944 
945 #undef PCE_BOOL_MACRO
946 
947 
948 //-------------------------- I/O Operators -----------------------
949 
950 namespace Sacado {
951 
952  namespace MP {
953 
954  template <typename T>
955  std::ostream& operator << (std::ostream& os,
956  const Expr<T>& x) {
957  typedef typename T::storage_type storage_type;
959  os << a;
960  return os;
961  }
962 
963  } // namespace MP
964 
965 } // namespace Sacado
966 
967 //-------------------------- Standard library -----------------------
968 namespace std {
969  template <typename T>
970  bool isfinite(const Sacado::MP::Expr<T>& xx) {
971  using std::isfinite;
972  const typename Sacado::MP::Expr<T>::derived_type& x = xx.derived();
973  for (int i=0; i<x.size(); i++)
974  if (!isfinite(x.coeff(i)))
975  return false;
976  return true;
977  }
978 }
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
#define MP_UNARYOP_MACRO(OPNAME, OP, OPER)
KOKKOS_INLINE_FUNCTION PCE< Storage > ceil(const PCE< Storage > &a)
#define MP_RELOP_MACRO(OP)
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
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