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