Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Sacado_ELRCacheFad_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_ELRCACHEFAD_OPS_HPP
53 #define SACADO_ELRCACHEFAD_OPS_HPP
54 
56 #include "Sacado_cmath.hpp"
58 #include "Sacado_mpl_is_same.hpp"
59 #include <ostream> // for std::ostream
60 
61 namespace Sacado {
62  namespace ELRCacheFad {
63 
64  //
65  // UnaryPlusOp
66  //
67 
68  template <typename ExprT>
69  class UnaryPlusOp {};
70 
71  template <typename ExprT>
72  class Expr< UnaryPlusOp<ExprT> > {
73  public:
74 
75  typedef typename ExprT::value_type value_type;
76  typedef typename ExprT::scalar_type scalar_type;
77 
78  typedef typename ExprT::base_expr_type base_expr_type;
79 
80  static const int num_args = ExprT::num_args;
81 
82  static const bool is_linear = true;
83 
85  explicit Expr(const ExprT& expr_) : expr(expr_) {}
86 
88  int size() const { return expr.size(); }
89 
90  template <int Arg>
92  bool isActive() const { return expr.template isActive<Arg>(); }
93 
95  bool updateValue() const { return expr.updateValue(); }
96 
98  void cache() const {
99  expr.cache();
100  }
101 
103  value_type val() const {
104  return expr.val();
105  }
106 
109  value_type partials[]) const {
110  expr.computePartials(bar, partials);
111  }
112 
114  void getTangents(int i, value_type dots[]) const {
115  expr.getTangents(i, dots); }
116 
117  template <int Arg>
118  value_type getTangent(int i) const {
119  return expr.template getTangent<Arg>(i);
120  }
121 
123  bool isLinear() const {
124  return expr.isLinear();
125  }
126 
128  bool hasFastAccess() const {
129  return expr.hasFastAccess();
130  }
131 
133  const value_type dx(int i) const {
134  return expr.dx(i);
135  }
136 
138  const value_type fastAccessDx(int i) const {
139  return expr.fastAccessDx(i);
140  }
141 
143  const value_type* getDx(int j) const {
144  return expr.getDx(j);
145  }
146 
147  protected:
148 
149  const ExprT& expr;
150  };
151 
152  template <typename T>
155  operator+ (const Expr<T>& expr)
156  {
157  typedef UnaryPlusOp< Expr<T> > expr_t;
158 
159  return Expr<expr_t>(expr);
160  }
161 
162  //
163  // UnaryMinusOp
164  //
165  template <typename ExprT>
166  class UnaryMinusOp {};
167 
168  template <typename ExprT>
169  class Expr< UnaryMinusOp<ExprT> > {
170  public:
171 
172  typedef typename ExprT::value_type value_type;
173  typedef typename ExprT::scalar_type scalar_type;
174 
175  typedef typename ExprT::base_expr_type base_expr_type;
176 
177  static const int num_args = ExprT::num_args;
178 
179  static const bool is_linear = true;
180 
182  explicit Expr(const ExprT& expr_) : expr(expr_) {}
183 
185  int size() const { return expr.size(); }
186 
187  template <int Arg>
189  bool isActive() const { return expr.template isActive<Arg>(); }
190 
192  bool updateValue() const { return expr.updateValue(); }
193 
195  void cache() const {
196  expr.cache();
197  }
198 
200  value_type val() const {
201  return -expr.val();
202  }
203 
206  value_type partials[]) const {
207  expr.computePartials(-bar, partials);
208  }
209 
211  void getTangents(int i, value_type dots[]) const {
212  expr.getTangents(i, dots); }
213 
214  template <int Arg>
216  value_type getTangent(int i) const {
217  return expr.template getTangent<Arg>(i);
218  }
219 
221  bool isLinear() const {
222  return expr.isLinear();
223  }
224 
226  bool hasFastAccess() const {
227  return expr.hasFastAccess();
228  }
229 
231  const value_type dx(int i) const {
232  return -expr.dx(i);
233  }
234 
236  const value_type fastAccessDx(int i) const {
237  return -expr.fastAccessDx(i);
238  }
239 
241  const value_type* getDx(int j) const {
242  return expr.getDx(j);
243  }
244 
245  protected:
246 
247  const ExprT& expr;
248  };
249 
250  template <typename T>
253  operator- (const Expr<T>& expr)
254  {
255  typedef UnaryMinusOp< Expr<T> > expr_t;
256 
257  return Expr<expr_t>(expr);
258  }
259 
260  //
261  // AbsOp
262  //
263 
264  template <typename ExprT>
265  class AbsOp {};
266 
267  template <typename ExprT>
268  class Expr< AbsOp<ExprT> > {
269  public:
270 
271  typedef typename ExprT::value_type value_type;
272  typedef typename ExprT::scalar_type scalar_type;
273 
274  typedef typename ExprT::base_expr_type base_expr_type;
275 
276  static const int num_args = ExprT::num_args;
277 
278  static const bool is_linear = false;
279 
281  explicit Expr(const ExprT& expr_) : expr(expr_) {}
282 
284  int size() const { return expr.size(); }
285 
286  template <int Arg>
288  bool isActive() const { return expr.template isActive<Arg>(); }
289 
291  bool updateValue() const { return expr.updateValue(); }
292 
294  void cache() const {
295  expr.cache();
296  v = expr.val();
297  v_pos = (v >= 0);
298  }
299 
301  value_type val() const {
302  return std::abs(v);
303  }
304 
307  value_type partials[]) const {
308  if (v_pos)
309  expr.computePartials(bar, partials);
310  else
311  expr.computePartials(-bar, partials);
312  }
313 
315  void getTangents(int i, value_type dots[]) const {
316  expr.getTangents(i, dots); }
317 
318  template <int Arg>
320  value_type getTangent(int i) const {
321  return expr.template getTangent<Arg>(i);
322  }
323 
325  bool isLinear() const {
326  return false;
327  }
328 
330  bool hasFastAccess() const {
331  return expr.hasFastAccess();
332  }
333 
335  const value_type dx(int i) const {
336  if (v_pos) return expr.dx(i);
337  else return -expr.dx(i);
338  }
339 
341  const value_type fastAccessDx(int i) const {
342  if (v_pos) return expr.fastAccessDx(i);
343  else return -expr.fastAccessDx(i);
344  }
345 
347  const value_type* getDx(int j) const {
348  return expr.getDx(j);
349  }
350 
351  protected:
352 
353  const ExprT& expr;
354  mutable value_type v;
355  mutable bool v_pos;
356  };
357 
358  template <typename T>
361  abs (const Expr<T>& expr)
362  {
363  typedef AbsOp< Expr<T> > expr_t;
364 
365  return Expr<expr_t>(expr);
366  }
367 
368  //
369  // FAbsOp
370  //
371 
372  template <typename ExprT>
373  class FAbsOp {};
374 
375  template <typename ExprT>
376  class Expr< FAbsOp<ExprT> > {
377  public:
378 
379  typedef typename ExprT::value_type value_type;
380  typedef typename ExprT::scalar_type scalar_type;
381 
382  typedef typename ExprT::base_expr_type base_expr_type;
383 
384  static const int num_args = ExprT::num_args;
385 
386  static const bool is_linear = false;
387 
389  explicit Expr(const ExprT& expr_) : expr(expr_) {}
390 
392  int size() const { return expr.size(); }
393 
394  template <int Arg>
396  bool isActive() const { return expr.template isActive<Arg>(); }
397 
399  bool updateValue() const { return expr.updateValue(); }
400 
402  void cache() const {
403  expr.cache();
404  v = expr.val();
405  v_pos = (v >= 0);
406  }
407 
409  value_type val() const {
410  return std::fabs(v);
411  }
412 
415  value_type partials[]) const {
416  if (v_pos)
417  expr.computePartials(bar, partials);
418  else
419  expr.computePartials(-bar, partials);
420  }
421 
423  void getTangents(int i, value_type dots[]) const {
424  expr.getTangents(i, dots); }
425 
426  template <int Arg>
428  value_type getTangent(int i) const {
429  return expr.template getTangent<Arg>(i);
430  }
431 
433  bool isLinear() const {
434  return false;
435  }
436 
438  bool hasFastAccess() const {
439  return expr.hasFastAccess();
440  }
441 
443  const value_type dx(int i) const {
444  if (v_pos) return expr.dx(i);
445  else return -expr.dx(i);
446  }
447 
449  const value_type fastAccessDx(int i) const {
450  if (v_pos) return expr.fastAccessDx(i);
451  else return -expr.fastAccessDx(i);
452  }
453 
455  const value_type* getDx(int j) const {
456  return expr.getDx(j);
457  }
458 
459  protected:
460 
461  const ExprT& expr;
462  mutable value_type v;
463  mutable bool v_pos;
464  };
465 
466  template <typename T>
469  fabs (const Expr<T>& expr)
470  {
471  typedef FAbsOp< Expr<T> > expr_t;
472 
473  return Expr<expr_t>(expr);
474  }
475 
476  }
477 }
478 
479 #define FAD_UNARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE) \
480 namespace Sacado { \
481  namespace ELRCacheFad { \
482  \
483  template <typename ExprT> \
484  class OP {}; \
485  \
486  template <typename ExprT> \
487  class Expr< OP<ExprT> > { \
488  public: \
489  \
490  typedef typename ExprT::value_type value_type; \
491  typedef typename ExprT::scalar_type scalar_type; \
492  \
493  typedef typename ExprT::base_expr_type base_expr_type; \
494  \
495  static const int num_args = ExprT::num_args; \
496  \
497  static const bool is_linear = false; \
498  \
499  KOKKOS_INLINE_FUNCTION \
500  explicit Expr(const ExprT& expr_) : expr(expr_) {} \
501  \
502  KOKKOS_INLINE_FUNCTION \
503  int size() const { return expr.size(); } \
504  \
505  template <int Arg> \
506  KOKKOS_INLINE_FUNCTION \
507  bool isActive() const { return expr.template isActive<Arg>(); } \
508  \
509  KOKKOS_INLINE_FUNCTION \
510  bool updateValue() const { return expr.updateValue(); } \
511  \
512  KOKKOS_INLINE_FUNCTION \
513  void cache() const { \
514  expr.cache(); \
515  v = expr.val(); \
516  PARTIAL; \
517  } \
518  \
519  KOKKOS_INLINE_FUNCTION \
520  value_type val() const { \
521  return VALUE; \
522  } \
523  \
524  KOKKOS_INLINE_FUNCTION \
525  void computePartials(const value_type& bar, \
526  value_type partials[]) const { \
527  expr.computePartials(bar*a, partials); \
528  } \
529  \
530  KOKKOS_INLINE_FUNCTION \
531  void getTangents(int i, value_type dots[]) const { \
532  expr.getTangents(i, dots); } \
533  \
534  template <int Arg> \
535  KOKKOS_INLINE_FUNCTION \
536  value_type getTangent(int i) const { \
537  return expr.template getTangent<Arg>(i); \
538  } \
539  \
540  KOKKOS_INLINE_FUNCTION \
541  bool isLinear() const { \
542  return false; \
543  } \
544  \
545  KOKKOS_INLINE_FUNCTION \
546  bool hasFastAccess() const { \
547  return expr.hasFastAccess(); \
548  } \
549  \
550  KOKKOS_INLINE_FUNCTION \
551  const value_type dx(int i) const { \
552  return expr.dx(i)*a; \
553  } \
554  \
555  KOKKOS_INLINE_FUNCTION \
556  const value_type fastAccessDx(int i) const { \
557  return expr.fastAccessDx(i)*a; \
558  } \
559  \
560  KOKKOS_INLINE_FUNCTION \
561  const value_type* getDx(int j) const { \
562  return expr.getDx(j); \
563  } \
564  \
565  protected: \
566  \
567  const ExprT& expr; \
568  mutable value_type v; \
569  mutable value_type a; \
570  }; \
571  \
572  template <typename T> \
573  KOKKOS_INLINE_FUNCTION \
574  Expr< OP< Expr<T> > > \
575  OPNAME (const Expr<T>& expr) \
576  { \
577  typedef OP< Expr<T> > expr_t; \
578  \
579  return Expr<expr_t>(expr); \
580  } \
581  } \
582 }
583 
585  ExpOp,
586  a = std::exp(v),
587  a)
590  a=scalar_type(1.0)/v,
591  std::log(v))
594  a = scalar_type(1.0)/(std::log(scalar_type(10.0))*v),
595  std::log10(v))
598  a = scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)),
599  std::sqrt(v))
602  a = (v == value_type(0.0) ? value_type(0.0) : value_type(scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)))),
603  std::sqrt(v))
606  a = -std::sin(v),
607  std::cos(v))
610  a = std::cos(v),
611  std::sin(v))
614  a = scalar_type(1.0)+std::tan(v)*std::tan(v),
615  std::tan(v))
618  a = scalar_type(-1.0)/std::sqrt(scalar_type(1.0)-v*v),
619  std::acos(v))
622  a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)-v*v),
623  std::asin(v))
626  a = scalar_type(1.0)/(scalar_type(1.0)+v*v),
627  std::atan(v))
630  a = std::sinh(v),
631  std::cosh(v))
634  a = std::cosh(v),
635  std::sinh(v))
638  a = scalar_type(1.0)-std::tanh(v)*std::tanh(v),
639  std::tanh(v))
642  a = scalar_type(1.0)/std::sqrt((v-scalar_type(1.0))*(v+scalar_type(1.0))),
643  std::acosh(v))
646  a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)+v*v),
647  std::asinh(v))
650  a = scalar_type(1.0)/(scalar_type(1.0)-v*v),
651  std::atanh(v))
652 #ifdef HAVE_SACADO_CXX11
654  CbrtOp,
655  a = scalar_type(1.0)/(scalar_type(3.0)*std::cbrt(v*v)),
656  std::cbrt(v))
657 #endif
658 
659 #undef FAD_UNARYOP_MACRO
660 
661 //
662 // Binary operators
663 //
664 namespace Sacado {
665  namespace ELRCacheFad {
666 
667  //
668  // AdditionOp
669  //
670 
671  template <typename ExprT1, typename ExprT2>
672  class AdditionOp {};
673 
674  template <typename ExprT1, typename ExprT2>
675  class Expr< AdditionOp<ExprT1,ExprT2> > {
676 
677  public:
678 
679  typedef typename ExprT1::value_type value_type_1;
680  typedef typename ExprT2::value_type value_type_2;
681  typedef typename Sacado::Promote<value_type_1,
682  value_type_2>::type value_type;
683  typedef typename ExprT1::scalar_type scalar_type_1;
684  typedef typename ExprT2::scalar_type scalar_type_2;
685  typedef typename Sacado::Promote<scalar_type_1,
686  scalar_type_2>::type scalar_type;
687 
688  typedef typename ExprT1::base_expr_type base_expr_type_1;
689  typedef typename ExprT2::base_expr_type base_expr_type_2;
690  typedef typename Sacado::Promote<base_expr_type_1,
691  base_expr_type_2>::type base_expr_type;
692 
693  static const int num_args1 = ExprT1::num_args;
694  static const int num_args2 = ExprT2::num_args;
695  static const int num_args = num_args1 + num_args2;
696 
697  static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
698 
700  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
701  expr1(expr1_), expr2(expr2_) {}
702 
704  int size() const {
705  int sz1 = expr1.size(), sz2 = expr2.size();
706  return sz1 > sz2 ? sz1 : sz2;
707  }
708 
709  template <int Arg>
711  bool isActive() const {
712  if (Arg < num_args1)
713  return expr1.template isActive<Arg>();
714  else
715  return expr2.template isActive<Arg-num_args1>();
716  }
717 
719  bool updateValue() const {
720  return expr1.updateValue() && expr2.updateValue();
721  }
722 
724  void cache() const {
725  expr1.cache();
726  expr2.cache();
727  }
728 
730  value_type val() const {
731  return expr1.val()+expr2.val();
732  }
733 
735  void computePartials(const value_type& bar,
736  value_type partials[]) const {
737  if (num_args1 > 0)
738  expr1.computePartials(bar, partials);
739  if (num_args2 > 0)
740  expr2.computePartials(bar, partials+num_args1);
741  }
742 
744  void getTangents(int i, value_type dots[]) const {
745  expr1.getTangents(i, dots);
746  expr2.getTangents(i, dots+num_args1);
747  }
748 
749  template <int Arg>
751  value_type getTangent(int i) const {
752  if (Arg < num_args1)
753  return expr1.template getTangent<Arg>(i);
754  else
755  return expr2.template getTangent<Arg-num_args1>(i);
756  }
757 
759  bool isLinear() const {
760  return expr1.isLinear() && expr2.isLinear();
761  }
762 
764  bool hasFastAccess() const {
765  return expr1.hasFastAccess() && expr2.hasFastAccess();
766  }
767 
769  const value_type dx(int i) const {
770  return expr1.dx(i) + expr2.dx(i);
771  }
772 
774  const value_type fastAccessDx(int i) const {
775  return expr1.fastAccessDx(i) + expr2.fastAccessDx(i);
776  }
777 
779  const value_type* getDx(int j) const {
780  if (j < num_args1)
781  return expr1.getDx(j);
782  else
783  return expr2.getDx(j-num_args1);
784  }
785 
786  protected:
787 
788  const ExprT1& expr1;
789  const ExprT2& expr2;
790 
791  };
792 
793  template <typename ExprT1, typename T2>
794  class Expr< AdditionOp<ExprT1, ConstExpr<T2> > > {
795 
796  public:
797 
798  typedef ConstExpr<T2> ExprT2;
799  typedef typename ExprT1::value_type value_type_1;
800  typedef typename ExprT2::value_type value_type_2;
801  typedef typename Sacado::Promote<value_type_1,
802  value_type_2>::type value_type;
803  typedef typename ExprT1::scalar_type scalar_type_1;
804  typedef typename ExprT2::scalar_type scalar_type_2;
805  typedef typename Sacado::Promote<scalar_type_1,
806  scalar_type_2>::type scalar_type;
807 
808  typedef typename ExprT1::base_expr_type base_expr_type_1;
809  typedef typename ExprT2::base_expr_type base_expr_type_2;
810  typedef typename Sacado::Promote<base_expr_type_1,
811  base_expr_type_2>::type base_expr_type;
812 
813  static const int num_args = ExprT1::num_args;
814 
815  static const bool is_linear = ExprT1::is_linear;
816 
818  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
819  expr1(expr1_), expr2(expr2_) {}
820 
822  int size() const {
823  return expr1.size();
824  }
825 
826  template <int Arg>
828  bool isActive() const {
829  return expr1.template isActive<Arg>();
830  }
831 
833  bool updateValue() const {
834  return expr1.updateValue();
835  }
836 
838  void cache() const {
839  expr1.cache();
840  }
841 
843  value_type val() const {
844  return expr1.val() + expr2.val();
845  }
846 
848  void computePartials(const value_type& bar,
849  value_type partials[]) const {
850  expr1.computePartials(bar, partials);
851  }
852 
854  void getTangents(int i, value_type dots[]) const {
855  expr1.getTangents(i, dots);
856  }
857 
858  template <int Arg>
860  value_type getTangent(int i) const {
861  return expr1.template getTangent<Arg>(i);
862  }
863 
865  bool isLinear() const {
866  return expr1.isLinear();
867  }
868 
870  bool hasFastAccess() const {
871  return expr1.hasFastAccess();
872  }
873 
875  const value_type dx(int i) const {
876  return expr1.dx(i);
877  }
878 
880  const value_type fastAccessDx(int i) const {
881  return expr1.fastAccessDx(i);
882  }
883 
885  const value_type* getDx(int j) const {
886  return expr1.getDx(j);
887  }
888 
889  protected:
890 
891  const ExprT1& expr1;
892  ExprT2 expr2;
893 
894  };
895 
896  template <typename T1, typename ExprT2>
897  class Expr< AdditionOp< ConstExpr<T1>,ExprT2> > {
898 
899  public:
900 
901  typedef ConstExpr<T1> ExprT1;
902  typedef typename ExprT1::value_type value_type_1;
903  typedef typename ExprT2::value_type value_type_2;
904  typedef typename Sacado::Promote<value_type_1,
905  value_type_2>::type value_type;
906  typedef typename ExprT1::scalar_type scalar_type_1;
907  typedef typename ExprT2::scalar_type scalar_type_2;
908  typedef typename Sacado::Promote<scalar_type_1,
909  scalar_type_2>::type scalar_type;
910 
911  typedef typename ExprT1::base_expr_type base_expr_type_1;
912  typedef typename ExprT2::base_expr_type base_expr_type_2;
913  typedef typename Sacado::Promote<base_expr_type_1,
914  base_expr_type_2>::type base_expr_type;
915 
916  static const int num_args = ExprT2::num_args;
917 
918  static const bool is_linear = ExprT2::is_linear;
919 
921  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
922  expr1(expr1_), expr2(expr2_) {}
923 
925  int size() const {
926  return expr2.size();
927  }
928 
929  template <int Arg>
931  bool isActive() const {
932  return expr2.template isActive<Arg>();
933  }
934 
936  bool updateValue() const {
937  return expr2.updateValue();
938  }
939 
941  void cache() const {
942  expr2.cache();
943  }
944 
946  value_type val() const {
947  return expr1.val() + expr2.val();
948  }
949 
951  void computePartials(const value_type& bar,
952  value_type partials[]) const {
953  expr2.computePartials(bar, partials);
954  }
955 
957  void getTangents(int i, value_type dots[]) const {
958  expr2.getTangents(i, dots);
959  }
960 
961  template <int Arg>
963  value_type getTangent(int i) const {
964  return expr2.template getTangent<Arg>(i);
965  }
966 
968  bool isLinear() const {
969  return expr2.isLinear();
970  }
971 
973  bool hasFastAccess() const {
974  return expr2.hasFastAccess();
975  }
976 
978  const value_type dx(int i) const {
979  return expr2.dx(i);
980  }
981 
983  const value_type fastAccessDx(int i) const {
984  return expr2.fastAccessDx(i);
985  }
986 
988  const value_type* getDx(int j) const {
989  return expr2.getDx(j);
990  }
991 
992  protected:
993 
994  ExprT1 expr1;
995  const ExprT2& expr2;
996 
997  };
998 
999  //
1000  // SubtractionOp
1001  //
1002 
1003  template <typename ExprT1, typename ExprT2>
1004  class SubtractionOp {};
1005 
1006  template <typename ExprT1, typename ExprT2>
1007  class Expr< SubtractionOp<ExprT1,ExprT2> > {
1008 
1009  public:
1010 
1011  typedef typename ExprT1::value_type value_type_1;
1012  typedef typename ExprT2::value_type value_type_2;
1013  typedef typename Sacado::Promote<value_type_1,
1014  value_type_2>::type value_type;
1015  typedef typename ExprT1::scalar_type scalar_type_1;
1016  typedef typename ExprT2::scalar_type scalar_type_2;
1017  typedef typename Sacado::Promote<scalar_type_1,
1018  scalar_type_2>::type scalar_type;
1019 
1020  typedef typename ExprT1::base_expr_type base_expr_type_1;
1021  typedef typename ExprT2::base_expr_type base_expr_type_2;
1022  typedef typename Sacado::Promote<base_expr_type_1,
1023  base_expr_type_2>::type base_expr_type;
1024 
1025  static const int num_args1 = ExprT1::num_args;
1026  static const int num_args2 = ExprT2::num_args;
1027  static const int num_args = num_args1 + num_args2;
1028 
1029  static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
1030 
1032  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1033  expr1(expr1_), expr2(expr2_) {}
1034 
1036  int size() const {
1037  int sz1 = expr1.size(), sz2 = expr2.size();
1038  return sz1 > sz2 ? sz1 : sz2;
1039  }
1040 
1041  template <int Arg>
1043  bool isActive() const {
1044  if (Arg < num_args1)
1045  return expr1.template isActive<Arg>();
1046  else
1047  return expr2.template isActive<Arg-num_args1>();
1048  }
1049 
1051  bool updateValue() const {
1052  return expr1.updateValue() && expr2.updateValue();
1053  }
1054 
1056  void cache() const {
1057  expr1.cache();
1058  expr2.cache();
1059  }
1060 
1062  value_type val() const {
1063  return expr1.val()-expr2.val();
1064  }
1065 
1067  void computePartials(const value_type& bar,
1068  value_type partials[]) const {
1069  if (num_args1 > 0)
1070  expr1.computePartials(bar, partials);
1071  if (num_args2 > 0)
1072  expr2.computePartials(-bar, partials+num_args1);
1073  }
1074 
1076  void getTangents(int i, value_type dots[]) const {
1077  expr1.getTangents(i, dots);
1078  expr2.getTangents(i, dots+num_args1);
1079  }
1080 
1081  template <int Arg>
1083  value_type getTangent(int i) const {
1084  if (Arg < num_args1)
1085  return expr1.template getTangent<Arg>(i);
1086  else
1087  return expr2.template getTangent<Arg-num_args1>(i);
1088  }
1089 
1091  bool isLinear() const {
1092  return expr1.isLinear() && expr2.isLinear();
1093  }
1094 
1096  bool hasFastAccess() const {
1097  return expr1.hasFastAccess() && expr2.hasFastAccess();
1098  }
1099 
1101  const value_type dx(int i) const {
1102  return expr1.dx(i) - expr2.dx(i);
1103  }
1104 
1106  const value_type fastAccessDx(int i) const {
1107  return expr1.fastAccessDx(i) - expr2.fastAccessDx(i);
1108  }
1109 
1111  const value_type* getDx(int j) const {
1112  if (j < num_args1)
1113  return expr1.getDx(j);
1114  else
1115  return expr2.getDx(j-num_args1);
1116  }
1117 
1118  protected:
1119 
1120  const ExprT1& expr1;
1121  const ExprT2& expr2;
1122 
1123  };
1124 
1125  template <typename ExprT1, typename T2>
1126  class Expr< SubtractionOp<ExprT1, ConstExpr<T2> > > {
1127 
1128  public:
1129 
1130  typedef ConstExpr<T2> ExprT2;
1131  typedef typename ExprT1::value_type value_type_1;
1132  typedef typename ExprT2::value_type value_type_2;
1133  typedef typename Sacado::Promote<value_type_1,
1134  value_type_2>::type value_type;
1135  typedef typename ExprT1::scalar_type scalar_type_1;
1136  typedef typename ExprT2::scalar_type scalar_type_2;
1137  typedef typename Sacado::Promote<scalar_type_1,
1138  scalar_type_2>::type scalar_type;
1139 
1140  typedef typename ExprT1::base_expr_type base_expr_type_1;
1141  typedef typename ExprT2::base_expr_type base_expr_type_2;
1142  typedef typename Sacado::Promote<base_expr_type_1,
1143  base_expr_type_2>::type base_expr_type;
1144 
1145  static const int num_args = ExprT1::num_args;
1146 
1147  static const bool is_linear = ExprT1::is_linear;
1148 
1150  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1151  expr1(expr1_), expr2(expr2_) {}
1152 
1154  int size() const {
1155  return expr1.size();
1156  }
1157 
1158  template <int Arg>
1160  bool isActive() const {
1161  return expr1.template isActive<Arg>();
1162  }
1163 
1165  bool updateValue() const {
1166  return expr1.updateValue();
1167  }
1168 
1170  void cache() const {
1171  expr1.cache();
1172  }
1173 
1175  value_type val() const {
1176  return expr1.val() - expr2.val();
1177  }
1178 
1180  void computePartials(const value_type& bar,
1181  value_type partials[]) const {
1182  expr1.computePartials(bar, partials);
1183  }
1184 
1186  void getTangents(int i, value_type dots[]) const {
1187  expr1.getTangents(i, dots);
1188  }
1189 
1190  template <int Arg>
1192  value_type getTangent(int i) const {
1193  return expr1.template getTangent<Arg>(i);
1194  }
1195 
1197  bool isLinear() const {
1198  return expr1.isLinear();
1199  }
1200 
1202  bool hasFastAccess() const {
1203  return expr1.hasFastAccess();
1204  }
1205 
1207  const value_type dx(int i) const {
1208  return expr1.dx(i);
1209  }
1210 
1212  const value_type fastAccessDx(int i) const {
1213  return expr1.fastAccessDx(i);
1214  }
1215 
1217  const value_type* getDx(int j) const {
1218  return expr1.getDx(j);
1219  }
1220 
1221  protected:
1222 
1223  const ExprT1& expr1;
1224  ExprT2 expr2;
1225 
1226  };
1227 
1228  template <typename T1, typename ExprT2>
1229  class Expr< SubtractionOp< ConstExpr<T1>,ExprT2> > {
1230 
1231  public:
1232 
1233  typedef ConstExpr<T1> ExprT1;
1234  typedef typename ExprT1::value_type value_type_1;
1235  typedef typename ExprT2::value_type value_type_2;
1236  typedef typename Sacado::Promote<value_type_1,
1237  value_type_2>::type value_type;
1238  typedef typename ExprT1::scalar_type scalar_type_1;
1239  typedef typename ExprT2::scalar_type scalar_type_2;
1240  typedef typename Sacado::Promote<scalar_type_1,
1241  scalar_type_2>::type scalar_type;
1242 
1243  typedef typename ExprT1::base_expr_type base_expr_type_1;
1244  typedef typename ExprT2::base_expr_type base_expr_type_2;
1245  typedef typename Sacado::Promote<base_expr_type_1,
1246  base_expr_type_2>::type base_expr_type;
1247 
1248  static const int num_args = ExprT2::num_args;
1249 
1250  static const bool is_linear = ExprT2::is_linear;
1251 
1253  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1254  expr1(expr1_), expr2(expr2_) {}
1255 
1257  int size() const {
1258  return expr2.size();
1259  }
1260 
1261  template <int Arg>
1263  bool isActive() const {
1264  return expr2.template isActive<Arg>();
1265  }
1266 
1268  bool updateValue() const {
1269  return expr2.updateValue();
1270  }
1271 
1273  void cache() const {
1274  expr2.cache();
1275  }
1276 
1278  value_type val() const {
1279  return expr1.val() - expr2.val();
1280  }
1281 
1283  void computePartials(const value_type& bar,
1284  value_type partials[]) const {
1285  expr2.computePartials(-bar, partials);
1286  }
1287 
1289  void getTangents(int i, value_type dots[]) const {
1290  expr2.getTangents(i, dots);
1291  }
1292 
1293  template <int Arg>
1295  value_type getTangent(int i) const {
1296  return expr2.template getTangent<Arg>(i);
1297  }
1298 
1300  bool isLinear() const {
1301  return expr2.isLinear();
1302  }
1303 
1305  bool hasFastAccess() const {
1306  return expr2.hasFastAccess();
1307  }
1308 
1310  const value_type dx(int i) const {
1311  return -expr2.dx(i);
1312  }
1313 
1315  const value_type fastAccessDx(int i) const {
1316  return -expr2.fastAccessDx(i);
1317  }
1318 
1320  const value_type* getDx(int j) const {
1321  return expr2.getDx(j);
1322  }
1323 
1324  protected:
1325 
1326  ExprT1 expr1;
1327  const ExprT2& expr2;
1328 
1329  };
1330 
1331  //
1332  // MultiplicationOp
1333  //
1334 
1335  template <typename ExprT1, typename ExprT2>
1336  class MultiplicationOp {};
1337 
1338  template <typename ExprT1, typename ExprT2>
1339  class Expr< MultiplicationOp<ExprT1,ExprT2> > {
1340 
1341  public:
1342 
1343  typedef typename ExprT1::value_type value_type_1;
1344  typedef typename ExprT2::value_type value_type_2;
1345  typedef typename Sacado::Promote<value_type_1,
1346  value_type_2>::type value_type;
1347  typedef typename ExprT1::scalar_type scalar_type_1;
1348  typedef typename ExprT2::scalar_type scalar_type_2;
1349  typedef typename Sacado::Promote<scalar_type_1,
1350  scalar_type_2>::type scalar_type;
1351 
1352  typedef typename ExprT1::base_expr_type base_expr_type_1;
1353  typedef typename ExprT2::base_expr_type base_expr_type_2;
1354  typedef typename Sacado::Promote<base_expr_type_1,
1355  base_expr_type_2>::type base_expr_type;
1356 
1357  static const int num_args1 = ExprT1::num_args;
1358  static const int num_args2 = ExprT2::num_args;
1359  static const int num_args = num_args1 + num_args2;
1360 
1361  static const bool is_linear = false;
1362 
1364  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1365  expr1(expr1_), expr2(expr2_) {}
1366 
1368  int size() const {
1369  int sz1 = expr1.size(), sz2 = expr2.size();
1370  return sz1 > sz2 ? sz1 : sz2;
1371  }
1372 
1373  template <int Arg>
1375  bool isActive() const {
1376  if (Arg < num_args1)
1377  return expr1.template isActive<Arg>();
1378  else
1379  return expr2.template isActive<Arg-num_args1>();
1380  }
1381 
1383  bool updateValue() const {
1384  return expr1.updateValue() && expr2.updateValue();
1385  }
1386 
1388  void cache() const {
1389  expr1.cache();
1390  expr2.cache();
1391  v1 = expr1.val();
1392  v2 = expr2.val();
1393  }
1394 
1396  value_type val() const {
1397  return v1*v2;
1398  }
1399 
1401  void computePartials(const value_type& bar,
1402  value_type partials[]) const {
1403  if (num_args1 > 0)
1404  expr1.computePartials(bar*v2, partials);
1405  if (num_args2 > 0)
1406  expr2.computePartials(bar*v1, partials+num_args1);
1407  }
1408 
1410  void getTangents(int i, value_type dots[]) const {
1411  expr1.getTangents(i, dots);
1412  expr2.getTangents(i, dots+num_args1);
1413  }
1414 
1415  template <int Arg>
1417  value_type getTangent(int i) const {
1418  if (Arg < num_args1)
1419  return expr1.template getTangent<Arg>(i);
1420  else
1421  return expr2.template getTangent<Arg-num_args1>(i);
1422  }
1423 
1425  bool isLinear() const {
1426  return false;
1427  }
1428 
1430  bool hasFastAccess() const {
1431  return expr1.hasFastAccess() && expr2.hasFastAccess();
1432  }
1433 
1435  const value_type dx(int i) const {
1436  if (expr1.size() > 0 && expr2.size() > 0)
1437  return v1*expr2.dx(i) + expr1.dx(i)*v2;
1438  else if (expr1.size() > 0)
1439  return expr1.dx(i)*v2;
1440  else
1441  return v1*expr2.dx(i);
1442  }
1443 
1445  const value_type fastAccessDx(int i) const {
1446  return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
1447  }
1448 
1450  const value_type* getDx(int j) const {
1451  if (j < num_args1)
1452  return expr1.getDx(j);
1453  else
1454  return expr2.getDx(j-num_args1);
1455  }
1456 
1457  protected:
1458 
1459  const ExprT1& expr1;
1460  const ExprT2& expr2;
1461  mutable value_type_1 v1;
1462  mutable value_type_2 v2;
1463 
1464  };
1465 
1466  template <typename ExprT1, typename T2>
1467  class Expr< MultiplicationOp<ExprT1, ConstExpr<T2> > > {
1468 
1469  public:
1470 
1471  typedef ConstExpr<T2> ExprT2;
1472  typedef typename ExprT1::value_type value_type_1;
1473  typedef typename ExprT2::value_type value_type_2;
1474  typedef typename Sacado::Promote<value_type_1,
1475  value_type_2>::type value_type;
1476  typedef typename ExprT1::scalar_type scalar_type_1;
1477  typedef typename ExprT2::scalar_type scalar_type_2;
1478  typedef typename Sacado::Promote<scalar_type_1,
1479  scalar_type_2>::type scalar_type;
1480 
1481  typedef typename ExprT1::base_expr_type base_expr_type_1;
1482  typedef typename ExprT2::base_expr_type base_expr_type_2;
1483  typedef typename Sacado::Promote<base_expr_type_1,
1484  base_expr_type_2>::type base_expr_type;
1485 
1486  static const int num_args = ExprT1::num_args;
1487 
1488  static const bool is_linear = ExprT1::is_linear;
1489 
1491  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1492  expr1(expr1_), expr2(expr2_) {}
1493 
1495  int size() const {
1496  return expr1.size();
1497  }
1498 
1499  template <int Arg>
1501  bool isActive() const {
1502  return expr1.template isActive<Arg>();
1503  }
1504 
1506  bool updateValue() const {
1507  return expr1.updateValue();
1508  }
1509 
1511  void cache() const {
1512  expr1.cache();
1513  }
1514 
1516  value_type val() const {
1517  return expr1.val()*expr2.val();
1518  }
1519 
1521  void computePartials(const value_type& bar,
1522  value_type partials[]) const {
1523  expr1.computePartials(bar*expr2.val(), partials);
1524  }
1525 
1527  void getTangents(int i, value_type dots[]) const {
1528  expr1.getTangents(i, dots);
1529  }
1530 
1531  template <int Arg>
1533  value_type getTangent(int i) const {
1534  return expr1.template getTangent<Arg>(i);
1535  }
1536 
1538  bool isLinear() const {
1539  return expr1.isLinear();
1540  }
1541 
1543  bool hasFastAccess() const {
1544  return expr1.hasFastAccess();
1545  }
1546 
1548  const value_type dx(int i) const {
1549  return expr1.dx(i)*expr2.val();
1550  }
1551 
1553  const value_type fastAccessDx(int i) const {
1554  return expr1.fastAccessDx(i)*expr2.val();
1555  }
1556 
1558  const value_type* getDx(int j) const {
1559  return expr1.getDx(j);
1560  }
1561 
1562  protected:
1563 
1564  const ExprT1& expr1;
1565  ExprT2 expr2;
1566 
1567  };
1568 
1569  template <typename T1, typename ExprT2>
1570  class Expr< MultiplicationOp< ConstExpr<T1>,ExprT2> > {
1571 
1572  public:
1573 
1574  typedef ConstExpr<T1> ExprT1;
1575  typedef typename ExprT1::value_type value_type_1;
1576  typedef typename ExprT2::value_type value_type_2;
1577  typedef typename Sacado::Promote<value_type_1,
1578  value_type_2>::type value_type;
1579  typedef typename ExprT1::scalar_type scalar_type_1;
1580  typedef typename ExprT2::scalar_type scalar_type_2;
1581  typedef typename Sacado::Promote<scalar_type_1,
1582  scalar_type_2>::type scalar_type;
1583 
1584  typedef typename ExprT1::base_expr_type base_expr_type_1;
1585  typedef typename ExprT2::base_expr_type base_expr_type_2;
1586  typedef typename Sacado::Promote<base_expr_type_1,
1587  base_expr_type_2>::type base_expr_type;
1588 
1589  static const int num_args = ExprT2::num_args;
1590 
1591  static const bool is_linear = ExprT2::is_linear;
1592 
1594  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1595  expr1(expr1_), expr2(expr2_) {}
1596 
1598  int size() const {
1599  return expr2.size();
1600  }
1601 
1602  template <int Arg>
1604  bool isActive() const {
1605  return expr2.template isActive<Arg>();
1606  }
1607 
1609  bool updateValue() const {
1610  return expr2.updateValue();
1611  }
1612 
1614  void cache() const {
1615  expr2.cache();
1616  }
1617 
1619  value_type val() const {
1620  return expr1.val()*expr2.val();
1621  }
1622 
1624  void computePartials(const value_type& bar,
1625  value_type partials[]) const {
1626  expr2.computePartials(bar*expr1.val(), partials);
1627  }
1628 
1630  void getTangents(int i, value_type dots[]) const {
1631  expr2.getTangents(i, dots);
1632  }
1633 
1634  template <int Arg>
1636  value_type getTangent(int i) const {
1637  return expr2.template getTangent<Arg>(i);
1638  }
1639 
1641  bool isLinear() const {
1642  return expr2.isLinear();
1643  }
1644 
1646  bool hasFastAccess() const {
1647  return expr2.hasFastAccess();
1648  }
1649 
1651  const value_type dx(int i) const {
1652  return expr1.val()*expr2.dx(i);
1653  }
1654 
1656  const value_type fastAccessDx(int i) const {
1657  return expr1.val()*expr2.fastAccessDx(i);
1658  }
1659 
1661  const value_type* getDx(int j) const {
1662  return expr2.getDx(j);
1663  }
1664 
1665  protected:
1666 
1667  ExprT1 expr1;
1668  const ExprT2& expr2;
1669 
1670  };
1671 
1672  //
1673  // DivisionOp
1674  //
1675 
1676  template <typename ExprT1, typename ExprT2>
1677  class DivisionOp {};
1678 
1679  template <typename ExprT1, typename ExprT2>
1680  class Expr< DivisionOp<ExprT1,ExprT2> > {
1681 
1682  public:
1683 
1684  typedef typename ExprT1::value_type value_type_1;
1685  typedef typename ExprT2::value_type value_type_2;
1686  typedef typename Sacado::Promote<value_type_1,
1687  value_type_2>::type value_type;
1688  typedef typename ExprT1::scalar_type scalar_type_1;
1689  typedef typename ExprT2::scalar_type scalar_type_2;
1690  typedef typename Sacado::Promote<scalar_type_1,
1691  scalar_type_2>::type scalar_type;
1692 
1693  typedef typename ExprT1::base_expr_type base_expr_type_1;
1694  typedef typename ExprT2::base_expr_type base_expr_type_2;
1695  typedef typename Sacado::Promote<base_expr_type_1,
1696  base_expr_type_2>::type base_expr_type;
1697 
1698  static const int num_args1 = ExprT1::num_args;
1699  static const int num_args2 = ExprT2::num_args;
1700  static const int num_args = num_args1 + num_args2;
1701 
1702  static const bool is_linear = false;
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 
1714  template <int Arg>
1716  bool isActive() const {
1717  if (Arg < num_args1)
1718  return expr1.template isActive<Arg>();
1719  else
1720  return expr2.template isActive<Arg-num_args1>();
1721  }
1722 
1724  bool updateValue() const {
1725  return expr1.updateValue() && expr2.updateValue();
1726  }
1727 
1729  void cache() const {
1730  expr1.cache();
1731  expr2.cache();
1732  const value_type_1 v1 = expr1.val();
1733  const value_type_2 v2 = expr2.val();
1734  a = scalar_type(1.0)/v2;
1735  v = v1*a;
1736  b = -v/v2;
1737  }
1738 
1740  value_type val() const {
1741  return v;
1742  }
1743 
1745  void computePartials(const value_type& bar,
1746  value_type partials[]) const {
1747  if (num_args1 > 0)
1748  expr1.computePartials(bar*a, partials);
1749  if (num_args2 > 0)
1750  expr2.computePartials(bar*b, partials+num_args1);
1751  }
1752 
1754  void getTangents(int i, value_type dots[]) const {
1755  expr1.getTangents(i, dots);
1756  expr2.getTangents(i, dots+num_args1);
1757  }
1758 
1759  template <int Arg>
1761  value_type getTangent(int i) const {
1762  if (Arg < num_args1)
1763  return expr1.template getTangent<Arg>(i);
1764  else
1765  return expr2.template getTangent<Arg-num_args1>(i);
1766  }
1767 
1769  bool isLinear() const {
1770  return false;
1771  }
1772 
1774  bool hasFastAccess() const {
1775  return expr1.hasFastAccess() && expr2.hasFastAccess();
1776  }
1777 
1779  const value_type dx(int i) const {
1780  if (expr1.size() > 0 && expr2.size() > 0)
1781  return expr1.dx(i)*a + expr2.dx(i)*b;
1782  else if (expr1.size() > 0)
1783  return expr1.dx(i)*a;
1784  else
1785  return expr1.val()*b;
1786  }
1787 
1789  const value_type fastAccessDx(int i) const {
1790  return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1791  }
1792 
1794  const value_type* getDx(int j) const {
1795  if (j < num_args1)
1796  return expr1.getDx(j);
1797  else
1798  return expr2.getDx(j-num_args1);
1799  }
1800 
1801  protected:
1802 
1803  const ExprT1& expr1;
1804  const ExprT2& expr2;
1805  mutable value_type v;
1806  mutable value_type a;
1807  mutable value_type b;
1808 
1809  };
1810 
1811  template <typename ExprT1, typename T2>
1812  class Expr< DivisionOp<ExprT1, ConstExpr<T2> > > {
1813 
1814  public:
1815 
1816  typedef ConstExpr<T2> ExprT2;
1817  typedef typename ExprT1::value_type value_type_1;
1818  typedef typename ExprT2::value_type value_type_2;
1819  typedef typename Sacado::Promote<value_type_1,
1820  value_type_2>::type value_type;
1821  typedef typename ExprT1::scalar_type scalar_type_1;
1822  typedef typename ExprT2::scalar_type scalar_type_2;
1823  typedef typename Sacado::Promote<scalar_type_1,
1824  scalar_type_2>::type scalar_type;
1825 
1826  typedef typename ExprT1::base_expr_type base_expr_type_1;
1827  typedef typename ExprT2::base_expr_type base_expr_type_2;
1828  typedef typename Sacado::Promote<base_expr_type_1,
1829  base_expr_type_2>::type base_expr_type;
1830 
1831  static const int num_args = ExprT1::num_args;
1832 
1833  static const bool is_linear = ExprT1::is_linear;
1834 
1836  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1837  expr1(expr1_), expr2(expr2_) {}
1838 
1840  int size() const {
1841  return expr1.size();
1842  }
1843 
1844  template <int Arg>
1846  bool isActive() const {
1847  return expr1.template isActive<Arg>();
1848  }
1849 
1851  bool updateValue() const {
1852  return expr1.updateValue();
1853  }
1854 
1856  void cache() const {
1857  expr1.cache();
1858  const value_type_1 v1 = expr1.val();
1859  a = scalar_type(1.0)/expr2.val();
1860  v = v1*a;
1861  }
1862 
1864  value_type val() const {
1865  return v;
1866  }
1867 
1869  void computePartials(const value_type& bar,
1870  value_type partials[]) const {
1871  expr1.computePartials(bar*a, partials);
1872  }
1873 
1875  void getTangents(int i, value_type dots[]) const {
1876  expr1.getTangents(i, dots);
1877  }
1878 
1879  template <int Arg>
1881  value_type getTangent(int i) const {
1882  return expr1.template getTangent<Arg>(i);
1883  }
1884 
1886  bool isLinear() const {
1887  return expr1.isLinear();
1888  }
1889 
1891  bool hasFastAccess() const {
1892  return expr1.hasFastAccess();
1893  }
1894 
1896  const value_type dx(int i) const {
1897  return expr1.dx(i)*a;
1898  }
1899 
1901  const value_type fastAccessDx(int i) const {
1902  return expr1.fastAccessDx(i)*a;
1903  }
1904 
1906  const value_type* getDx(int j) const {
1907  return expr1.getDx(j);
1908  }
1909 
1910  protected:
1911 
1912  const ExprT1& expr1;
1913  ExprT2 expr2;
1914  mutable value_type v;
1915  mutable value_type a;
1916 
1917  };
1918 
1919  template <typename T1, typename ExprT2>
1920  class Expr< DivisionOp< ConstExpr<T1>,ExprT2> > {
1921 
1922  public:
1923 
1924  typedef ConstExpr<T1> ExprT1;
1925  typedef typename ExprT1::value_type value_type_1;
1926  typedef typename ExprT2::value_type value_type_2;
1927  typedef typename Sacado::Promote<value_type_1,
1928  value_type_2>::type value_type;
1929  typedef typename ExprT1::scalar_type scalar_type_1;
1930  typedef typename ExprT2::scalar_type scalar_type_2;
1931  typedef typename Sacado::Promote<scalar_type_1,
1932  scalar_type_2>::type scalar_type;
1933 
1934  typedef typename ExprT1::base_expr_type base_expr_type_1;
1935  typedef typename ExprT2::base_expr_type base_expr_type_2;
1936  typedef typename Sacado::Promote<base_expr_type_1,
1937  base_expr_type_2>::type base_expr_type;
1938 
1939  static const int num_args = ExprT2::num_args;
1940 
1941  static const bool is_linear = false;
1942 
1944  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1945  expr1(expr1_), expr2(expr2_) {}
1946 
1948  int size() const {
1949  return expr2.size();
1950  }
1951 
1952  template <int Arg>
1954  bool isActive() const {
1955  return expr2.template isActive<Arg>();
1956  }
1957 
1959  bool updateValue() const {
1960  return expr2.updateValue();
1961  }
1962 
1964  void cache() const {
1965  expr2.cache();
1966  const value_type_2 v2 = expr2.val();
1967  v = expr1.val()/v2;
1968  b = -v/v2;
1969  }
1970 
1972  value_type val() const {
1973  return v;
1974  }
1975 
1977  void computePartials(const value_type& bar,
1978  value_type partials[]) const {
1979  expr2.computePartials(bar*b, partials);
1980  }
1981 
1983  void getTangents(int i, value_type dots[]) const {
1984  expr2.getTangents(i, dots);
1985  }
1986 
1987  template <int Arg>
1989  value_type getTangent(int i) const {
1990  return expr2.template getTangent<Arg>(i);
1991  }
1992 
1994  bool isLinear() const {
1995  return false;
1996  }
1997 
1999  bool hasFastAccess() const {
2000  return expr2.hasFastAccess();
2001  }
2002 
2004  const value_type dx(int i) const {
2005  return expr2.dx(i)*b;
2006  }
2007 
2009  const value_type fastAccessDx(int i) const {
2010  return expr2.fastAccessDx(i)*b;
2011  }
2012 
2014  const value_type* getDx(int j) const {
2015  return expr2.getDx(j);
2016  }
2017 
2018  protected:
2019 
2020  ExprT1 expr1;
2021  const ExprT2& expr2;
2022  mutable value_type v;
2023  mutable value_type b;
2024 
2025  };
2026 
2027  //
2028  // Atan2Op
2029  //
2030 
2031  template <typename ExprT1, typename ExprT2>
2032  class Atan2Op {};
2033 
2034  template <typename ExprT1, typename ExprT2>
2035  class Expr< Atan2Op<ExprT1,ExprT2> > {
2036 
2037  public:
2038 
2039  typedef typename ExprT1::value_type value_type_1;
2040  typedef typename ExprT2::value_type value_type_2;
2041  typedef typename Sacado::Promote<value_type_1,
2042  value_type_2>::type value_type;
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 
2053  static const int num_args1 = ExprT1::num_args;
2054  static const int num_args2 = ExprT2::num_args;
2055  static const int num_args = num_args1 + num_args2;
2056 
2057  static const bool is_linear = false;
2058 
2060  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2061  expr1(expr1_), expr2(expr2_) {}
2062 
2064  int size() const {
2065  int sz1 = expr1.size(), sz2 = expr2.size();
2066  return sz1 > sz2 ? sz1 : sz2;
2067  }
2068 
2069  template <int Arg>
2071  bool isActive() const {
2072  if (Arg < num_args1)
2073  return expr1.template isActive<Arg>();
2074  else
2075  return expr2.template isActive<Arg-num_args1>();
2076  }
2077 
2079  bool updateValue() const {
2080  return expr1.updateValue() && expr2.updateValue();
2081  }
2082 
2084  void cache() const {
2085  expr1.cache();
2086  expr2.cache();
2087  const value_type_1 v1 = expr1.val();
2088  const value_type_2 v2 = expr2.val();
2089  a = scalar_type(1.0)/(v1*v1 + v2*v2);
2090  b = -v1*a;
2091  a = v2*a;
2092  v = std::atan2(v1,v2);
2093  }
2094 
2096  value_type val() const {
2097  return v;
2098  }
2099 
2101  void computePartials(const value_type& bar,
2102  value_type partials[]) const {
2103  if (num_args1 > 0)
2104  expr1.computePartials(bar*a, partials);
2105  if (num_args2 > 0)
2106  expr2.computePartials(bar*b, partials+num_args1);
2107  }
2108 
2110  void getTangents(int i, value_type dots[]) const {
2111  expr1.getTangents(i, dots);
2112  expr2.getTangents(i, dots+num_args1);
2113  }
2114 
2115  template <int Arg>
2117  value_type getTangent(int i) const {
2118  if (Arg < num_args1)
2119  return expr1.template getTangent<Arg>(i);
2120  else
2121  return expr2.template getTangent<Arg-num_args1>(i);
2122  }
2123 
2125  bool isLinear() const {
2126  return false;
2127  }
2128 
2130  bool hasFastAccess() const {
2131  return expr1.hasFastAccess() && expr2.hasFastAccess();
2132  }
2133 
2135  const value_type dx(int i) const {
2136  if (expr1.size() > 0 && expr2.size() > 0)
2137  return expr1.dx(i)*a + expr2.dx(i)*b;
2138  else if (expr1.size() > 0)
2139  return expr1.dx(i)*a;
2140  else
2141  return expr1.val()*b;
2142  }
2143 
2145  const value_type fastAccessDx(int i) const {
2146  return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
2147  }
2148 
2150  const value_type* getDx(int j) const {
2151  if (j < num_args1)
2152  return expr1.getDx(j);
2153  else
2154  return expr2.getDx(j-num_args1);
2155  }
2156 
2157  protected:
2158 
2159  const ExprT1& expr1;
2160  const ExprT2& expr2;
2161  mutable value_type v;
2162  mutable value_type a;
2163  mutable value_type b;
2164 
2165  };
2166 
2167  template <typename ExprT1, typename T2>
2168  class Expr< Atan2Op<ExprT1, ConstExpr<T2> > > {
2169 
2170  public:
2171 
2172  typedef ConstExpr<T2> ExprT2;
2173  typedef typename ExprT1::value_type value_type_1;
2174  typedef typename ExprT2::value_type value_type_2;
2175  typedef typename Sacado::Promote<value_type_1,
2176  value_type_2>::type value_type;
2177  typedef typename ExprT1::scalar_type scalar_type_1;
2178  typedef typename ExprT2::scalar_type scalar_type_2;
2179  typedef typename Sacado::Promote<scalar_type_1,
2180  scalar_type_2>::type scalar_type;
2181 
2182  typedef typename ExprT1::base_expr_type base_expr_type_1;
2183  typedef typename ExprT2::base_expr_type base_expr_type_2;
2184  typedef typename Sacado::Promote<base_expr_type_1,
2185  base_expr_type_2>::type base_expr_type;
2186 
2187  static const int num_args = ExprT1::num_args;
2188 
2189  static const bool is_linear = false;
2190 
2192  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2193  expr1(expr1_), expr2(expr2_) {}
2194 
2196  int size() const {
2197  return expr1.size();
2198  }
2199 
2200  template <int Arg>
2202  bool isActive() const {
2203  return expr1.template isActive<Arg>();
2204  }
2205 
2207  bool updateValue() const {
2208  return expr1.updateValue();
2209  }
2210 
2212  void cache() const {
2213  expr1.cache();
2214  const value_type_1 v1 = expr1.val();
2215  const value_type_2 v2 = expr2.val();
2216  a = v2/(v1*v1 + v2*v2);
2217  v = std::atan2(v1,v2);
2218  }
2219 
2221  value_type val() const {
2222  return v;
2223  }
2224 
2226  void computePartials(const value_type& bar,
2227  value_type partials[]) const {
2228  expr1.computePartials(bar*a, partials);
2229  }
2230 
2232  void getTangents(int i, value_type dots[]) const {
2233  expr1.getTangents(i, dots);
2234  }
2235 
2236  template <int Arg>
2238  value_type getTangent(int i) const {
2239  return expr1.template getTangent<Arg>(i);
2240  }
2241 
2243  bool isLinear() const {
2244  return false;
2245  }
2246 
2248  bool hasFastAccess() const {
2249  return expr1.hasFastAccess();
2250  }
2251 
2253  const value_type dx(int i) const {
2254  return expr1.dx(i)*a;
2255  }
2256 
2258  const value_type fastAccessDx(int i) const {
2259  return expr1.fastAccessDx(i)*a;
2260  }
2261 
2263  const value_type* getDx(int j) const {
2264  return expr1.getDx(j);
2265  }
2266 
2267  protected:
2268 
2269  const ExprT1& expr1;
2270  ExprT2 expr2;
2271  mutable value_type v;
2272  mutable value_type a;
2273 
2274  };
2275 
2276  template <typename T1, typename ExprT2>
2277  class Expr< Atan2Op< ConstExpr<T1>,ExprT2> > {
2278 
2279  public:
2280 
2281  typedef ConstExpr<T1> ExprT1;
2282  typedef typename ExprT1::value_type value_type_1;
2283  typedef typename ExprT2::value_type value_type_2;
2284  typedef typename Sacado::Promote<value_type_1,
2285  value_type_2>::type value_type;
2286  typedef typename ExprT1::scalar_type scalar_type_1;
2287  typedef typename ExprT2::scalar_type scalar_type_2;
2288  typedef typename Sacado::Promote<scalar_type_1,
2289  scalar_type_2>::type scalar_type;
2290 
2291  typedef typename ExprT1::base_expr_type base_expr_type_1;
2292  typedef typename ExprT2::base_expr_type base_expr_type_2;
2293  typedef typename Sacado::Promote<base_expr_type_1,
2294  base_expr_type_2>::type base_expr_type;
2295 
2296  static const int num_args = ExprT2::num_args;
2297 
2298  static const bool is_linear = false;
2299 
2301  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2302  expr1(expr1_), expr2(expr2_) {}
2303 
2305  int size() const {
2306  return expr2.size();
2307  }
2308 
2309  template <int Arg>
2311  bool isActive() const {
2312  return expr2.template isActive<Arg>();
2313  }
2314 
2316  bool updateValue() const {
2317  return expr2.updateValue();
2318  }
2319 
2321  void cache() const {
2322  expr2.cache();
2323  const value_type_1 v1 = expr1.val();
2324  const value_type_2 v2 = expr2.val();
2325  b = -v1/(v1*v1 + v2*v2);
2326  v = std::atan2(v1,v2);
2327  }
2328 
2330  value_type val() const {
2331  return v;
2332  }
2333 
2335  void computePartials(const value_type& bar,
2336  value_type partials[]) const {
2337  expr2.computePartials(bar*b, partials);
2338  }
2339 
2341  void getTangents(int i, value_type dots[]) const {
2342  expr2.getTangents(i, dots);
2343  }
2344 
2345  template <int Arg>
2347  value_type getTangent(int i) const {
2348  return expr2.template getTangent<Arg>(i);
2349  }
2350 
2352  bool isLinear() const {
2353  return false;
2354  }
2355 
2357  bool hasFastAccess() const {
2358  return expr2.hasFastAccess();
2359  }
2360 
2362  const value_type dx(int i) const {
2363  return expr2.dx(i)*b;
2364  }
2365 
2367  const value_type fastAccessDx(int i) const {
2368  return expr2.fastAccessDx(i)*b;
2369  }
2370 
2372  const value_type* getDx(int j) const {
2373  return expr2.getDx(j);
2374  }
2375 
2376  protected:
2377 
2378  ExprT1 expr1;
2379  const ExprT2& expr2;
2380  mutable value_type v;
2381  mutable value_type b;
2382 
2383  };
2384 
2385  //
2386  // PowerOp
2387  //
2388 
2389  template <typename ExprT1, typename ExprT2>
2390  class PowerOp {};
2391 
2392  template <typename ExprT1, typename ExprT2>
2393  class Expr< PowerOp<ExprT1,ExprT2> > {
2394 
2395  public:
2396 
2397  typedef typename ExprT1::value_type value_type_1;
2398  typedef typename ExprT2::value_type value_type_2;
2399  typedef typename Sacado::Promote<value_type_1,
2400  value_type_2>::type value_type;
2401  typedef typename ExprT1::scalar_type scalar_type_1;
2402  typedef typename ExprT2::scalar_type scalar_type_2;
2403  typedef typename Sacado::Promote<scalar_type_1,
2404  scalar_type_2>::type scalar_type;
2405 
2406  typedef typename ExprT1::base_expr_type base_expr_type_1;
2407  typedef typename ExprT2::base_expr_type base_expr_type_2;
2408  typedef typename Sacado::Promote<base_expr_type_1,
2409  base_expr_type_2>::type base_expr_type;
2410 
2411  static const int num_args1 = ExprT1::num_args;
2412  static const int num_args2 = ExprT2::num_args;
2413  static const int num_args = num_args1 + num_args2;
2414 
2415  static const bool is_linear = false;
2416 
2418  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2419  expr1(expr1_), expr2(expr2_) {}
2420 
2422  int size() const {
2423  int sz1 = expr1.size(), sz2 = expr2.size();
2424  return sz1 > sz2 ? sz1 : sz2;
2425  }
2426 
2427  template <int Arg>
2429  bool isActive() const {
2430  if (Arg < num_args1)
2431  return expr1.template isActive<Arg>();
2432  else
2433  return expr2.template isActive<Arg-num_args1>();
2434  }
2435 
2437  bool updateValue() const {
2438  return expr1.updateValue() && expr2.updateValue();
2439  }
2440 
2442  void cache() const {
2443  expr1.cache();
2444  expr2.cache();
2445  const value_type_1 v1 = expr1.val();
2446  const value_type_2 v2 = expr2.val();
2447  v = std::pow(v1,v2);
2448  if (v1 == scalar_type(0.0)) {
2449  a = scalar_type(0.0);
2450  b = scalar_type(0.0);
2451  }
2452  else {
2453  a = v*v2/v1;
2454  b = v*std::log(v1);
2455  }
2456  }
2457 
2459  value_type val() const {
2460  return v;
2461  }
2462 
2464  void computePartials(const value_type& bar,
2465  value_type partials[]) const {
2466  if (num_args1 > 0)
2467  expr1.computePartials(bar*a, partials);
2468  if (num_args2 > 0)
2469  expr2.computePartials(bar*b, partials+num_args1);
2470  }
2471 
2473  void getTangents(int i, value_type dots[]) const {
2474  expr1.getTangents(i, dots);
2475  expr2.getTangents(i, dots+num_args1);
2476  }
2477 
2478  template <int Arg>
2480  value_type getTangent(int i) const {
2481  if (Arg < num_args1)
2482  return expr1.template getTangent<Arg>(i);
2483  else
2484  return expr2.template getTangent<Arg-num_args1>(i);
2485  }
2486 
2488  bool isLinear() const {
2489  return false;
2490  }
2491 
2493  bool hasFastAccess() const {
2494  return expr1.hasFastAccess() && expr2.hasFastAccess();
2495  }
2496 
2498  const value_type dx(int i) const {
2499  if (expr1.size() > 0 && expr2.size() > 0)
2500  return expr1.dx(i)*a + expr2.dx(i)*b;
2501  else if (expr1.size() > 0)
2502  return expr1.dx(i)*a;
2503  else
2504  return expr1.val()*b;
2505  }
2506 
2508  const value_type fastAccessDx(int i) const {
2509  return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
2510  }
2511 
2513  const value_type* getDx(int j) const {
2514  if (j < num_args1)
2515  return expr1.getDx(j);
2516  else
2517  return expr2.getDx(j-num_args1);
2518  }
2519 
2520  protected:
2521 
2522  const ExprT1& expr1;
2523  const ExprT2& expr2;
2524  mutable value_type v;
2525  mutable value_type a;
2526  mutable value_type b;
2527 
2528  };
2529 
2530  template <typename ExprT1, typename T2>
2531  class Expr< PowerOp<ExprT1, ConstExpr<T2> > > {
2532 
2533  public:
2534 
2535  typedef ConstExpr<T2> ExprT2;
2536  typedef typename ExprT1::value_type value_type_1;
2537  typedef typename ExprT2::value_type value_type_2;
2538  typedef typename Sacado::Promote<value_type_1,
2539  value_type_2>::type value_type;
2540  typedef typename ExprT1::scalar_type scalar_type_1;
2541  typedef typename ExprT2::scalar_type scalar_type_2;
2542  typedef typename Sacado::Promote<scalar_type_1,
2543  scalar_type_2>::type scalar_type;
2544 
2545  typedef typename ExprT1::base_expr_type base_expr_type_1;
2546  typedef typename ExprT2::base_expr_type base_expr_type_2;
2547  typedef typename Sacado::Promote<base_expr_type_1,
2548  base_expr_type_2>::type base_expr_type;
2549 
2550  static const int num_args = ExprT1::num_args;
2551 
2552  static const bool is_linear = false;
2553 
2555  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2556  expr1(expr1_), expr2(expr2_) {}
2557 
2559  int size() const {
2560  return expr1.size();
2561  }
2562 
2563  template <int Arg>
2565  bool isActive() const {
2566  return expr1.template isActive<Arg>();
2567  }
2568 
2570  bool updateValue() const {
2571  return expr1.updateValue();
2572  }
2573 
2575  void cache() const {
2576  expr1.cache();
2577  const value_type_1 v1 = expr1.val();
2578  const value_type_2 v2 = expr2.val();
2579  v = std::pow(v1,v2);
2580  if (v1 == scalar_type(0.0)) {
2581  a = scalar_type(0.0);
2582  }
2583  else {
2584  a = v*v2/v1;
2585  }
2586  }
2587 
2589  value_type val() const {
2590  return v;
2591  }
2592 
2594  void computePartials(const value_type& bar,
2595  value_type partials[]) const {
2596  expr1.computePartials(bar*a, partials);
2597  }
2598 
2600  void getTangents(int i, value_type dots[]) const {
2601  expr1.getTangents(i, dots);
2602  }
2603 
2604  template <int Arg>
2606  value_type getTangent(int i) const {
2607  return expr1.template getTangent<Arg>(i);
2608  }
2609 
2611  bool isLinear() const {
2612  return false;
2613  }
2614 
2616  bool hasFastAccess() const {
2617  return expr1.hasFastAccess();
2618  }
2619 
2621  const value_type dx(int i) const {
2622  return expr1.dx(i)*a;
2623  }
2624 
2626  const value_type fastAccessDx(int i) const {
2627  return expr1.fastAccessDx(i)*a;
2628  }
2629 
2631  const value_type* getDx(int j) const {
2632  return expr1.getDx(j);
2633  }
2634 
2635  protected:
2636 
2637  const ExprT1& expr1;
2638  ExprT2 expr2;
2639  mutable value_type v;
2640  mutable value_type a;
2641 
2642  };
2643 
2644  template <typename T1, typename ExprT2>
2645  class Expr< PowerOp< ConstExpr<T1>,ExprT2> > {
2646 
2647  public:
2648 
2649  typedef ConstExpr<T1> ExprT1;
2650  typedef typename ExprT1::value_type value_type_1;
2651  typedef typename ExprT2::value_type value_type_2;
2652  typedef typename Sacado::Promote<value_type_1,
2653  value_type_2>::type value_type;
2654  typedef typename ExprT1::scalar_type scalar_type_1;
2655  typedef typename ExprT2::scalar_type scalar_type_2;
2656  typedef typename Sacado::Promote<scalar_type_1,
2657  scalar_type_2>::type scalar_type;
2658 
2659  typedef typename ExprT1::base_expr_type base_expr_type_1;
2660  typedef typename ExprT2::base_expr_type base_expr_type_2;
2661  typedef typename Sacado::Promote<base_expr_type_1,
2662  base_expr_type_2>::type base_expr_type;
2663 
2664  static const int num_args = ExprT2::num_args;
2665 
2666  static const bool is_linear = false;
2667 
2669  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2670  expr1(expr1_), expr2(expr2_) {}
2671 
2673  int size() const {
2674  return expr2.size();
2675  }
2676 
2677  template <int Arg>
2679  bool isActive() const {
2680  return expr2.template isActive<Arg>();
2681  }
2682 
2684  bool updateValue() const {
2685  return expr2.updateValue();
2686  }
2687 
2689  void cache() const {
2690  expr2.cache();
2691  const value_type_1 v1 = expr1.val();
2692  const value_type_2 v2 = expr2.val();
2693  v = std::pow(v1,v2);
2694  if (v1 == scalar_type(0.0)) {
2695  b = scalar_type(0.0);
2696  }
2697  else {
2698  b = v*std::log(v1);
2699  }
2700  }
2701 
2703  value_type val() const {
2704  return v;
2705  }
2706 
2708  void computePartials(const value_type& bar,
2709  value_type partials[]) const {
2710  expr2.computePartials(bar*b, partials);
2711  }
2712 
2714  void getTangents(int i, value_type dots[]) const {
2715  expr2.getTangents(i, dots);
2716  }
2717 
2718  template <int Arg>
2720  value_type getTangent(int i) const {
2721  return expr2.template getTangent<Arg>(i);
2722  }
2723 
2725  bool isLinear() const {
2726  return false;
2727  }
2728 
2730  bool hasFastAccess() const {
2731  return expr2.hasFastAccess();
2732  }
2733 
2735  const value_type dx(int i) const {
2736  return expr2.dx(i)*b;
2737  }
2738 
2740  const value_type fastAccessDx(int i) const {
2741  return expr2.fastAccessDx(i)*b;
2742  }
2743 
2745  const value_type* getDx(int j) const {
2746  return expr2.getDx(j);
2747  }
2748 
2749  protected:
2750 
2751  ExprT1 expr1;
2752  const ExprT2& expr2;
2753  mutable value_type v;
2754  mutable value_type b;
2755 
2756  };
2757 
2758  //
2759  // MaxOp
2760  //
2761 
2762  template <typename ExprT1, typename ExprT2>
2763  class MaxOp {};
2764 
2765  template <typename ExprT1, typename ExprT2>
2766  class Expr< MaxOp<ExprT1,ExprT2> > {
2767 
2768  public:
2769 
2770  typedef typename ExprT1::value_type value_type_1;
2771  typedef typename ExprT2::value_type value_type_2;
2772  typedef typename Sacado::Promote<value_type_1,
2773  value_type_2>::type value_type;
2774  typedef typename ExprT1::scalar_type scalar_type_1;
2775  typedef typename ExprT2::scalar_type scalar_type_2;
2776  typedef typename Sacado::Promote<scalar_type_1,
2777  scalar_type_2>::type scalar_type;
2778 
2779  typedef typename ExprT1::base_expr_type base_expr_type_1;
2780  typedef typename ExprT2::base_expr_type base_expr_type_2;
2781  typedef typename Sacado::Promote<base_expr_type_1,
2782  base_expr_type_2>::type base_expr_type;
2783 
2784  static const int num_args1 = ExprT1::num_args;
2785  static const int num_args2 = ExprT2::num_args;
2786  static const int num_args = num_args1 + num_args2;
2787 
2788  static const bool is_linear = false;
2789 
2791  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2792  expr1(expr1_), expr2(expr2_) {}
2793 
2795  int size() const {
2796  int sz1 = expr1.size(), sz2 = expr2.size();
2797  return sz1 > sz2 ? sz1 : sz2;
2798  }
2799 
2800  template <int Arg>
2802  bool isActive() const {
2803  if (Arg < num_args1)
2804  return expr1.template isActive<Arg>();
2805  else
2806  return expr2.template isActive<Arg-num_args1>();
2807  }
2808 
2810  bool updateValue() const {
2811  return expr1.updateValue() && expr2.updateValue();
2812  }
2813 
2815  void cache() const {
2816  expr1.cache();
2817  expr2.cache();
2818  const value_type_1 v1 = expr1.val();
2819  const value_type_2 v2 = expr2.val();
2820  max_v1 = (v1 >= v2);
2821  v = max_v1 ? v1 : v2;
2822  }
2823 
2825  value_type val() const {
2826  return v;
2827  }
2828 
2830  void computePartials(const value_type& bar,
2831  value_type partials[]) const {
2832  if (num_args1 > 0) {
2833  if (max_v1)
2834  expr1.computePartials(bar, partials);
2835  else
2836  expr1.computePartials(value_type(0.0), partials);
2837  }
2838  if (num_args2 > 0) {
2839  if (max_v1)
2840  expr2.computePartials(value_type(0.0), partials+num_args1);
2841  else
2842  expr2.computePartials(bar, partials+num_args1);
2843  }
2844  }
2845 
2847  void getTangents(int i, value_type dots[]) const {
2848  expr1.getTangents(i, dots);
2849  expr2.getTangents(i, dots+num_args1);
2850  }
2851 
2852  template <int Arg>
2854  value_type getTangent(int i) const {
2855  if (Arg < num_args1)
2856  return expr1.template getTangent<Arg>(i);
2857  else
2858  return expr2.template getTangent<Arg-num_args1>(i);
2859  }
2860 
2862  bool isLinear() const {
2863  return false;
2864  }
2865 
2867  bool hasFastAccess() const {
2868  return expr1.hasFastAccess() && expr2.hasFastAccess();
2869  }
2870 
2872  const value_type dx(int i) const {
2873  return max_v1 ? expr1.dx(i) : expr2.dx(i);
2874  }
2875 
2877  const value_type fastAccessDx(int i) const {
2878  return max_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2879  }
2880 
2882  const value_type* getDx(int j) const {
2883  if (j < num_args1)
2884  return expr1.getDx(j);
2885  else
2886  return expr2.getDx(j-num_args1);
2887  }
2888 
2889  protected:
2890 
2891  const ExprT1& expr1;
2892  const ExprT2& expr2;
2893  mutable value_type v;
2894  mutable bool max_v1;
2895 
2896  };
2897 
2898  template <typename ExprT1, typename T2>
2899  class Expr< MaxOp<ExprT1, ConstExpr<T2> > > {
2900 
2901  public:
2902 
2903  typedef ConstExpr<T2> ExprT2;
2904  typedef typename ExprT1::value_type value_type_1;
2905  typedef typename ExprT2::value_type value_type_2;
2906  typedef typename Sacado::Promote<value_type_1,
2907  value_type_2>::type value_type;
2908  typedef typename ExprT1::scalar_type scalar_type_1;
2909  typedef typename ExprT2::scalar_type scalar_type_2;
2910  typedef typename Sacado::Promote<scalar_type_1,
2911  scalar_type_2>::type scalar_type;
2912 
2913  typedef typename ExprT1::base_expr_type base_expr_type_1;
2914  typedef typename ExprT2::base_expr_type base_expr_type_2;
2915  typedef typename Sacado::Promote<base_expr_type_1,
2916  base_expr_type_2>::type base_expr_type;
2917 
2918  static const int num_args = ExprT1::num_args;
2919 
2920  static const bool is_linear = false;
2921 
2923  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2924  expr1(expr1_), expr2(expr2_) {}
2925 
2927  int size() const {
2928  return expr1.size();
2929  }
2930 
2931  template <int Arg>
2933  bool isActive() const {
2934  return expr1.template isActive<Arg>();
2935  }
2936 
2938  bool updateValue() const {
2939  return expr1.updateValue();
2940  }
2941 
2943  void cache() const {
2944  expr1.cache();
2945  const value_type_1 v1 = expr1.val();
2946  const value_type_2 v2 = expr2.val();
2947  max_v1 = (v1 >= v2);
2948  v = max_v1 ? v1 : v2;
2949  }
2950 
2952  value_type val() const {
2953  return v;
2954  }
2955 
2957  void computePartials(const value_type& bar,
2958  value_type partials[]) const {
2959  if (max_v1)
2960  expr1.computePartials(bar, partials);
2961  else
2962  expr1.computePartials(value_type(0.0), partials);
2963  }
2964 
2966  void getTangents(int i, value_type dots[]) const {
2967  expr1.getTangents(i, dots);
2968  }
2969 
2970  template <int Arg>
2972  value_type getTangent(int i) const {
2973  return expr1.template getTangent<Arg>(i);
2974  }
2975 
2977  bool isLinear() const {
2978  return false;
2979  }
2980 
2982  bool hasFastAccess() const {
2983  return expr1.hasFastAccess();
2984  }
2985 
2987  const value_type dx(int i) const {
2988  return max_v1 ? expr1.dx(i) : value_type(0.0);
2989  }
2990 
2992  const value_type fastAccessDx(int i) const {
2993  return max_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
2994  }
2995 
2997  const value_type* getDx(int j) const {
2998  return expr1.getDx(j);
2999  }
3000 
3001  protected:
3002 
3003  const ExprT1& expr1;
3004  ExprT2 expr2;
3005  mutable value_type v;
3006  mutable bool max_v1;
3007 
3008  };
3009 
3010  template <typename T1, typename ExprT2>
3011  class Expr< MaxOp< ConstExpr<T1>,ExprT2> > {
3012 
3013  public:
3014 
3015  typedef ConstExpr<T1> ExprT1;
3016  typedef typename ExprT1::value_type value_type_1;
3017  typedef typename ExprT2::value_type value_type_2;
3018  typedef typename Sacado::Promote<value_type_1,
3019  value_type_2>::type value_type;
3020  typedef typename ExprT1::scalar_type scalar_type_1;
3021  typedef typename ExprT2::scalar_type scalar_type_2;
3022  typedef typename Sacado::Promote<scalar_type_1,
3023  scalar_type_2>::type scalar_type;
3024 
3025  typedef typename ExprT1::base_expr_type base_expr_type_1;
3026  typedef typename ExprT2::base_expr_type base_expr_type_2;
3027  typedef typename Sacado::Promote<base_expr_type_1,
3028  base_expr_type_2>::type base_expr_type;
3029 
3030  static const int num_args = ExprT2::num_args;
3031 
3032  static const bool is_linear = false;
3033 
3035  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3036  expr1(expr1_), expr2(expr2_) {}
3037 
3039  int size() const {
3040  return expr2.size();
3041  }
3042 
3043  template <int Arg>
3045  bool isActive() const {
3046  return expr2.template isActive<Arg>();
3047  }
3048 
3050  bool updateValue() const {
3051  return expr2.updateValue();
3052  }
3053 
3055  void cache() const {
3056  expr2.cache();
3057  const value_type_1 v1 = expr1.val();
3058  const value_type_2 v2 = expr2.val();
3059  max_v1 = (v1 >= v2);
3060  v = max_v1 ? v1 : v2;
3061  }
3062 
3064  value_type val() const {
3065  return v;
3066  }
3067 
3069  void computePartials(const value_type& bar,
3070  value_type partials[]) const {
3071  if (max_v1)
3072  expr2.computePartials(value_type(0.0), partials);
3073  else
3074  expr2.computePartials(bar, partials);
3075  }
3076 
3078  void getTangents(int i, value_type dots[]) const {
3079  expr2.getTangents(i, dots);
3080  }
3081 
3082  template <int Arg>
3084  value_type getTangent(int i) const {
3085  return expr2.template getTangent<Arg>(i);
3086  }
3087 
3089  bool isLinear() const {
3090  return false;
3091  }
3092 
3094  bool hasFastAccess() const {
3095  return expr2.hasFastAccess();
3096  }
3097 
3099  const value_type dx(int i) const {
3100  return max_v1 ? value_type(0.0) : expr2.dx(i);
3101  }
3102 
3104  const value_type fastAccessDx(int i) const {
3105  return max_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3106  }
3107 
3109  const value_type* getDx(int j) const {
3110  return expr2.getDx(j);
3111  }
3112 
3113  protected:
3114 
3115  ExprT1 expr1;
3116  const ExprT2& expr2;
3117  mutable value_type v;
3118  mutable bool max_v1;
3119 
3120  };
3121 
3122  //
3123  // MinOp
3124  //
3125 
3126  template <typename ExprT1, typename ExprT2>
3127  class MinOp {};
3128 
3129  template <typename ExprT1, typename ExprT2>
3130  class Expr< MinOp<ExprT1,ExprT2> > {
3131 
3132  public:
3133 
3134  typedef typename ExprT1::value_type value_type_1;
3135  typedef typename ExprT2::value_type value_type_2;
3136  typedef typename Sacado::Promote<value_type_1,
3137  value_type_2>::type value_type;
3138  typedef typename ExprT1::scalar_type scalar_type_1;
3139  typedef typename ExprT2::scalar_type scalar_type_2;
3140  typedef typename Sacado::Promote<scalar_type_1,
3141  scalar_type_2>::type scalar_type;
3142 
3143  typedef typename ExprT1::base_expr_type base_expr_type_1;
3144  typedef typename ExprT2::base_expr_type base_expr_type_2;
3145  typedef typename Sacado::Promote<base_expr_type_1,
3146  base_expr_type_2>::type base_expr_type;
3147 
3148  static const int num_args1 = ExprT1::num_args;
3149  static const int num_args2 = ExprT2::num_args;
3150  static const int num_args = num_args1 + num_args2;
3151 
3152  static const bool is_linear = false;
3153 
3155  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3156  expr1(expr1_), expr2(expr2_) {}
3157 
3159  int size() const {
3160  int sz1 = expr1.size(), sz2 = expr2.size();
3161  return sz1 > sz2 ? sz1 : sz2;
3162  }
3163 
3164  template <int Arg>
3166  bool isActive() const {
3167  if (Arg < num_args1)
3168  return expr1.template isActive<Arg>();
3169  else
3170  return expr2.template isActive<Arg-num_args1>();
3171  }
3172 
3174  bool updateValue() const {
3175  return expr1.updateValue() && expr2.updateValue();
3176  }
3177 
3179  void cache() const {
3180  expr1.cache();
3181  expr2.cache();
3182  const value_type_1 v1 = expr1.val();
3183  const value_type_2 v2 = expr2.val();
3184  min_v1 = (v1 <= v2);
3185  v = min_v1 ? v1 : v2;
3186  }
3187 
3189  value_type val() const {
3190  return v;
3191  }
3192 
3194  void computePartials(const value_type& bar,
3195  value_type partials[]) const {
3196  if (num_args1 > 0) {
3197  if (min_v1)
3198  expr1.computePartials(bar, partials);
3199  else
3200  expr1.computePartials(value_type(0.0), partials);
3201  }
3202  if (num_args2 > 0) {
3203  if (min_v1)
3204  expr2.computePartials(value_type(0.0), partials+num_args1);
3205  else
3206  expr2.computePartials(bar, partials+num_args1);
3207  }
3208  }
3209 
3211  void getTangents(int i, value_type dots[]) const {
3212  expr1.getTangents(i, dots);
3213  expr2.getTangents(i, dots+num_args1);
3214  }
3215 
3216  template <int Arg>
3218  value_type getTangent(int i) const {
3219  if (Arg < num_args1)
3220  return expr1.template getTangent<Arg>(i);
3221  else
3222  return expr2.template getTangent<Arg-num_args1>(i);
3223  }
3224 
3226  bool isLinear() const {
3227  return false;
3228  }
3229 
3231  bool hasFastAccess() const {
3232  return expr1.hasFastAccess() && expr2.hasFastAccess();
3233  }
3234 
3236  const value_type dx(int i) const {
3237  return min_v1 ? expr1.dx(i) : expr2.dx(i);
3238  }
3239 
3241  const value_type fastAccessDx(int i) const {
3242  return min_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
3243  }
3244 
3246  const value_type* getDx(int j) const {
3247  if (j < num_args1)
3248  return expr1.getDx(j);
3249  else
3250  return expr2.getDx(j-num_args1);
3251  }
3252 
3253  protected:
3254 
3255  const ExprT1& expr1;
3256  const ExprT2& expr2;
3257  mutable value_type v;
3258  mutable bool min_v1;
3259 
3260  };
3261 
3262  template <typename ExprT1, typename T2>
3263  class Expr< MinOp<ExprT1, ConstExpr<T2> > > {
3264 
3265  public:
3266 
3267  typedef ConstExpr<T2> ExprT2;
3268  typedef typename ExprT1::value_type value_type_1;
3269  typedef typename ExprT2::value_type value_type_2;
3270  typedef typename Sacado::Promote<value_type_1,
3271  value_type_2>::type value_type;
3272  typedef typename ExprT1::scalar_type scalar_type_1;
3273  typedef typename ExprT2::scalar_type scalar_type_2;
3274  typedef typename Sacado::Promote<scalar_type_1,
3275  scalar_type_2>::type scalar_type;
3276 
3277  typedef typename ExprT1::base_expr_type base_expr_type_1;
3278  typedef typename ExprT2::base_expr_type base_expr_type_2;
3279  typedef typename Sacado::Promote<base_expr_type_1,
3280  base_expr_type_2>::type base_expr_type;
3281 
3282  static const int num_args = ExprT1::num_args;
3283 
3284  static const bool is_linear = false;
3285 
3287  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3288  expr1(expr1_), expr2(expr2_) {}
3289 
3291  int size() const {
3292  return expr1.size();
3293  }
3294 
3295  template <int Arg>
3297  bool isActive() const {
3298  return expr1.template isActive<Arg>();
3299  }
3300 
3302  bool updateValue() const {
3303  return expr1.updateValue();
3304  }
3305 
3307  void cache() const {
3308  expr1.cache();
3309  const value_type_1 v1 = expr1.val();
3310  const value_type_2 v2 = expr2.val();
3311  min_v1 = (v1 <= v2);
3312  v = min_v1 ? v1 : v2;
3313  }
3314 
3316  value_type val() const {
3317  return v;
3318  }
3319 
3321  void computePartials(const value_type& bar,
3322  value_type partials[]) const {
3323  if (min_v1)
3324  expr1.computePartials(bar, partials);
3325  else
3326  expr1.computePartials(value_type(0.0), partials);
3327  }
3328 
3330  void getTangents(int i, value_type dots[]) const {
3331  expr1.getTangents(i, dots);
3332  }
3333 
3334  template <int Arg>
3336  value_type getTangent(int i) const {
3337  return expr1.template getTangent<Arg>(i);
3338  }
3339 
3341  bool isLinear() const {
3342  return false;
3343  }
3344 
3346  bool hasFastAccess() const {
3347  return expr1.hasFastAccess();
3348  }
3349 
3351  const value_type dx(int i) const {
3352  return min_v1 ? expr1.dx(i) : value_type(0.0);
3353  }
3354 
3356  const value_type fastAccessDx(int i) const {
3357  return min_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
3358  }
3359 
3361  const value_type* getDx(int j) const {
3362  return expr1.getDx(j);
3363  }
3364 
3365  protected:
3366 
3367  const ExprT1& expr1;
3368  ExprT2 expr2;
3369  mutable value_type v;
3370  mutable bool min_v1;
3371 
3372  };
3373 
3374  template <typename T1, typename ExprT2>
3375  class Expr< MinOp< ConstExpr<T1>,ExprT2> > {
3376 
3377  public:
3378 
3379  typedef ConstExpr<T1> ExprT1;
3380  typedef typename ExprT1::value_type value_type_1;
3381  typedef typename ExprT2::value_type value_type_2;
3382  typedef typename Sacado::Promote<value_type_1,
3383  value_type_2>::type value_type;
3384  typedef typename ExprT1::scalar_type scalar_type_1;
3385  typedef typename ExprT2::scalar_type scalar_type_2;
3386  typedef typename Sacado::Promote<scalar_type_1,
3387  scalar_type_2>::type scalar_type;
3388 
3389  typedef typename ExprT1::base_expr_type base_expr_type_1;
3390  typedef typename ExprT2::base_expr_type base_expr_type_2;
3391  typedef typename Sacado::Promote<base_expr_type_1,
3392  base_expr_type_2>::type base_expr_type;
3393 
3394  static const int num_args = ExprT2::num_args;
3395 
3396  static const bool is_linear = false;
3397 
3399  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3400  expr1(expr1_), expr2(expr2_) {}
3401 
3403  int size() const {
3404  return expr2.size();
3405  }
3406 
3407  template <int Arg>
3409  bool isActive() const {
3410  return expr2.template isActive<Arg>();
3411  }
3412 
3414  bool updateValue() const {
3415  return expr2.updateValue();
3416  }
3417 
3419  void cache() const {
3420  expr2.cache();
3421  const value_type_1 v1 = expr1.val();
3422  const value_type_2 v2 = expr2.val();
3423  min_v1 = (v1 <= v2);
3424  v = min_v1 ? v1 : v2;
3425  }
3426 
3428  value_type val() const {
3429  return v;
3430  }
3431 
3433  void computePartials(const value_type& bar,
3434  value_type partials[]) const {
3435  if (min_v1)
3436  expr2.computePartials(value_type(0.0), partials);
3437  else
3438  expr2.computePartials(bar, partials);
3439  }
3440 
3442  void getTangents(int i, value_type dots[]) const {
3443  expr2.getTangents(i, dots);
3444  }
3445 
3446  template <int Arg>
3448  value_type getTangent(int i) const {
3449  return expr2.template getTangent<Arg>(i);
3450  }
3451 
3453  bool isLinear() const {
3454  return false;
3455  }
3456 
3458  bool hasFastAccess() const {
3459  return expr2.hasFastAccess();
3460  }
3461 
3463  const value_type dx(int i) const {
3464  return min_v1 ? value_type(0.0) : expr2.dx(i);
3465  }
3466 
3468  const value_type fastAccessDx(int i) const {
3469  return min_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3470  }
3471 
3473  const value_type* getDx(int j) const {
3474  return expr2.getDx(j);
3475  }
3476 
3477  protected:
3478 
3479  ExprT1 expr1;
3480  const ExprT2& expr2;
3481  mutable value_type v;
3482  mutable bool min_v1;
3483 
3484  };
3485 
3486  }
3487 
3488 }
3489 
3490 #define FAD_BINARYOP_MACRO(OPNAME,OP) \
3491 namespace Sacado { \
3492  namespace ELRCacheFad { \
3493  \
3494  template <typename T1, typename T2> \
3495  KOKKOS_INLINE_FUNCTION \
3496  SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \
3497  OPNAME (const T1& expr1, const T2& expr2) \
3498  { \
3499  typedef OP< T1, T2 > expr_t; \
3500  \
3501  return Expr<expr_t>(expr1, expr2); \
3502  } \
3503  \
3504  template <typename T> \
3505  KOKKOS_INLINE_FUNCTION \
3506  Expr< OP< Expr<T>, Expr<T> > > \
3507  OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
3508  { \
3509  typedef OP< Expr<T>, Expr<T> > expr_t; \
3510  \
3511  return Expr<expr_t>(expr1, expr2); \
3512  } \
3513  \
3514  template <typename T> \
3515  KOKKOS_INLINE_FUNCTION \
3516  Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
3517  Expr<T> > > \
3518  OPNAME (const typename Expr<T>::value_type& c, \
3519  const Expr<T>& expr) \
3520  { \
3521  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3522  typedef OP< ConstT, Expr<T> > expr_t; \
3523  \
3524  return Expr<expr_t>(ConstT(c), expr); \
3525  } \
3526  \
3527  template <typename T> \
3528  KOKKOS_INLINE_FUNCTION \
3529  Expr< OP< Expr<T>, \
3530  ConstExpr<typename Expr<T>::value_type> > > \
3531  OPNAME (const Expr<T>& expr, \
3532  const typename Expr<T>::value_type& c) \
3533  { \
3534  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3535  typedef OP< Expr<T>, ConstT > expr_t; \
3536  \
3537  return Expr<expr_t>(expr, ConstT(c)); \
3538  } \
3539  \
3540  template <typename T> \
3541  KOKKOS_INLINE_FUNCTION \
3542  SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \
3543  OPNAME (const typename Expr<T>::scalar_type& c, \
3544  const Expr<T>& expr) \
3545  { \
3546  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3547  typedef OP< ConstT, Expr<T> > expr_t; \
3548  \
3549  return Expr<expr_t>(ConstT(c), expr); \
3550  } \
3551  \
3552  template <typename T> \
3553  KOKKOS_INLINE_FUNCTION \
3554  SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \
3555  OPNAME (const Expr<T>& expr, \
3556  const typename Expr<T>::scalar_type& c) \
3557  { \
3558  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3559  typedef OP< Expr<T>, ConstT > expr_t; \
3560  \
3561  return Expr<expr_t>(expr, ConstT(c)); \
3562  } \
3563  } \
3564 }
3565 
3566 
3567 FAD_BINARYOP_MACRO(operator+, AdditionOp)
3570 FAD_BINARYOP_MACRO(operator/, DivisionOp)
3575 
3576 #undef FAD_BINARYOP_MACRO
3577 
3578 //-------------------------- Relational Operators -----------------------
3579 
3580 #define FAD_RELOP_MACRO(OP) \
3581 namespace Sacado { \
3582  namespace ELRCacheFad { \
3583  template <typename ExprT1, typename ExprT2> \
3584  KOKKOS_INLINE_FUNCTION \
3585  bool \
3586  operator OP (const Expr<ExprT1>& expr1, \
3587  const Expr<ExprT2>& expr2) \
3588  { \
3589  expr1.cache(); \
3590  expr2.cache(); \
3591  return expr1.val() OP expr2.val(); \
3592  } \
3593  \
3594  template <typename ExprT2> \
3595  KOKKOS_INLINE_FUNCTION \
3596  bool \
3597  operator OP (const typename Expr<ExprT2>::value_type& a, \
3598  const Expr<ExprT2>& expr2) \
3599  { \
3600  expr2.cache(); \
3601  return a OP expr2.val(); \
3602  } \
3603  \
3604  template <typename ExprT1> \
3605  KOKKOS_INLINE_FUNCTION \
3606  bool \
3607  operator OP (const Expr<ExprT1>& expr1, \
3608  const typename Expr<ExprT1>::value_type& b) \
3609  { \
3610  expr1.cache(); \
3611  return expr1.val() OP b; \
3612  } \
3613  } \
3614 }
3615 
3616 FAD_RELOP_MACRO(==)
3617 FAD_RELOP_MACRO(!=)
3618 FAD_RELOP_MACRO(<)
3619 FAD_RELOP_MACRO(>)
3620 FAD_RELOP_MACRO(<=)
3621 FAD_RELOP_MACRO(>=)
3622 FAD_RELOP_MACRO(<<=)
3623 FAD_RELOP_MACRO(>>=)
3624 FAD_RELOP_MACRO(&)
3625 FAD_RELOP_MACRO(|)
3626 
3627 #undef FAD_RELOP_MACRO
3628 
3629 namespace Sacado {
3630 
3631  namespace ELRCacheFad {
3632 
3633  template <typename ExprT>
3635  bool operator ! (const Expr<ExprT>& expr)
3636  {
3637  expr.cache();
3638  return ! expr.val();
3639  }
3640 
3641  } // namespace ELRCacheFad
3642 
3643 } // namespace Sacado
3644 
3645 //-------------------------- Boolean Operators -----------------------
3646 namespace Sacado {
3647 
3648  namespace ELRCacheFad {
3649 
3650  template <typename ExprT>
3652  bool toBool(const Expr<ExprT>& x) {
3653  x.cache();
3654  bool is_zero = (x.val() == 0.0);
3655  for (int i=0; i<x.size(); i++)
3656  is_zero = is_zero && (x.dx(i) == 0.0);
3657  return !is_zero;
3658  }
3659 
3660  } // namespace Fad
3661 
3662 } // namespace Sacado
3663 
3664 #define FAD_BOOL_MACRO(OP) \
3665 namespace Sacado { \
3666  namespace ELRCacheFad { \
3667  template <typename ExprT1, typename ExprT2> \
3668  KOKKOS_INLINE_FUNCTION \
3669  bool \
3670  operator OP (const Expr<ExprT1>& expr1, \
3671  const Expr<ExprT2>& expr2) \
3672  { \
3673  return toBool(expr1) OP toBool(expr2); \
3674  } \
3675  \
3676  template <typename ExprT2> \
3677  KOKKOS_INLINE_FUNCTION \
3678  bool \
3679  operator OP (const typename Expr<ExprT2>::value_type& a, \
3680  const Expr<ExprT2>& expr2) \
3681  { \
3682  return a OP toBool(expr2); \
3683  } \
3684  \
3685  template <typename ExprT1> \
3686  KOKKOS_INLINE_FUNCTION \
3687  bool \
3688  operator OP (const Expr<ExprT1>& expr1, \
3689  const typename Expr<ExprT1>::value_type& b) \
3690  { \
3691  return toBool(expr1) OP b; \
3692  } \
3693  } \
3694 }
3695 
3696 FAD_BOOL_MACRO(&&)
3697 FAD_BOOL_MACRO(||)
3698 
3699 #undef FAD_BOOL_MACRO
3700 
3701 //-------------------------- I/O Operators -----------------------
3702 
3703 namespace Sacado {
3704 
3705  namespace ELRCacheFad {
3706 
3707  template <typename ExprT>
3708  std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
3709  os << x.val() << " [";
3710 
3711  for (int i=0; i< x.size(); i++) {
3712  os << " " << x.dx(i);
3713  }
3714 
3715  os << " ]";
3716  return os;
3717  }
3718 
3719  } // namespace Fad
3720 
3721 } // namespace Sacado
3722 
3723 #endif // SACADO_CACHEFAD_OPS_HPP
KOKKOS_INLINE_FUNCTION const value_type * getDx(int j) const
cbrt(expr.val())
KOKKOS_INLINE_FUNCTION bool isLinear() const
expr expr SinOp
KOKKOS_INLINE_FUNCTION const value_type * getDx(int j) const
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
asinh(expr.val())
KOKKOS_INLINE_FUNCTION Expr< AbsOp< Expr< T > > > abs(const Expr< T > &expr)
KOKKOS_INLINE_FUNCTION bool isLinear() const
#define FAD_UNARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, FASTACCESSDX)
KOKKOS_INLINE_FUNCTION Expr< FAbsOp< Expr< T > > > fabs(const Expr< T > &expr)
asin(expr.val())
cosh(expr.val())
KOKKOS_INLINE_FUNCTION value_type val() const
expr expr dx(i)
abs(expr.val())
KOKKOS_INLINE_FUNCTION value_type val() const
KOKKOS_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MinOp
atanh(expr.val())
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
expr expr CoshOp
expr expr ATanhOp
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
expr expr TanhOp
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
KOKKOS_INLINE_FUNCTION value_type getTangent(int i) const
expr expr SqrtOp
expr expr ASinhOp
expr bar
KOKKOS_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
atan(expr.val())
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
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 computePartials(const value_type &bar, value_type partials[]) 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 void cache() const
KOKKOS_INLINE_FUNCTION T safe_sqrt(const T &x)
tanh(expr.val())
expr expr CosOp
KOKKOS_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
KOKKOS_INLINE_FUNCTION value_type getTangent(int i) const
#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)
expr expr ATanOp
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
expr expr ACosOp
#define FAD_RELOP_MACRO(OP)
KOKKOS_INLINE_FUNCTION bool updateValue() const
sqrt(expr.val())
Wrapper for a generic expression template.
sinh(expr.val())
KOKKOS_INLINE_FUNCTION value_type val() const
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 const value_type fastAccessDx(int i) const
KOKKOS_INLINE_FUNCTION bool isActive() const
KOKKOS_INLINE_FUNCTION bool updateValue() const
#define FAD_BOOL_MACRO(OP)
KOKKOS_INLINE_FUNCTION bool toBool(const Expr< ExprT > &x)
atan2(expr1.val(), expr2.val())
KOKKOS_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
sin(expr.val())
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
KOKKOS_INLINE_FUNCTION bool hasFastAccess() const
KOKKOS_INLINE_FUNCTION const value_type * getDx(int j) const
KOKKOS_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
KOKKOS_INLINE_FUNCTION Expr< UnaryPlusOp< Expr< T > > > operator+(const Expr< T > &expr)
log(expr.val())
expr expr ACoshOp
KOKKOS_INLINE_FUNCTION bool isActive() const
KOKKOS_INLINE_FUNCTION const value_type fastAccessDx(int i) const
expr expr Log10Op
expr expr SinhOp
KOKKOS_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
acosh(expr.val())
acos(expr.val())
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
expr expr ASinOp
KOKKOS_INLINE_FUNCTION const value_type * getDx(int j) const
KOKKOS_INLINE_FUNCTION value_type val() const
KOKKOS_INLINE_FUNCTION void cache() const
KOKKOS_INLINE_FUNCTION value_type getTangent(int i) const
KOKKOS_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
exp(expr.val())
expr expr expr ExpOp
fabs(expr.val())
KOKKOS_INLINE_FUNCTION Expr(const ExprT &expr_)
expr expr TanOp
KOKKOS_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
log10(expr.val())
Base template specification for Promote.
cos(expr.val())
KOKKOS_INLINE_FUNCTION const value_type dx(int i) const
KOKKOS_INLINE_FUNCTION Expr< UnaryMinusOp< Expr< T > > > operator-(const Expr< T > &expr)
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