Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Sacado_CacheFad_Ops.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 //
29 // The forward-mode AD classes in Sacado are a derivative work of the
30 // expression template classes in the Fad package by Nicolas Di Cesare.
31 // The following banner is included in the original Fad source code:
32 //
33 // ************ DO NOT REMOVE THIS BANNER ****************
34 //
35 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
36 // http://www.ann.jussieu.fr/~dicesare
37 //
38 // CEMRACS 98 : C++ courses,
39 // templates : new C++ techniques
40 // for scientific computing
41 //
42 //********************************************************
43 //
44 // A short implementation ( not all operators and
45 // functions are overloaded ) of 1st order Automatic
46 // Differentiation in forward mode (FAD) using
47 // EXPRESSION TEMPLATES.
48 //
49 //********************************************************
50 // @HEADER
51 
52 #ifndef SACADO_CACHEFAD_OPS_HPP
53 #define SACADO_CACHEFAD_OPS_HPP
54 
56 #include "Sacado_cmath.hpp"
57 #include "Sacado_dummy_arg.hpp"
58 #include <ostream> // for std::ostream
59 
60 namespace Sacado {
61  namespace CacheFad {
62 
63  //
64  // UnaryPlusOp
65  //
66 
67  template <typename ExprT>
68  class UnaryPlusOp {};
69 
70  template <typename ExprT>
71  class Expr< UnaryPlusOp<ExprT> > {
72  public:
73 
74  typedef typename ExprT::value_type value_type;
75  typedef typename ExprT::scalar_type scalar_type;
76  typedef typename ExprT::base_expr_type base_expr_type;
77 
79  Expr(const ExprT& expr_) : expr(expr_) {}
80 
82  int size() const { return expr.size(); }
83 
85  bool updateValue() const { return expr.updateValue(); }
86 
88  void cache() const {
89  expr.cache();
90  }
91 
93  value_type val() const {
94  return expr.val();
95  }
96 
98  bool isLinear() const {
99  return expr.isLinear();
100  }
101 
103  bool hasFastAccess() const {
104  return expr.hasFastAccess();
105  }
106 
108  const value_type dx(int i) const {
109  return expr.dx(i);
110  }
111 
113  const value_type fastAccessDx(int i) const {
114  return expr.fastAccessDx(i);
115  }
116 
117  protected:
118 
119  const ExprT& expr;
120  };
121 
122  template <typename T>
125  operator+ (const Expr<T>& expr)
126  {
127  typedef UnaryPlusOp< Expr<T> > expr_t;
128 
129  return Expr<expr_t>(expr);
130  }
131 
132  //
133  // UnaryMinusOp
134  //
135  template <typename ExprT>
136  class UnaryMinusOp {};
137 
138  template <typename ExprT>
139  class Expr< UnaryMinusOp<ExprT> > {
140  public:
141 
142  typedef typename ExprT::value_type value_type;
143  typedef typename ExprT::scalar_type scalar_type;
144  typedef typename ExprT::base_expr_type base_expr_type;
145 
147  Expr(const ExprT& expr_) : expr(expr_) {}
148 
150  int size() const { return expr.size(); }
151 
153  bool updateValue() const { return expr.updateValue(); }
154 
156  void cache() const {
157  expr.cache();
158  }
159 
161  value_type val() const {
162  return -expr.val();
163  }
164 
166  bool isLinear() const {
167  return expr.isLinear();
168  }
169 
171  bool hasFastAccess() const {
172  return expr.hasFastAccess();
173  }
174 
176  const value_type dx(int i) const {
177  return -expr.dx(i);
178  }
179 
181  const value_type fastAccessDx(int i) const {
182  return -expr.fastAccessDx(i);
183  }
184 
185  protected:
186 
187  const ExprT& expr;
188  };
189 
190  template <typename T>
193  operator- (const Expr<T>& expr)
194  {
195  typedef UnaryMinusOp< Expr<T> > expr_t;
196 
197  return Expr<expr_t>(expr);
198  }
199 
200  //
201  // AbsOp
202  //
203 
204  template <typename ExprT>
205  class AbsOp {};
206 
207  template <typename ExprT>
208  class Expr< AbsOp<ExprT> > {
209  public:
210 
211  typedef typename ExprT::value_type value_type;
212  typedef typename ExprT::scalar_type scalar_type;
213  typedef typename ExprT::base_expr_type base_expr_type;
214 
216  Expr(const ExprT& expr_) : expr(expr_) {}
217 
219  int size() const { return expr.size(); }
220 
222  bool updateValue() const { return expr.updateValue(); }
223 
225  void cache() const {
226  expr.cache();
227  v = expr.val();
228  v_pos = (v >= 0);
229  }
230 
232  value_type val() const {
233  return std::abs(v);
234  }
235 
237  bool isLinear() const {
238  return false;
239  }
240 
242  bool hasFastAccess() const {
243  return expr.hasFastAccess();
244  }
245 
247  const value_type dx(int i) const {
248  return v_pos ? expr.dx(i) : value_type(-expr.dx(i));
249  }
250 
252  const value_type fastAccessDx(int i) const {
253  return v_pos ? expr.fastAccessDx(i) : value_type(-expr.fastAccessDx(i));
254  }
255 
256  protected:
257 
258  const ExprT& expr;
259  mutable value_type v;
260  mutable bool v_pos;
261  };
262 
263  template <typename T>
266  abs (const Expr<T>& expr)
267  {
268  typedef AbsOp< Expr<T> > expr_t;
269 
270  return Expr<expr_t>(expr);
271  }
272 
273  //
274  // FAbsOp
275  //
276 
277  template <typename ExprT>
278  class FAbsOp {};
279 
280  template <typename ExprT>
281  class Expr< FAbsOp<ExprT> > {
282  public:
283 
284  typedef typename ExprT::value_type value_type;
285  typedef typename ExprT::scalar_type scalar_type;
286  typedef typename ExprT::base_expr_type base_expr_type;
287 
289  Expr(const ExprT& expr_) : expr(expr_) {}
290 
292  int size() const { return expr.size(); }
293 
295  bool updateValue() const { return expr.updateValue(); }
296 
298  void cache() const {
299  expr.cache();
300  v = expr.val();
301  v_pos = (v >= 0);
302  }
303 
305  value_type val() const {
306  return std::fabs(v);
307  }
308 
310  bool isLinear() const {
311  return false;
312  }
313 
315  bool hasFastAccess() const {
316  return expr.hasFastAccess();
317  }
318 
320  const value_type dx(int i) const {
321  return v_pos ? expr.dx(i) : value_type(-expr.dx(i));
322  }
323 
325  const value_type fastAccessDx(int i) const {
326  return v_pos ? expr.fastAccessDx(i) : value_type(-expr.fastAccessDx(i));
327  }
328 
329  protected:
330 
331  const ExprT& expr;
332  mutable value_type v;
333  mutable bool v_pos;
334  };
335 
336  template <typename T>
339  fabs (const Expr<T>& expr)
340  {
341  typedef FAbsOp< Expr<T> > expr_t;
342 
343  return Expr<expr_t>(expr);
344  }
345 
346  }
347 }
348 
349 #define FAD_UNARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE) \
350 namespace Sacado { \
351  namespace CacheFad { \
352  \
353  template <typename ExprT> \
354  class OP {}; \
355  \
356  template <typename ExprT> \
357  class Expr< OP<ExprT> > { \
358  public: \
359  \
360  typedef typename ExprT::value_type value_type; \
361  typedef typename ExprT::scalar_type scalar_type; \
362  typedef typename ExprT::base_expr_type base_expr_type; \
363  \
364  KOKKOS_INLINE_FUNCTION \
365  Expr(const ExprT& expr_) : expr(expr_) {} \
366  \
367  KOKKOS_INLINE_FUNCTION \
368  int size() const { return expr.size(); } \
369  \
370  KOKKOS_INLINE_FUNCTION \
371  bool hasFastAccess() const { return expr.hasFastAccess(); } \
372  \
373  KOKKOS_INLINE_FUNCTION \
374  bool isPassive() const { return expr.isPassive();} \
375  \
376  KOKKOS_INLINE_FUNCTION \
377  bool updateValue() const { return expr.updateValue(); } \
378  \
379  KOKKOS_INLINE_FUNCTION \
380  void cache() const { \
381  expr.cache(); \
382  v = expr.val(); \
383  PARTIAL; \
384  } \
385  \
386  KOKKOS_INLINE_FUNCTION \
387  value_type val() const { \
388  return VALUE; \
389  } \
390  \
391  KOKKOS_INLINE_FUNCTION \
392  value_type dx(int i) const { \
393  return expr.dx(i)*a; \
394  } \
395  \
396  KOKKOS_INLINE_FUNCTION \
397  value_type fastAccessDx(int i) const { \
398  return expr.fastAccessDx(i)*a; \
399  } \
400  \
401  protected: \
402  \
403  const ExprT& expr; \
404  mutable value_type v; \
405  mutable value_type a; \
406  }; \
407  \
408  template <typename T> \
409  KOKKOS_INLINE_FUNCTION \
410  Expr< OP< Expr<T> > > \
411  OPNAME (const Expr<T>& expr) \
412  { \
413  typedef OP< Expr<T> > expr_t; \
414  \
415  return Expr<expr_t>(expr); \
416  } \
417  } \
418 }
419 
421  ExpOp,
422  a = std::exp(v),
423  a)
426  a=value_type(1)/v,
427  std::log(v))
430  a = value_type(1)/(std::log(value_type(10))*v),
431  std::log10(v))
434  a = value_type(1)/(value_type(2)*std::sqrt(v)),
435  std::sqrt(v))
438  a = -std::sin(v),
439  std::cos(v))
442  a = std::cos(v),
443  std::sin(v))
446  a = value_type(1)+std::tan(v)*std::tan(v),
447  std::tan(v))
450  a = value_type(-1)/std::sqrt(value_type(1)-v*v),
451  std::acos(v))
454  a = value_type(1)/std::sqrt(value_type(1)-v*v),
455  std::asin(v))
458  a = value_type(1)/(value_type(1)+v*v),
459  std::atan(v))
462  a = std::sinh(v),
463  std::cosh(v))
466  a = std::cosh(v),
467  std::sinh(v))
470  a = value_type(1)/(std::cosh(v)*std::cosh(v)),
471  std::tanh(v))
474  a = value_type(1)/std::sqrt((v-value_type(1))*(v+value_type(1))),
475  std::acosh(v))
478  a = value_type(1)/std::sqrt(value_type(1)+v*v),
479  std::asinh(v))
482  a = value_type(1)/(value_type(1)-v*v),
483  std::atanh(v))
484 #ifdef HAVE_SACADO_CXX11
486  CbrtOp,
487  a = value_type(1)/(value_type(3)*std::cbrt(v*v)),
488  std::cbrt(v))
489 #endif
490 
491 #undef FAD_UNARYOP_MACRO
492 
493 //
494 // Binary operators
495 //
496 namespace Sacado {
497  namespace CacheFad {
498 
499  //
500  // AdditionOp
501  //
502 
503  template <typename ExprT1, typename ExprT2>
504  class AdditionOp {};
505 
506  template <typename ExprT1, typename ExprT2>
507  class Expr< AdditionOp<ExprT1,ExprT2> > {
508 
509  public:
510 
511  typedef typename ExprT1::value_type value_type_1;
512  typedef typename ExprT2::value_type value_type_2;
513  typedef typename Sacado::Promote<value_type_1,
514  value_type_2>::type value_type;
515 
516  typedef typename ExprT1::scalar_type scalar_type_1;
517  typedef typename ExprT2::scalar_type scalar_type_2;
518  typedef typename Sacado::Promote<scalar_type_1,
519  scalar_type_2>::type scalar_type;
520 
521  typedef typename ExprT1::base_expr_type base_expr_type_1;
522  typedef typename ExprT2::base_expr_type base_expr_type_2;
523  typedef typename Sacado::Promote<base_expr_type_1,
524  base_expr_type_2>::type base_expr_type;
525 
527  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
528  expr1(expr1_), expr2(expr2_) {}
529 
531  int size() const {
532  int sz1 = expr1.size(), sz2 = expr2.size();
533  return sz1 > sz2 ? sz1 : sz2;
534  }
535 
537  bool updateValue() const {
538  return expr1.updateValue() && expr2.updateValue();
539  }
540 
542  void cache() const {
543  expr1.cache();
544  expr2.cache();
545  }
546 
548  value_type val() const {
549  return expr1.val()+expr2.val();
550  }
551 
553  bool isLinear() const {
554  return expr1.isLinear() && expr2.isLinear();
555  }
556 
558  bool hasFastAccess() const {
559  return expr1.hasFastAccess() && expr2.hasFastAccess();
560  }
561 
563  const value_type dx(int i) const {
564  return expr1.dx(i) + expr2.dx(i);
565  }
566 
568  const value_type fastAccessDx(int i) const {
569  return expr1.fastAccessDx(i) + expr2.fastAccessDx(i);
570  }
571 
572  protected:
573 
574  const ExprT1& expr1;
575  const ExprT2& expr2;
576 
577  };
578 
579  template <typename ExprT1, typename T2>
580  class Expr< AdditionOp<ExprT1, ConstExpr<T2> > > {
581 
582  public:
583 
584  typedef ConstExpr<T2> ExprT2;
585  typedef typename ExprT1::value_type value_type_1;
586  typedef typename ExprT2::value_type value_type_2;
587  typedef typename Sacado::Promote<value_type_1,
588  value_type_2>::type value_type;
589 
590  typedef typename ExprT1::scalar_type scalar_type_1;
591  typedef typename ExprT2::scalar_type scalar_type_2;
592  typedef typename Sacado::Promote<scalar_type_1,
593  scalar_type_2>::type scalar_type;
594 
595  typedef typename ExprT1::base_expr_type base_expr_type_1;
596  typedef typename ExprT2::base_expr_type base_expr_type_2;
597  typedef typename Sacado::Promote<base_expr_type_1,
598  base_expr_type_2>::type base_expr_type;
599 
601  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
602  expr1(expr1_), expr2(expr2_) {}
603 
605  int size() const {
606  return expr1.size();
607  }
608 
610  bool updateValue() const {
611  return expr1.updateValue();
612  }
613 
615  void cache() const {
616  expr1.cache();
617  }
618 
620  value_type val() const {
621  return expr1.val() + expr2.val();
622  }
623 
625  bool isLinear() const {
626  return expr1.isLinear();
627  }
628 
630  bool hasFastAccess() const {
631  return expr1.hasFastAccess();
632  }
633 
635  const value_type dx(int i) const {
636  return expr1.dx(i);
637  }
638 
640  const value_type fastAccessDx(int i) const {
641  return expr1.fastAccessDx(i);
642  }
643 
644  protected:
645 
646  const ExprT1& expr1;
647  ExprT2 expr2;
648 
649  };
650 
651  template <typename T1, typename ExprT2>
652  class Expr< AdditionOp< ConstExpr<T1>,ExprT2> > {
653 
654  public:
655 
656  typedef ConstExpr<T1> ExprT1;
657  typedef typename ExprT1::value_type value_type_1;
658  typedef typename ExprT2::value_type value_type_2;
659  typedef typename Sacado::Promote<value_type_1,
660  value_type_2>::type value_type;
661 
662  typedef typename ExprT1::scalar_type scalar_type_1;
663  typedef typename ExprT2::scalar_type scalar_type_2;
664  typedef typename Sacado::Promote<scalar_type_1,
665  scalar_type_2>::type scalar_type;
666 
667  typedef typename ExprT1::base_expr_type base_expr_type_1;
668  typedef typename ExprT2::base_expr_type base_expr_type_2;
669  typedef typename Sacado::Promote<base_expr_type_1,
670  base_expr_type_2>::type base_expr_type;
671 
673  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
674  expr1(expr1_), expr2(expr2_) {}
675 
677  int size() const {
678  return expr2.size();
679  }
680 
682  bool updateValue() const {
683  return expr2.updateValue();
684  }
685 
687  void cache() const {
688  expr2.cache();
689  }
690 
692  value_type val() const {
693  return expr1.val() + expr2.val();
694  }
695 
697  bool isLinear() const {
698  return expr2.isLinear();
699  }
700 
702  bool hasFastAccess() const {
703  return expr2.hasFastAccess();
704  }
705 
707  const value_type dx(int i) const {
708  return expr2.dx(i);
709  }
710 
712  const value_type fastAccessDx(int i) const {
713  return expr2.fastAccessDx(i);
714  }
715 
716  protected:
717 
718  ExprT1 expr1;
719  const ExprT2& expr2;
720 
721  };
722 
723  //
724  // SubtractionOp
725  //
726 
727  template <typename ExprT1, typename ExprT2>
728  class SubtractionOp {};
729 
730  template <typename ExprT1, typename ExprT2>
731  class Expr< SubtractionOp<ExprT1,ExprT2> > {
732 
733  public:
734 
735  typedef typename ExprT1::value_type value_type_1;
736  typedef typename ExprT2::value_type value_type_2;
737  typedef typename Sacado::Promote<value_type_1,
738  value_type_2>::type value_type;
739 
740  typedef typename ExprT1::scalar_type scalar_type_1;
741  typedef typename ExprT2::scalar_type scalar_type_2;
742  typedef typename Sacado::Promote<scalar_type_1,
743  scalar_type_2>::type scalar_type;
744 
745  typedef typename ExprT1::base_expr_type base_expr_type_1;
746  typedef typename ExprT2::base_expr_type base_expr_type_2;
747  typedef typename Sacado::Promote<base_expr_type_1,
748  base_expr_type_2>::type base_expr_type;
749 
751  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
752  expr1(expr1_), expr2(expr2_) {}
753 
755  int size() const {
756  int sz1 = expr1.size(), sz2 = expr2.size();
757  return sz1 > sz2 ? sz1 : sz2;
758  }
759 
761  bool updateValue() const {
762  return expr1.updateValue() && expr2.updateValue();
763  }
764 
766  void cache() const {
767  expr1.cache();
768  expr2.cache();
769  }
770 
772  value_type val() const {
773  return expr1.val()-expr2.val();
774  }
775 
777  bool isLinear() const {
778  return expr1.isLinear() && expr2.isLinear();
779  }
780 
782  bool hasFastAccess() const {
783  return expr1.hasFastAccess() && expr2.hasFastAccess();
784  }
785 
787  const value_type dx(int i) const {
788  return expr1.dx(i) - expr2.dx(i);
789  }
790 
792  const value_type fastAccessDx(int i) const {
793  return expr1.fastAccessDx(i) - expr2.fastAccessDx(i);
794  }
795 
796  protected:
797 
798  const ExprT1& expr1;
799  const ExprT2& expr2;
800 
801  };
802 
803  template <typename ExprT1, typename T2>
804  class Expr< SubtractionOp<ExprT1, ConstExpr<T2> > > {
805 
806  public:
807 
808  typedef ConstExpr<T2> ExprT2;
809  typedef typename ExprT1::value_type value_type_1;
810  typedef typename ExprT2::value_type value_type_2;
811  typedef typename Sacado::Promote<value_type_1,
812  value_type_2>::type value_type;
813 
814  typedef typename ExprT1::scalar_type scalar_type_1;
815  typedef typename ExprT2::scalar_type scalar_type_2;
816  typedef typename Sacado::Promote<scalar_type_1,
817  scalar_type_2>::type scalar_type;
818 
819  typedef typename ExprT1::base_expr_type base_expr_type_1;
820  typedef typename ExprT2::base_expr_type base_expr_type_2;
821  typedef typename Sacado::Promote<base_expr_type_1,
822  base_expr_type_2>::type base_expr_type;
823 
825  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
826  expr1(expr1_), expr2(expr2_) {}
827 
829  int size() const {
830  return expr1.size();
831  }
832 
834  bool updateValue() const {
835  return expr1.updateValue();
836  }
837 
839  void cache() const {
840  expr1.cache();
841  }
842 
844  value_type val() const {
845  return expr1.val() - expr2.val();
846  }
847 
849  bool isLinear() const {
850  return expr1.isLinear();
851  }
852 
854  bool hasFastAccess() const {
855  return expr1.hasFastAccess();
856  }
857 
859  const value_type dx(int i) const {
860  return expr1.dx(i);
861  }
862 
864  const value_type fastAccessDx(int i) const {
865  return expr1.fastAccessDx(i);
866  }
867 
868  protected:
869 
870  const ExprT1& expr1;
871  ExprT2 expr2;
872 
873  };
874 
875  template <typename T1, typename ExprT2>
876  class Expr< SubtractionOp< ConstExpr<T1>,ExprT2> > {
877 
878  public:
879 
880  typedef ConstExpr<T1> ExprT1;
881  typedef typename ExprT1::value_type value_type_1;
882  typedef typename ExprT2::value_type value_type_2;
883  typedef typename Sacado::Promote<value_type_1,
884  value_type_2>::type value_type;
885 
886  typedef typename ExprT1::scalar_type scalar_type_1;
887  typedef typename ExprT2::scalar_type scalar_type_2;
888  typedef typename Sacado::Promote<scalar_type_1,
889  scalar_type_2>::type scalar_type;
890 
891  typedef typename ExprT1::base_expr_type base_expr_type_1;
892  typedef typename ExprT2::base_expr_type base_expr_type_2;
893  typedef typename Sacado::Promote<base_expr_type_1,
894  base_expr_type_2>::type base_expr_type;
895 
897  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
898  expr1(expr1_), expr2(expr2_) {}
899 
901  int size() const {
902  return expr2.size();
903  }
904 
906  bool updateValue() const {
907  return expr2.updateValue();
908  }
909 
911  void cache() const {
912  expr2.cache();
913  }
914 
916  value_type val() const {
917  return expr1.val() - expr2.val();
918  }
919 
921  bool isLinear() const {
922  return expr2.isLinear();
923  }
924 
926  bool hasFastAccess() const {
927  return expr2.hasFastAccess();
928  }
929 
931  const value_type dx(int i) const {
932  return -expr2.dx(i);
933  }
934 
936  const value_type fastAccessDx(int i) const {
937  return -expr2.fastAccessDx(i);
938  }
939 
940  protected:
941 
942  ExprT1 expr1;
943  const ExprT2& expr2;
944 
945  };
946 
947  //
948  // MultiplicationOp
949  //
950 
951  template <typename ExprT1, typename ExprT2>
952  class MultiplicationOp {};
953 
954  template <typename ExprT1, typename ExprT2>
955  class Expr< MultiplicationOp<ExprT1,ExprT2> > {
956 
957  public:
958 
959  typedef typename ExprT1::value_type value_type_1;
960  typedef typename ExprT2::value_type value_type_2;
961  typedef typename Sacado::Promote<value_type_1,
962  value_type_2>::type value_type;
963 
964  typedef typename ExprT1::scalar_type scalar_type_1;
965  typedef typename ExprT2::scalar_type scalar_type_2;
966  typedef typename Sacado::Promote<scalar_type_1,
967  scalar_type_2>::type scalar_type;
968 
969  typedef typename ExprT1::base_expr_type base_expr_type_1;
970  typedef typename ExprT2::base_expr_type base_expr_type_2;
971  typedef typename Sacado::Promote<base_expr_type_1,
972  base_expr_type_2>::type base_expr_type;
973 
975  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
976  expr1(expr1_), expr2(expr2_) {}
977 
979  int size() const {
980  int sz1 = expr1.size(), sz2 = expr2.size();
981  return sz1 > sz2 ? sz1 : sz2;
982  }
983 
985  bool updateValue() const {
986  return expr1.updateValue() && expr2.updateValue();
987  }
988 
990  void cache() const {
991  expr1.cache();
992  expr2.cache();
993  v1 = expr1.val();
994  v2 = expr2.val();
995  }
996 
998  value_type val() const {
999  return v1*v2;
1000  }
1001 
1003  bool isLinear() const {
1004  return false;
1005  }
1006 
1008  bool hasFastAccess() const {
1009  return expr1.hasFastAccess() && expr2.hasFastAccess();
1010  }
1011 
1013  const value_type dx(int i) const {
1014  if (expr1.size() > 0 && expr2.size() > 0)
1015  return v1*expr2.dx(i) + expr1.dx(i)*v2;
1016  else if (expr1.size() > 0)
1017  return expr1.dx(i)*v2;
1018  else
1019  return v1*expr2.dx(i);
1020  }
1021 
1023  const value_type fastAccessDx(int i) const {
1024  return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
1025  }
1026 
1027  protected:
1028 
1029  const ExprT1& expr1;
1030  const ExprT2& expr2;
1031  mutable value_type_1 v1;
1032  mutable value_type_2 v2;
1033 
1034  };
1035 
1036  template <typename ExprT1, typename T2>
1037  class Expr< MultiplicationOp<ExprT1, ConstExpr<T2> > > {
1038 
1039  public:
1040 
1041  typedef ConstExpr<T2> ExprT2;
1042  typedef typename ExprT1::value_type value_type_1;
1043  typedef typename ExprT2::value_type value_type_2;
1044  typedef typename Sacado::Promote<value_type_1,
1045  value_type_2>::type value_type;
1046 
1047  typedef typename ExprT1::scalar_type scalar_type_1;
1048  typedef typename ExprT2::scalar_type scalar_type_2;
1049  typedef typename Sacado::Promote<scalar_type_1,
1050  scalar_type_2>::type scalar_type;
1051 
1052  typedef typename ExprT1::base_expr_type base_expr_type_1;
1053  typedef typename ExprT2::base_expr_type base_expr_type_2;
1054  typedef typename Sacado::Promote<base_expr_type_1,
1055  base_expr_type_2>::type base_expr_type;
1056 
1058  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1059  expr1(expr1_), expr2(expr2_) {}
1060 
1062  int size() const {
1063  return expr1.size();
1064  }
1065 
1067  bool updateValue() const {
1068  return expr1.updateValue();
1069  }
1070 
1072  void cache() const {
1073  expr1.cache();
1074  }
1075 
1077  value_type val() const {
1078  return expr1.val()*expr2.val();
1079  }
1080 
1082  bool isLinear() const {
1083  return expr1.isLinear();
1084  }
1085 
1087  bool hasFastAccess() const {
1088  return expr1.hasFastAccess();
1089  }
1090 
1092  const value_type dx(int i) const {
1093  return expr1.dx(i)*expr2.val();
1094  }
1095 
1097  const value_type fastAccessDx(int i) const {
1098  return expr1.fastAccessDx(i)*expr2.val();
1099  }
1100 
1101  protected:
1102 
1103  const ExprT1& expr1;
1104  ExprT2 expr2;
1105 
1106  };
1107 
1108  template <typename T1, typename ExprT2>
1109  class Expr< MultiplicationOp< ConstExpr<T1>,ExprT2> > {
1110 
1111  public:
1112 
1113  typedef ConstExpr<T1> ExprT1;
1114  typedef typename ExprT1::value_type value_type_1;
1115  typedef typename ExprT2::value_type value_type_2;
1116  typedef typename Sacado::Promote<value_type_1,
1117  value_type_2>::type value_type;
1118 
1119  typedef typename ExprT1::scalar_type scalar_type_1;
1120  typedef typename ExprT2::scalar_type scalar_type_2;
1121  typedef typename Sacado::Promote<scalar_type_1,
1122  scalar_type_2>::type scalar_type;
1123 
1124  typedef typename ExprT1::base_expr_type base_expr_type_1;
1125  typedef typename ExprT2::base_expr_type base_expr_type_2;
1126  typedef typename Sacado::Promote<base_expr_type_1,
1127  base_expr_type_2>::type base_expr_type;
1128 
1130  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1131  expr1(expr1_), expr2(expr2_) {}
1132 
1134  int size() const {
1135  return expr2.size();
1136  }
1137 
1139  bool updateValue() const {
1140  return expr2.updateValue();
1141  }
1142 
1144  void cache() const {
1145  expr2.cache();
1146  }
1147 
1149  value_type val() const {
1150  return expr1.val()*expr2.val();
1151  }
1152 
1154  bool isLinear() const {
1155  return expr2.isLinear();
1156  }
1157 
1159  bool hasFastAccess() const {
1160  return expr2.hasFastAccess();
1161  }
1162 
1164  const value_type dx(int i) const {
1165  return expr1.val()*expr2.dx(i);
1166  }
1167 
1169  const value_type fastAccessDx(int i) const {
1170  return expr1.val()*expr2.fastAccessDx(i);
1171  }
1172 
1173  protected:
1174 
1175  ExprT1 expr1;
1176  const ExprT2& expr2;
1177 
1178  };
1179 
1180  //
1181  // DivisionOp
1182  //
1183 
1184  template <typename ExprT1, typename ExprT2>
1185  class DivisionOp {};
1186 
1187  template <typename ExprT1, typename ExprT2>
1188  class Expr< DivisionOp<ExprT1,ExprT2> > {
1189 
1190  public:
1191 
1192  typedef typename ExprT1::value_type value_type_1;
1193  typedef typename ExprT2::value_type value_type_2;
1194  typedef typename Sacado::Promote<value_type_1,
1195  value_type_2>::type value_type;
1196 
1197  typedef typename ExprT1::scalar_type scalar_type_1;
1198  typedef typename ExprT2::scalar_type scalar_type_2;
1199  typedef typename Sacado::Promote<scalar_type_1,
1200  scalar_type_2>::type scalar_type;
1201 
1202  typedef typename ExprT1::base_expr_type base_expr_type_1;
1203  typedef typename ExprT2::base_expr_type base_expr_type_2;
1204  typedef typename Sacado::Promote<base_expr_type_1,
1205  base_expr_type_2>::type base_expr_type;
1206 
1208  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1209  expr1(expr1_), expr2(expr2_) {}
1210 
1212  int size() const {
1213  int sz1 = expr1.size(), sz2 = expr2.size();
1214  return sz1 > sz2 ? sz1 : sz2;
1215  }
1216 
1218  bool updateValue() const {
1219  return expr1.updateValue() && expr2.updateValue();
1220  }
1221 
1223  void cache() const {
1224  expr1.cache();
1225  expr2.cache();
1226  const value_type_1 v1 = expr1.val();
1227  const value_type_2 v2 = expr2.val();
1228  a = value_type(1)/v2;
1229  v = v1*a;
1230  b = -v/v2;
1231  }
1232 
1234  value_type val() const {
1235  return v;
1236  }
1237 
1239  bool isLinear() const {
1240  return false;
1241  }
1242 
1244  bool hasFastAccess() const {
1245  return expr1.hasFastAccess() && expr2.hasFastAccess();
1246  }
1247 
1249  const value_type dx(int i) const {
1250  if (expr1.size() > 0 && expr2.size() > 0)
1251  return expr1.dx(i)*a + expr2.dx(i)*b;
1252  else if (expr1.size() > 0)
1253  return expr1.dx(i)*a;
1254  else
1255  return expr1.val()*b;
1256  }
1257 
1259  const value_type fastAccessDx(int i) const {
1260  return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1261  }
1262 
1263  protected:
1264 
1265  const ExprT1& expr1;
1266  const ExprT2& expr2;
1267  mutable value_type v;
1268  mutable value_type a;
1269  mutable value_type b;
1270 
1271  };
1272 
1273  template <typename ExprT1, typename T2>
1274  class Expr< DivisionOp<ExprT1, ConstExpr<T2> > > {
1275 
1276  public:
1277 
1278  typedef ConstExpr<T2> ExprT2;
1279  typedef typename ExprT1::value_type value_type_1;
1280  typedef typename ExprT2::value_type value_type_2;
1281  typedef typename Sacado::Promote<value_type_1,
1282  value_type_2>::type value_type;
1283 
1284  typedef typename ExprT1::scalar_type scalar_type_1;
1285  typedef typename ExprT2::scalar_type scalar_type_2;
1286  typedef typename Sacado::Promote<scalar_type_1,
1287  scalar_type_2>::type scalar_type;
1288 
1289  typedef typename ExprT1::base_expr_type base_expr_type_1;
1290  typedef typename ExprT2::base_expr_type base_expr_type_2;
1291  typedef typename Sacado::Promote<base_expr_type_1,
1292  base_expr_type_2>::type base_expr_type;
1293 
1295  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1296  expr1(expr1_), expr2(expr2_) {}
1297 
1299  int size() const {
1300  return expr1.size();
1301  }
1302 
1304  bool updateValue() const {
1305  return expr1.updateValue();
1306  }
1307 
1309  void cache() const {
1310  expr1.cache();
1311  const value_type_1 v1 = expr1.val();
1312  a = value_type(1)/expr2.val();
1313  v = v1*a;
1314  }
1315 
1317  value_type val() const {
1318  return v;
1319  }
1320 
1322  bool isLinear() const {
1323  return expr1.isLinear();
1324  }
1325 
1327  bool hasFastAccess() const {
1328  return expr1.hasFastAccess();
1329  }
1330 
1332  const value_type dx(int i) const {
1333  return expr1.dx(i)*a;
1334  }
1335 
1337  const value_type fastAccessDx(int i) const {
1338  return expr1.fastAccessDx(i)*a;
1339  }
1340 
1341  protected:
1342 
1343  const ExprT1& expr1;
1344  ExprT2 expr2;
1345  mutable value_type v;
1346  mutable value_type a;
1347 
1348  };
1349 
1350  template <typename T1, typename ExprT2>
1351  class Expr< DivisionOp< ConstExpr<T1>,ExprT2> > {
1352 
1353  public:
1354 
1355  typedef ConstExpr<T1> ExprT1;
1356  typedef typename ExprT1::value_type value_type_1;
1357  typedef typename ExprT2::value_type value_type_2;
1358  typedef typename Sacado::Promote<value_type_1,
1359  value_type_2>::type value_type;
1360 
1361  typedef typename ExprT1::scalar_type scalar_type_1;
1362  typedef typename ExprT2::scalar_type scalar_type_2;
1363  typedef typename Sacado::Promote<scalar_type_1,
1364  scalar_type_2>::type scalar_type;
1365 
1366  typedef typename ExprT1::base_expr_type base_expr_type_1;
1367  typedef typename ExprT2::base_expr_type base_expr_type_2;
1368  typedef typename Sacado::Promote<base_expr_type_1,
1369  base_expr_type_2>::type base_expr_type;
1370 
1372  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1373  expr1(expr1_), expr2(expr2_) {}
1374 
1376  int size() const {
1377  return expr2.size();
1378  }
1379 
1381  bool updateValue() const {
1382  return expr2.updateValue();
1383  }
1384 
1386  void cache() const {
1387  expr2.cache();
1388  const value_type_2 v2 = expr2.val();
1389  v = expr1.val()/v2;
1390  b = -v/v2;
1391  }
1392 
1394  value_type val() const {
1395  return v;
1396  }
1397 
1399  bool isLinear() const {
1400  return false;
1401  }
1402 
1404  bool hasFastAccess() const {
1405  return expr2.hasFastAccess();
1406  }
1407 
1409  const value_type dx(int i) const {
1410  return expr2.dx(i)*b;
1411  }
1412 
1414  const value_type fastAccessDx(int i) const {
1415  return expr2.fastAccessDx(i)*b;
1416  }
1417 
1418  protected:
1419 
1420  ExprT1 expr1;
1421  const ExprT2& expr2;
1422  mutable value_type v;
1423  mutable value_type b;
1424 
1425  };
1426 
1427  //
1428  // Atan2Op
1429  //
1430 
1431  template <typename ExprT1, typename ExprT2>
1432  class Atan2Op {};
1433 
1434  template <typename ExprT1, typename ExprT2>
1435  class Expr< Atan2Op<ExprT1,ExprT2> > {
1436 
1437  public:
1438 
1439  typedef typename ExprT1::value_type value_type_1;
1440  typedef typename ExprT2::value_type value_type_2;
1441  typedef typename Sacado::Promote<value_type_1,
1442  value_type_2>::type value_type;
1443 
1444  typedef typename ExprT1::scalar_type scalar_type_1;
1445  typedef typename ExprT2::scalar_type scalar_type_2;
1446  typedef typename Sacado::Promote<scalar_type_1,
1447  scalar_type_2>::type scalar_type;
1448 
1449  typedef typename ExprT1::base_expr_type base_expr_type_1;
1450  typedef typename ExprT2::base_expr_type base_expr_type_2;
1451  typedef typename Sacado::Promote<base_expr_type_1,
1452  base_expr_type_2>::type base_expr_type;
1453 
1455  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1456  expr1(expr1_), expr2(expr2_) {}
1457 
1459  int size() const {
1460  int sz1 = expr1.size(), sz2 = expr2.size();
1461  return sz1 > sz2 ? sz1 : sz2;
1462  }
1463 
1465  bool updateValue() const {
1466  return expr1.updateValue() && expr2.updateValue();
1467  }
1468 
1470  void cache() const {
1471  expr1.cache();
1472  expr2.cache();
1473  const value_type_1 v1 = expr1.val();
1474  const value_type_2 v2 = expr2.val();
1475  a = value_type(1)/(v1*v1 + v2*v2);
1476  b = -v1*a;
1477  a = v2*a;
1478  v = std::atan2(v1,v2);
1479  }
1480 
1482  value_type val() const {
1483  return v;
1484  }
1485 
1487  bool isLinear() const {
1488  return false;
1489  }
1490 
1492  bool hasFastAccess() const {
1493  return expr1.hasFastAccess() && expr2.hasFastAccess();
1494  }
1495 
1497  const value_type dx(int i) const {
1498  if (expr1.size() > 0 && expr2.size() > 0)
1499  return expr1.dx(i)*a + expr2.dx(i)*b;
1500  else if (expr1.size() > 0)
1501  return expr1.dx(i)*a;
1502  else
1503  return expr1.val()*b;
1504  }
1505 
1507  const value_type fastAccessDx(int i) const {
1508  return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1509  }
1510 
1511  protected:
1512 
1513  const ExprT1& expr1;
1514  const ExprT2& expr2;
1515  mutable value_type v;
1516  mutable value_type a;
1517  mutable value_type b;
1518 
1519  };
1520 
1521  template <typename ExprT1, typename T2>
1522  class Expr< Atan2Op<ExprT1, ConstExpr<T2> > > {
1523 
1524  public:
1525 
1526  typedef ConstExpr<T2> ExprT2;
1527  typedef typename ExprT1::value_type value_type_1;
1528  typedef typename ExprT2::value_type value_type_2;
1529  typedef typename Sacado::Promote<value_type_1,
1530  value_type_2>::type value_type;
1531 
1532  typedef typename ExprT1::scalar_type scalar_type_1;
1533  typedef typename ExprT2::scalar_type scalar_type_2;
1534  typedef typename Sacado::Promote<scalar_type_1,
1535  scalar_type_2>::type scalar_type;
1536 
1537  typedef typename ExprT1::base_expr_type base_expr_type_1;
1538  typedef typename ExprT2::base_expr_type base_expr_type_2;
1539  typedef typename Sacado::Promote<base_expr_type_1,
1540  base_expr_type_2>::type base_expr_type;
1541 
1543  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1544  expr1(expr1_), expr2(expr2_) {}
1545 
1547  int size() const {
1548  return expr1.size();
1549  }
1550 
1552  bool updateValue() const {
1553  return expr1.updateValue();
1554  }
1555 
1557  void cache() const {
1558  expr1.cache();
1559  const value_type_1 v1 = expr1.val();
1560  const value_type_2 v2 = expr2.val();
1561  a = v2/(v1*v1 + v2*v2);
1562  v = std::atan2(v1,v2);
1563  }
1564 
1566  value_type val() const {
1567  return v;
1568  }
1569 
1571  bool isLinear() const {
1572  return false;
1573  }
1574 
1576  bool hasFastAccess() const {
1577  return expr1.hasFastAccess();
1578  }
1579 
1581  const value_type dx(int i) const {
1582  return expr1.dx(i)*a;
1583  }
1584 
1586  const value_type fastAccessDx(int i) const {
1587  return expr1.fastAccessDx(i)*a;
1588  }
1589 
1590  protected:
1591 
1592  const ExprT1& expr1;
1593  ExprT2 expr2;
1594  mutable value_type v;
1595  mutable value_type a;
1596 
1597  };
1598 
1599  template <typename T1, typename ExprT2>
1600  class Expr< Atan2Op< ConstExpr<T1>,ExprT2> > {
1601 
1602  public:
1603 
1604  typedef ConstExpr<T1> ExprT1;
1605  typedef typename ExprT1::value_type value_type_1;
1606  typedef typename ExprT2::value_type value_type_2;
1607  typedef typename Sacado::Promote<value_type_1,
1608  value_type_2>::type value_type;
1609 
1610  typedef typename ExprT1::scalar_type scalar_type_1;
1611  typedef typename ExprT2::scalar_type scalar_type_2;
1612  typedef typename Sacado::Promote<scalar_type_1,
1613  scalar_type_2>::type scalar_type;
1614 
1615  typedef typename ExprT1::base_expr_type base_expr_type_1;
1616  typedef typename ExprT2::base_expr_type base_expr_type_2;
1617  typedef typename Sacado::Promote<base_expr_type_1,
1618  base_expr_type_2>::type base_expr_type;
1619 
1621  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1622  expr1(expr1_), expr2(expr2_) {}
1623 
1625  int size() const {
1626  return expr2.size();
1627  }
1628 
1630  bool updateValue() const {
1631  return expr2.updateValue();
1632  }
1633 
1635  void cache() const {
1636  expr2.cache();
1637  const value_type_1 v1 = expr1.val();
1638  const value_type_2 v2 = expr2.val();
1639  b = -v1/(v1*v1 + v2*v2);
1640  v = std::atan2(v1,v2);
1641  }
1642 
1644  value_type val() const {
1645  return v;
1646  }
1647 
1649  bool isLinear() const {
1650  return false;
1651  }
1652 
1654  bool hasFastAccess() const {
1655  return expr2.hasFastAccess();
1656  }
1657 
1659  const value_type dx(int i) const {
1660  return expr2.dx(i)*b;
1661  }
1662 
1664  const value_type fastAccessDx(int i) const {
1665  return expr2.fastAccessDx(i)*b;
1666  }
1667 
1668  protected:
1669 
1670  ExprT1 expr1;
1671  const ExprT2& expr2;
1672  mutable value_type v;
1673  mutable value_type b;
1674 
1675  };
1676 
1677  //
1678  // PowerOp
1679  //
1680 
1681  template <typename ExprT1, typename ExprT2>
1682  class PowerOp {};
1683 
1684  template <typename ExprT1, typename ExprT2>
1685  class Expr< PowerOp<ExprT1,ExprT2> > {
1686 
1687  public:
1688 
1689  typedef typename ExprT1::value_type value_type_1;
1690  typedef typename ExprT2::value_type value_type_2;
1691  typedef typename Sacado::Promote<value_type_1,
1692  value_type_2>::type value_type;
1693 
1694  typedef typename ExprT1::scalar_type scalar_type_1;
1695  typedef typename ExprT2::scalar_type scalar_type_2;
1696  typedef typename Sacado::Promote<scalar_type_1,
1697  scalar_type_2>::type scalar_type;
1698 
1699  typedef typename ExprT1::base_expr_type base_expr_type_1;
1700  typedef typename ExprT2::base_expr_type base_expr_type_2;
1701  typedef typename Sacado::Promote<base_expr_type_1,
1702  base_expr_type_2>::type base_expr_type;
1703 
1705  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1706  expr1(expr1_), expr2(expr2_) {}
1707 
1709  int size() const {
1710  int sz1 = expr1.size(), sz2 = expr2.size();
1711  return sz1 > sz2 ? sz1 : sz2;
1712  }
1713 
1715  bool updateValue() const {
1716  return expr1.updateValue() && expr2.updateValue();
1717  }
1718 
1720  void cache() const {
1721  expr1.cache();
1722  expr2.cache();
1723  const value_type_1 v1 = expr1.val();
1724  const value_type_2 v2 = expr2.val();
1725  v = std::pow(v1,v2);
1726  if (v1 == value_type(0)) {
1727  a = value_type(0);
1728  b = value_type(0);
1729  }
1730  else {
1731  a = v*v2/v1;
1732  b = v*std::log(v1);
1733  }
1734  }
1735 
1737  value_type val() const {
1738  return v;
1739  }
1740 
1742  bool isLinear() const {
1743  return false;
1744  }
1745 
1747  bool hasFastAccess() const {
1748  return expr1.hasFastAccess() && expr2.hasFastAccess();
1749  }
1750 
1752  const value_type dx(int i) const {
1753  if (expr1.size() > 0 && expr2.size() > 0)
1754  return expr1.dx(i)*a + expr2.dx(i)*b;
1755  else if (expr1.size() > 0)
1756  return expr1.dx(i)*a;
1757  else
1758  return expr1.val()*b;
1759  }
1760 
1762  const value_type fastAccessDx(int i) const {
1763  return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1764  }
1765 
1766  protected:
1767 
1768  const ExprT1& expr1;
1769  const ExprT2& expr2;
1770  mutable value_type v;
1771  mutable value_type a;
1772  mutable value_type b;
1773 
1774  };
1775 
1776  template <typename ExprT1, typename T2>
1777  class Expr< PowerOp<ExprT1, ConstExpr<T2> > > {
1778 
1779  public:
1780 
1781  typedef ConstExpr<T2> ExprT2;
1782  typedef typename ExprT1::value_type value_type_1;
1783  typedef typename ExprT2::value_type value_type_2;
1784  typedef typename Sacado::Promote<value_type_1,
1785  value_type_2>::type value_type;
1786 
1787  typedef typename ExprT1::scalar_type scalar_type_1;
1788  typedef typename ExprT2::scalar_type scalar_type_2;
1789  typedef typename Sacado::Promote<scalar_type_1,
1790  scalar_type_2>::type scalar_type;
1791 
1792  typedef typename ExprT1::base_expr_type base_expr_type_1;
1793  typedef typename ExprT2::base_expr_type base_expr_type_2;
1794  typedef typename Sacado::Promote<base_expr_type_1,
1795  base_expr_type_2>::type base_expr_type;
1796 
1798  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1799  expr1(expr1_), expr2(expr2_) {}
1800 
1802  int size() const {
1803  return expr1.size();
1804  }
1805 
1807  bool updateValue() const {
1808  return expr1.updateValue();
1809  }
1810 
1812  void cache() const {
1813  expr1.cache();
1814  const value_type_1 v1 = expr1.val();
1815  const value_type_2 v2 = expr2.val();
1816  v = std::pow(v1,v2);
1817  if (v1 == value_type_1(0)) {
1818  a = value_type(0);
1819  }
1820  else {
1821  a = v*v2/v1;
1822  }
1823  }
1824 
1826  value_type val() const {
1827  return v;
1828  }
1829 
1831  bool isLinear() const {
1832  return false;
1833  }
1834 
1836  bool hasFastAccess() const {
1837  return expr1.hasFastAccess();
1838  }
1839 
1841  const value_type dx(int i) const {
1842  return expr1.dx(i)*a;
1843  }
1844 
1846  const value_type fastAccessDx(int i) const {
1847  return expr1.fastAccessDx(i)*a;
1848  }
1849 
1850  protected:
1851 
1852  const ExprT1& expr1;
1853  ExprT2 expr2;
1854  mutable value_type v;
1855  mutable value_type a;
1856 
1857  };
1858 
1859  template <typename T1, typename ExprT2>
1860  class Expr< PowerOp< ConstExpr<T1>,ExprT2> > {
1861 
1862  public:
1863 
1864  typedef ConstExpr<T1> ExprT1;
1865  typedef typename ExprT1::value_type value_type_1;
1866  typedef typename ExprT2::value_type value_type_2;
1867  typedef typename Sacado::Promote<value_type_1,
1868  value_type_2>::type value_type;
1869 
1870  typedef typename ExprT1::scalar_type scalar_type_1;
1871  typedef typename ExprT2::scalar_type scalar_type_2;
1872  typedef typename Sacado::Promote<scalar_type_1,
1873  scalar_type_2>::type scalar_type;
1874 
1875  typedef typename ExprT1::base_expr_type base_expr_type_1;
1876  typedef typename ExprT2::base_expr_type base_expr_type_2;
1877  typedef typename Sacado::Promote<base_expr_type_1,
1878  base_expr_type_2>::type base_expr_type;
1879 
1881  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1882  expr1(expr1_), expr2(expr2_) {}
1883 
1885  int size() const {
1886  return expr2.size();
1887  }
1888 
1890  bool updateValue() const {
1891  return expr2.updateValue();
1892  }
1893 
1895  void cache() const {
1896  expr2.cache();
1897  const value_type_1 v1 = expr1.val();
1898  const value_type_2 v2 = expr2.val();
1899  v = std::pow(v1,v2);
1900  if (v1 == value_type(0)) {
1901  b = value_type(0);
1902  }
1903  else {
1904  b = v*std::log(v1);
1905  }
1906  }
1907 
1909  value_type val() const {
1910  return v;
1911  }
1912 
1914  bool isLinear() const {
1915  return false;
1916  }
1917 
1919  bool hasFastAccess() const {
1920  return expr2.hasFastAccess();
1921  }
1922 
1924  const value_type dx(int i) const {
1925  return expr2.dx(i)*b;
1926  }
1927 
1929  const value_type fastAccessDx(int i) const {
1930  return expr2.fastAccessDx(i)*b;
1931  }
1932 
1933  protected:
1934 
1935  ExprT1 expr1;
1936  const ExprT2& expr2;
1937  mutable value_type v;
1938  mutable value_type b;
1939 
1940  };
1941 
1942  //
1943  // MaxOp
1944  //
1945 
1946  template <typename ExprT1, typename ExprT2>
1947  class MaxOp {};
1948 
1949  template <typename ExprT1, typename ExprT2>
1950  class Expr< MaxOp<ExprT1,ExprT2> > {
1951 
1952  public:
1953 
1954  typedef typename ExprT1::value_type value_type_1;
1955  typedef typename ExprT2::value_type value_type_2;
1956  typedef typename Sacado::Promote<value_type_1,
1957  value_type_2>::type value_type;
1958 
1959  typedef typename ExprT1::scalar_type scalar_type_1;
1960  typedef typename ExprT2::scalar_type scalar_type_2;
1961  typedef typename Sacado::Promote<scalar_type_1,
1962  scalar_type_2>::type scalar_type;
1963 
1964  typedef typename ExprT1::base_expr_type base_expr_type_1;
1965  typedef typename ExprT2::base_expr_type base_expr_type_2;
1966  typedef typename Sacado::Promote<base_expr_type_1,
1967  base_expr_type_2>::type base_expr_type;
1968 
1970  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1971  expr1(expr1_), expr2(expr2_) {}
1972 
1974  int size() const {
1975  int sz1 = expr1.size(), sz2 = expr2.size();
1976  return sz1 > sz2 ? sz1 : sz2;
1977  }
1978 
1980  bool updateValue() const {
1981  return expr1.updateValue() && expr2.updateValue();
1982  }
1983 
1985  void cache() const {
1986  expr1.cache();
1987  expr2.cache();
1988  const value_type_1 v1 = expr1.val();
1989  const value_type_2 v2 = expr2.val();
1990  max_v1 = (v1 >= v2);
1991  v = max_v1 ? v1 : v2;
1992  }
1993 
1995  value_type val() const {
1996  return v;
1997  }
1998 
2000  bool isLinear() const {
2001  return false;
2002  }
2003 
2005  bool hasFastAccess() const {
2006  return expr1.hasFastAccess() && expr2.hasFastAccess();
2007  }
2008 
2010  const value_type dx(int i) const {
2011  return max_v1 ? expr1.dx(i) : expr2.dx(i);
2012  }
2013 
2015  const value_type fastAccessDx(int i) const {
2016  return max_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2017  }
2018 
2019  protected:
2020 
2021  const ExprT1& expr1;
2022  const ExprT2& expr2;
2023  mutable value_type v;
2024  mutable bool max_v1;
2025 
2026  };
2027 
2028  template <typename ExprT1, typename T2>
2029  class Expr< MaxOp<ExprT1, ConstExpr<T2> > > {
2030 
2031  public:
2032 
2033  typedef ConstExpr<T2> ExprT2;
2034  typedef typename ExprT1::value_type value_type_1;
2035  typedef typename ExprT2::value_type value_type_2;
2036  typedef typename Sacado::Promote<value_type_1,
2037  value_type_2>::type value_type;
2038 
2039  typedef typename ExprT1::scalar_type scalar_type_1;
2040  typedef typename ExprT2::scalar_type scalar_type_2;
2041  typedef typename Sacado::Promote<scalar_type_1,
2042  scalar_type_2>::type scalar_type;
2043 
2044  typedef typename ExprT1::base_expr_type base_expr_type_1;
2045  typedef typename ExprT2::base_expr_type base_expr_type_2;
2046  typedef typename Sacado::Promote<base_expr_type_1,
2047  base_expr_type_2>::type base_expr_type;
2048 
2050  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2051  expr1(expr1_), expr2(expr2_) {}
2052 
2054  int size() const {
2055  return expr1.size();
2056  }
2057 
2059  bool updateValue() const {
2060  return expr1.updateValue();
2061  }
2062 
2064  void cache() const {
2065  expr1.cache();
2066  const value_type_1 v1 = expr1.val();
2067  const value_type_2 v2 = expr2.val();
2068  max_v1 = (v1 >= v2);
2069  v = max_v1 ? v1 : v2;
2070  }
2071 
2073  value_type val() const {
2074  return v;
2075  }
2076 
2078  bool isLinear() const {
2079  return false;
2080  }
2081 
2083  bool hasFastAccess() const {
2084  return expr1.hasFastAccess();
2085  }
2086 
2088  const value_type dx(int i) const {
2089  return max_v1 ? expr1.dx(i) : value_type(0);
2090  }
2091 
2093  const value_type fastAccessDx(int i) const {
2094  return max_v1 ? expr1.fastAccessDx(i) : value_type(0);
2095  }
2096 
2097  protected:
2098 
2099  const ExprT1& expr1;
2100  ExprT2 expr2;
2101  mutable value_type v;
2102  mutable bool max_v1;
2103 
2104  };
2105 
2106  template <typename T1, typename ExprT2>
2107  class Expr< MaxOp< ConstExpr<T1>,ExprT2> > {
2108 
2109  public:
2110 
2111  typedef ConstExpr<T1> ExprT1;
2112  typedef typename ExprT1::value_type value_type_1;
2113  typedef typename ExprT2::value_type value_type_2;
2114  typedef typename Sacado::Promote<value_type_1,
2115  value_type_2>::type value_type;
2116 
2117  typedef typename ExprT1::scalar_type scalar_type_1;
2118  typedef typename ExprT2::scalar_type scalar_type_2;
2119  typedef typename Sacado::Promote<scalar_type_1,
2120  scalar_type_2>::type scalar_type;
2121 
2122  typedef typename ExprT1::base_expr_type base_expr_type_1;
2123  typedef typename ExprT2::base_expr_type base_expr_type_2;
2124  typedef typename Sacado::Promote<base_expr_type_1,
2125  base_expr_type_2>::type base_expr_type;
2126 
2128  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2129  expr1(expr1_), expr2(expr2_) {}
2130 
2132  int size() const {
2133  return expr2.size();
2134  }
2135 
2137  bool updateValue() const {
2138  return expr2.updateValue();
2139  }
2140 
2142  void cache() const {
2143  expr2.cache();
2144  const value_type_1 v1 = expr1.val();
2145  const value_type_2 v2 = expr2.val();
2146  max_v1 = (v1 >= v2);
2147  v = max_v1 ? v1 : v2;
2148  }
2149 
2151  value_type val() const {
2152  return v;
2153  }
2154 
2156  bool isLinear() const {
2157  return false;
2158  }
2159 
2161  bool hasFastAccess() const {
2162  return expr2.hasFastAccess();
2163  }
2164 
2166  const value_type dx(int i) const {
2167  return max_v1 ? value_type(0) : expr2.dx(i);
2168  }
2169 
2171  const value_type fastAccessDx(int i) const {
2172  return max_v1 ? value_type(0) : expr2.fastAccessDx(i);
2173  }
2174 
2175  protected:
2176 
2177  ExprT1 expr1;
2178  const ExprT2& expr2;
2179  mutable value_type v;
2180  mutable bool max_v1;
2181 
2182  };
2183 
2184  //
2185  // MinOp
2186  //
2187 
2188  template <typename ExprT1, typename ExprT2>
2189  class MinOp {};
2190 
2191  template <typename ExprT1, typename ExprT2>
2192  class Expr< MinOp<ExprT1,ExprT2> > {
2193 
2194  public:
2195 
2196  typedef typename ExprT1::value_type value_type_1;
2197  typedef typename ExprT2::value_type value_type_2;
2198  typedef typename Sacado::Promote<value_type_1,
2199  value_type_2>::type value_type;
2200 
2201  typedef typename ExprT1::scalar_type scalar_type_1;
2202  typedef typename ExprT2::scalar_type scalar_type_2;
2203  typedef typename Sacado::Promote<scalar_type_1,
2204  scalar_type_2>::type scalar_type;
2205 
2206  typedef typename ExprT1::base_expr_type base_expr_type_1;
2207  typedef typename ExprT2::base_expr_type base_expr_type_2;
2208  typedef typename Sacado::Promote<base_expr_type_1,
2209  base_expr_type_2>::type base_expr_type;
2210 
2212  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2213  expr1(expr1_), expr2(expr2_) {}
2214 
2216  int size() const {
2217  int sz1 = expr1.size(), sz2 = expr2.size();
2218  return sz1 > sz2 ? sz1 : sz2;
2219  }
2220 
2222  bool updateValue() const {
2223  return expr1.updateValue() && expr2.updateValue();
2224  }
2225 
2227  void cache() const {
2228  expr1.cache();
2229  expr2.cache();
2230  const value_type_1 v1 = expr1.val();
2231  const value_type_2 v2 = expr2.val();
2232  min_v1 = (v1 <= v2);
2233  v = min_v1 ? v1 : v2;
2234  }
2235 
2237  value_type val() const {
2238  return v;
2239  }
2240 
2242  bool isLinear() const {
2243  return false;
2244  }
2245 
2247  bool hasFastAccess() const {
2248  return expr1.hasFastAccess() && expr2.hasFastAccess();
2249  }
2250 
2252  const value_type dx(int i) const {
2253  return min_v1 ? expr1.dx(i) : expr2.dx(i);
2254  }
2255 
2257  const value_type fastAccessDx(int i) const {
2258  return min_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2259  }
2260 
2261  protected:
2262 
2263  const ExprT1& expr1;
2264  const ExprT2& expr2;
2265  mutable value_type v;
2266  mutable bool min_v1;
2267 
2268  };
2269 
2270  template <typename ExprT1, typename T2>
2271  class Expr< MinOp<ExprT1, ConstExpr<T2> > > {
2272 
2273  public:
2274 
2275  typedef ConstExpr<T2> ExprT2;
2276  typedef typename ExprT1::value_type value_type_1;
2277  typedef typename ExprT2::value_type value_type_2;
2278  typedef typename Sacado::Promote<value_type_1,
2279  value_type_2>::type value_type;
2280 
2281  typedef typename ExprT1::scalar_type scalar_type_1;
2282  typedef typename ExprT2::scalar_type scalar_type_2;
2283  typedef typename Sacado::Promote<scalar_type_1,
2284  scalar_type_2>::type scalar_type;
2285 
2286  typedef typename ExprT1::base_expr_type base_expr_type_1;
2287  typedef typename ExprT2::base_expr_type base_expr_type_2;
2288  typedef typename Sacado::Promote<base_expr_type_1,
2289  base_expr_type_2>::type base_expr_type;
2290 
2292  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2293  expr1(expr1_), expr2(expr2_) {}
2294 
2296  int size() const {
2297  return expr1.size();
2298  }
2299 
2301  bool updateValue() const {
2302  return expr1.updateValue();
2303  }
2304 
2306  void cache() const {
2307  expr1.cache();
2308  const value_type_1 v1 = expr1.val();
2309  const value_type_2 v2 = expr2.val();
2310  min_v1 = (v1 <= v2);
2311  v = min_v1 ? v1 : v2;
2312  }
2313 
2315  value_type val() const {
2316  return v;
2317  }
2318 
2320  bool isLinear() const {
2321  return false;
2322  }
2323 
2325  bool hasFastAccess() const {
2326  return expr1.hasFastAccess();
2327  }
2328 
2330  const value_type dx(int i) const {
2331  return min_v1 ? expr1.dx(i) : value_type(0);
2332  }
2333 
2335  const value_type fastAccessDx(int i) const {
2336  return min_v1 ? expr1.fastAccessDx(i) : value_type(0);
2337  }
2338 
2339  protected:
2340 
2341  const ExprT1& expr1;
2342  ExprT2 expr2;
2343  mutable value_type v;
2344  mutable bool min_v1;
2345 
2346  };
2347 
2348  template <typename T1, typename ExprT2>
2349  class Expr< MinOp< ConstExpr<T1>,ExprT2> > {
2350 
2351  public:
2352 
2353  typedef ConstExpr<T1> ExprT1;
2354  typedef typename ExprT1::value_type value_type_1;
2355  typedef typename ExprT2::value_type value_type_2;
2356  typedef typename Sacado::Promote<value_type_1,
2357  value_type_2>::type value_type;
2358 
2359  typedef typename ExprT1::scalar_type scalar_type_1;
2360  typedef typename ExprT2::scalar_type scalar_type_2;
2361  typedef typename Sacado::Promote<scalar_type_1,
2362  scalar_type_2>::type scalar_type;
2363 
2364  typedef typename ExprT1::base_expr_type base_expr_type_1;
2365  typedef typename ExprT2::base_expr_type base_expr_type_2;
2366  typedef typename Sacado::Promote<base_expr_type_1,
2367  base_expr_type_2>::type base_expr_type;
2368 
2370  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2371  expr1(expr1_), expr2(expr2_) {}
2372 
2374  int size() const {
2375  return expr2.size();
2376  }
2377 
2379  bool updateValue() const {
2380  return expr2.updateValue();
2381  }
2382 
2384  void cache() const {
2385  expr2.cache();
2386  const value_type_1 v1 = expr1.val();
2387  const value_type_2 v2 = expr2.val();
2388  min_v1 = (v1 <= v2);
2389  v = min_v1 ? v1 : v2;
2390  }
2391 
2393  value_type val() const {
2394  return v;
2395  }
2396 
2398  bool isLinear() const {
2399  return false;
2400  }
2401 
2403  bool hasFastAccess() const {
2404  return expr2.hasFastAccess();
2405  }
2406 
2408  const value_type dx(int i) const {
2409  return min_v1 ? value_type(0) : expr2.dx(i);
2410  }
2411 
2413  const value_type fastAccessDx(int i) const {
2414  return min_v1 ? value_type(0) : expr2.fastAccessDx(i);
2415  }
2416 
2417  protected:
2418 
2419  ExprT1 expr1;
2420  const ExprT2& expr2;
2421  mutable value_type v;
2422  mutable bool min_v1;
2423 
2424  };
2425 
2426  }
2427 
2428 }
2429 
2430 #define FAD_BINARYOP_MACRO(OPNAME,OP) \
2431 namespace Sacado { \
2432  namespace CacheFad { \
2433  \
2434  template <typename T1, typename T2> \
2435  KOKKOS_INLINE_FUNCTION \
2436  SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \
2437  OPNAME (const T1& expr1, const T2& expr2) \
2438  { \
2439  typedef OP< T1, T2 > expr_t; \
2440  \
2441  return Expr<expr_t>(expr1, expr2); \
2442  } \
2443  \
2444  template <typename T> \
2445  KOKKOS_INLINE_FUNCTION \
2446  Expr< OP< Expr<T>, Expr<T> > > \
2447  OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
2448  { \
2449  typedef OP< Expr<T>, Expr<T> > expr_t; \
2450  \
2451  return Expr<expr_t>(expr1, expr2); \
2452  } \
2453  \
2454  template <typename T> \
2455  KOKKOS_INLINE_FUNCTION \
2456  Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
2457  Expr<T> > > \
2458  OPNAME (const typename Expr<T>::value_type& c, \
2459  const Expr<T>& expr) \
2460  { \
2461  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
2462  typedef OP< ConstT, Expr<T> > expr_t; \
2463  \
2464  return Expr<expr_t>(ConstT(c), expr); \
2465  } \
2466  \
2467  template <typename T> \
2468  KOKKOS_INLINE_FUNCTION \
2469  Expr< OP< Expr<T>, \
2470  ConstExpr<typename Expr<T>::value_type> > > \
2471  OPNAME (const Expr<T>& expr, \
2472  const typename Expr<T>::value_type& c) \
2473  { \
2474  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
2475  typedef OP< Expr<T>, ConstT > expr_t; \
2476  \
2477  return Expr<expr_t>(expr, ConstT(c)); \
2478  } \
2479  \
2480  template <typename T> \
2481  KOKKOS_INLINE_FUNCTION \
2482  SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \
2483  OPNAME (const typename Expr<T>::scalar_type& c, \
2484  const Expr<T>& expr) \
2485  { \
2486  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
2487  typedef OP< ConstT, Expr<T> > expr_t; \
2488  \
2489  return Expr<expr_t>(ConstT(c), expr); \
2490  } \
2491  \
2492  template <typename T> \
2493  KOKKOS_INLINE_FUNCTION \
2494  SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \
2495  OPNAME (const Expr<T>& expr, \
2496  const typename Expr<T>::scalar_type& c) \
2497  { \
2498  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
2499  typedef OP< Expr<T>, ConstT > expr_t; \
2500  \
2501  return Expr<expr_t>(expr, ConstT(c)); \
2502  } \
2503  } \
2504 }
2505 
2506 
2507 FAD_BINARYOP_MACRO(operator+, AdditionOp)
2510 FAD_BINARYOP_MACRO(operator/, DivisionOp)
2515 
2516 #undef FAD_BINARYOP_MACRO
2517 
2518 //-------------------------- Relational Operators -----------------------
2519 
2520 #define FAD_RELOP_MACRO(OP) \
2521 namespace Sacado { \
2522  namespace CacheFad { \
2523  template <typename ExprT1, typename ExprT2> \
2524  KOKKOS_INLINE_FUNCTION \
2525  bool \
2526  operator OP (const Expr<ExprT1>& expr1, \
2527  const Expr<ExprT2>& expr2) \
2528  { \
2529  expr1.cache(); \
2530  expr2.cache(); \
2531  return expr1.val() OP expr2.val(); \
2532  } \
2533  \
2534  template <typename ExprT2> \
2535  KOKKOS_INLINE_FUNCTION \
2536  bool \
2537  operator OP (const typename Expr<ExprT2>::value_type& a, \
2538  const Expr<ExprT2>& expr2) \
2539  { \
2540  expr2.cache(); \
2541  return a OP expr2.val(); \
2542  } \
2543  \
2544  template <typename ExprT1> \
2545  KOKKOS_INLINE_FUNCTION \
2546  bool \
2547  operator OP (const Expr<ExprT1>& expr1, \
2548  const typename Expr<ExprT1>::value_type& b) \
2549  { \
2550  expr1.cache(); \
2551  return expr1.val() OP b; \
2552  } \
2553  } \
2554 }
2555 
2556 FAD_RELOP_MACRO(==)
2557 FAD_RELOP_MACRO(!=)
2558 FAD_RELOP_MACRO(<)
2559 FAD_RELOP_MACRO(>)
2560 FAD_RELOP_MACRO(<=)
2561 FAD_RELOP_MACRO(>=)
2562 FAD_RELOP_MACRO(<<=)
2563 FAD_RELOP_MACRO(>>=)
2564 FAD_RELOP_MACRO(&)
2565 FAD_RELOP_MACRO(|)
2566 
2567 #undef FAD_RELOP_MACRO
2568 
2569 namespace Sacado {
2570 
2571  namespace CacheFad {
2572 
2573  template <typename ExprT>
2575  bool operator ! (const Expr<ExprT>& expr)
2576  {
2577  expr.cache();
2578  return ! expr.val();
2579  }
2580 
2581  } // namespace CacheFad
2582 
2583 } // namespace Sacado
2584 
2585 //-------------------------- Boolean Operators -----------------------
2586 namespace Sacado {
2587 
2588  namespace CacheFad {
2589 
2590  template <typename ExprT>
2592  bool toBool(const Expr<ExprT>& x) {
2593  x.cache();
2594  bool is_zero = (x.val() == 0.0);
2595  for (int i=0; i<x.size(); i++)
2596  is_zero = is_zero && (x.dx(i) == 0.0);
2597  return !is_zero;
2598  }
2599 
2600  } // namespace Fad
2601 
2602 } // namespace Sacado
2603 
2604 #define FAD_BOOL_MACRO(OP) \
2605 namespace Sacado { \
2606  namespace CacheFad { \
2607  template <typename ExprT1, typename ExprT2> \
2608  KOKKOS_INLINE_FUNCTION \
2609  bool \
2610  operator OP (const Expr<ExprT1>& expr1, \
2611  const Expr<ExprT2>& expr2) \
2612  { \
2613  return toBool(expr1) OP toBool(expr2); \
2614  } \
2615  \
2616  template <typename ExprT2> \
2617  KOKKOS_INLINE_FUNCTION \
2618  bool \
2619  operator OP (const typename Expr<ExprT2>::value_type& a, \
2620  const Expr<ExprT2>& expr2) \
2621  { \
2622  return a OP toBool(expr2); \
2623  } \
2624  \
2625  template <typename ExprT1> \
2626  KOKKOS_INLINE_FUNCTION \
2627  bool \
2628  operator OP (const Expr<ExprT1>& expr1, \
2629  const typename Expr<ExprT1>::value_type& b) \
2630  { \
2631  return toBool(expr1) OP b; \
2632  } \
2633  } \
2634 }
2635 
2636 FAD_BOOL_MACRO(&&)
2637 FAD_BOOL_MACRO(||)
2638 
2639 #undef FAD_BOOL_MACRO
2640 
2641 //-------------------------- I/O Operators -----------------------
2642 
2643 namespace Sacado {
2644 
2645  namespace CacheFad {
2646 
2647  template <typename ExprT>
2648  std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
2649  x.cache();
2650  os << x.val() << " [";
2651 
2652  for (int i=0; i< x.size(); i++) {
2653  os << " " << x.dx(i);
2654  }
2655 
2656  os << " ]";
2657  return os;
2658  }
2659 
2660  } // namespace CacheFad
2661 
2662 } // namespace Sacado
2663 
2664 #endif // SACADO_CACHEFAD_OPS_HPP
cbrt(expr.val())
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
#define FAD_RELOP_MACRO(OP)
expr expr AdditionOp
expr expr SinOp
#define FAD_BINARYOP_MACRO(OPNAME, OP)
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
asinh(expr.val())
KOKKOS_INLINE_FUNCTION value_type val() const
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 MultiplicationOp
KOKKOS_INLINE_FUNCTION bool updateValue() const
#define FAD_UNARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, FASTACCESSDX)
asin(expr.val())
KOKKOS_INLINE_FUNCTION int size() const
cosh(expr.val())
expr expr dx(i)
abs(expr.val())
KOKKOS_INLINE_FUNCTION int size() const
KOKKOS_INLINE_FUNCTION int size() const
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
KOKKOS_INLINE_FUNCTION Expr< UnaryPlusOp< Expr< T > > > operator+(const Expr< T > &expr)
KOKKOS_INLINE_FUNCTION void cache() const
KOKKOS_INLINE_FUNCTION bool isLinear() const
KOKKOS_INLINE_FUNCTION void cache() const
KOKKOS_INLINE_FUNCTION bool toBool(const Expr< ExprT > &x)
expr expr TanhOp
KOKKOS_INLINE_FUNCTION bool isLinear() const
expr expr SqrtOp
expr expr ASinhOp
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
atan(expr.val())
#define FAD_BOOL_MACRO(OP)
KOKKOS_INLINE_FUNCTION void cache() const
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 DivisionOp
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)
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
KOKKOS_INLINE_FUNCTION void cache() const
KOKKOS_INLINE_FUNCTION bool updateValue() const
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
expr val()
#define KOKKOS_INLINE_FUNCTION
KOKKOS_INLINE_FUNCTION bool isLinear() const
tanh(expr.val())
expr expr CosOp
KOKKOS_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
expr expr ATanOp
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
expr expr ACosOp
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
KOKKOS_INLINE_FUNCTION bool isLinear() const
KOKKOS_INLINE_FUNCTION value_type val() const
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
sqrt(expr.val())
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
sinh(expr.val())
tan(expr.val())
KOKKOS_INLINE_FUNCTION bool updateValue() const
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
atan2(expr1.val(), expr2.val())
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
KOKKOS_INLINE_FUNCTION value_type val() const
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
sin(expr.val())
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
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
KOKKOS_INLINE_FUNCTION bool updateValue() const
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
KOKKOS_INLINE_FUNCTION Expr< AbsOp< Expr< T > > > abs(const Expr< T > &expr)
KOKKOS_INLINE_FUNCTION Expr< FAbsOp< Expr< T > > > fabs(const Expr< T > &expr)
KOKKOS_INLINE_FUNCTION value_type val() const
exp(expr.val())
expr expr expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 SubtractionOp
expr expr expr ExpOp
fabs(expr.val())
KOKKOS_INLINE_FUNCTION Expr< UnaryMinusOp< Expr< T > > > operator-(const Expr< T > &expr)
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
Wrapper for a generic expression template.
expr expr TanOp
log10(expr.val())
Base template specification for Promote.
cos(expr.val())
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
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