Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Sacado_MathFunctions.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Sacado Package
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25 // (etphipp@sandia.gov).
26 //
27 // ***********************************************************************
28 // @HEADER
29 
30 #ifndef SACADO_MATHFUNCTIONS_HPP
31 #define SACADO_MATHFUNCTIONS_HPP
32 
33 #include <cmath>
34 
35 #include "Sacado_ConfigDefs.h"
36 #include "Sacado_Base.hpp"
38 #include "Sacado_SFINAE_Macros.hpp"
39 
40 // Note: Sacado::Fad::Ops are forward-declared here, instead of in macros
41 // below.
42 #include "Sacado_Fad_Ops_Fwd.hpp"
43 
44 #define UNARYFUNC_MACRO(OP,FADOP) \
45 namespace Sacado { \
46  \
47  namespace Fad { \
48  template <typename T> \
49  KOKKOS_INLINE_FUNCTION \
50  Expr< FADOP< Expr<T> > > OP (const Expr<T>&); \
51  \
52  template <typename T> class SimpleFad; \
53  template <typename T> \
54  SimpleFad<T> OP (const SimpleFad<T>&); \
55  } \
56  \
57  namespace ELRFad { \
58  template <typename T> class FADOP; \
59  template <typename T> class Expr; \
60  template <typename T> \
61  KOKKOS_INLINE_FUNCTION \
62  Expr< FADOP< Expr<T> > > OP (const Expr<T>&); \
63  } \
64  \
65  namespace CacheFad { \
66  template <typename T> class FADOP; \
67  template <typename T> class Expr; \
68  template <typename T> \
69  KOKKOS_INLINE_FUNCTION \
70  Expr< FADOP< Expr<T> > > OP (const Expr<T>&); \
71  } \
72  \
73  namespace ELRCacheFad { \
74  template <typename T> class FADOP; \
75  template <typename T> class Expr; \
76  template <typename T> \
77  KOKKOS_INLINE_FUNCTION \
78  Expr< FADOP< Expr<T> > > OP (const Expr<T>&); \
79  } \
80  \
81  namespace LFad { \
82  template <typename T> class FADOP; \
83  template <typename T> class Expr; \
84  template <typename T> \
85  Expr< FADOP< Expr<T> > > OP (const Expr<T>&); \
86  } \
87  \
88  namespace Tay { \
89  template <typename T> class Taylor; \
90  template <typename T> Taylor<T> OP (const Base< Taylor<T> >&); \
91  } \
92  \
93  namespace FlopCounterPack { \
94  template <typename T> class ScalarFlopCounter; \
95  template <typename T> \
96  ScalarFlopCounter<T> OP (const Base< ScalarFlopCounter<T> >&); \
97  } \
98  \
99  namespace Rad { \
100  template <typename T> class ADvari; \
101  template <typename T> class IndepADvar; \
102  template <typename T> ADvari<T>& OP (const Base< ADvari<T> >&); \
103  template <typename T> ADvari<T>& OP (const Base< IndepADvar<T> >&); \
104  } \
105 } \
106  \
107 namespace std { \
108  using Sacado::Fad::OP; \
109  using Sacado::ELRFad::OP; \
110  using Sacado::CacheFad::OP; \
111  using Sacado::ELRCacheFad::OP; \
112  using Sacado::LFad::OP; \
113  using Sacado::Tay::OP; \
114  using Sacado::FlopCounterPack::OP; \
115  using Sacado::Rad::OP; \
116 }
117 
136 #ifdef HAVE_SACADO_CXX11
138 #endif
139 
140 #undef UNARYFUNC_MACRO
141 
142 #define BINARYFUNC_MACRO(OP,FADOP) \
143 namespace Sacado { \
144  \
145  namespace Fad { \
146  template <typename T> class ConstExpr; \
147  template <typename T> struct IsFadExpr; \
148  template <typename T> struct ExprLevel; \
149  template <typename T1, typename T2> \
150  KOKKOS_INLINE_FUNCTION \
151  typename mpl::enable_if_c< \
152  ExprLevel< Expr<T1> >::value == ExprLevel< Expr<T2> >::value, \
153  Expr< FADOP< Expr<T1>, Expr<T2> > > \
154  >::type \
155  /*SACADO_FAD_OP_ENABLE_EXPR_EXPR(FADOP)*/ \
156  OP (const Expr<T1>&, const Expr<T2>&); \
157  \
158  template <typename T> \
159  KOKKOS_INLINE_FUNCTION \
160  Expr< FADOP< Expr<T>, Expr<T> > > \
161  OP (const Expr<T>&, const Expr<T>&); \
162  \
163  template <typename T> \
164  KOKKOS_INLINE_FUNCTION \
165  Expr< FADOP< ConstExpr<typename Expr<T>::value_type>, Expr<T> > > \
166  OP (const typename Expr<T>::value_type&, const Expr<T>&); \
167  \
168  template <typename T> \
169  KOKKOS_INLINE_FUNCTION \
170  Expr< FADOP< Expr<T>, ConstExpr<typename Expr<T>::value_type> > > \
171  OP (const Expr<T>&, const typename Expr<T>::value_type&); \
172  \
173  template <typename T> \
174  KOKKOS_INLINE_FUNCTION \
175  SACADO_FAD_OP_ENABLE_SCALAR_EXPR(FADOP) \
176  OP (const typename Expr<T>::scalar_type&, const Expr<T>&); \
177  \
178  template <typename T> \
179  KOKKOS_INLINE_FUNCTION \
180  SACADO_FAD_OP_ENABLE_EXPR_SCALAR(FADOP) \
181  OP (const Expr<T>&, const typename Expr<T>::scalar_type&); \
182  \
183  template <typename T> class SimpleFad; \
184  template <typename T> \
185  SimpleFad<T> \
186  OP (const SimpleFad<T>&, const SimpleFad<T>&); \
187  \
188  template <typename T> \
189  SimpleFad<T> \
190  OP (const SimpleFad<T>&, \
191  const typename SimpleFad<T>::value_type&); \
192  \
193  template <typename T> \
194  SimpleFad<T> \
195  OP (const typename SimpleFad<T>::value_type&, \
196  const SimpleFad<T>&); \
197  } \
198  \
199  namespace ELRFad { \
200  template <typename T1, typename T2> class FADOP; \
201  template <typename T> class Expr; \
202  template <typename T> class ConstExpr; \
203  template <typename T> struct IsFadExpr; \
204  template <typename T> struct ExprLevel; \
205  template <typename T1, typename T2> \
206  KOKKOS_INLINE_FUNCTION \
207  SACADO_FAD_OP_ENABLE_EXPR_EXPR(FADOP) \
208  OP (const T1&, const T2&); \
209  \
210  template <typename T> \
211  KOKKOS_INLINE_FUNCTION \
212  Expr< FADOP< Expr<T>, Expr<T> > > \
213  OP (const Expr<T>&, const Expr<T>&); \
214  \
215  template <typename T> \
216  KOKKOS_INLINE_FUNCTION \
217  Expr< FADOP< ConstExpr<typename Expr<T>::value_type>, Expr<T> > > \
218  OP (const typename Expr<T>::value_type&, const Expr<T>&); \
219  \
220  template <typename T> \
221  KOKKOS_INLINE_FUNCTION \
222  Expr< FADOP< Expr<T>, ConstExpr<typename Expr<T>::value_type> > > \
223  OP (const Expr<T>&, const typename Expr<T>::value_type&); \
224  \
225  template <typename T> \
226  KOKKOS_INLINE_FUNCTION \
227  SACADO_FAD_OP_ENABLE_SCALAR_EXPR(FADOP) \
228  OP (const typename Expr<T>::scalar_type&, const Expr<T>&); \
229  \
230  template <typename T> \
231  KOKKOS_INLINE_FUNCTION \
232  SACADO_FAD_OP_ENABLE_EXPR_SCALAR(FADOP) \
233  OP (const Expr<T>&, const typename Expr<T>::scalar_type&); \
234  } \
235  \
236  namespace CacheFad { \
237  template <typename T1, typename T2> class FADOP; \
238  template <typename T> class Expr; \
239  template <typename T> class ConstExpr; \
240  template <typename T> struct IsFadExpr; \
241  template <typename T> struct ExprLevel; \
242  template <typename T1, typename T2> \
243  KOKKOS_INLINE_FUNCTION \
244  SACADO_FAD_OP_ENABLE_EXPR_EXPR(FADOP) \
245  OP (const T1&, const T2&); \
246  \
247  template <typename T> \
248  KOKKOS_INLINE_FUNCTION \
249  Expr< FADOP< Expr<T>, Expr<T> > > \
250  OP (const Expr<T>&, const Expr<T>&); \
251  \
252  template <typename T> \
253  KOKKOS_INLINE_FUNCTION \
254  Expr< FADOP< ConstExpr<typename Expr<T>::value_type>, Expr<T> > > \
255  OP (const typename Expr<T>::value_type&, const Expr<T>&); \
256  \
257  template <typename T> \
258  KOKKOS_INLINE_FUNCTION \
259  Expr< FADOP< Expr<T>, ConstExpr<typename Expr<T>::value_type> > > \
260  OP (const Expr<T>&, const typename Expr<T>::value_type&); \
261  \
262  template <typename T> \
263  KOKKOS_INLINE_FUNCTION \
264  SACADO_FAD_OP_ENABLE_SCALAR_EXPR(FADOP) \
265  OP (const typename Expr<T>::scalar_type&, const Expr<T>&); \
266  \
267  template <typename T> \
268  KOKKOS_INLINE_FUNCTION \
269  SACADO_FAD_OP_ENABLE_EXPR_SCALAR(FADOP) \
270  OP (const Expr<T>&, const typename Expr<T>::scalar_type&); \
271  } \
272  \
273  namespace ELRCacheFad { \
274  template <typename T1, typename T2> class FADOP; \
275  template <typename T> class Expr; \
276  template <typename T> class ConstExpr; \
277  template <typename T> struct IsFadExpr; \
278  template <typename T> struct ExprLevel; \
279  template <typename T1, typename T2> \
280  KOKKOS_INLINE_FUNCTION \
281  SACADO_FAD_OP_ENABLE_EXPR_EXPR(FADOP) \
282  OP (const T1&, const T2&); \
283  \
284  template <typename T> \
285  KOKKOS_INLINE_FUNCTION \
286  Expr< FADOP< Expr<T>, Expr<T> > > \
287  OP (const Expr<T>&, const Expr<T>&); \
288  \
289  template <typename T> \
290  KOKKOS_INLINE_FUNCTION \
291  Expr< FADOP< ConstExpr<typename Expr<T>::value_type>, Expr<T> > > \
292  OP (const typename Expr<T>::value_type&, const Expr<T>&); \
293  \
294  template <typename T> \
295  KOKKOS_INLINE_FUNCTION \
296  Expr< FADOP< Expr<T>, ConstExpr<typename Expr<T>::value_type> > > \
297  OP (const Expr<T>&, const typename Expr<T>::value_type&); \
298  \
299  template <typename T> \
300  KOKKOS_INLINE_FUNCTION \
301  SACADO_FAD_OP_ENABLE_SCALAR_EXPR(FADOP) \
302  OP (const typename Expr<T>::scalar_type&, const Expr<T>&); \
303  \
304  template <typename T> \
305  KOKKOS_INLINE_FUNCTION \
306  SACADO_FAD_OP_ENABLE_EXPR_SCALAR(FADOP) \
307  OP (const Expr<T>&, const typename Expr<T>::scalar_type&); \
308  } \
309  \
310  namespace LFad { \
311  template <typename T1, typename T2> class FADOP; \
312  template <typename T> class Expr; \
313  \
314  template <typename T1, typename T2> \
315  Expr< FADOP< Expr<T1>, Expr<T2> > > \
316  OP (const Expr<T1>&, const Expr<T2>&); \
317  \
318  template <typename T> \
319  Expr< FADOP< Expr<T>, Expr<T> > > \
320  OP (const Expr<T>&, const Expr<T>&); \
321  \
322  template <typename T> \
323  Expr< FADOP< typename Expr<T>::value_type, Expr<T> > > \
324  OP (const typename Expr<T>::value_type&, const Expr<T>&); \
325  \
326  template <typename T> \
327  Expr< FADOP< Expr<T>, typename Expr<T>::value_type > > \
328  OP (const Expr<T>&, const typename Expr<T>::value_type&); \
329  } \
330  \
331  namespace Tay { \
332  template <typename T> class Taylor; \
333  template <typename T> Taylor<T> OP ( \
334  const Base< Taylor<T> >&, \
335  const Base< Taylor<T> >&); \
336  template <typename T> Taylor<T> OP ( \
337  const typename Taylor<T>::value_type&, \
338  const Base< Taylor<T> >&); \
339  template <typename T> Taylor<T> OP ( \
340  const Base< Taylor<T> >&, \
341  const typename Taylor<T>::value_type&); \
342  } \
343  \
344  namespace FlopCounterPack { \
345  template <typename T> class ScalarFlopCounter; \
346  template <typename T> \
347  ScalarFlopCounter<T> OP ( \
348  const Base< ScalarFlopCounter<T> >&, \
349  const Base< ScalarFlopCounter<T> >&); \
350  template <typename T> \
351  ScalarFlopCounter<T> OP ( \
352  const typename ScalarFlopCounter<T>::value_type&, \
353  const Base< ScalarFlopCounter<T> >&); \
354  template <typename T> \
355  ScalarFlopCounter<T> OP ( \
356  const Base< ScalarFlopCounter<T> >&, \
357  const typename ScalarFlopCounter<T>::value_type&); \
358  template <typename T> \
359  ScalarFlopCounter<T> OP ( \
360  const int&, \
361  const Base< ScalarFlopCounter<T> >&); \
362  template <typename T> \
363  ScalarFlopCounter<T> OP ( \
364  const Base< ScalarFlopCounter<T> >&, \
365  const int&); \
366  } \
367  \
368  namespace Rad { \
369  template <typename T> class ADvari; \
370  template <typename T> class IndepADvar; \
371  template <typename T> class DoubleAvoid; \
372  template <typename T> ADvari<T>& OP (const Base< ADvari<T> >&, \
373  const Base< ADvari<T> >&); \
374  template <typename T> ADvari<T>& OP (const Base< IndepADvar<T> >&, \
375  const Base< ADvari<T> >&); \
376  template <typename T> ADvari<T>& OP (T, \
377  const Base< ADvari<T> >&); \
378  template <typename T> ADvari<T>& OP (typename DoubleAvoid<T>::dtype,\
379  const Base< ADvari<T> >&); \
380  template <typename T> ADvari<T>& OP (typename DoubleAvoid<T>::itype,\
381  const Base< ADvari<T> >&); \
382  template <typename T> ADvari<T>& OP (typename DoubleAvoid<T>::ltype,\
383  const Base< ADvari<T> >&); \
384  template <typename T> ADvari<T>& OP (const Base< ADvari<T> >&, \
385  const Base< IndepADvar<T> >&); \
386  template <typename T> ADvari<T>& OP (const Base< ADvari<T> >&, \
387  T); \
388  template <typename T> ADvari<T>& OP (const Base< ADvari<T> >&, \
389  typename DoubleAvoid<T>::dtype);\
390  template <typename T> ADvari<T>& OP (const Base< ADvari<T> >&, \
391  typename DoubleAvoid<T>::itype);\
392  template <typename T> ADvari<T>& OP (const Base< ADvari<T> >&, \
393  typename DoubleAvoid<T>::ltype);\
394  template <typename T> ADvari<T>& OP (const Base< IndepADvar<T> >&, \
395  const Base< IndepADvar<T> >&); \
396  template <typename T> ADvari<T>& OP (T, \
397  const Base< IndepADvar<T> >&); \
398  template <typename T> ADvari<T>& OP (typename DoubleAvoid<T>::dtype,\
399  const Base< IndepADvar<T> >&); \
400  template <typename T> ADvari<T>& OP (typename DoubleAvoid<T>::itype,\
401  const Base< IndepADvar<T> >&); \
402  template <typename T> ADvari<T>& OP (typename DoubleAvoid<T>::ltype,\
403  const Base< IndepADvar<T> >&); \
404  template <typename T> ADvari<T>& OP (const Base< IndepADvar<T> >&, \
405  T); \
406  template <typename T> ADvari<T>& OP (const Base< IndepADvar<T> >&, \
407  typename DoubleAvoid<T>::dtype);\
408  template <typename T> ADvari<T>& OP (const Base< IndepADvar<T> >&, \
409  typename DoubleAvoid<T>::itype);\
410  template <typename T> ADvari<T>& OP (const Base< IndepADvar<T> >&, \
411  typename DoubleAvoid<T>::ltype);\
412  } \
413  \
414 } \
415  \
416 namespace std { \
417  using Sacado::Fad::OP; \
418  using Sacado::ELRFad::OP; \
419  using Sacado::CacheFad::OP; \
420  using Sacado::ELRCacheFad::OP; \
421  using Sacado::LFad::OP; \
422  using Sacado::Tay::OP; \
423  using Sacado::FlopCounterPack::OP; \
424  using Sacado::Rad::OP; \
425 }
426 
431 
432 #undef BINARYFUNC_MACRO
433 
434 #if defined(HAVE_SACADO_KOKKOSCORE)
435 
436 namespace Sacado {
437 #ifndef SACADO_NEW_FAD_DESIGN_IS_DEFAULT
438  namespace Fad {
439  template <typename ValT, unsigned sl, unsigned ss, typename U>
440  class ViewFadPtr;
441  template <typename T> class DFad;
442  template <typename T, int N> class SFad;
443  template <typename T, int N> class SLFad;
444  template <typename T>
446  void atomic_add(DFad<T>* dst, const DFad<T>& x);
447  template <typename T, int N>
449  void atomic_add(SFad<T,N>* dst, const SFad<T,N>& x);
450  template <typename T, int N>
452  void atomic_add(SLFad<T,N>* dst, const SLFad<T,N>& x);
453  template <typename ValT, unsigned sl, unsigned ss, typename U, typename T>
455  void atomic_add(ViewFadPtr<ValT,sl,ss,U> dst, const Expr<T>& x);
456  }
457 #endif
458  namespace ELRFad {
459  template <typename ValT, unsigned sl, unsigned ss, typename U>
460  class ViewFadPtr;
461  template <typename T> class DFad;
462  template <typename T, int N> class SFad;
463  template <typename T, int N> class SLFad;
464  template <typename T>
466  void atomic_add(DFad<T>* dst, const DFad<T>& x);
467  template <typename T, int N>
469  void atomic_add(SFad<T,N>* dst, const SFad<T,N>& x);
470  template <typename T, int N>
472  void atomic_add(SLFad<T,N>* dst, const SLFad<T,N>& x);
473  template <typename ValT, unsigned sl, unsigned ss, typename U, typename T>
475  void atomic_add(ViewFadPtr<ValT,sl,ss,U> dst, const Expr<T>& x);
476  }
477  namespace CacheFad {
478  template <typename ValT, unsigned sl, unsigned ss, typename U>
479  class ViewFadPtr;
480  template <typename T> class DFad;
481  template <typename T, int N> class SFad;
482  template <typename T, int N> class SLFad;
483  template <typename T>
485  void atomic_add(DFad<T>* dst, const DFad<T>& x);
486  template <typename T, int N>
488  void atomic_add(SFad<T,N>* dst, const SFad<T,N>& x);
489  template <typename T, int N>
491  void atomic_add(SLFad<T,N>* dst, const SLFad<T,N>& x);
492  template <typename ValT, unsigned sl, unsigned ss, typename U, typename T>
494  void atomic_add(ViewFadPtr<ValT,sl,ss,U> dst, const Expr<T>& x);
495  }
496  namespace ELRCacheFad {
497  template <typename ValT, unsigned sl, unsigned ss, typename U>
498  class ViewFadPtr;
499  template <typename T> class DFad;
500  template <typename T, int N> class SFad;
501  template <typename T, int N> class SLFad;
502  template <typename T>
504  void atomic_add(DFad<T>* dst, const DFad<T>& x);
505  template <typename T, int N>
507  void atomic_add(SFad<T,N>* dst, const SFad<T,N>& x);
508  template <typename T, int N>
510  void atomic_add(SLFad<T,N>* dst, const SLFad<T,N>& x);
511  template <typename ValT, unsigned sl, unsigned ss, typename U, typename T>
513  void atomic_add(ViewFadPtr<ValT,sl,ss,U> dst, const Expr<T>& x);
514  }
515 }
516 
517 namespace Kokkos {
518 #ifndef SACADO_NEW_FAD_DESIGN_IS_DEFAULT
519  using Sacado::Fad::atomic_add;
520 #endif
521  using Sacado::ELRFad::atomic_add;
522  using Sacado::CacheFad::atomic_add;
523  using Sacado::ELRCacheFad::atomic_add;
524 }
525 
526 #endif
527 
528 #ifdef SACADO_ENABLE_NEW_DESIGN
530 #endif
531 
532 #endif // SACADO_MATHFUNCTIONS_HPP
cbrt(expr.val())
expr expr SinOp
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
asinh(expr.val())
asin(expr.val())
cosh(expr.val())
abs(expr.val())
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MinOp
atanh(expr.val())
expr expr expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 expr1 expr1 c *expr2 expr1 c *expr2 expr1 c *expr2 expr1 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 Atan2Op
expr expr CoshOp
expr expr ATanhOp
GeneralFad< StaticStorage< T, Num > > SLFad
expr expr TanhOp
expr expr SqrtOp
expr expr ASinhOp
atan(expr.val())
KOKKOS_INLINE_FUNCTION mpl::enable_if_c< ExprLevel< Expr< T1 > >::value==ExprLevel< Expr< T2 > >::value, Expr< PowerOp< Expr< T1 >, Expr< T2 > > > >::type pow(const Expr< T1 > &expr1, const Expr< T2 > &expr2)
#define KOKKOS_INLINE_FUNCTION
tanh(expr.val())
expr expr CosOp
#define BINARYFUNC_MACRO(OP, FADOP)
expr expr ATanOp
GeneralFad< DynamicStorage< T > > DFad
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
expr expr ACosOp
sqrt(expr.val())
sinh(expr.val())
tan(expr.val())
atan2(expr1.val(), expr2.val())
sin(expr.val())
log(expr.val())
expr expr ACoshOp
expr expr Log10Op
expr expr SinhOp
acosh(expr.val())
acos(expr.val())
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
expr expr ASinOp
exp(expr.val())
expr expr expr ExpOp
fabs(expr.val())
expr expr AbsOp
expr expr TanOp
GeneralFad< StaticFixedStorage< T, Num > > SFad
log10(expr.val())
cos(expr.val())
#define UNARYFUNC_MACRO(OP, FADOP)
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 PowerOp