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  explicit 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  explicit 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  explicit 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  explicit 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  explicit 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 = (v == value_type(0.0) ? value_type(0.0) : value_type(value_type(1)/(value_type(2)*std::sqrt(v)))),
439  std::sqrt(v))
442  a = -std::sin(v),
443  std::cos(v))
446  a = std::cos(v),
447  std::sin(v))
450  a = value_type(1)+std::tan(v)*std::tan(v),
451  std::tan(v))
454  a = value_type(-1)/std::sqrt(value_type(1)-v*v),
455  std::acos(v))
458  a = value_type(1)/std::sqrt(value_type(1)-v*v),
459  std::asin(v))
462  a = value_type(1)/(value_type(1)+v*v),
463  std::atan(v))
466  a = std::sinh(v),
467  std::cosh(v))
470  a = std::cosh(v),
471  std::sinh(v))
474  a = value_type(1)-std::tanh(v)*std::tanh(v),
475  std::tanh(v))
478  a = value_type(1)/std::sqrt((v-value_type(1))*(v+value_type(1))),
479  std::acosh(v))
482  a = value_type(1)/std::sqrt(value_type(1)+v*v),
483  std::asinh(v))
486  a = value_type(1)/(value_type(1)-v*v),
487  std::atanh(v))
488 #ifdef HAVE_SACADO_CXX11
490  CbrtOp,
491  a = value_type(1)/(value_type(3)*std::cbrt(v*v)),
492  std::cbrt(v))
493 #endif
494 
495 #undef FAD_UNARYOP_MACRO
496 
497 //
498 // Binary operators
499 //
500 namespace Sacado {
501  namespace CacheFad {
502 
503  //
504  // AdditionOp
505  //
506 
507  template <typename ExprT1, typename ExprT2>
508  class AdditionOp {};
509 
510  template <typename ExprT1, typename ExprT2>
511  class Expr< AdditionOp<ExprT1,ExprT2> > {
512 
513  public:
514 
515  typedef typename ExprT1::value_type value_type_1;
516  typedef typename ExprT2::value_type value_type_2;
517  typedef typename Sacado::Promote<value_type_1,
518  value_type_2>::type value_type;
519 
520  typedef typename ExprT1::scalar_type scalar_type_1;
521  typedef typename ExprT2::scalar_type scalar_type_2;
522  typedef typename Sacado::Promote<scalar_type_1,
523  scalar_type_2>::type scalar_type;
524 
525  typedef typename ExprT1::base_expr_type base_expr_type_1;
526  typedef typename ExprT2::base_expr_type base_expr_type_2;
527  typedef typename Sacado::Promote<base_expr_type_1,
528  base_expr_type_2>::type base_expr_type;
529 
531  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
532  expr1(expr1_), expr2(expr2_) {}
533 
535  int size() const {
536  int sz1 = expr1.size(), sz2 = expr2.size();
537  return sz1 > sz2 ? sz1 : sz2;
538  }
539 
541  bool updateValue() const {
542  return expr1.updateValue() && expr2.updateValue();
543  }
544 
546  void cache() const {
547  expr1.cache();
548  expr2.cache();
549  }
550 
552  value_type val() const {
553  return expr1.val()+expr2.val();
554  }
555 
557  bool isLinear() const {
558  return expr1.isLinear() && expr2.isLinear();
559  }
560 
562  bool hasFastAccess() const {
563  return expr1.hasFastAccess() && expr2.hasFastAccess();
564  }
565 
567  const value_type dx(int i) const {
568  return expr1.dx(i) + expr2.dx(i);
569  }
570 
572  const value_type fastAccessDx(int i) const {
573  return expr1.fastAccessDx(i) + expr2.fastAccessDx(i);
574  }
575 
576  protected:
577 
578  const ExprT1& expr1;
579  const ExprT2& expr2;
580 
581  };
582 
583  template <typename ExprT1, typename T2>
584  class Expr< AdditionOp<ExprT1, ConstExpr<T2> > > {
585 
586  public:
587 
588  typedef ConstExpr<T2> ExprT2;
589  typedef typename ExprT1::value_type value_type_1;
590  typedef typename ExprT2::value_type value_type_2;
591  typedef typename Sacado::Promote<value_type_1,
592  value_type_2>::type value_type;
593 
594  typedef typename ExprT1::scalar_type scalar_type_1;
595  typedef typename ExprT2::scalar_type scalar_type_2;
596  typedef typename Sacado::Promote<scalar_type_1,
597  scalar_type_2>::type scalar_type;
598 
599  typedef typename ExprT1::base_expr_type base_expr_type_1;
600  typedef typename ExprT2::base_expr_type base_expr_type_2;
601  typedef typename Sacado::Promote<base_expr_type_1,
602  base_expr_type_2>::type base_expr_type;
603 
605  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
606  expr1(expr1_), expr2(expr2_) {}
607 
609  int size() const {
610  return expr1.size();
611  }
612 
614  bool updateValue() const {
615  return expr1.updateValue();
616  }
617 
619  void cache() const {
620  expr1.cache();
621  }
622 
624  value_type val() const {
625  return expr1.val() + expr2.val();
626  }
627 
629  bool isLinear() const {
630  return expr1.isLinear();
631  }
632 
634  bool hasFastAccess() const {
635  return expr1.hasFastAccess();
636  }
637 
639  const value_type dx(int i) const {
640  return expr1.dx(i);
641  }
642 
644  const value_type fastAccessDx(int i) const {
645  return expr1.fastAccessDx(i);
646  }
647 
648  protected:
649 
650  const ExprT1& expr1;
651  ExprT2 expr2;
652 
653  };
654 
655  template <typename T1, typename ExprT2>
656  class Expr< AdditionOp< ConstExpr<T1>,ExprT2> > {
657 
658  public:
659 
660  typedef ConstExpr<T1> ExprT1;
661  typedef typename ExprT1::value_type value_type_1;
662  typedef typename ExprT2::value_type value_type_2;
663  typedef typename Sacado::Promote<value_type_1,
664  value_type_2>::type value_type;
665 
666  typedef typename ExprT1::scalar_type scalar_type_1;
667  typedef typename ExprT2::scalar_type scalar_type_2;
668  typedef typename Sacado::Promote<scalar_type_1,
669  scalar_type_2>::type scalar_type;
670 
671  typedef typename ExprT1::base_expr_type base_expr_type_1;
672  typedef typename ExprT2::base_expr_type base_expr_type_2;
673  typedef typename Sacado::Promote<base_expr_type_1,
674  base_expr_type_2>::type base_expr_type;
675 
677  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
678  expr1(expr1_), expr2(expr2_) {}
679 
681  int size() const {
682  return expr2.size();
683  }
684 
686  bool updateValue() const {
687  return expr2.updateValue();
688  }
689 
691  void cache() const {
692  expr2.cache();
693  }
694 
696  value_type val() const {
697  return expr1.val() + expr2.val();
698  }
699 
701  bool isLinear() const {
702  return expr2.isLinear();
703  }
704 
706  bool hasFastAccess() const {
707  return expr2.hasFastAccess();
708  }
709 
711  const value_type dx(int i) const {
712  return expr2.dx(i);
713  }
714 
716  const value_type fastAccessDx(int i) const {
717  return expr2.fastAccessDx(i);
718  }
719 
720  protected:
721 
722  ExprT1 expr1;
723  const ExprT2& expr2;
724 
725  };
726 
727  //
728  // SubtractionOp
729  //
730 
731  template <typename ExprT1, typename ExprT2>
732  class SubtractionOp {};
733 
734  template <typename ExprT1, typename ExprT2>
735  class Expr< SubtractionOp<ExprT1,ExprT2> > {
736 
737  public:
738 
739  typedef typename ExprT1::value_type value_type_1;
740  typedef typename ExprT2::value_type value_type_2;
741  typedef typename Sacado::Promote<value_type_1,
742  value_type_2>::type value_type;
743 
744  typedef typename ExprT1::scalar_type scalar_type_1;
745  typedef typename ExprT2::scalar_type scalar_type_2;
746  typedef typename Sacado::Promote<scalar_type_1,
747  scalar_type_2>::type scalar_type;
748 
749  typedef typename ExprT1::base_expr_type base_expr_type_1;
750  typedef typename ExprT2::base_expr_type base_expr_type_2;
751  typedef typename Sacado::Promote<base_expr_type_1,
752  base_expr_type_2>::type base_expr_type;
753 
755  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
756  expr1(expr1_), expr2(expr2_) {}
757 
759  int size() const {
760  int sz1 = expr1.size(), sz2 = expr2.size();
761  return sz1 > sz2 ? sz1 : sz2;
762  }
763 
765  bool updateValue() const {
766  return expr1.updateValue() && expr2.updateValue();
767  }
768 
770  void cache() const {
771  expr1.cache();
772  expr2.cache();
773  }
774 
776  value_type val() const {
777  return expr1.val()-expr2.val();
778  }
779 
781  bool isLinear() const {
782  return expr1.isLinear() && expr2.isLinear();
783  }
784 
786  bool hasFastAccess() const {
787  return expr1.hasFastAccess() && expr2.hasFastAccess();
788  }
789 
791  const value_type dx(int i) const {
792  return expr1.dx(i) - expr2.dx(i);
793  }
794 
796  const value_type fastAccessDx(int i) const {
797  return expr1.fastAccessDx(i) - expr2.fastAccessDx(i);
798  }
799 
800  protected:
801 
802  const ExprT1& expr1;
803  const ExprT2& expr2;
804 
805  };
806 
807  template <typename ExprT1, typename T2>
808  class Expr< SubtractionOp<ExprT1, ConstExpr<T2> > > {
809 
810  public:
811 
812  typedef ConstExpr<T2> ExprT2;
813  typedef typename ExprT1::value_type value_type_1;
814  typedef typename ExprT2::value_type value_type_2;
815  typedef typename Sacado::Promote<value_type_1,
816  value_type_2>::type value_type;
817 
818  typedef typename ExprT1::scalar_type scalar_type_1;
819  typedef typename ExprT2::scalar_type scalar_type_2;
820  typedef typename Sacado::Promote<scalar_type_1,
821  scalar_type_2>::type scalar_type;
822 
823  typedef typename ExprT1::base_expr_type base_expr_type_1;
824  typedef typename ExprT2::base_expr_type base_expr_type_2;
825  typedef typename Sacado::Promote<base_expr_type_1,
826  base_expr_type_2>::type base_expr_type;
827 
829  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
830  expr1(expr1_), expr2(expr2_) {}
831 
833  int size() const {
834  return expr1.size();
835  }
836 
838  bool updateValue() const {
839  return expr1.updateValue();
840  }
841 
843  void cache() const {
844  expr1.cache();
845  }
846 
848  value_type val() const {
849  return expr1.val() - expr2.val();
850  }
851 
853  bool isLinear() const {
854  return expr1.isLinear();
855  }
856 
858  bool hasFastAccess() const {
859  return expr1.hasFastAccess();
860  }
861 
863  const value_type dx(int i) const {
864  return expr1.dx(i);
865  }
866 
868  const value_type fastAccessDx(int i) const {
869  return expr1.fastAccessDx(i);
870  }
871 
872  protected:
873 
874  const ExprT1& expr1;
875  ExprT2 expr2;
876 
877  };
878 
879  template <typename T1, typename ExprT2>
880  class Expr< SubtractionOp< ConstExpr<T1>,ExprT2> > {
881 
882  public:
883 
884  typedef ConstExpr<T1> ExprT1;
885  typedef typename ExprT1::value_type value_type_1;
886  typedef typename ExprT2::value_type value_type_2;
887  typedef typename Sacado::Promote<value_type_1,
888  value_type_2>::type value_type;
889 
890  typedef typename ExprT1::scalar_type scalar_type_1;
891  typedef typename ExprT2::scalar_type scalar_type_2;
892  typedef typename Sacado::Promote<scalar_type_1,
893  scalar_type_2>::type scalar_type;
894 
895  typedef typename ExprT1::base_expr_type base_expr_type_1;
896  typedef typename ExprT2::base_expr_type base_expr_type_2;
897  typedef typename Sacado::Promote<base_expr_type_1,
898  base_expr_type_2>::type base_expr_type;
899 
901  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
902  expr1(expr1_), expr2(expr2_) {}
903 
905  int size() const {
906  return expr2.size();
907  }
908 
910  bool updateValue() const {
911  return expr2.updateValue();
912  }
913 
915  void cache() const {
916  expr2.cache();
917  }
918 
920  value_type val() const {
921  return expr1.val() - expr2.val();
922  }
923 
925  bool isLinear() const {
926  return expr2.isLinear();
927  }
928 
930  bool hasFastAccess() const {
931  return expr2.hasFastAccess();
932  }
933 
935  const value_type dx(int i) const {
936  return -expr2.dx(i);
937  }
938 
940  const value_type fastAccessDx(int i) const {
941  return -expr2.fastAccessDx(i);
942  }
943 
944  protected:
945 
946  ExprT1 expr1;
947  const ExprT2& expr2;
948 
949  };
950 
951  //
952  // MultiplicationOp
953  //
954 
955  template <typename ExprT1, typename ExprT2>
956  class MultiplicationOp {};
957 
958  template <typename ExprT1, typename ExprT2>
959  class Expr< MultiplicationOp<ExprT1,ExprT2> > {
960 
961  public:
962 
963  typedef typename ExprT1::value_type value_type_1;
964  typedef typename ExprT2::value_type value_type_2;
965  typedef typename Sacado::Promote<value_type_1,
966  value_type_2>::type value_type;
967 
968  typedef typename ExprT1::scalar_type scalar_type_1;
969  typedef typename ExprT2::scalar_type scalar_type_2;
970  typedef typename Sacado::Promote<scalar_type_1,
971  scalar_type_2>::type scalar_type;
972 
973  typedef typename ExprT1::base_expr_type base_expr_type_1;
974  typedef typename ExprT2::base_expr_type base_expr_type_2;
975  typedef typename Sacado::Promote<base_expr_type_1,
976  base_expr_type_2>::type base_expr_type;
977 
979  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
980  expr1(expr1_), expr2(expr2_) {}
981 
983  int size() const {
984  int sz1 = expr1.size(), sz2 = expr2.size();
985  return sz1 > sz2 ? sz1 : sz2;
986  }
987 
989  bool updateValue() const {
990  return expr1.updateValue() && expr2.updateValue();
991  }
992 
994  void cache() const {
995  expr1.cache();
996  expr2.cache();
997  v1 = expr1.val();
998  v2 = expr2.val();
999  }
1000 
1002  value_type val() const {
1003  return v1*v2;
1004  }
1005 
1007  bool isLinear() const {
1008  return false;
1009  }
1010 
1012  bool hasFastAccess() const {
1013  return expr1.hasFastAccess() && expr2.hasFastAccess();
1014  }
1015 
1017  const value_type dx(int i) const {
1018  if (expr1.size() > 0 && expr2.size() > 0)
1019  return v1*expr2.dx(i) + expr1.dx(i)*v2;
1020  else if (expr1.size() > 0)
1021  return expr1.dx(i)*v2;
1022  else
1023  return v1*expr2.dx(i);
1024  }
1025 
1027  const value_type fastAccessDx(int i) const {
1028  return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
1029  }
1030 
1031  protected:
1032 
1033  const ExprT1& expr1;
1034  const ExprT2& expr2;
1035  mutable value_type_1 v1;
1036  mutable value_type_2 v2;
1037 
1038  };
1039 
1040  template <typename ExprT1, typename T2>
1041  class Expr< MultiplicationOp<ExprT1, ConstExpr<T2> > > {
1042 
1043  public:
1044 
1045  typedef ConstExpr<T2> ExprT2;
1046  typedef typename ExprT1::value_type value_type_1;
1047  typedef typename ExprT2::value_type value_type_2;
1048  typedef typename Sacado::Promote<value_type_1,
1049  value_type_2>::type value_type;
1050 
1051  typedef typename ExprT1::scalar_type scalar_type_1;
1052  typedef typename ExprT2::scalar_type scalar_type_2;
1053  typedef typename Sacado::Promote<scalar_type_1,
1054  scalar_type_2>::type scalar_type;
1055 
1056  typedef typename ExprT1::base_expr_type base_expr_type_1;
1057  typedef typename ExprT2::base_expr_type base_expr_type_2;
1058  typedef typename Sacado::Promote<base_expr_type_1,
1059  base_expr_type_2>::type base_expr_type;
1060 
1062  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1063  expr1(expr1_), expr2(expr2_) {}
1064 
1066  int size() const {
1067  return expr1.size();
1068  }
1069 
1071  bool updateValue() const {
1072  return expr1.updateValue();
1073  }
1074 
1076  void cache() const {
1077  expr1.cache();
1078  }
1079 
1081  value_type val() const {
1082  return expr1.val()*expr2.val();
1083  }
1084 
1086  bool isLinear() const {
1087  return expr1.isLinear();
1088  }
1089 
1091  bool hasFastAccess() const {
1092  return expr1.hasFastAccess();
1093  }
1094 
1096  const value_type dx(int i) const {
1097  return expr1.dx(i)*expr2.val();
1098  }
1099 
1101  const value_type fastAccessDx(int i) const {
1102  return expr1.fastAccessDx(i)*expr2.val();
1103  }
1104 
1105  protected:
1106 
1107  const ExprT1& expr1;
1108  ExprT2 expr2;
1109 
1110  };
1111 
1112  template <typename T1, typename ExprT2>
1113  class Expr< MultiplicationOp< ConstExpr<T1>,ExprT2> > {
1114 
1115  public:
1116 
1117  typedef ConstExpr<T1> ExprT1;
1118  typedef typename ExprT1::value_type value_type_1;
1119  typedef typename ExprT2::value_type value_type_2;
1120  typedef typename Sacado::Promote<value_type_1,
1121  value_type_2>::type value_type;
1122 
1123  typedef typename ExprT1::scalar_type scalar_type_1;
1124  typedef typename ExprT2::scalar_type scalar_type_2;
1125  typedef typename Sacado::Promote<scalar_type_1,
1126  scalar_type_2>::type scalar_type;
1127 
1128  typedef typename ExprT1::base_expr_type base_expr_type_1;
1129  typedef typename ExprT2::base_expr_type base_expr_type_2;
1130  typedef typename Sacado::Promote<base_expr_type_1,
1131  base_expr_type_2>::type base_expr_type;
1132 
1134  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1135  expr1(expr1_), expr2(expr2_) {}
1136 
1138  int size() const {
1139  return expr2.size();
1140  }
1141 
1143  bool updateValue() const {
1144  return expr2.updateValue();
1145  }
1146 
1148  void cache() const {
1149  expr2.cache();
1150  }
1151 
1153  value_type val() const {
1154  return expr1.val()*expr2.val();
1155  }
1156 
1158  bool isLinear() const {
1159  return expr2.isLinear();
1160  }
1161 
1163  bool hasFastAccess() const {
1164  return expr2.hasFastAccess();
1165  }
1166 
1168  const value_type dx(int i) const {
1169  return expr1.val()*expr2.dx(i);
1170  }
1171 
1173  const value_type fastAccessDx(int i) const {
1174  return expr1.val()*expr2.fastAccessDx(i);
1175  }
1176 
1177  protected:
1178 
1179  ExprT1 expr1;
1180  const ExprT2& expr2;
1181 
1182  };
1183 
1184  //
1185  // DivisionOp
1186  //
1187 
1188  template <typename ExprT1, typename ExprT2>
1189  class DivisionOp {};
1190 
1191  template <typename ExprT1, typename ExprT2>
1192  class Expr< DivisionOp<ExprT1,ExprT2> > {
1193 
1194  public:
1195 
1196  typedef typename ExprT1::value_type value_type_1;
1197  typedef typename ExprT2::value_type value_type_2;
1198  typedef typename Sacado::Promote<value_type_1,
1199  value_type_2>::type value_type;
1200 
1201  typedef typename ExprT1::scalar_type scalar_type_1;
1202  typedef typename ExprT2::scalar_type scalar_type_2;
1203  typedef typename Sacado::Promote<scalar_type_1,
1204  scalar_type_2>::type scalar_type;
1205 
1206  typedef typename ExprT1::base_expr_type base_expr_type_1;
1207  typedef typename ExprT2::base_expr_type base_expr_type_2;
1208  typedef typename Sacado::Promote<base_expr_type_1,
1209  base_expr_type_2>::type base_expr_type;
1210 
1212  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1213  expr1(expr1_), expr2(expr2_) {}
1214 
1216  int size() const {
1217  int sz1 = expr1.size(), sz2 = expr2.size();
1218  return sz1 > sz2 ? sz1 : sz2;
1219  }
1220 
1222  bool updateValue() const {
1223  return expr1.updateValue() && expr2.updateValue();
1224  }
1225 
1227  void cache() const {
1228  expr1.cache();
1229  expr2.cache();
1230  const value_type_1 v1 = expr1.val();
1231  const value_type_2 v2 = expr2.val();
1232  a = value_type(1)/v2;
1233  v = v1*a;
1234  b = -v/v2;
1235  }
1236 
1238  value_type val() const {
1239  return v;
1240  }
1241 
1243  bool isLinear() const {
1244  return false;
1245  }
1246 
1248  bool hasFastAccess() const {
1249  return expr1.hasFastAccess() && expr2.hasFastAccess();
1250  }
1251 
1253  const value_type dx(int i) const {
1254  if (expr1.size() > 0 && expr2.size() > 0)
1255  return expr1.dx(i)*a + expr2.dx(i)*b;
1256  else if (expr1.size() > 0)
1257  return expr1.dx(i)*a;
1258  else
1259  return expr1.val()*b;
1260  }
1261 
1263  const value_type fastAccessDx(int i) const {
1264  return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1265  }
1266 
1267  protected:
1268 
1269  const ExprT1& expr1;
1270  const ExprT2& expr2;
1271  mutable value_type v;
1272  mutable value_type a;
1273  mutable value_type b;
1274 
1275  };
1276 
1277  template <typename ExprT1, typename T2>
1278  class Expr< DivisionOp<ExprT1, ConstExpr<T2> > > {
1279 
1280  public:
1281 
1282  typedef ConstExpr<T2> ExprT2;
1283  typedef typename ExprT1::value_type value_type_1;
1284  typedef typename ExprT2::value_type value_type_2;
1285  typedef typename Sacado::Promote<value_type_1,
1286  value_type_2>::type value_type;
1287 
1288  typedef typename ExprT1::scalar_type scalar_type_1;
1289  typedef typename ExprT2::scalar_type scalar_type_2;
1290  typedef typename Sacado::Promote<scalar_type_1,
1291  scalar_type_2>::type scalar_type;
1292 
1293  typedef typename ExprT1::base_expr_type base_expr_type_1;
1294  typedef typename ExprT2::base_expr_type base_expr_type_2;
1295  typedef typename Sacado::Promote<base_expr_type_1,
1296  base_expr_type_2>::type base_expr_type;
1297 
1299  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1300  expr1(expr1_), expr2(expr2_) {}
1301 
1303  int size() const {
1304  return expr1.size();
1305  }
1306 
1308  bool updateValue() const {
1309  return expr1.updateValue();
1310  }
1311 
1313  void cache() const {
1314  expr1.cache();
1315  const value_type_1 v1 = expr1.val();
1316  a = value_type(1)/expr2.val();
1317  v = v1*a;
1318  }
1319 
1321  value_type val() const {
1322  return v;
1323  }
1324 
1326  bool isLinear() const {
1327  return expr1.isLinear();
1328  }
1329 
1331  bool hasFastAccess() const {
1332  return expr1.hasFastAccess();
1333  }
1334 
1336  const value_type dx(int i) const {
1337  return expr1.dx(i)*a;
1338  }
1339 
1341  const value_type fastAccessDx(int i) const {
1342  return expr1.fastAccessDx(i)*a;
1343  }
1344 
1345  protected:
1346 
1347  const ExprT1& expr1;
1348  ExprT2 expr2;
1349  mutable value_type v;
1350  mutable value_type a;
1351 
1352  };
1353 
1354  template <typename T1, typename ExprT2>
1355  class Expr< DivisionOp< ConstExpr<T1>,ExprT2> > {
1356 
1357  public:
1358 
1359  typedef ConstExpr<T1> ExprT1;
1360  typedef typename ExprT1::value_type value_type_1;
1361  typedef typename ExprT2::value_type value_type_2;
1362  typedef typename Sacado::Promote<value_type_1,
1363  value_type_2>::type value_type;
1364 
1365  typedef typename ExprT1::scalar_type scalar_type_1;
1366  typedef typename ExprT2::scalar_type scalar_type_2;
1367  typedef typename Sacado::Promote<scalar_type_1,
1368  scalar_type_2>::type scalar_type;
1369 
1370  typedef typename ExprT1::base_expr_type base_expr_type_1;
1371  typedef typename ExprT2::base_expr_type base_expr_type_2;
1372  typedef typename Sacado::Promote<base_expr_type_1,
1373  base_expr_type_2>::type base_expr_type;
1374 
1376  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1377  expr1(expr1_), expr2(expr2_) {}
1378 
1380  int size() const {
1381  return expr2.size();
1382  }
1383 
1385  bool updateValue() const {
1386  return expr2.updateValue();
1387  }
1388 
1390  void cache() const {
1391  expr2.cache();
1392  const value_type_2 v2 = expr2.val();
1393  v = expr1.val()/v2;
1394  b = -v/v2;
1395  }
1396 
1398  value_type val() const {
1399  return v;
1400  }
1401 
1403  bool isLinear() const {
1404  return false;
1405  }
1406 
1408  bool hasFastAccess() const {
1409  return expr2.hasFastAccess();
1410  }
1411 
1413  const value_type dx(int i) const {
1414  return expr2.dx(i)*b;
1415  }
1416 
1418  const value_type fastAccessDx(int i) const {
1419  return expr2.fastAccessDx(i)*b;
1420  }
1421 
1422  protected:
1423 
1424  ExprT1 expr1;
1425  const ExprT2& expr2;
1426  mutable value_type v;
1427  mutable value_type b;
1428 
1429  };
1430 
1431  //
1432  // Atan2Op
1433  //
1434 
1435  template <typename ExprT1, typename ExprT2>
1436  class Atan2Op {};
1437 
1438  template <typename ExprT1, typename ExprT2>
1439  class Expr< Atan2Op<ExprT1,ExprT2> > {
1440 
1441  public:
1442 
1443  typedef typename ExprT1::value_type value_type_1;
1444  typedef typename ExprT2::value_type value_type_2;
1445  typedef typename Sacado::Promote<value_type_1,
1446  value_type_2>::type value_type;
1447 
1448  typedef typename ExprT1::scalar_type scalar_type_1;
1449  typedef typename ExprT2::scalar_type scalar_type_2;
1450  typedef typename Sacado::Promote<scalar_type_1,
1451  scalar_type_2>::type scalar_type;
1452 
1453  typedef typename ExprT1::base_expr_type base_expr_type_1;
1454  typedef typename ExprT2::base_expr_type base_expr_type_2;
1455  typedef typename Sacado::Promote<base_expr_type_1,
1456  base_expr_type_2>::type base_expr_type;
1457 
1459  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1460  expr1(expr1_), expr2(expr2_) {}
1461 
1463  int size() const {
1464  int sz1 = expr1.size(), sz2 = expr2.size();
1465  return sz1 > sz2 ? sz1 : sz2;
1466  }
1467 
1469  bool updateValue() const {
1470  return expr1.updateValue() && expr2.updateValue();
1471  }
1472 
1474  void cache() const {
1475  expr1.cache();
1476  expr2.cache();
1477  const value_type_1 v1 = expr1.val();
1478  const value_type_2 v2 = expr2.val();
1479  a = value_type(1)/(v1*v1 + v2*v2);
1480  b = -v1*a;
1481  a = v2*a;
1482  v = std::atan2(v1,v2);
1483  }
1484 
1486  value_type val() const {
1487  return v;
1488  }
1489 
1491  bool isLinear() const {
1492  return false;
1493  }
1494 
1496  bool hasFastAccess() const {
1497  return expr1.hasFastAccess() && expr2.hasFastAccess();
1498  }
1499 
1501  const value_type dx(int i) const {
1502  if (expr1.size() > 0 && expr2.size() > 0)
1503  return expr1.dx(i)*a + expr2.dx(i)*b;
1504  else if (expr1.size() > 0)
1505  return expr1.dx(i)*a;
1506  else
1507  return expr1.val()*b;
1508  }
1509 
1511  const value_type fastAccessDx(int i) const {
1512  return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1513  }
1514 
1515  protected:
1516 
1517  const ExprT1& expr1;
1518  const ExprT2& expr2;
1519  mutable value_type v;
1520  mutable value_type a;
1521  mutable value_type b;
1522 
1523  };
1524 
1525  template <typename ExprT1, typename T2>
1526  class Expr< Atan2Op<ExprT1, ConstExpr<T2> > > {
1527 
1528  public:
1529 
1530  typedef ConstExpr<T2> ExprT2;
1531  typedef typename ExprT1::value_type value_type_1;
1532  typedef typename ExprT2::value_type value_type_2;
1533  typedef typename Sacado::Promote<value_type_1,
1534  value_type_2>::type value_type;
1535 
1536  typedef typename ExprT1::scalar_type scalar_type_1;
1537  typedef typename ExprT2::scalar_type scalar_type_2;
1538  typedef typename Sacado::Promote<scalar_type_1,
1539  scalar_type_2>::type scalar_type;
1540 
1541  typedef typename ExprT1::base_expr_type base_expr_type_1;
1542  typedef typename ExprT2::base_expr_type base_expr_type_2;
1543  typedef typename Sacado::Promote<base_expr_type_1,
1544  base_expr_type_2>::type base_expr_type;
1545 
1547  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1548  expr1(expr1_), expr2(expr2_) {}
1549 
1551  int size() const {
1552  return expr1.size();
1553  }
1554 
1556  bool updateValue() const {
1557  return expr1.updateValue();
1558  }
1559 
1561  void cache() const {
1562  expr1.cache();
1563  const value_type_1 v1 = expr1.val();
1564  const value_type_2 v2 = expr2.val();
1565  a = v2/(v1*v1 + v2*v2);
1566  v = std::atan2(v1,v2);
1567  }
1568 
1570  value_type val() const {
1571  return v;
1572  }
1573 
1575  bool isLinear() const {
1576  return false;
1577  }
1578 
1580  bool hasFastAccess() const {
1581  return expr1.hasFastAccess();
1582  }
1583 
1585  const value_type dx(int i) const {
1586  return expr1.dx(i)*a;
1587  }
1588 
1590  const value_type fastAccessDx(int i) const {
1591  return expr1.fastAccessDx(i)*a;
1592  }
1593 
1594  protected:
1595 
1596  const ExprT1& expr1;
1597  ExprT2 expr2;
1598  mutable value_type v;
1599  mutable value_type a;
1600 
1601  };
1602 
1603  template <typename T1, typename ExprT2>
1604  class Expr< Atan2Op< ConstExpr<T1>,ExprT2> > {
1605 
1606  public:
1607 
1608  typedef ConstExpr<T1> ExprT1;
1609  typedef typename ExprT1::value_type value_type_1;
1610  typedef typename ExprT2::value_type value_type_2;
1611  typedef typename Sacado::Promote<value_type_1,
1612  value_type_2>::type value_type;
1613 
1614  typedef typename ExprT1::scalar_type scalar_type_1;
1615  typedef typename ExprT2::scalar_type scalar_type_2;
1616  typedef typename Sacado::Promote<scalar_type_1,
1617  scalar_type_2>::type scalar_type;
1618 
1619  typedef typename ExprT1::base_expr_type base_expr_type_1;
1620  typedef typename ExprT2::base_expr_type base_expr_type_2;
1621  typedef typename Sacado::Promote<base_expr_type_1,
1622  base_expr_type_2>::type base_expr_type;
1623 
1625  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1626  expr1(expr1_), expr2(expr2_) {}
1627 
1629  int size() const {
1630  return expr2.size();
1631  }
1632 
1634  bool updateValue() const {
1635  return expr2.updateValue();
1636  }
1637 
1639  void cache() const {
1640  expr2.cache();
1641  const value_type_1 v1 = expr1.val();
1642  const value_type_2 v2 = expr2.val();
1643  b = -v1/(v1*v1 + v2*v2);
1644  v = std::atan2(v1,v2);
1645  }
1646 
1648  value_type val() const {
1649  return v;
1650  }
1651 
1653  bool isLinear() const {
1654  return false;
1655  }
1656 
1658  bool hasFastAccess() const {
1659  return expr2.hasFastAccess();
1660  }
1661 
1663  const value_type dx(int i) const {
1664  return expr2.dx(i)*b;
1665  }
1666 
1668  const value_type fastAccessDx(int i) const {
1669  return expr2.fastAccessDx(i)*b;
1670  }
1671 
1672  protected:
1673 
1674  ExprT1 expr1;
1675  const ExprT2& expr2;
1676  mutable value_type v;
1677  mutable value_type b;
1678 
1679  };
1680 
1681  //
1682  // PowerOp
1683  //
1684 
1685  template <typename ExprT1, typename ExprT2>
1686  class PowerOp {};
1687 
1688  template <typename ExprT1, typename ExprT2>
1689  class Expr< PowerOp<ExprT1,ExprT2> > {
1690 
1691  public:
1692 
1693  typedef typename ExprT1::value_type value_type_1;
1694  typedef typename ExprT2::value_type value_type_2;
1695  typedef typename Sacado::Promote<value_type_1,
1696  value_type_2>::type value_type;
1697 
1698  typedef typename ExprT1::scalar_type scalar_type_1;
1699  typedef typename ExprT2::scalar_type scalar_type_2;
1700  typedef typename Sacado::Promote<scalar_type_1,
1701  scalar_type_2>::type scalar_type;
1702 
1703  typedef typename ExprT1::base_expr_type base_expr_type_1;
1704  typedef typename ExprT2::base_expr_type base_expr_type_2;
1705  typedef typename Sacado::Promote<base_expr_type_1,
1706  base_expr_type_2>::type base_expr_type;
1707 
1709  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1710  expr1(expr1_), expr2(expr2_) {}
1711 
1713  int size() const {
1714  int sz1 = expr1.size(), sz2 = expr2.size();
1715  return sz1 > sz2 ? sz1 : sz2;
1716  }
1717 
1719  bool updateValue() const {
1720  return expr1.updateValue() && expr2.updateValue();
1721  }
1722 
1724  void cache() const {
1725  expr1.cache();
1726  expr2.cache();
1727  const value_type_1 v1 = expr1.val();
1728  const value_type_2 v2 = expr2.val();
1729  v = std::pow(v1,v2);
1730  if (v1 == value_type(0)) {
1731  a = value_type(0);
1732  b = value_type(0);
1733  }
1734  else {
1735  a = v*v2/v1;
1736  b = v*std::log(v1);
1737  }
1738  }
1739 
1741  value_type val() const {
1742  return v;
1743  }
1744 
1746  bool isLinear() const {
1747  return false;
1748  }
1749 
1751  bool hasFastAccess() const {
1752  return expr1.hasFastAccess() && expr2.hasFastAccess();
1753  }
1754 
1756  const value_type dx(int i) const {
1757  if (expr1.size() > 0 && expr2.size() > 0)
1758  return expr1.dx(i)*a + expr2.dx(i)*b;
1759  else if (expr1.size() > 0)
1760  return expr1.dx(i)*a;
1761  else
1762  return expr1.val()*b;
1763  }
1764 
1766  const value_type fastAccessDx(int i) const {
1767  return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1768  }
1769 
1770  protected:
1771 
1772  const ExprT1& expr1;
1773  const ExprT2& expr2;
1774  mutable value_type v;
1775  mutable value_type a;
1776  mutable value_type b;
1777 
1778  };
1779 
1780  template <typename ExprT1, typename T2>
1781  class Expr< PowerOp<ExprT1, ConstExpr<T2> > > {
1782 
1783  public:
1784 
1785  typedef ConstExpr<T2> ExprT2;
1786  typedef typename ExprT1::value_type value_type_1;
1787  typedef typename ExprT2::value_type value_type_2;
1788  typedef typename Sacado::Promote<value_type_1,
1789  value_type_2>::type value_type;
1790 
1791  typedef typename ExprT1::scalar_type scalar_type_1;
1792  typedef typename ExprT2::scalar_type scalar_type_2;
1793  typedef typename Sacado::Promote<scalar_type_1,
1794  scalar_type_2>::type scalar_type;
1795 
1796  typedef typename ExprT1::base_expr_type base_expr_type_1;
1797  typedef typename ExprT2::base_expr_type base_expr_type_2;
1798  typedef typename Sacado::Promote<base_expr_type_1,
1799  base_expr_type_2>::type base_expr_type;
1800 
1802  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1803  expr1(expr1_), expr2(expr2_) {}
1804 
1806  int size() const {
1807  return expr1.size();
1808  }
1809 
1811  bool updateValue() const {
1812  return expr1.updateValue();
1813  }
1814 
1816  void cache() const {
1817  expr1.cache();
1818  const value_type_1 v1 = expr1.val();
1819  const value_type_2 v2 = expr2.val();
1820  v = std::pow(v1,v2);
1821  if (v1 == value_type_1(0)) {
1822  a = value_type(0);
1823  }
1824  else {
1825  a = v*v2/v1;
1826  }
1827  }
1828 
1830  value_type val() const {
1831  return v;
1832  }
1833 
1835  bool isLinear() const {
1836  return false;
1837  }
1838 
1840  bool hasFastAccess() const {
1841  return expr1.hasFastAccess();
1842  }
1843 
1845  const value_type dx(int i) const {
1846  return expr1.dx(i)*a;
1847  }
1848 
1850  const value_type fastAccessDx(int i) const {
1851  return expr1.fastAccessDx(i)*a;
1852  }
1853 
1854  protected:
1855 
1856  const ExprT1& expr1;
1857  ExprT2 expr2;
1858  mutable value_type v;
1859  mutable value_type a;
1860 
1861  };
1862 
1863  template <typename T1, typename ExprT2>
1864  class Expr< PowerOp< ConstExpr<T1>,ExprT2> > {
1865 
1866  public:
1867 
1868  typedef ConstExpr<T1> ExprT1;
1869  typedef typename ExprT1::value_type value_type_1;
1870  typedef typename ExprT2::value_type value_type_2;
1871  typedef typename Sacado::Promote<value_type_1,
1872  value_type_2>::type value_type;
1873 
1874  typedef typename ExprT1::scalar_type scalar_type_1;
1875  typedef typename ExprT2::scalar_type scalar_type_2;
1876  typedef typename Sacado::Promote<scalar_type_1,
1877  scalar_type_2>::type scalar_type;
1878 
1879  typedef typename ExprT1::base_expr_type base_expr_type_1;
1880  typedef typename ExprT2::base_expr_type base_expr_type_2;
1881  typedef typename Sacado::Promote<base_expr_type_1,
1882  base_expr_type_2>::type base_expr_type;
1883 
1885  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1886  expr1(expr1_), expr2(expr2_) {}
1887 
1889  int size() const {
1890  return expr2.size();
1891  }
1892 
1894  bool updateValue() const {
1895  return expr2.updateValue();
1896  }
1897 
1899  void cache() const {
1900  expr2.cache();
1901  const value_type_1 v1 = expr1.val();
1902  const value_type_2 v2 = expr2.val();
1903  v = std::pow(v1,v2);
1904  if (v1 == value_type(0)) {
1905  b = value_type(0);
1906  }
1907  else {
1908  b = v*std::log(v1);
1909  }
1910  }
1911 
1913  value_type val() const {
1914  return v;
1915  }
1916 
1918  bool isLinear() const {
1919  return false;
1920  }
1921 
1923  bool hasFastAccess() const {
1924  return expr2.hasFastAccess();
1925  }
1926 
1928  const value_type dx(int i) const {
1929  return expr2.dx(i)*b;
1930  }
1931 
1933  const value_type fastAccessDx(int i) const {
1934  return expr2.fastAccessDx(i)*b;
1935  }
1936 
1937  protected:
1938 
1939  ExprT1 expr1;
1940  const ExprT2& expr2;
1941  mutable value_type v;
1942  mutable value_type b;
1943 
1944  };
1945 
1946  //
1947  // MaxOp
1948  //
1949 
1950  template <typename ExprT1, typename ExprT2>
1951  class MaxOp {};
1952 
1953  template <typename ExprT1, typename ExprT2>
1954  class Expr< MaxOp<ExprT1,ExprT2> > {
1955 
1956  public:
1957 
1958  typedef typename ExprT1::value_type value_type_1;
1959  typedef typename ExprT2::value_type value_type_2;
1960  typedef typename Sacado::Promote<value_type_1,
1961  value_type_2>::type value_type;
1962 
1963  typedef typename ExprT1::scalar_type scalar_type_1;
1964  typedef typename ExprT2::scalar_type scalar_type_2;
1965  typedef typename Sacado::Promote<scalar_type_1,
1966  scalar_type_2>::type scalar_type;
1967 
1968  typedef typename ExprT1::base_expr_type base_expr_type_1;
1969  typedef typename ExprT2::base_expr_type base_expr_type_2;
1970  typedef typename Sacado::Promote<base_expr_type_1,
1971  base_expr_type_2>::type base_expr_type;
1972 
1974  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1975  expr1(expr1_), expr2(expr2_) {}
1976 
1978  int size() const {
1979  int sz1 = expr1.size(), sz2 = expr2.size();
1980  return sz1 > sz2 ? sz1 : sz2;
1981  }
1982 
1984  bool updateValue() const {
1985  return expr1.updateValue() && expr2.updateValue();
1986  }
1987 
1989  void cache() const {
1990  expr1.cache();
1991  expr2.cache();
1992  const value_type_1 v1 = expr1.val();
1993  const value_type_2 v2 = expr2.val();
1994  max_v1 = (v1 >= v2);
1995  v = max_v1 ? v1 : v2;
1996  }
1997 
1999  value_type val() const {
2000  return v;
2001  }
2002 
2004  bool isLinear() const {
2005  return false;
2006  }
2007 
2009  bool hasFastAccess() const {
2010  return expr1.hasFastAccess() && expr2.hasFastAccess();
2011  }
2012 
2014  const value_type dx(int i) const {
2015  return max_v1 ? expr1.dx(i) : expr2.dx(i);
2016  }
2017 
2019  const value_type fastAccessDx(int i) const {
2020  return max_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2021  }
2022 
2023  protected:
2024 
2025  const ExprT1& expr1;
2026  const ExprT2& expr2;
2027  mutable value_type v;
2028  mutable bool max_v1;
2029 
2030  };
2031 
2032  template <typename ExprT1, typename T2>
2033  class Expr< MaxOp<ExprT1, ConstExpr<T2> > > {
2034 
2035  public:
2036 
2037  typedef ConstExpr<T2> ExprT2;
2038  typedef typename ExprT1::value_type value_type_1;
2039  typedef typename ExprT2::value_type value_type_2;
2040  typedef typename Sacado::Promote<value_type_1,
2041  value_type_2>::type value_type;
2042 
2043  typedef typename ExprT1::scalar_type scalar_type_1;
2044  typedef typename ExprT2::scalar_type scalar_type_2;
2045  typedef typename Sacado::Promote<scalar_type_1,
2046  scalar_type_2>::type scalar_type;
2047 
2048  typedef typename ExprT1::base_expr_type base_expr_type_1;
2049  typedef typename ExprT2::base_expr_type base_expr_type_2;
2050  typedef typename Sacado::Promote<base_expr_type_1,
2051  base_expr_type_2>::type base_expr_type;
2052 
2054  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2055  expr1(expr1_), expr2(expr2_) {}
2056 
2058  int size() const {
2059  return expr1.size();
2060  }
2061 
2063  bool updateValue() const {
2064  return expr1.updateValue();
2065  }
2066 
2068  void cache() const {
2069  expr1.cache();
2070  const value_type_1 v1 = expr1.val();
2071  const value_type_2 v2 = expr2.val();
2072  max_v1 = (v1 >= v2);
2073  v = max_v1 ? v1 : v2;
2074  }
2075 
2077  value_type val() const {
2078  return v;
2079  }
2080 
2082  bool isLinear() const {
2083  return false;
2084  }
2085 
2087  bool hasFastAccess() const {
2088  return expr1.hasFastAccess();
2089  }
2090 
2092  const value_type dx(int i) const {
2093  return max_v1 ? expr1.dx(i) : value_type(0);
2094  }
2095 
2097  const value_type fastAccessDx(int i) const {
2098  return max_v1 ? expr1.fastAccessDx(i) : value_type(0);
2099  }
2100 
2101  protected:
2102 
2103  const ExprT1& expr1;
2104  ExprT2 expr2;
2105  mutable value_type v;
2106  mutable bool max_v1;
2107 
2108  };
2109 
2110  template <typename T1, typename ExprT2>
2111  class Expr< MaxOp< ConstExpr<T1>,ExprT2> > {
2112 
2113  public:
2114 
2115  typedef ConstExpr<T1> ExprT1;
2116  typedef typename ExprT1::value_type value_type_1;
2117  typedef typename ExprT2::value_type value_type_2;
2118  typedef typename Sacado::Promote<value_type_1,
2119  value_type_2>::type value_type;
2120 
2121  typedef typename ExprT1::scalar_type scalar_type_1;
2122  typedef typename ExprT2::scalar_type scalar_type_2;
2123  typedef typename Sacado::Promote<scalar_type_1,
2124  scalar_type_2>::type scalar_type;
2125 
2126  typedef typename ExprT1::base_expr_type base_expr_type_1;
2127  typedef typename ExprT2::base_expr_type base_expr_type_2;
2128  typedef typename Sacado::Promote<base_expr_type_1,
2129  base_expr_type_2>::type base_expr_type;
2130 
2132  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2133  expr1(expr1_), expr2(expr2_) {}
2134 
2136  int size() const {
2137  return expr2.size();
2138  }
2139 
2141  bool updateValue() const {
2142  return expr2.updateValue();
2143  }
2144 
2146  void cache() const {
2147  expr2.cache();
2148  const value_type_1 v1 = expr1.val();
2149  const value_type_2 v2 = expr2.val();
2150  max_v1 = (v1 >= v2);
2151  v = max_v1 ? v1 : v2;
2152  }
2153 
2155  value_type val() const {
2156  return v;
2157  }
2158 
2160  bool isLinear() const {
2161  return false;
2162  }
2163 
2165  bool hasFastAccess() const {
2166  return expr2.hasFastAccess();
2167  }
2168 
2170  const value_type dx(int i) const {
2171  return max_v1 ? value_type(0) : expr2.dx(i);
2172  }
2173 
2175  const value_type fastAccessDx(int i) const {
2176  return max_v1 ? value_type(0) : expr2.fastAccessDx(i);
2177  }
2178 
2179  protected:
2180 
2181  ExprT1 expr1;
2182  const ExprT2& expr2;
2183  mutable value_type v;
2184  mutable bool max_v1;
2185 
2186  };
2187 
2188  //
2189  // MinOp
2190  //
2191 
2192  template <typename ExprT1, typename ExprT2>
2193  class MinOp {};
2194 
2195  template <typename ExprT1, typename ExprT2>
2196  class Expr< MinOp<ExprT1,ExprT2> > {
2197 
2198  public:
2199 
2200  typedef typename ExprT1::value_type value_type_1;
2201  typedef typename ExprT2::value_type value_type_2;
2202  typedef typename Sacado::Promote<value_type_1,
2203  value_type_2>::type value_type;
2204 
2205  typedef typename ExprT1::scalar_type scalar_type_1;
2206  typedef typename ExprT2::scalar_type scalar_type_2;
2207  typedef typename Sacado::Promote<scalar_type_1,
2208  scalar_type_2>::type scalar_type;
2209 
2210  typedef typename ExprT1::base_expr_type base_expr_type_1;
2211  typedef typename ExprT2::base_expr_type base_expr_type_2;
2212  typedef typename Sacado::Promote<base_expr_type_1,
2213  base_expr_type_2>::type base_expr_type;
2214 
2216  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2217  expr1(expr1_), expr2(expr2_) {}
2218 
2220  int size() const {
2221  int sz1 = expr1.size(), sz2 = expr2.size();
2222  return sz1 > sz2 ? sz1 : sz2;
2223  }
2224 
2226  bool updateValue() const {
2227  return expr1.updateValue() && expr2.updateValue();
2228  }
2229 
2231  void cache() const {
2232  expr1.cache();
2233  expr2.cache();
2234  const value_type_1 v1 = expr1.val();
2235  const value_type_2 v2 = expr2.val();
2236  min_v1 = (v1 <= v2);
2237  v = min_v1 ? v1 : v2;
2238  }
2239 
2241  value_type val() const {
2242  return v;
2243  }
2244 
2246  bool isLinear() const {
2247  return false;
2248  }
2249 
2251  bool hasFastAccess() const {
2252  return expr1.hasFastAccess() && expr2.hasFastAccess();
2253  }
2254 
2256  const value_type dx(int i) const {
2257  return min_v1 ? expr1.dx(i) : expr2.dx(i);
2258  }
2259 
2261  const value_type fastAccessDx(int i) const {
2262  return min_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2263  }
2264 
2265  protected:
2266 
2267  const ExprT1& expr1;
2268  const ExprT2& expr2;
2269  mutable value_type v;
2270  mutable bool min_v1;
2271 
2272  };
2273 
2274  template <typename ExprT1, typename T2>
2275  class Expr< MinOp<ExprT1, ConstExpr<T2> > > {
2276 
2277  public:
2278 
2279  typedef ConstExpr<T2> ExprT2;
2280  typedef typename ExprT1::value_type value_type_1;
2281  typedef typename ExprT2::value_type value_type_2;
2282  typedef typename Sacado::Promote<value_type_1,
2283  value_type_2>::type value_type;
2284 
2285  typedef typename ExprT1::scalar_type scalar_type_1;
2286  typedef typename ExprT2::scalar_type scalar_type_2;
2287  typedef typename Sacado::Promote<scalar_type_1,
2288  scalar_type_2>::type scalar_type;
2289 
2290  typedef typename ExprT1::base_expr_type base_expr_type_1;
2291  typedef typename ExprT2::base_expr_type base_expr_type_2;
2292  typedef typename Sacado::Promote<base_expr_type_1,
2293  base_expr_type_2>::type base_expr_type;
2294 
2296  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2297  expr1(expr1_), expr2(expr2_) {}
2298 
2300  int size() const {
2301  return expr1.size();
2302  }
2303 
2305  bool updateValue() const {
2306  return expr1.updateValue();
2307  }
2308 
2310  void cache() const {
2311  expr1.cache();
2312  const value_type_1 v1 = expr1.val();
2313  const value_type_2 v2 = expr2.val();
2314  min_v1 = (v1 <= v2);
2315  v = min_v1 ? v1 : v2;
2316  }
2317 
2319  value_type val() const {
2320  return v;
2321  }
2322 
2324  bool isLinear() const {
2325  return false;
2326  }
2327 
2329  bool hasFastAccess() const {
2330  return expr1.hasFastAccess();
2331  }
2332 
2334  const value_type dx(int i) const {
2335  return min_v1 ? expr1.dx(i) : value_type(0);
2336  }
2337 
2339  const value_type fastAccessDx(int i) const {
2340  return min_v1 ? expr1.fastAccessDx(i) : value_type(0);
2341  }
2342 
2343  protected:
2344 
2345  const ExprT1& expr1;
2346  ExprT2 expr2;
2347  mutable value_type v;
2348  mutable bool min_v1;
2349 
2350  };
2351 
2352  template <typename T1, typename ExprT2>
2353  class Expr< MinOp< ConstExpr<T1>,ExprT2> > {
2354 
2355  public:
2356 
2357  typedef ConstExpr<T1> ExprT1;
2358  typedef typename ExprT1::value_type value_type_1;
2359  typedef typename ExprT2::value_type value_type_2;
2360  typedef typename Sacado::Promote<value_type_1,
2361  value_type_2>::type value_type;
2362 
2363  typedef typename ExprT1::scalar_type scalar_type_1;
2364  typedef typename ExprT2::scalar_type scalar_type_2;
2365  typedef typename Sacado::Promote<scalar_type_1,
2366  scalar_type_2>::type scalar_type;
2367 
2368  typedef typename ExprT1::base_expr_type base_expr_type_1;
2369  typedef typename ExprT2::base_expr_type base_expr_type_2;
2370  typedef typename Sacado::Promote<base_expr_type_1,
2371  base_expr_type_2>::type base_expr_type;
2372 
2374  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2375  expr1(expr1_), expr2(expr2_) {}
2376 
2378  int size() const {
2379  return expr2.size();
2380  }
2381 
2383  bool updateValue() const {
2384  return expr2.updateValue();
2385  }
2386 
2388  void cache() const {
2389  expr2.cache();
2390  const value_type_1 v1 = expr1.val();
2391  const value_type_2 v2 = expr2.val();
2392  min_v1 = (v1 <= v2);
2393  v = min_v1 ? v1 : v2;
2394  }
2395 
2397  value_type val() const {
2398  return v;
2399  }
2400 
2402  bool isLinear() const {
2403  return false;
2404  }
2405 
2407  bool hasFastAccess() const {
2408  return expr2.hasFastAccess();
2409  }
2410 
2412  const value_type dx(int i) const {
2413  return min_v1 ? value_type(0) : expr2.dx(i);
2414  }
2415 
2417  const value_type fastAccessDx(int i) const {
2418  return min_v1 ? value_type(0) : expr2.fastAccessDx(i);
2419  }
2420 
2421  protected:
2422 
2423  ExprT1 expr1;
2424  const ExprT2& expr2;
2425  mutable value_type v;
2426  mutable bool min_v1;
2427 
2428  };
2429 
2430  }
2431 
2432 }
2433 
2434 #define FAD_BINARYOP_MACRO(OPNAME,OP) \
2435 namespace Sacado { \
2436  namespace CacheFad { \
2437  \
2438  template <typename T1, typename T2> \
2439  KOKKOS_INLINE_FUNCTION \
2440  SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \
2441  OPNAME (const T1& expr1, const T2& expr2) \
2442  { \
2443  typedef OP< T1, T2 > expr_t; \
2444  \
2445  return Expr<expr_t>(expr1, expr2); \
2446  } \
2447  \
2448  template <typename T> \
2449  KOKKOS_INLINE_FUNCTION \
2450  Expr< OP< Expr<T>, Expr<T> > > \
2451  OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
2452  { \
2453  typedef OP< Expr<T>, Expr<T> > expr_t; \
2454  \
2455  return Expr<expr_t>(expr1, expr2); \
2456  } \
2457  \
2458  template <typename T> \
2459  KOKKOS_INLINE_FUNCTION \
2460  Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
2461  Expr<T> > > \
2462  OPNAME (const typename Expr<T>::value_type& c, \
2463  const Expr<T>& expr) \
2464  { \
2465  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
2466  typedef OP< ConstT, Expr<T> > expr_t; \
2467  \
2468  return Expr<expr_t>(ConstT(c), expr); \
2469  } \
2470  \
2471  template <typename T> \
2472  KOKKOS_INLINE_FUNCTION \
2473  Expr< OP< Expr<T>, \
2474  ConstExpr<typename Expr<T>::value_type> > > \
2475  OPNAME (const Expr<T>& expr, \
2476  const typename Expr<T>::value_type& c) \
2477  { \
2478  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
2479  typedef OP< Expr<T>, ConstT > expr_t; \
2480  \
2481  return Expr<expr_t>(expr, ConstT(c)); \
2482  } \
2483  \
2484  template <typename T> \
2485  KOKKOS_INLINE_FUNCTION \
2486  SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \
2487  OPNAME (const typename Expr<T>::scalar_type& c, \
2488  const Expr<T>& expr) \
2489  { \
2490  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
2491  typedef OP< ConstT, Expr<T> > expr_t; \
2492  \
2493  return Expr<expr_t>(ConstT(c), expr); \
2494  } \
2495  \
2496  template <typename T> \
2497  KOKKOS_INLINE_FUNCTION \
2498  SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \
2499  OPNAME (const Expr<T>& expr, \
2500  const typename Expr<T>::scalar_type& c) \
2501  { \
2502  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
2503  typedef OP< Expr<T>, ConstT > expr_t; \
2504  \
2505  return Expr<expr_t>(expr, ConstT(c)); \
2506  } \
2507  } \
2508 }
2509 
2510 
2511 FAD_BINARYOP_MACRO(operator+, AdditionOp)
2514 FAD_BINARYOP_MACRO(operator/, DivisionOp)
2519 
2520 #undef FAD_BINARYOP_MACRO
2521 
2522 //-------------------------- Relational Operators -----------------------
2523 
2524 #define FAD_RELOP_MACRO(OP) \
2525 namespace Sacado { \
2526  namespace CacheFad { \
2527  template <typename ExprT1, typename ExprT2> \
2528  KOKKOS_INLINE_FUNCTION \
2529  bool \
2530  operator OP (const Expr<ExprT1>& expr1, \
2531  const Expr<ExprT2>& expr2) \
2532  { \
2533  expr1.cache(); \
2534  expr2.cache(); \
2535  return expr1.val() OP expr2.val(); \
2536  } \
2537  \
2538  template <typename ExprT2> \
2539  KOKKOS_INLINE_FUNCTION \
2540  bool \
2541  operator OP (const typename Expr<ExprT2>::value_type& a, \
2542  const Expr<ExprT2>& expr2) \
2543  { \
2544  expr2.cache(); \
2545  return a OP expr2.val(); \
2546  } \
2547  \
2548  template <typename ExprT1> \
2549  KOKKOS_INLINE_FUNCTION \
2550  bool \
2551  operator OP (const Expr<ExprT1>& expr1, \
2552  const typename Expr<ExprT1>::value_type& b) \
2553  { \
2554  expr1.cache(); \
2555  return expr1.val() OP b; \
2556  } \
2557  } \
2558 }
2559 
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 FAD_RELOP_MACRO(<<=)
2567 FAD_RELOP_MACRO(>>=)
2568 FAD_RELOP_MACRO(&)
2569 FAD_RELOP_MACRO(|)
2570 
2571 #undef FAD_RELOP_MACRO
2572 
2573 namespace Sacado {
2574 
2575  namespace CacheFad {
2576 
2577  template <typename ExprT>
2579  bool operator ! (const Expr<ExprT>& expr)
2580  {
2581  expr.cache();
2582  return ! expr.val();
2583  }
2584 
2585  } // namespace CacheFad
2586 
2587 } // namespace Sacado
2588 
2589 //-------------------------- Boolean Operators -----------------------
2590 namespace Sacado {
2591 
2592  namespace CacheFad {
2593 
2594  template <typename ExprT>
2596  bool toBool(const Expr<ExprT>& x) {
2597  x.cache();
2598  bool is_zero = (x.val() == 0.0);
2599  for (int i=0; i<x.size(); i++)
2600  is_zero = is_zero && (x.dx(i) == 0.0);
2601  return !is_zero;
2602  }
2603 
2604  } // namespace Fad
2605 
2606 } // namespace Sacado
2607 
2608 #define FAD_BOOL_MACRO(OP) \
2609 namespace Sacado { \
2610  namespace CacheFad { \
2611  template <typename ExprT1, typename ExprT2> \
2612  KOKKOS_INLINE_FUNCTION \
2613  bool \
2614  operator OP (const Expr<ExprT1>& expr1, \
2615  const Expr<ExprT2>& expr2) \
2616  { \
2617  return toBool(expr1) OP toBool(expr2); \
2618  } \
2619  \
2620  template <typename ExprT2> \
2621  KOKKOS_INLINE_FUNCTION \
2622  bool \
2623  operator OP (const typename Expr<ExprT2>::value_type& a, \
2624  const Expr<ExprT2>& expr2) \
2625  { \
2626  return a OP toBool(expr2); \
2627  } \
2628  \
2629  template <typename ExprT1> \
2630  KOKKOS_INLINE_FUNCTION \
2631  bool \
2632  operator OP (const Expr<ExprT1>& expr1, \
2633  const typename Expr<ExprT1>::value_type& b) \
2634  { \
2635  return toBool(expr1) OP b; \
2636  } \
2637  } \
2638 }
2639 
2640 FAD_BOOL_MACRO(&&)
2641 FAD_BOOL_MACRO(||)
2642 
2643 #undef FAD_BOOL_MACRO
2644 
2645 //-------------------------- I/O Operators -----------------------
2646 
2647 namespace Sacado {
2648 
2649  namespace CacheFad {
2650 
2651  template <typename ExprT>
2652  std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
2653  x.cache();
2654  os << x.val() << " [";
2655 
2656  for (int i=0; i< x.size(); i++) {
2657  os << " " << x.dx(i);
2658  }
2659 
2660  os << " ]";
2661  return os;
2662  }
2663 
2664  } // namespace CacheFad
2665 
2666 } // namespace Sacado
2667 
2668 #endif // SACADO_CACHEFAD_OPS_HPP
cbrt(expr.val())
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
#define FAD_RELOP_MACRO(OP)
expr expr SinOp
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
asinh(expr.val())
KOKKOS_INLINE_FUNCTION value_type val() const
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 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)
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
KOKKOS_INLINE_FUNCTION void cache() const
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
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 val()
#define KOKKOS_INLINE_FUNCTION
KOKKOS_INLINE_FUNCTION T safe_sqrt(const T &x)
KOKKOS_INLINE_FUNCTION bool isLinear() const
tanh(expr.val())
expr expr CosOp
KOKKOS_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
#define FAD_BINARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, CDX1, CDX2, FASTACCESSDX, VAL_CONST_DX_1, VAL_CONST_DX_2, CONST_DX_1, CONST_DX_2, CONST_FASTACCESSDX_1, CONST_FASTACCESSDX_2)
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())
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 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 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