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 // Sacado Package
4 //
5 // Copyright 2006 NTESS and the Sacado contributors.
6 // SPDX-License-Identifier: LGPL-2.1-or-later
7 //
8 // ***********************************************************************
9 //
10 // The forward-mode AD classes in Sacado are a derivative work of the
11 // expression template classes in the Fad package by Nicolas Di Cesare.
12 // The following banner is included in the original Fad source code:
13 //
14 // ************ DO NOT REMOVE THIS BANNER ****************
15 //
16 // Nicolas Di Cesare <Nicolas.Dicesare@ann.jussieu.fr>
17 // http://www.ann.jussieu.fr/~dicesare
18 //
19 // CEMRACS 98 : C++ courses,
20 // templates : new C++ techniques
21 // for scientific computing
22 //
23 //********************************************************
24 //
25 // A short implementation ( not all operators and
26 // functions are overloaded ) of 1st order Automatic
27 // Differentiation in forward mode (FAD) using
28 // EXPRESSION TEMPLATES.
29 //
30 //********************************************************
31 // @HEADER
32 
33 #ifndef SACADO_ELRCACHEFAD_OPS_HPP
34 #define SACADO_ELRCACHEFAD_OPS_HPP
35 
37 #include "Sacado_cmath.hpp"
39 #include <ostream> // for std::ostream
40 
41 namespace Sacado {
42  namespace ELRCacheFad {
43 
44  //
45  // UnaryPlusOp
46  //
47 
48  template <typename ExprT>
49  class UnaryPlusOp {};
50 
51  template <typename ExprT>
52  class Expr< UnaryPlusOp<ExprT> > {
53  public:
54 
55  typedef typename ExprT::value_type value_type;
56  typedef typename ExprT::scalar_type scalar_type;
57 
58  typedef typename ExprT::base_expr_type base_expr_type;
59 
60  static const int num_args = ExprT::num_args;
61 
62  static const bool is_linear = true;
63 
65  explicit Expr(const ExprT& expr_) : expr(expr_) {}
66 
68  int size() const { return expr.size(); }
69 
70  template <int Arg>
72  bool isActive() const { return expr.template isActive<Arg>(); }
73 
75  bool updateValue() const { return expr.updateValue(); }
76 
78  void cache() const {
79  expr.cache();
80  }
81 
83  value_type val() const {
84  return expr.val();
85  }
86 
89  value_type partials[]) const {
90  expr.computePartials(bar, partials);
91  }
92 
94  void getTangents(int i, value_type dots[]) const {
95  expr.getTangents(i, dots); }
96 
97  template <int Arg>
98  value_type getTangent(int i) const {
99  return expr.template getTangent<Arg>(i);
100  }
101 
103  bool isLinear() const {
104  return expr.isLinear();
105  }
106 
108  bool hasFastAccess() const {
109  return expr.hasFastAccess();
110  }
111 
113  const value_type dx(int i) const {
114  return expr.dx(i);
115  }
116 
118  const value_type fastAccessDx(int i) const {
119  return expr.fastAccessDx(i);
120  }
121 
123  const value_type* getDx(int j) const {
124  return expr.getDx(j);
125  }
126 
127  protected:
128 
129  const ExprT& expr;
130  };
131 
132  template <typename T>
135  operator+ (const Expr<T>& expr)
136  {
137  typedef UnaryPlusOp< Expr<T> > expr_t;
138 
139  return Expr<expr_t>(expr);
140  }
141 
142  //
143  // UnaryMinusOp
144  //
145  template <typename ExprT>
146  class UnaryMinusOp {};
147 
148  template <typename ExprT>
149  class Expr< UnaryMinusOp<ExprT> > {
150  public:
151 
152  typedef typename ExprT::value_type value_type;
153  typedef typename ExprT::scalar_type scalar_type;
154 
155  typedef typename ExprT::base_expr_type base_expr_type;
156 
157  static const int num_args = ExprT::num_args;
158 
159  static const bool is_linear = true;
160 
162  explicit Expr(const ExprT& expr_) : expr(expr_) {}
163 
165  int size() const { return expr.size(); }
166 
167  template <int Arg>
169  bool isActive() const { return expr.template isActive<Arg>(); }
170 
172  bool updateValue() const { return expr.updateValue(); }
173 
175  void cache() const {
176  expr.cache();
177  }
178 
180  value_type val() const {
181  return -expr.val();
182  }
183 
186  value_type partials[]) const {
187  expr.computePartials(-bar, partials);
188  }
189 
191  void getTangents(int i, value_type dots[]) const {
192  expr.getTangents(i, dots); }
193 
194  template <int Arg>
196  value_type getTangent(int i) const {
197  return expr.template getTangent<Arg>(i);
198  }
199 
201  bool isLinear() const {
202  return expr.isLinear();
203  }
204 
206  bool hasFastAccess() const {
207  return expr.hasFastAccess();
208  }
209 
211  const value_type dx(int i) const {
212  return -expr.dx(i);
213  }
214 
216  const value_type fastAccessDx(int i) const {
217  return -expr.fastAccessDx(i);
218  }
219 
221  const value_type* getDx(int j) const {
222  return expr.getDx(j);
223  }
224 
225  protected:
226 
227  const ExprT& expr;
228  };
229 
230  template <typename T>
233  operator- (const Expr<T>& expr)
234  {
235  typedef UnaryMinusOp< Expr<T> > expr_t;
236 
237  return Expr<expr_t>(expr);
238  }
239 
240  //
241  // AbsOp
242  //
243 
244  template <typename ExprT>
245  class AbsOp {};
246 
247  template <typename ExprT>
248  class Expr< AbsOp<ExprT> > {
249  public:
250 
251  typedef typename ExprT::value_type value_type;
252  typedef typename ExprT::scalar_type scalar_type;
253 
254  typedef typename ExprT::base_expr_type base_expr_type;
255 
256  static const int num_args = ExprT::num_args;
257 
258  static const bool is_linear = false;
259 
261  explicit Expr(const ExprT& expr_) : expr(expr_) {}
262 
264  int size() const { return expr.size(); }
265 
266  template <int Arg>
268  bool isActive() const { return expr.template isActive<Arg>(); }
269 
271  bool updateValue() const { return expr.updateValue(); }
272 
274  void cache() const {
275  expr.cache();
276  v = expr.val();
277  v_pos = (v >= 0);
278  }
279 
281  value_type val() const {
282  return std::abs(v);
283  }
284 
287  value_type partials[]) const {
288  if (v_pos)
289  expr.computePartials(bar, partials);
290  else
291  expr.computePartials(-bar, partials);
292  }
293 
295  void getTangents(int i, value_type dots[]) const {
296  expr.getTangents(i, dots); }
297 
298  template <int Arg>
300  value_type getTangent(int i) const {
301  return expr.template getTangent<Arg>(i);
302  }
303 
305  bool isLinear() const {
306  return false;
307  }
308 
310  bool hasFastAccess() const {
311  return expr.hasFastAccess();
312  }
313 
315  const value_type dx(int i) const {
316  if (v_pos) return expr.dx(i);
317  else return -expr.dx(i);
318  }
319 
321  const value_type fastAccessDx(int i) const {
322  if (v_pos) return expr.fastAccessDx(i);
323  else return -expr.fastAccessDx(i);
324  }
325 
327  const value_type* getDx(int j) const {
328  return expr.getDx(j);
329  }
330 
331  protected:
332 
333  const ExprT& expr;
334  mutable value_type v;
335  mutable bool v_pos;
336  };
337 
338  template <typename T>
341  abs (const Expr<T>& expr)
342  {
343  typedef AbsOp< Expr<T> > expr_t;
344 
345  return Expr<expr_t>(expr);
346  }
347 
348  //
349  // FAbsOp
350  //
351 
352  template <typename ExprT>
353  class FAbsOp {};
354 
355  template <typename ExprT>
356  class Expr< FAbsOp<ExprT> > {
357  public:
358 
359  typedef typename ExprT::value_type value_type;
360  typedef typename ExprT::scalar_type scalar_type;
361 
362  typedef typename ExprT::base_expr_type base_expr_type;
363 
364  static const int num_args = ExprT::num_args;
365 
366  static const bool is_linear = false;
367 
369  explicit Expr(const ExprT& expr_) : expr(expr_) {}
370 
372  int size() const { return expr.size(); }
373 
374  template <int Arg>
376  bool isActive() const { return expr.template isActive<Arg>(); }
377 
379  bool updateValue() const { return expr.updateValue(); }
380 
382  void cache() const {
383  expr.cache();
384  v = expr.val();
385  v_pos = (v >= 0);
386  }
387 
389  value_type val() const {
390  return std::fabs(v);
391  }
392 
395  value_type partials[]) const {
396  if (v_pos)
397  expr.computePartials(bar, partials);
398  else
399  expr.computePartials(-bar, partials);
400  }
401 
403  void getTangents(int i, value_type dots[]) const {
404  expr.getTangents(i, dots); }
405 
406  template <int Arg>
408  value_type getTangent(int i) const {
409  return expr.template getTangent<Arg>(i);
410  }
411 
413  bool isLinear() const {
414  return false;
415  }
416 
418  bool hasFastAccess() const {
419  return expr.hasFastAccess();
420  }
421 
423  const value_type dx(int i) const {
424  if (v_pos) return expr.dx(i);
425  else return -expr.dx(i);
426  }
427 
429  const value_type fastAccessDx(int i) const {
430  if (v_pos) return expr.fastAccessDx(i);
431  else return -expr.fastAccessDx(i);
432  }
433 
435  const value_type* getDx(int j) const {
436  return expr.getDx(j);
437  }
438 
439  protected:
440 
441  const ExprT& expr;
442  mutable value_type v;
443  mutable bool v_pos;
444  };
445 
446  template <typename T>
449  fabs (const Expr<T>& expr)
450  {
451  typedef FAbsOp< Expr<T> > expr_t;
452 
453  return Expr<expr_t>(expr);
454  }
455 
456  }
457 }
458 
459 #define FAD_UNARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE) \
460 namespace Sacado { \
461  namespace ELRCacheFad { \
462  \
463  template <typename ExprT> \
464  class OP {}; \
465  \
466  template <typename ExprT> \
467  class Expr< OP<ExprT> > { \
468  public: \
469  \
470  typedef typename ExprT::value_type value_type; \
471  typedef typename ExprT::scalar_type scalar_type; \
472  \
473  typedef typename ExprT::base_expr_type base_expr_type; \
474  \
475  static const int num_args = ExprT::num_args; \
476  \
477  static const bool is_linear = false; \
478  \
479  SACADO_INLINE_FUNCTION \
480  explicit Expr(const ExprT& expr_) : expr(expr_) {} \
481  \
482  SACADO_INLINE_FUNCTION \
483  int size() const { return expr.size(); } \
484  \
485  template <int Arg> \
486  SACADO_INLINE_FUNCTION \
487  bool isActive() const { return expr.template isActive<Arg>(); } \
488  \
489  SACADO_INLINE_FUNCTION \
490  bool updateValue() const { return expr.updateValue(); } \
491  \
492  SACADO_INLINE_FUNCTION \
493  void cache() const { \
494  expr.cache(); \
495  v = expr.val(); \
496  PARTIAL; \
497  } \
498  \
499  SACADO_INLINE_FUNCTION \
500  value_type val() const { \
501  return VALUE; \
502  } \
503  \
504  SACADO_INLINE_FUNCTION \
505  void computePartials(const value_type& bar, \
506  value_type partials[]) const { \
507  expr.computePartials(bar*a, partials); \
508  } \
509  \
510  SACADO_INLINE_FUNCTION \
511  void getTangents(int i, value_type dots[]) const { \
512  expr.getTangents(i, dots); } \
513  \
514  template <int Arg> \
515  SACADO_INLINE_FUNCTION \
516  value_type getTangent(int i) const { \
517  return expr.template getTangent<Arg>(i); \
518  } \
519  \
520  SACADO_INLINE_FUNCTION \
521  bool isLinear() const { \
522  return false; \
523  } \
524  \
525  SACADO_INLINE_FUNCTION \
526  bool hasFastAccess() const { \
527  return expr.hasFastAccess(); \
528  } \
529  \
530  SACADO_INLINE_FUNCTION \
531  const value_type dx(int i) const { \
532  return expr.dx(i)*a; \
533  } \
534  \
535  SACADO_INLINE_FUNCTION \
536  const value_type fastAccessDx(int i) const { \
537  return expr.fastAccessDx(i)*a; \
538  } \
539  \
540  SACADO_INLINE_FUNCTION \
541  const value_type* getDx(int j) const { \
542  return expr.getDx(j); \
543  } \
544  \
545  protected: \
546  \
547  const ExprT& expr; \
548  mutable value_type v; \
549  mutable value_type a; \
550  }; \
551  \
552  template <typename T> \
553  SACADO_INLINE_FUNCTION \
554  Expr< OP< Expr<T> > > \
555  OPNAME (const Expr<T>& expr) \
556  { \
557  typedef OP< Expr<T> > expr_t; \
558  \
559  return Expr<expr_t>(expr); \
560  } \
561  } \
562 }
563 
565  ExpOp,
566  a = std::exp(v),
567  a)
570  a=scalar_type(1.0)/v,
571  std::log(v))
574  a = scalar_type(1.0)/(std::log(scalar_type(10.0))*v),
575  std::log10(v))
578  a = scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)),
579  std::sqrt(v))
582  a = (v == value_type(0.0) ? value_type(0.0) : value_type(scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)))),
583  std::sqrt(v))
586  a = -std::sin(v),
587  std::cos(v))
590  a = std::cos(v),
591  std::sin(v))
594  a = scalar_type(1.0)+std::tan(v)*std::tan(v),
595  std::tan(v))
598  a = scalar_type(-1.0)/std::sqrt(scalar_type(1.0)-v*v),
599  std::acos(v))
602  a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)-v*v),
603  std::asin(v))
606  a = scalar_type(1.0)/(scalar_type(1.0)+v*v),
607  std::atan(v))
610  a = std::sinh(v),
611  std::cosh(v))
614  a = std::cosh(v),
615  std::sinh(v))
618  a = scalar_type(1.0)-std::tanh(v)*std::tanh(v),
619  std::tanh(v))
622  a = scalar_type(1.0)/std::sqrt((v-scalar_type(1.0))*(v+scalar_type(1.0))),
623  std::acosh(v))
626  a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)+v*v),
627  std::asinh(v))
630  a = scalar_type(1.0)/(scalar_type(1.0)-v*v),
631  std::atanh(v))
634  a = scalar_type(1.0)/(scalar_type(3.0)*std::cbrt(v*v)),
635  std::cbrt(v))
636 
637 #undef FAD_UNARYOP_MACRO
638 
639 //
640 // Binary operators
641 //
642 namespace Sacado {
643  namespace ELRCacheFad {
644 
645  //
646  // AdditionOp
647  //
648 
649  template <typename ExprT1, typename ExprT2>
650  class AdditionOp {};
651 
652  template <typename ExprT1, typename ExprT2>
653  class Expr< AdditionOp<ExprT1,ExprT2> > {
654 
655  public:
656 
657  typedef typename ExprT1::value_type value_type_1;
658  typedef typename ExprT2::value_type value_type_2;
659  typedef typename Sacado::Promote<value_type_1,
660  value_type_2>::type value_type;
661  typedef typename ExprT1::scalar_type scalar_type_1;
662  typedef typename ExprT2::scalar_type scalar_type_2;
663  typedef typename Sacado::Promote<scalar_type_1,
664  scalar_type_2>::type scalar_type;
665 
666  typedef typename ExprT1::base_expr_type base_expr_type_1;
667  typedef typename ExprT2::base_expr_type base_expr_type_2;
668  typedef typename Sacado::Promote<base_expr_type_1,
669  base_expr_type_2>::type base_expr_type;
670 
671  static const int num_args1 = ExprT1::num_args;
672  static const int num_args2 = ExprT2::num_args;
673  static const int num_args = num_args1 + num_args2;
674 
675  static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
676 
678  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
679  expr1(expr1_), expr2(expr2_) {}
680 
682  int size() const {
683  int sz1 = expr1.size(), sz2 = expr2.size();
684  return sz1 > sz2 ? sz1 : sz2;
685  }
686 
687  template <int Arg>
689  bool isActive() const {
690  if (Arg < num_args1)
691  return expr1.template isActive<Arg>();
692  else
693  return expr2.template isActive<Arg-num_args1>();
694  }
695 
697  bool updateValue() const {
698  return expr1.updateValue() && expr2.updateValue();
699  }
700 
702  void cache() const {
703  expr1.cache();
704  expr2.cache();
705  }
706 
708  value_type val() const {
709  return expr1.val()+expr2.val();
710  }
711 
713  void computePartials(const value_type& bar,
714  value_type partials[]) const {
715  if (num_args1 > 0)
716  expr1.computePartials(bar, partials);
717  if (num_args2 > 0)
718  expr2.computePartials(bar, partials+num_args1);
719  }
720 
722  void getTangents(int i, value_type dots[]) const {
723  expr1.getTangents(i, dots);
724  expr2.getTangents(i, dots+num_args1);
725  }
726 
727  template <int Arg>
729  value_type getTangent(int i) const {
730  if (Arg < num_args1)
731  return expr1.template getTangent<Arg>(i);
732  else
733  return expr2.template getTangent<Arg-num_args1>(i);
734  }
735 
737  bool isLinear() const {
738  return expr1.isLinear() && expr2.isLinear();
739  }
740 
742  bool hasFastAccess() const {
743  return expr1.hasFastAccess() && expr2.hasFastAccess();
744  }
745 
747  const value_type dx(int i) const {
748  return expr1.dx(i) + expr2.dx(i);
749  }
750 
752  const value_type fastAccessDx(int i) const {
753  return expr1.fastAccessDx(i) + expr2.fastAccessDx(i);
754  }
755 
757  const value_type* getDx(int j) const {
758  if (j < num_args1)
759  return expr1.getDx(j);
760  else
761  return expr2.getDx(j-num_args1);
762  }
763 
764  protected:
765 
766  const ExprT1& expr1;
767  const ExprT2& expr2;
768 
769  };
770 
771  template <typename ExprT1, typename T2>
772  class Expr< AdditionOp<ExprT1, ConstExpr<T2> > > {
773 
774  public:
775 
776  typedef ConstExpr<T2> ExprT2;
777  typedef typename ExprT1::value_type value_type_1;
778  typedef typename ExprT2::value_type value_type_2;
779  typedef typename Sacado::Promote<value_type_1,
780  value_type_2>::type value_type;
781  typedef typename ExprT1::scalar_type scalar_type_1;
782  typedef typename ExprT2::scalar_type scalar_type_2;
783  typedef typename Sacado::Promote<scalar_type_1,
784  scalar_type_2>::type scalar_type;
785 
786  typedef typename ExprT1::base_expr_type base_expr_type_1;
787  typedef typename ExprT2::base_expr_type base_expr_type_2;
788  typedef typename Sacado::Promote<base_expr_type_1,
789  base_expr_type_2>::type base_expr_type;
790 
791  static const int num_args = ExprT1::num_args;
792 
793  static const bool is_linear = ExprT1::is_linear;
794 
796  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
797  expr1(expr1_), expr2(expr2_) {}
798 
800  int size() const {
801  return expr1.size();
802  }
803 
804  template <int Arg>
806  bool isActive() const {
807  return expr1.template isActive<Arg>();
808  }
809 
811  bool updateValue() const {
812  return expr1.updateValue();
813  }
814 
816  void cache() const {
817  expr1.cache();
818  }
819 
821  value_type val() const {
822  return expr1.val() + expr2.val();
823  }
824 
826  void computePartials(const value_type& bar,
827  value_type partials[]) const {
828  expr1.computePartials(bar, partials);
829  }
830 
832  void getTangents(int i, value_type dots[]) const {
833  expr1.getTangents(i, dots);
834  }
835 
836  template <int Arg>
838  value_type getTangent(int i) const {
839  return expr1.template getTangent<Arg>(i);
840  }
841 
843  bool isLinear() const {
844  return expr1.isLinear();
845  }
846 
848  bool hasFastAccess() const {
849  return expr1.hasFastAccess();
850  }
851 
853  const value_type dx(int i) const {
854  return expr1.dx(i);
855  }
856 
858  const value_type fastAccessDx(int i) const {
859  return expr1.fastAccessDx(i);
860  }
861 
863  const value_type* getDx(int j) const {
864  return expr1.getDx(j);
865  }
866 
867  protected:
868 
869  const ExprT1& expr1;
870  ExprT2 expr2;
871 
872  };
873 
874  template <typename T1, typename ExprT2>
875  class Expr< AdditionOp< ConstExpr<T1>,ExprT2> > {
876 
877  public:
878 
879  typedef ConstExpr<T1> ExprT1;
880  typedef typename ExprT1::value_type value_type_1;
881  typedef typename ExprT2::value_type value_type_2;
882  typedef typename Sacado::Promote<value_type_1,
883  value_type_2>::type value_type;
884  typedef typename ExprT1::scalar_type scalar_type_1;
885  typedef typename ExprT2::scalar_type scalar_type_2;
886  typedef typename Sacado::Promote<scalar_type_1,
887  scalar_type_2>::type scalar_type;
888 
889  typedef typename ExprT1::base_expr_type base_expr_type_1;
890  typedef typename ExprT2::base_expr_type base_expr_type_2;
891  typedef typename Sacado::Promote<base_expr_type_1,
892  base_expr_type_2>::type base_expr_type;
893 
894  static const int num_args = ExprT2::num_args;
895 
896  static const bool is_linear = ExprT2::is_linear;
897 
899  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
900  expr1(expr1_), expr2(expr2_) {}
901 
903  int size() const {
904  return expr2.size();
905  }
906 
907  template <int Arg>
909  bool isActive() const {
910  return expr2.template isActive<Arg>();
911  }
912 
914  bool updateValue() const {
915  return expr2.updateValue();
916  }
917 
919  void cache() const {
920  expr2.cache();
921  }
922 
924  value_type val() const {
925  return expr1.val() + expr2.val();
926  }
927 
929  void computePartials(const value_type& bar,
930  value_type partials[]) const {
931  expr2.computePartials(bar, partials);
932  }
933 
935  void getTangents(int i, value_type dots[]) const {
936  expr2.getTangents(i, dots);
937  }
938 
939  template <int Arg>
941  value_type getTangent(int i) const {
942  return expr2.template getTangent<Arg>(i);
943  }
944 
946  bool isLinear() const {
947  return expr2.isLinear();
948  }
949 
951  bool hasFastAccess() const {
952  return expr2.hasFastAccess();
953  }
954 
956  const value_type dx(int i) const {
957  return expr2.dx(i);
958  }
959 
961  const value_type fastAccessDx(int i) const {
962  return expr2.fastAccessDx(i);
963  }
964 
966  const value_type* getDx(int j) const {
967  return expr2.getDx(j);
968  }
969 
970  protected:
971 
972  ExprT1 expr1;
973  const ExprT2& expr2;
974 
975  };
976 
977  //
978  // SubtractionOp
979  //
980 
981  template <typename ExprT1, typename ExprT2>
982  class SubtractionOp {};
983 
984  template <typename ExprT1, typename ExprT2>
985  class Expr< SubtractionOp<ExprT1,ExprT2> > {
986 
987  public:
988 
989  typedef typename ExprT1::value_type value_type_1;
990  typedef typename ExprT2::value_type value_type_2;
991  typedef typename Sacado::Promote<value_type_1,
992  value_type_2>::type value_type;
993  typedef typename ExprT1::scalar_type scalar_type_1;
994  typedef typename ExprT2::scalar_type scalar_type_2;
995  typedef typename Sacado::Promote<scalar_type_1,
996  scalar_type_2>::type scalar_type;
997 
998  typedef typename ExprT1::base_expr_type base_expr_type_1;
999  typedef typename ExprT2::base_expr_type base_expr_type_2;
1000  typedef typename Sacado::Promote<base_expr_type_1,
1001  base_expr_type_2>::type base_expr_type;
1002 
1003  static const int num_args1 = ExprT1::num_args;
1004  static const int num_args2 = ExprT2::num_args;
1005  static const int num_args = num_args1 + num_args2;
1006 
1007  static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
1008 
1010  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1011  expr1(expr1_), expr2(expr2_) {}
1012 
1014  int size() const {
1015  int sz1 = expr1.size(), sz2 = expr2.size();
1016  return sz1 > sz2 ? sz1 : sz2;
1017  }
1018 
1019  template <int Arg>
1021  bool isActive() const {
1022  if (Arg < num_args1)
1023  return expr1.template isActive<Arg>();
1024  else
1025  return expr2.template isActive<Arg-num_args1>();
1026  }
1027 
1029  bool updateValue() const {
1030  return expr1.updateValue() && expr2.updateValue();
1031  }
1032 
1034  void cache() const {
1035  expr1.cache();
1036  expr2.cache();
1037  }
1038 
1040  value_type val() const {
1041  return expr1.val()-expr2.val();
1042  }
1043 
1045  void computePartials(const value_type& bar,
1046  value_type partials[]) const {
1047  if (num_args1 > 0)
1048  expr1.computePartials(bar, partials);
1049  if (num_args2 > 0)
1050  expr2.computePartials(-bar, partials+num_args1);
1051  }
1052 
1054  void getTangents(int i, value_type dots[]) const {
1055  expr1.getTangents(i, dots);
1056  expr2.getTangents(i, dots+num_args1);
1057  }
1058 
1059  template <int Arg>
1061  value_type getTangent(int i) const {
1062  if (Arg < num_args1)
1063  return expr1.template getTangent<Arg>(i);
1064  else
1065  return expr2.template getTangent<Arg-num_args1>(i);
1066  }
1067 
1069  bool isLinear() const {
1070  return expr1.isLinear() && expr2.isLinear();
1071  }
1072 
1074  bool hasFastAccess() const {
1075  return expr1.hasFastAccess() && expr2.hasFastAccess();
1076  }
1077 
1079  const value_type dx(int i) const {
1080  return expr1.dx(i) - expr2.dx(i);
1081  }
1082 
1084  const value_type fastAccessDx(int i) const {
1085  return expr1.fastAccessDx(i) - expr2.fastAccessDx(i);
1086  }
1087 
1089  const value_type* getDx(int j) const {
1090  if (j < num_args1)
1091  return expr1.getDx(j);
1092  else
1093  return expr2.getDx(j-num_args1);
1094  }
1095 
1096  protected:
1097 
1098  const ExprT1& expr1;
1099  const ExprT2& expr2;
1100 
1101  };
1102 
1103  template <typename ExprT1, typename T2>
1104  class Expr< SubtractionOp<ExprT1, ConstExpr<T2> > > {
1105 
1106  public:
1107 
1108  typedef ConstExpr<T2> ExprT2;
1109  typedef typename ExprT1::value_type value_type_1;
1110  typedef typename ExprT2::value_type value_type_2;
1111  typedef typename Sacado::Promote<value_type_1,
1112  value_type_2>::type value_type;
1113  typedef typename ExprT1::scalar_type scalar_type_1;
1114  typedef typename ExprT2::scalar_type scalar_type_2;
1115  typedef typename Sacado::Promote<scalar_type_1,
1116  scalar_type_2>::type scalar_type;
1117 
1118  typedef typename ExprT1::base_expr_type base_expr_type_1;
1119  typedef typename ExprT2::base_expr_type base_expr_type_2;
1120  typedef typename Sacado::Promote<base_expr_type_1,
1121  base_expr_type_2>::type base_expr_type;
1122 
1123  static const int num_args = ExprT1::num_args;
1124 
1125  static const bool is_linear = ExprT1::is_linear;
1126 
1128  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1129  expr1(expr1_), expr2(expr2_) {}
1130 
1132  int size() const {
1133  return expr1.size();
1134  }
1135 
1136  template <int Arg>
1138  bool isActive() const {
1139  return expr1.template isActive<Arg>();
1140  }
1141 
1143  bool updateValue() const {
1144  return expr1.updateValue();
1145  }
1146 
1148  void cache() const {
1149  expr1.cache();
1150  }
1151 
1153  value_type val() const {
1154  return expr1.val() - expr2.val();
1155  }
1156 
1158  void computePartials(const value_type& bar,
1159  value_type partials[]) const {
1160  expr1.computePartials(bar, partials);
1161  }
1162 
1164  void getTangents(int i, value_type dots[]) const {
1165  expr1.getTangents(i, dots);
1166  }
1167 
1168  template <int Arg>
1170  value_type getTangent(int i) const {
1171  return expr1.template getTangent<Arg>(i);
1172  }
1173 
1175  bool isLinear() const {
1176  return expr1.isLinear();
1177  }
1178 
1180  bool hasFastAccess() const {
1181  return expr1.hasFastAccess();
1182  }
1183 
1185  const value_type dx(int i) const {
1186  return expr1.dx(i);
1187  }
1188 
1190  const value_type fastAccessDx(int i) const {
1191  return expr1.fastAccessDx(i);
1192  }
1193 
1195  const value_type* getDx(int j) const {
1196  return expr1.getDx(j);
1197  }
1198 
1199  protected:
1200 
1201  const ExprT1& expr1;
1202  ExprT2 expr2;
1203 
1204  };
1205 
1206  template <typename T1, typename ExprT2>
1207  class Expr< SubtractionOp< ConstExpr<T1>,ExprT2> > {
1208 
1209  public:
1210 
1211  typedef ConstExpr<T1> ExprT1;
1212  typedef typename ExprT1::value_type value_type_1;
1213  typedef typename ExprT2::value_type value_type_2;
1214  typedef typename Sacado::Promote<value_type_1,
1215  value_type_2>::type value_type;
1216  typedef typename ExprT1::scalar_type scalar_type_1;
1217  typedef typename ExprT2::scalar_type scalar_type_2;
1218  typedef typename Sacado::Promote<scalar_type_1,
1219  scalar_type_2>::type scalar_type;
1220 
1221  typedef typename ExprT1::base_expr_type base_expr_type_1;
1222  typedef typename ExprT2::base_expr_type base_expr_type_2;
1223  typedef typename Sacado::Promote<base_expr_type_1,
1224  base_expr_type_2>::type base_expr_type;
1225 
1226  static const int num_args = ExprT2::num_args;
1227 
1228  static const bool is_linear = ExprT2::is_linear;
1229 
1231  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1232  expr1(expr1_), expr2(expr2_) {}
1233 
1235  int size() const {
1236  return expr2.size();
1237  }
1238 
1239  template <int Arg>
1241  bool isActive() const {
1242  return expr2.template isActive<Arg>();
1243  }
1244 
1246  bool updateValue() const {
1247  return expr2.updateValue();
1248  }
1249 
1251  void cache() const {
1252  expr2.cache();
1253  }
1254 
1256  value_type val() const {
1257  return expr1.val() - expr2.val();
1258  }
1259 
1261  void computePartials(const value_type& bar,
1262  value_type partials[]) const {
1263  expr2.computePartials(-bar, partials);
1264  }
1265 
1267  void getTangents(int i, value_type dots[]) const {
1268  expr2.getTangents(i, dots);
1269  }
1270 
1271  template <int Arg>
1273  value_type getTangent(int i) const {
1274  return expr2.template getTangent<Arg>(i);
1275  }
1276 
1278  bool isLinear() const {
1279  return expr2.isLinear();
1280  }
1281 
1283  bool hasFastAccess() const {
1284  return expr2.hasFastAccess();
1285  }
1286 
1288  const value_type dx(int i) const {
1289  return -expr2.dx(i);
1290  }
1291 
1293  const value_type fastAccessDx(int i) const {
1294  return -expr2.fastAccessDx(i);
1295  }
1296 
1298  const value_type* getDx(int j) const {
1299  return expr2.getDx(j);
1300  }
1301 
1302  protected:
1303 
1304  ExprT1 expr1;
1305  const ExprT2& expr2;
1306 
1307  };
1308 
1309  //
1310  // MultiplicationOp
1311  //
1312 
1313  template <typename ExprT1, typename ExprT2>
1314  class MultiplicationOp {};
1315 
1316  template <typename ExprT1, typename ExprT2>
1317  class Expr< MultiplicationOp<ExprT1,ExprT2> > {
1318 
1319  public:
1320 
1321  typedef typename ExprT1::value_type value_type_1;
1322  typedef typename ExprT2::value_type value_type_2;
1323  typedef typename Sacado::Promote<value_type_1,
1324  value_type_2>::type value_type;
1325  typedef typename ExprT1::scalar_type scalar_type_1;
1326  typedef typename ExprT2::scalar_type scalar_type_2;
1327  typedef typename Sacado::Promote<scalar_type_1,
1328  scalar_type_2>::type scalar_type;
1329 
1330  typedef typename ExprT1::base_expr_type base_expr_type_1;
1331  typedef typename ExprT2::base_expr_type base_expr_type_2;
1332  typedef typename Sacado::Promote<base_expr_type_1,
1333  base_expr_type_2>::type base_expr_type;
1334 
1335  static const int num_args1 = ExprT1::num_args;
1336  static const int num_args2 = ExprT2::num_args;
1337  static const int num_args = num_args1 + num_args2;
1338 
1339  static const bool is_linear = false;
1340 
1342  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1343  expr1(expr1_), expr2(expr2_) {}
1344 
1346  int size() const {
1347  int sz1 = expr1.size(), sz2 = expr2.size();
1348  return sz1 > sz2 ? sz1 : sz2;
1349  }
1350 
1351  template <int Arg>
1353  bool isActive() const {
1354  if (Arg < num_args1)
1355  return expr1.template isActive<Arg>();
1356  else
1357  return expr2.template isActive<Arg-num_args1>();
1358  }
1359 
1361  bool updateValue() const {
1362  return expr1.updateValue() && expr2.updateValue();
1363  }
1364 
1366  void cache() const {
1367  expr1.cache();
1368  expr2.cache();
1369  v1 = expr1.val();
1370  v2 = expr2.val();
1371  }
1372 
1374  value_type val() const {
1375  return v1*v2;
1376  }
1377 
1379  void computePartials(const value_type& bar,
1380  value_type partials[]) const {
1381  if (num_args1 > 0)
1382  expr1.computePartials(bar*v2, partials);
1383  if (num_args2 > 0)
1384  expr2.computePartials(bar*v1, partials+num_args1);
1385  }
1386 
1388  void getTangents(int i, value_type dots[]) const {
1389  expr1.getTangents(i, dots);
1390  expr2.getTangents(i, dots+num_args1);
1391  }
1392 
1393  template <int Arg>
1395  value_type getTangent(int i) const {
1396  if (Arg < num_args1)
1397  return expr1.template getTangent<Arg>(i);
1398  else
1399  return expr2.template getTangent<Arg-num_args1>(i);
1400  }
1401 
1403  bool isLinear() const {
1404  return false;
1405  }
1406 
1408  bool hasFastAccess() const {
1409  return expr1.hasFastAccess() && expr2.hasFastAccess();
1410  }
1411 
1413  const value_type dx(int i) const {
1414  if (expr1.size() > 0 && expr2.size() > 0)
1415  return v1*expr2.dx(i) + expr1.dx(i)*v2;
1416  else if (expr1.size() > 0)
1417  return expr1.dx(i)*v2;
1418  else
1419  return v1*expr2.dx(i);
1420  }
1421 
1423  const value_type fastAccessDx(int i) const {
1424  return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
1425  }
1426 
1428  const value_type* getDx(int j) const {
1429  if (j < num_args1)
1430  return expr1.getDx(j);
1431  else
1432  return expr2.getDx(j-num_args1);
1433  }
1434 
1435  protected:
1436 
1437  const ExprT1& expr1;
1438  const ExprT2& expr2;
1439  mutable value_type_1 v1;
1440  mutable value_type_2 v2;
1441 
1442  };
1443 
1444  template <typename ExprT1, typename T2>
1445  class Expr< MultiplicationOp<ExprT1, ConstExpr<T2> > > {
1446 
1447  public:
1448 
1449  typedef ConstExpr<T2> ExprT2;
1450  typedef typename ExprT1::value_type value_type_1;
1451  typedef typename ExprT2::value_type value_type_2;
1452  typedef typename Sacado::Promote<value_type_1,
1453  value_type_2>::type value_type;
1454  typedef typename ExprT1::scalar_type scalar_type_1;
1455  typedef typename ExprT2::scalar_type scalar_type_2;
1456  typedef typename Sacado::Promote<scalar_type_1,
1457  scalar_type_2>::type scalar_type;
1458 
1459  typedef typename ExprT1::base_expr_type base_expr_type_1;
1460  typedef typename ExprT2::base_expr_type base_expr_type_2;
1461  typedef typename Sacado::Promote<base_expr_type_1,
1462  base_expr_type_2>::type base_expr_type;
1463 
1464  static const int num_args = ExprT1::num_args;
1465 
1466  static const bool is_linear = ExprT1::is_linear;
1467 
1469  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1470  expr1(expr1_), expr2(expr2_) {}
1471 
1473  int size() const {
1474  return expr1.size();
1475  }
1476 
1477  template <int Arg>
1479  bool isActive() const {
1480  return expr1.template isActive<Arg>();
1481  }
1482 
1484  bool updateValue() const {
1485  return expr1.updateValue();
1486  }
1487 
1489  void cache() const {
1490  expr1.cache();
1491  }
1492 
1494  value_type val() const {
1495  return expr1.val()*expr2.val();
1496  }
1497 
1499  void computePartials(const value_type& bar,
1500  value_type partials[]) const {
1501  expr1.computePartials(bar*expr2.val(), partials);
1502  }
1503 
1505  void getTangents(int i, value_type dots[]) const {
1506  expr1.getTangents(i, dots);
1507  }
1508 
1509  template <int Arg>
1511  value_type getTangent(int i) const {
1512  return expr1.template getTangent<Arg>(i);
1513  }
1514 
1516  bool isLinear() const {
1517  return expr1.isLinear();
1518  }
1519 
1521  bool hasFastAccess() const {
1522  return expr1.hasFastAccess();
1523  }
1524 
1526  const value_type dx(int i) const {
1527  return expr1.dx(i)*expr2.val();
1528  }
1529 
1531  const value_type fastAccessDx(int i) const {
1532  return expr1.fastAccessDx(i)*expr2.val();
1533  }
1534 
1536  const value_type* getDx(int j) const {
1537  return expr1.getDx(j);
1538  }
1539 
1540  protected:
1541 
1542  const ExprT1& expr1;
1543  ExprT2 expr2;
1544 
1545  };
1546 
1547  template <typename T1, typename ExprT2>
1548  class Expr< MultiplicationOp< ConstExpr<T1>,ExprT2> > {
1549 
1550  public:
1551 
1552  typedef ConstExpr<T1> ExprT1;
1553  typedef typename ExprT1::value_type value_type_1;
1554  typedef typename ExprT2::value_type value_type_2;
1555  typedef typename Sacado::Promote<value_type_1,
1556  value_type_2>::type value_type;
1557  typedef typename ExprT1::scalar_type scalar_type_1;
1558  typedef typename ExprT2::scalar_type scalar_type_2;
1559  typedef typename Sacado::Promote<scalar_type_1,
1560  scalar_type_2>::type scalar_type;
1561 
1562  typedef typename ExprT1::base_expr_type base_expr_type_1;
1563  typedef typename ExprT2::base_expr_type base_expr_type_2;
1564  typedef typename Sacado::Promote<base_expr_type_1,
1565  base_expr_type_2>::type base_expr_type;
1566 
1567  static const int num_args = ExprT2::num_args;
1568 
1569  static const bool is_linear = ExprT2::is_linear;
1570 
1572  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1573  expr1(expr1_), expr2(expr2_) {}
1574 
1576  int size() const {
1577  return expr2.size();
1578  }
1579 
1580  template <int Arg>
1582  bool isActive() const {
1583  return expr2.template isActive<Arg>();
1584  }
1585 
1587  bool updateValue() const {
1588  return expr2.updateValue();
1589  }
1590 
1592  void cache() const {
1593  expr2.cache();
1594  }
1595 
1597  value_type val() const {
1598  return expr1.val()*expr2.val();
1599  }
1600 
1602  void computePartials(const value_type& bar,
1603  value_type partials[]) const {
1604  expr2.computePartials(bar*expr1.val(), partials);
1605  }
1606 
1608  void getTangents(int i, value_type dots[]) const {
1609  expr2.getTangents(i, dots);
1610  }
1611 
1612  template <int Arg>
1614  value_type getTangent(int i) const {
1615  return expr2.template getTangent<Arg>(i);
1616  }
1617 
1619  bool isLinear() const {
1620  return expr2.isLinear();
1621  }
1622 
1624  bool hasFastAccess() const {
1625  return expr2.hasFastAccess();
1626  }
1627 
1629  const value_type dx(int i) const {
1630  return expr1.val()*expr2.dx(i);
1631  }
1632 
1634  const value_type fastAccessDx(int i) const {
1635  return expr1.val()*expr2.fastAccessDx(i);
1636  }
1637 
1639  const value_type* getDx(int j) const {
1640  return expr2.getDx(j);
1641  }
1642 
1643  protected:
1644 
1645  ExprT1 expr1;
1646  const ExprT2& expr2;
1647 
1648  };
1649 
1650  //
1651  // DivisionOp
1652  //
1653 
1654  template <typename ExprT1, typename ExprT2>
1655  class DivisionOp {};
1656 
1657  template <typename ExprT1, typename ExprT2>
1658  class Expr< DivisionOp<ExprT1,ExprT2> > {
1659 
1660  public:
1661 
1662  typedef typename ExprT1::value_type value_type_1;
1663  typedef typename ExprT2::value_type value_type_2;
1664  typedef typename Sacado::Promote<value_type_1,
1665  value_type_2>::type value_type;
1666  typedef typename ExprT1::scalar_type scalar_type_1;
1667  typedef typename ExprT2::scalar_type scalar_type_2;
1668  typedef typename Sacado::Promote<scalar_type_1,
1669  scalar_type_2>::type scalar_type;
1670 
1671  typedef typename ExprT1::base_expr_type base_expr_type_1;
1672  typedef typename ExprT2::base_expr_type base_expr_type_2;
1673  typedef typename Sacado::Promote<base_expr_type_1,
1674  base_expr_type_2>::type base_expr_type;
1675 
1676  static const int num_args1 = ExprT1::num_args;
1677  static const int num_args2 = ExprT2::num_args;
1678  static const int num_args = num_args1 + num_args2;
1679 
1680  static const bool is_linear = false;
1681 
1683  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1684  expr1(expr1_), expr2(expr2_) {}
1685 
1687  int size() const {
1688  int sz1 = expr1.size(), sz2 = expr2.size();
1689  return sz1 > sz2 ? sz1 : sz2;
1690  }
1691 
1692  template <int Arg>
1694  bool isActive() const {
1695  if (Arg < num_args1)
1696  return expr1.template isActive<Arg>();
1697  else
1698  return expr2.template isActive<Arg-num_args1>();
1699  }
1700 
1702  bool updateValue() const {
1703  return expr1.updateValue() && expr2.updateValue();
1704  }
1705 
1707  void cache() const {
1708  expr1.cache();
1709  expr2.cache();
1710  const value_type_1 v1 = expr1.val();
1711  const value_type_2 v2 = expr2.val();
1712  a = scalar_type(1.0)/v2;
1713  v = v1*a;
1714  b = -v/v2;
1715  }
1716 
1718  value_type val() const {
1719  return v;
1720  }
1721 
1723  void computePartials(const value_type& bar,
1724  value_type partials[]) const {
1725  if (num_args1 > 0)
1726  expr1.computePartials(bar*a, partials);
1727  if (num_args2 > 0)
1728  expr2.computePartials(bar*b, partials+num_args1);
1729  }
1730 
1732  void getTangents(int i, value_type dots[]) const {
1733  expr1.getTangents(i, dots);
1734  expr2.getTangents(i, dots+num_args1);
1735  }
1736 
1737  template <int Arg>
1739  value_type getTangent(int i) const {
1740  if (Arg < num_args1)
1741  return expr1.template getTangent<Arg>(i);
1742  else
1743  return expr2.template getTangent<Arg-num_args1>(i);
1744  }
1745 
1747  bool isLinear() const {
1748  return false;
1749  }
1750 
1752  bool hasFastAccess() const {
1753  return expr1.hasFastAccess() && expr2.hasFastAccess();
1754  }
1755 
1757  const value_type dx(int i) const {
1758  if (expr1.size() > 0 && expr2.size() > 0)
1759  return expr1.dx(i)*a + expr2.dx(i)*b;
1760  else if (expr1.size() > 0)
1761  return expr1.dx(i)*a;
1762  else
1763  return expr1.val()*b;
1764  }
1765 
1767  const value_type fastAccessDx(int i) const {
1768  return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1769  }
1770 
1772  const value_type* getDx(int j) const {
1773  if (j < num_args1)
1774  return expr1.getDx(j);
1775  else
1776  return expr2.getDx(j-num_args1);
1777  }
1778 
1779  protected:
1780 
1781  const ExprT1& expr1;
1782  const ExprT2& expr2;
1783  mutable value_type v;
1784  mutable value_type a;
1785  mutable value_type b;
1786 
1787  };
1788 
1789  template <typename ExprT1, typename T2>
1790  class Expr< DivisionOp<ExprT1, ConstExpr<T2> > > {
1791 
1792  public:
1793 
1794  typedef ConstExpr<T2> ExprT2;
1795  typedef typename ExprT1::value_type value_type_1;
1796  typedef typename ExprT2::value_type value_type_2;
1797  typedef typename Sacado::Promote<value_type_1,
1798  value_type_2>::type value_type;
1799  typedef typename ExprT1::scalar_type scalar_type_1;
1800  typedef typename ExprT2::scalar_type scalar_type_2;
1801  typedef typename Sacado::Promote<scalar_type_1,
1802  scalar_type_2>::type scalar_type;
1803 
1804  typedef typename ExprT1::base_expr_type base_expr_type_1;
1805  typedef typename ExprT2::base_expr_type base_expr_type_2;
1806  typedef typename Sacado::Promote<base_expr_type_1,
1807  base_expr_type_2>::type base_expr_type;
1808 
1809  static const int num_args = ExprT1::num_args;
1810 
1811  static const bool is_linear = ExprT1::is_linear;
1812 
1814  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1815  expr1(expr1_), expr2(expr2_) {}
1816 
1818  int size() const {
1819  return expr1.size();
1820  }
1821 
1822  template <int Arg>
1824  bool isActive() const {
1825  return expr1.template isActive<Arg>();
1826  }
1827 
1829  bool updateValue() const {
1830  return expr1.updateValue();
1831  }
1832 
1834  void cache() const {
1835  expr1.cache();
1836  const value_type_1 v1 = expr1.val();
1837  a = scalar_type(1.0)/expr2.val();
1838  v = v1*a;
1839  }
1840 
1842  value_type val() const {
1843  return v;
1844  }
1845 
1847  void computePartials(const value_type& bar,
1848  value_type partials[]) const {
1849  expr1.computePartials(bar*a, partials);
1850  }
1851 
1853  void getTangents(int i, value_type dots[]) const {
1854  expr1.getTangents(i, dots);
1855  }
1856 
1857  template <int Arg>
1859  value_type getTangent(int i) const {
1860  return expr1.template getTangent<Arg>(i);
1861  }
1862 
1864  bool isLinear() const {
1865  return expr1.isLinear();
1866  }
1867 
1869  bool hasFastAccess() const {
1870  return expr1.hasFastAccess();
1871  }
1872 
1874  const value_type dx(int i) const {
1875  return expr1.dx(i)*a;
1876  }
1877 
1879  const value_type fastAccessDx(int i) const {
1880  return expr1.fastAccessDx(i)*a;
1881  }
1882 
1884  const value_type* getDx(int j) const {
1885  return expr1.getDx(j);
1886  }
1887 
1888  protected:
1889 
1890  const ExprT1& expr1;
1891  ExprT2 expr2;
1892  mutable value_type v;
1893  mutable value_type a;
1894 
1895  };
1896 
1897  template <typename T1, typename ExprT2>
1898  class Expr< DivisionOp< ConstExpr<T1>,ExprT2> > {
1899 
1900  public:
1901 
1902  typedef ConstExpr<T1> ExprT1;
1903  typedef typename ExprT1::value_type value_type_1;
1904  typedef typename ExprT2::value_type value_type_2;
1905  typedef typename Sacado::Promote<value_type_1,
1906  value_type_2>::type value_type;
1907  typedef typename ExprT1::scalar_type scalar_type_1;
1908  typedef typename ExprT2::scalar_type scalar_type_2;
1909  typedef typename Sacado::Promote<scalar_type_1,
1910  scalar_type_2>::type scalar_type;
1911 
1912  typedef typename ExprT1::base_expr_type base_expr_type_1;
1913  typedef typename ExprT2::base_expr_type base_expr_type_2;
1914  typedef typename Sacado::Promote<base_expr_type_1,
1915  base_expr_type_2>::type base_expr_type;
1916 
1917  static const int num_args = ExprT2::num_args;
1918 
1919  static const bool is_linear = false;
1920 
1922  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1923  expr1(expr1_), expr2(expr2_) {}
1924 
1926  int size() const {
1927  return expr2.size();
1928  }
1929 
1930  template <int Arg>
1932  bool isActive() const {
1933  return expr2.template isActive<Arg>();
1934  }
1935 
1937  bool updateValue() const {
1938  return expr2.updateValue();
1939  }
1940 
1942  void cache() const {
1943  expr2.cache();
1944  const value_type_2 v2 = expr2.val();
1945  v = expr1.val()/v2;
1946  b = -v/v2;
1947  }
1948 
1950  value_type val() const {
1951  return v;
1952  }
1953 
1955  void computePartials(const value_type& bar,
1956  value_type partials[]) const {
1957  expr2.computePartials(bar*b, partials);
1958  }
1959 
1961  void getTangents(int i, value_type dots[]) const {
1962  expr2.getTangents(i, dots);
1963  }
1964 
1965  template <int Arg>
1967  value_type getTangent(int i) const {
1968  return expr2.template getTangent<Arg>(i);
1969  }
1970 
1972  bool isLinear() const {
1973  return false;
1974  }
1975 
1977  bool hasFastAccess() const {
1978  return expr2.hasFastAccess();
1979  }
1980 
1982  const value_type dx(int i) const {
1983  return expr2.dx(i)*b;
1984  }
1985 
1987  const value_type fastAccessDx(int i) const {
1988  return expr2.fastAccessDx(i)*b;
1989  }
1990 
1992  const value_type* getDx(int j) const {
1993  return expr2.getDx(j);
1994  }
1995 
1996  protected:
1997 
1998  ExprT1 expr1;
1999  const ExprT2& expr2;
2000  mutable value_type v;
2001  mutable value_type b;
2002 
2003  };
2004 
2005  //
2006  // Atan2Op
2007  //
2008 
2009  template <typename ExprT1, typename ExprT2>
2010  class Atan2Op {};
2011 
2012  template <typename ExprT1, typename ExprT2>
2013  class Expr< Atan2Op<ExprT1,ExprT2> > {
2014 
2015  public:
2016 
2017  typedef typename ExprT1::value_type value_type_1;
2018  typedef typename ExprT2::value_type value_type_2;
2019  typedef typename Sacado::Promote<value_type_1,
2020  value_type_2>::type value_type;
2021  typedef typename ExprT1::scalar_type scalar_type_1;
2022  typedef typename ExprT2::scalar_type scalar_type_2;
2023  typedef typename Sacado::Promote<scalar_type_1,
2024  scalar_type_2>::type scalar_type;
2025 
2026  typedef typename ExprT1::base_expr_type base_expr_type_1;
2027  typedef typename ExprT2::base_expr_type base_expr_type_2;
2028  typedef typename Sacado::Promote<base_expr_type_1,
2029  base_expr_type_2>::type base_expr_type;
2030 
2031  static const int num_args1 = ExprT1::num_args;
2032  static const int num_args2 = ExprT2::num_args;
2033  static const int num_args = num_args1 + num_args2;
2034 
2035  static const bool is_linear = false;
2036 
2038  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2039  expr1(expr1_), expr2(expr2_) {}
2040 
2042  int size() const {
2043  int sz1 = expr1.size(), sz2 = expr2.size();
2044  return sz1 > sz2 ? sz1 : sz2;
2045  }
2046 
2047  template <int Arg>
2049  bool isActive() const {
2050  if (Arg < num_args1)
2051  return expr1.template isActive<Arg>();
2052  else
2053  return expr2.template isActive<Arg-num_args1>();
2054  }
2055 
2057  bool updateValue() const {
2058  return expr1.updateValue() && expr2.updateValue();
2059  }
2060 
2062  void cache() const {
2063  expr1.cache();
2064  expr2.cache();
2065  const value_type_1 v1 = expr1.val();
2066  const value_type_2 v2 = expr2.val();
2067  a = scalar_type(1.0)/(v1*v1 + v2*v2);
2068  b = -v1*a;
2069  a = v2*a;
2070  v = std::atan2(v1,v2);
2071  }
2072 
2074  value_type val() const {
2075  return v;
2076  }
2077 
2079  void computePartials(const value_type& bar,
2080  value_type partials[]) const {
2081  if (num_args1 > 0)
2082  expr1.computePartials(bar*a, partials);
2083  if (num_args2 > 0)
2084  expr2.computePartials(bar*b, partials+num_args1);
2085  }
2086 
2088  void getTangents(int i, value_type dots[]) const {
2089  expr1.getTangents(i, dots);
2090  expr2.getTangents(i, dots+num_args1);
2091  }
2092 
2093  template <int Arg>
2095  value_type getTangent(int i) const {
2096  if (Arg < num_args1)
2097  return expr1.template getTangent<Arg>(i);
2098  else
2099  return expr2.template getTangent<Arg-num_args1>(i);
2100  }
2101 
2103  bool isLinear() const {
2104  return false;
2105  }
2106 
2108  bool hasFastAccess() const {
2109  return expr1.hasFastAccess() && expr2.hasFastAccess();
2110  }
2111 
2113  const value_type dx(int i) const {
2114  if (expr1.size() > 0 && expr2.size() > 0)
2115  return expr1.dx(i)*a + expr2.dx(i)*b;
2116  else if (expr1.size() > 0)
2117  return expr1.dx(i)*a;
2118  else
2119  return expr1.val()*b;
2120  }
2121 
2123  const value_type fastAccessDx(int i) const {
2124  return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
2125  }
2126 
2128  const value_type* getDx(int j) const {
2129  if (j < num_args1)
2130  return expr1.getDx(j);
2131  else
2132  return expr2.getDx(j-num_args1);
2133  }
2134 
2135  protected:
2136 
2137  const ExprT1& expr1;
2138  const ExprT2& expr2;
2139  mutable value_type v;
2140  mutable value_type a;
2141  mutable value_type b;
2142 
2143  };
2144 
2145  template <typename ExprT1, typename T2>
2146  class Expr< Atan2Op<ExprT1, ConstExpr<T2> > > {
2147 
2148  public:
2149 
2150  typedef ConstExpr<T2> ExprT2;
2151  typedef typename ExprT1::value_type value_type_1;
2152  typedef typename ExprT2::value_type value_type_2;
2153  typedef typename Sacado::Promote<value_type_1,
2154  value_type_2>::type value_type;
2155  typedef typename ExprT1::scalar_type scalar_type_1;
2156  typedef typename ExprT2::scalar_type scalar_type_2;
2157  typedef typename Sacado::Promote<scalar_type_1,
2158  scalar_type_2>::type scalar_type;
2159 
2160  typedef typename ExprT1::base_expr_type base_expr_type_1;
2161  typedef typename ExprT2::base_expr_type base_expr_type_2;
2162  typedef typename Sacado::Promote<base_expr_type_1,
2163  base_expr_type_2>::type base_expr_type;
2164 
2165  static const int num_args = ExprT1::num_args;
2166 
2167  static const bool is_linear = false;
2168 
2170  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2171  expr1(expr1_), expr2(expr2_) {}
2172 
2174  int size() const {
2175  return expr1.size();
2176  }
2177 
2178  template <int Arg>
2180  bool isActive() const {
2181  return expr1.template isActive<Arg>();
2182  }
2183 
2185  bool updateValue() const {
2186  return expr1.updateValue();
2187  }
2188 
2190  void cache() const {
2191  expr1.cache();
2192  const value_type_1 v1 = expr1.val();
2193  const value_type_2 v2 = expr2.val();
2194  a = v2/(v1*v1 + v2*v2);
2195  v = std::atan2(v1,v2);
2196  }
2197 
2199  value_type val() const {
2200  return v;
2201  }
2202 
2204  void computePartials(const value_type& bar,
2205  value_type partials[]) const {
2206  expr1.computePartials(bar*a, partials);
2207  }
2208 
2210  void getTangents(int i, value_type dots[]) const {
2211  expr1.getTangents(i, dots);
2212  }
2213 
2214  template <int Arg>
2216  value_type getTangent(int i) const {
2217  return expr1.template getTangent<Arg>(i);
2218  }
2219 
2221  bool isLinear() const {
2222  return false;
2223  }
2224 
2226  bool hasFastAccess() const {
2227  return expr1.hasFastAccess();
2228  }
2229 
2231  const value_type dx(int i) const {
2232  return expr1.dx(i)*a;
2233  }
2234 
2236  const value_type fastAccessDx(int i) const {
2237  return expr1.fastAccessDx(i)*a;
2238  }
2239 
2241  const value_type* getDx(int j) const {
2242  return expr1.getDx(j);
2243  }
2244 
2245  protected:
2246 
2247  const ExprT1& expr1;
2248  ExprT2 expr2;
2249  mutable value_type v;
2250  mutable value_type a;
2251 
2252  };
2253 
2254  template <typename T1, typename ExprT2>
2255  class Expr< Atan2Op< ConstExpr<T1>,ExprT2> > {
2256 
2257  public:
2258 
2259  typedef ConstExpr<T1> ExprT1;
2260  typedef typename ExprT1::value_type value_type_1;
2261  typedef typename ExprT2::value_type value_type_2;
2262  typedef typename Sacado::Promote<value_type_1,
2263  value_type_2>::type value_type;
2264  typedef typename ExprT1::scalar_type scalar_type_1;
2265  typedef typename ExprT2::scalar_type scalar_type_2;
2266  typedef typename Sacado::Promote<scalar_type_1,
2267  scalar_type_2>::type scalar_type;
2268 
2269  typedef typename ExprT1::base_expr_type base_expr_type_1;
2270  typedef typename ExprT2::base_expr_type base_expr_type_2;
2271  typedef typename Sacado::Promote<base_expr_type_1,
2272  base_expr_type_2>::type base_expr_type;
2273 
2274  static const int num_args = ExprT2::num_args;
2275 
2276  static const bool is_linear = false;
2277 
2279  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2280  expr1(expr1_), expr2(expr2_) {}
2281 
2283  int size() const {
2284  return expr2.size();
2285  }
2286 
2287  template <int Arg>
2289  bool isActive() const {
2290  return expr2.template isActive<Arg>();
2291  }
2292 
2294  bool updateValue() const {
2295  return expr2.updateValue();
2296  }
2297 
2299  void cache() const {
2300  expr2.cache();
2301  const value_type_1 v1 = expr1.val();
2302  const value_type_2 v2 = expr2.val();
2303  b = -v1/(v1*v1 + v2*v2);
2304  v = std::atan2(v1,v2);
2305  }
2306 
2308  value_type val() const {
2309  return v;
2310  }
2311 
2313  void computePartials(const value_type& bar,
2314  value_type partials[]) const {
2315  expr2.computePartials(bar*b, partials);
2316  }
2317 
2319  void getTangents(int i, value_type dots[]) const {
2320  expr2.getTangents(i, dots);
2321  }
2322 
2323  template <int Arg>
2325  value_type getTangent(int i) const {
2326  return expr2.template getTangent<Arg>(i);
2327  }
2328 
2330  bool isLinear() const {
2331  return false;
2332  }
2333 
2335  bool hasFastAccess() const {
2336  return expr2.hasFastAccess();
2337  }
2338 
2340  const value_type dx(int i) const {
2341  return expr2.dx(i)*b;
2342  }
2343 
2345  const value_type fastAccessDx(int i) const {
2346  return expr2.fastAccessDx(i)*b;
2347  }
2348 
2350  const value_type* getDx(int j) const {
2351  return expr2.getDx(j);
2352  }
2353 
2354  protected:
2355 
2356  ExprT1 expr1;
2357  const ExprT2& expr2;
2358  mutable value_type v;
2359  mutable value_type b;
2360 
2361  };
2362 
2363  //
2364  // PowerOp
2365  //
2366 
2367  template <typename ExprT1, typename ExprT2>
2368  class PowerOp {};
2369 
2370  template <typename ExprT1, typename ExprT2>
2371  class Expr< PowerOp<ExprT1,ExprT2> > {
2372 
2373  public:
2374 
2375  typedef typename ExprT1::value_type value_type_1;
2376  typedef typename ExprT2::value_type value_type_2;
2377  typedef typename Sacado::Promote<value_type_1,
2378  value_type_2>::type value_type;
2379  typedef typename ExprT1::scalar_type scalar_type_1;
2380  typedef typename ExprT2::scalar_type scalar_type_2;
2381  typedef typename Sacado::Promote<scalar_type_1,
2382  scalar_type_2>::type scalar_type;
2383 
2384  typedef typename ExprT1::base_expr_type base_expr_type_1;
2385  typedef typename ExprT2::base_expr_type base_expr_type_2;
2386  typedef typename Sacado::Promote<base_expr_type_1,
2387  base_expr_type_2>::type base_expr_type;
2388 
2389  static const int num_args1 = ExprT1::num_args;
2390  static const int num_args2 = ExprT2::num_args;
2391  static const int num_args = num_args1 + num_args2;
2392 
2393  static const bool is_linear = false;
2394 
2396  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2397  expr1(expr1_), expr2(expr2_) {}
2398 
2400  int size() const {
2401  int sz1 = expr1.size(), sz2 = expr2.size();
2402  return sz1 > sz2 ? sz1 : sz2;
2403  }
2404 
2405  template <int Arg>
2407  bool isActive() const {
2408  if (Arg < num_args1)
2409  return expr1.template isActive<Arg>();
2410  else
2411  return expr2.template isActive<Arg-num_args1>();
2412  }
2413 
2415  bool updateValue() const {
2416  return expr1.updateValue() && expr2.updateValue();
2417  }
2418 
2420  void cache() const {
2421  expr1.cache();
2422  expr2.cache();
2423  const value_type_1 v1 = expr1.val();
2424  const value_type_2 v2 = expr2.val();
2425  v = std::pow(v1,v2);
2426  if (expr2.size() == 0 && v2 == scalar_type(1.0)) {
2427  a = scalar_type(1.0);
2428  b = scalar_type(0.0);
2429  }
2430  else if (v1 == scalar_type(0.0)) {
2431  a = scalar_type(0.0);
2432  b = scalar_type(0.0);
2433  }
2434  else {
2435  a = v*v2/v1;
2436  b = v*std::log(v1);
2437  }
2438  }
2439 
2441  value_type val() const {
2442  return v;
2443  }
2444 
2446  void computePartials(const value_type& bar,
2447  value_type partials[]) const {
2448  if (num_args1 > 0)
2449  expr1.computePartials(bar*a, partials);
2450  if (num_args2 > 0)
2451  expr2.computePartials(bar*b, partials+num_args1);
2452  }
2453 
2455  void getTangents(int i, value_type dots[]) const {
2456  expr1.getTangents(i, dots);
2457  expr2.getTangents(i, dots+num_args1);
2458  }
2459 
2460  template <int Arg>
2462  value_type getTangent(int i) const {
2463  if (Arg < num_args1)
2464  return expr1.template getTangent<Arg>(i);
2465  else
2466  return expr2.template getTangent<Arg-num_args1>(i);
2467  }
2468 
2470  bool isLinear() const {
2471  return false;
2472  }
2473 
2475  bool hasFastAccess() const {
2476  return expr1.hasFastAccess() && expr2.hasFastAccess();
2477  }
2478 
2480  const value_type dx(int i) const {
2481  if (expr1.size() > 0 && expr2.size() > 0)
2482  return expr1.dx(i)*a + expr2.dx(i)*b;
2483  else if (expr1.size() > 0)
2484  return expr1.dx(i)*a;
2485  else
2486  return expr1.val()*b;
2487  }
2488 
2490  const value_type fastAccessDx(int i) const {
2491  return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
2492  }
2493 
2495  const value_type* getDx(int j) const {
2496  if (j < num_args1)
2497  return expr1.getDx(j);
2498  else
2499  return expr2.getDx(j-num_args1);
2500  }
2501 
2502  protected:
2503 
2504  const ExprT1& expr1;
2505  const ExprT2& expr2;
2506  mutable value_type v;
2507  mutable value_type a;
2508  mutable value_type b;
2509 
2510  };
2511 
2512  template <typename ExprT1, typename T2>
2513  class Expr< PowerOp<ExprT1, ConstExpr<T2> > > {
2514 
2515  public:
2516 
2517  typedef ConstExpr<T2> ExprT2;
2518  typedef typename ExprT1::value_type value_type_1;
2519  typedef typename ExprT2::value_type value_type_2;
2520  typedef typename Sacado::Promote<value_type_1,
2521  value_type_2>::type value_type;
2522  typedef typename ExprT1::scalar_type scalar_type_1;
2523  typedef typename ExprT2::scalar_type scalar_type_2;
2524  typedef typename Sacado::Promote<scalar_type_1,
2525  scalar_type_2>::type scalar_type;
2526 
2527  typedef typename ExprT1::base_expr_type base_expr_type_1;
2528  typedef typename ExprT2::base_expr_type base_expr_type_2;
2529  typedef typename Sacado::Promote<base_expr_type_1,
2530  base_expr_type_2>::type base_expr_type;
2531 
2532  static const int num_args = ExprT1::num_args;
2533 
2534  static const bool is_linear = false;
2535 
2537  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2538  expr1(expr1_), expr2(expr2_) {}
2539 
2541  int size() const {
2542  return expr1.size();
2543  }
2544 
2545  template <int Arg>
2547  bool isActive() const {
2548  return expr1.template isActive<Arg>();
2549  }
2550 
2552  bool updateValue() const {
2553  return expr1.updateValue();
2554  }
2555 
2557  void cache() const {
2558  expr1.cache();
2559  const value_type_1 v1 = expr1.val();
2560  const value_type_2 v2 = expr2.val();
2561  v = std::pow(v1,v2);
2562  if (v2 == scalar_type(1.0)) {
2563  a = scalar_type(1.0);
2564  }
2565  else if (v1 == scalar_type(0.0)) {
2566  a = scalar_type(0.0);
2567  }
2568  else {
2569  a = v*v2/v1;
2570  }
2571  }
2572 
2574  value_type val() const {
2575  return v;
2576  }
2577 
2579  void computePartials(const value_type& bar,
2580  value_type partials[]) const {
2581  expr1.computePartials(bar*a, partials);
2582  }
2583 
2585  void getTangents(int i, value_type dots[]) const {
2586  expr1.getTangents(i, dots);
2587  }
2588 
2589  template <int Arg>
2591  value_type getTangent(int i) const {
2592  return expr1.template getTangent<Arg>(i);
2593  }
2594 
2596  bool isLinear() const {
2597  return false;
2598  }
2599 
2601  bool hasFastAccess() const {
2602  return expr1.hasFastAccess();
2603  }
2604 
2606  const value_type dx(int i) const {
2607  return expr1.dx(i)*a;
2608  }
2609 
2611  const value_type fastAccessDx(int i) const {
2612  return expr1.fastAccessDx(i)*a;
2613  }
2614 
2616  const value_type* getDx(int j) const {
2617  return expr1.getDx(j);
2618  }
2619 
2620  protected:
2621 
2622  const ExprT1& expr1;
2623  ExprT2 expr2;
2624  mutable value_type v;
2625  mutable value_type a;
2626 
2627  };
2628 
2629  template <typename T1, typename ExprT2>
2630  class Expr< PowerOp< ConstExpr<T1>,ExprT2> > {
2631 
2632  public:
2633 
2634  typedef ConstExpr<T1> ExprT1;
2635  typedef typename ExprT1::value_type value_type_1;
2636  typedef typename ExprT2::value_type value_type_2;
2637  typedef typename Sacado::Promote<value_type_1,
2638  value_type_2>::type value_type;
2639  typedef typename ExprT1::scalar_type scalar_type_1;
2640  typedef typename ExprT2::scalar_type scalar_type_2;
2641  typedef typename Sacado::Promote<scalar_type_1,
2642  scalar_type_2>::type scalar_type;
2643 
2644  typedef typename ExprT1::base_expr_type base_expr_type_1;
2645  typedef typename ExprT2::base_expr_type base_expr_type_2;
2646  typedef typename Sacado::Promote<base_expr_type_1,
2647  base_expr_type_2>::type base_expr_type;
2648 
2649  static const int num_args = ExprT2::num_args;
2650 
2651  static const bool is_linear = false;
2652 
2654  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2655  expr1(expr1_), expr2(expr2_) {}
2656 
2658  int size() const {
2659  return expr2.size();
2660  }
2661 
2662  template <int Arg>
2664  bool isActive() const {
2665  return expr2.template isActive<Arg>();
2666  }
2667 
2669  bool updateValue() const {
2670  return expr2.updateValue();
2671  }
2672 
2674  void cache() const {
2675  expr2.cache();
2676  const value_type_1 v1 = expr1.val();
2677  const value_type_2 v2 = expr2.val();
2678  v = std::pow(v1,v2);
2679  if (v1 == scalar_type(0.0)) {
2680  b = scalar_type(0.0);
2681  }
2682  else {
2683  b = v*std::log(v1);
2684  }
2685  }
2686 
2688  value_type val() const {
2689  return v;
2690  }
2691 
2693  void computePartials(const value_type& bar,
2694  value_type partials[]) const {
2695  expr2.computePartials(bar*b, partials);
2696  }
2697 
2699  void getTangents(int i, value_type dots[]) const {
2700  expr2.getTangents(i, dots);
2701  }
2702 
2703  template <int Arg>
2705  value_type getTangent(int i) const {
2706  return expr2.template getTangent<Arg>(i);
2707  }
2708 
2710  bool isLinear() const {
2711  return false;
2712  }
2713 
2715  bool hasFastAccess() const {
2716  return expr2.hasFastAccess();
2717  }
2718 
2720  const value_type dx(int i) const {
2721  return expr2.dx(i)*b;
2722  }
2723 
2725  const value_type fastAccessDx(int i) const {
2726  return expr2.fastAccessDx(i)*b;
2727  }
2728 
2730  const value_type* getDx(int j) const {
2731  return expr2.getDx(j);
2732  }
2733 
2734  protected:
2735 
2736  ExprT1 expr1;
2737  const ExprT2& expr2;
2738  mutable value_type v;
2739  mutable value_type b;
2740 
2741  };
2742 
2743  //
2744  // MaxOp
2745  //
2746 
2747  template <typename ExprT1, typename ExprT2>
2748  class MaxOp {};
2749 
2750  template <typename ExprT1, typename ExprT2>
2751  class Expr< MaxOp<ExprT1,ExprT2> > {
2752 
2753  public:
2754 
2755  typedef typename ExprT1::value_type value_type_1;
2756  typedef typename ExprT2::value_type value_type_2;
2757  typedef typename Sacado::Promote<value_type_1,
2758  value_type_2>::type value_type;
2759  typedef typename ExprT1::scalar_type scalar_type_1;
2760  typedef typename ExprT2::scalar_type scalar_type_2;
2761  typedef typename Sacado::Promote<scalar_type_1,
2762  scalar_type_2>::type scalar_type;
2763 
2764  typedef typename ExprT1::base_expr_type base_expr_type_1;
2765  typedef typename ExprT2::base_expr_type base_expr_type_2;
2766  typedef typename Sacado::Promote<base_expr_type_1,
2767  base_expr_type_2>::type base_expr_type;
2768 
2769  static const int num_args1 = ExprT1::num_args;
2770  static const int num_args2 = ExprT2::num_args;
2771  static const int num_args = num_args1 + num_args2;
2772 
2773  static const bool is_linear = false;
2774 
2776  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2777  expr1(expr1_), expr2(expr2_) {}
2778 
2780  int size() const {
2781  int sz1 = expr1.size(), sz2 = expr2.size();
2782  return sz1 > sz2 ? sz1 : sz2;
2783  }
2784 
2785  template <int Arg>
2787  bool isActive() const {
2788  if (Arg < num_args1)
2789  return expr1.template isActive<Arg>();
2790  else
2791  return expr2.template isActive<Arg-num_args1>();
2792  }
2793 
2795  bool updateValue() const {
2796  return expr1.updateValue() && expr2.updateValue();
2797  }
2798 
2800  void cache() const {
2801  expr1.cache();
2802  expr2.cache();
2803  const value_type_1 v1 = expr1.val();
2804  const value_type_2 v2 = expr2.val();
2805  max_v1 = (v1 >= v2);
2806  v = max_v1 ? v1 : v2;
2807  }
2808 
2810  value_type val() const {
2811  return v;
2812  }
2813 
2815  void computePartials(const value_type& bar,
2816  value_type partials[]) const {
2817  if (num_args1 > 0) {
2818  if (max_v1)
2819  expr1.computePartials(bar, partials);
2820  else
2821  expr1.computePartials(value_type(0.0), partials);
2822  }
2823  if (num_args2 > 0) {
2824  if (max_v1)
2825  expr2.computePartials(value_type(0.0), partials+num_args1);
2826  else
2827  expr2.computePartials(bar, partials+num_args1);
2828  }
2829  }
2830 
2832  void getTangents(int i, value_type dots[]) const {
2833  expr1.getTangents(i, dots);
2834  expr2.getTangents(i, dots+num_args1);
2835  }
2836 
2837  template <int Arg>
2839  value_type getTangent(int i) const {
2840  if (Arg < num_args1)
2841  return expr1.template getTangent<Arg>(i);
2842  else
2843  return expr2.template getTangent<Arg-num_args1>(i);
2844  }
2845 
2847  bool isLinear() const {
2848  return false;
2849  }
2850 
2852  bool hasFastAccess() const {
2853  return expr1.hasFastAccess() && expr2.hasFastAccess();
2854  }
2855 
2857  const value_type dx(int i) const {
2858  return max_v1 ? expr1.dx(i) : expr2.dx(i);
2859  }
2860 
2862  const value_type fastAccessDx(int i) const {
2863  return max_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2864  }
2865 
2867  const value_type* getDx(int j) const {
2868  if (j < num_args1)
2869  return expr1.getDx(j);
2870  else
2871  return expr2.getDx(j-num_args1);
2872  }
2873 
2874  protected:
2875 
2876  const ExprT1& expr1;
2877  const ExprT2& expr2;
2878  mutable value_type v;
2879  mutable bool max_v1;
2880 
2881  };
2882 
2883  template <typename ExprT1, typename T2>
2884  class Expr< MaxOp<ExprT1, ConstExpr<T2> > > {
2885 
2886  public:
2887 
2888  typedef ConstExpr<T2> ExprT2;
2889  typedef typename ExprT1::value_type value_type_1;
2890  typedef typename ExprT2::value_type value_type_2;
2891  typedef typename Sacado::Promote<value_type_1,
2892  value_type_2>::type value_type;
2893  typedef typename ExprT1::scalar_type scalar_type_1;
2894  typedef typename ExprT2::scalar_type scalar_type_2;
2895  typedef typename Sacado::Promote<scalar_type_1,
2896  scalar_type_2>::type scalar_type;
2897 
2898  typedef typename ExprT1::base_expr_type base_expr_type_1;
2899  typedef typename ExprT2::base_expr_type base_expr_type_2;
2900  typedef typename Sacado::Promote<base_expr_type_1,
2901  base_expr_type_2>::type base_expr_type;
2902 
2903  static const int num_args = ExprT1::num_args;
2904 
2905  static const bool is_linear = false;
2906 
2908  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2909  expr1(expr1_), expr2(expr2_) {}
2910 
2912  int size() const {
2913  return expr1.size();
2914  }
2915 
2916  template <int Arg>
2918  bool isActive() const {
2919  return expr1.template isActive<Arg>();
2920  }
2921 
2923  bool updateValue() const {
2924  return expr1.updateValue();
2925  }
2926 
2928  void cache() const {
2929  expr1.cache();
2930  const value_type_1 v1 = expr1.val();
2931  const value_type_2 v2 = expr2.val();
2932  max_v1 = (v1 >= v2);
2933  v = max_v1 ? v1 : v2;
2934  }
2935 
2937  value_type val() const {
2938  return v;
2939  }
2940 
2942  void computePartials(const value_type& bar,
2943  value_type partials[]) const {
2944  if (max_v1)
2945  expr1.computePartials(bar, partials);
2946  else
2947  expr1.computePartials(value_type(0.0), partials);
2948  }
2949 
2951  void getTangents(int i, value_type dots[]) const {
2952  expr1.getTangents(i, dots);
2953  }
2954 
2955  template <int Arg>
2957  value_type getTangent(int i) const {
2958  return expr1.template getTangent<Arg>(i);
2959  }
2960 
2962  bool isLinear() const {
2963  return false;
2964  }
2965 
2967  bool hasFastAccess() const {
2968  return expr1.hasFastAccess();
2969  }
2970 
2972  const value_type dx(int i) const {
2973  return max_v1 ? expr1.dx(i) : value_type(0.0);
2974  }
2975 
2977  const value_type fastAccessDx(int i) const {
2978  return max_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
2979  }
2980 
2982  const value_type* getDx(int j) const {
2983  return expr1.getDx(j);
2984  }
2985 
2986  protected:
2987 
2988  const ExprT1& expr1;
2989  ExprT2 expr2;
2990  mutable value_type v;
2991  mutable bool max_v1;
2992 
2993  };
2994 
2995  template <typename T1, typename ExprT2>
2996  class Expr< MaxOp< ConstExpr<T1>,ExprT2> > {
2997 
2998  public:
2999 
3000  typedef ConstExpr<T1> ExprT1;
3001  typedef typename ExprT1::value_type value_type_1;
3002  typedef typename ExprT2::value_type value_type_2;
3003  typedef typename Sacado::Promote<value_type_1,
3004  value_type_2>::type value_type;
3005  typedef typename ExprT1::scalar_type scalar_type_1;
3006  typedef typename ExprT2::scalar_type scalar_type_2;
3007  typedef typename Sacado::Promote<scalar_type_1,
3008  scalar_type_2>::type scalar_type;
3009 
3010  typedef typename ExprT1::base_expr_type base_expr_type_1;
3011  typedef typename ExprT2::base_expr_type base_expr_type_2;
3012  typedef typename Sacado::Promote<base_expr_type_1,
3013  base_expr_type_2>::type base_expr_type;
3014 
3015  static const int num_args = ExprT2::num_args;
3016 
3017  static const bool is_linear = false;
3018 
3020  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3021  expr1(expr1_), expr2(expr2_) {}
3022 
3024  int size() const {
3025  return expr2.size();
3026  }
3027 
3028  template <int Arg>
3030  bool isActive() const {
3031  return expr2.template isActive<Arg>();
3032  }
3033 
3035  bool updateValue() const {
3036  return expr2.updateValue();
3037  }
3038 
3040  void cache() const {
3041  expr2.cache();
3042  const value_type_1 v1 = expr1.val();
3043  const value_type_2 v2 = expr2.val();
3044  max_v1 = (v1 >= v2);
3045  v = max_v1 ? v1 : v2;
3046  }
3047 
3049  value_type val() const {
3050  return v;
3051  }
3052 
3054  void computePartials(const value_type& bar,
3055  value_type partials[]) const {
3056  if (max_v1)
3057  expr2.computePartials(value_type(0.0), partials);
3058  else
3059  expr2.computePartials(bar, partials);
3060  }
3061 
3063  void getTangents(int i, value_type dots[]) const {
3064  expr2.getTangents(i, dots);
3065  }
3066 
3067  template <int Arg>
3069  value_type getTangent(int i) const {
3070  return expr2.template getTangent<Arg>(i);
3071  }
3072 
3074  bool isLinear() const {
3075  return false;
3076  }
3077 
3079  bool hasFastAccess() const {
3080  return expr2.hasFastAccess();
3081  }
3082 
3084  const value_type dx(int i) const {
3085  return max_v1 ? value_type(0.0) : expr2.dx(i);
3086  }
3087 
3089  const value_type fastAccessDx(int i) const {
3090  return max_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3091  }
3092 
3094  const value_type* getDx(int j) const {
3095  return expr2.getDx(j);
3096  }
3097 
3098  protected:
3099 
3100  ExprT1 expr1;
3101  const ExprT2& expr2;
3102  mutable value_type v;
3103  mutable bool max_v1;
3104 
3105  };
3106 
3107  //
3108  // MinOp
3109  //
3110 
3111  template <typename ExprT1, typename ExprT2>
3112  class MinOp {};
3113 
3114  template <typename ExprT1, typename ExprT2>
3115  class Expr< MinOp<ExprT1,ExprT2> > {
3116 
3117  public:
3118 
3119  typedef typename ExprT1::value_type value_type_1;
3120  typedef typename ExprT2::value_type value_type_2;
3121  typedef typename Sacado::Promote<value_type_1,
3122  value_type_2>::type value_type;
3123  typedef typename ExprT1::scalar_type scalar_type_1;
3124  typedef typename ExprT2::scalar_type scalar_type_2;
3125  typedef typename Sacado::Promote<scalar_type_1,
3126  scalar_type_2>::type scalar_type;
3127 
3128  typedef typename ExprT1::base_expr_type base_expr_type_1;
3129  typedef typename ExprT2::base_expr_type base_expr_type_2;
3130  typedef typename Sacado::Promote<base_expr_type_1,
3131  base_expr_type_2>::type base_expr_type;
3132 
3133  static const int num_args1 = ExprT1::num_args;
3134  static const int num_args2 = ExprT2::num_args;
3135  static const int num_args = num_args1 + num_args2;
3136 
3137  static const bool is_linear = false;
3138 
3140  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3141  expr1(expr1_), expr2(expr2_) {}
3142 
3144  int size() const {
3145  int sz1 = expr1.size(), sz2 = expr2.size();
3146  return sz1 > sz2 ? sz1 : sz2;
3147  }
3148 
3149  template <int Arg>
3151  bool isActive() const {
3152  if (Arg < num_args1)
3153  return expr1.template isActive<Arg>();
3154  else
3155  return expr2.template isActive<Arg-num_args1>();
3156  }
3157 
3159  bool updateValue() const {
3160  return expr1.updateValue() && expr2.updateValue();
3161  }
3162 
3164  void cache() const {
3165  expr1.cache();
3166  expr2.cache();
3167  const value_type_1 v1 = expr1.val();
3168  const value_type_2 v2 = expr2.val();
3169  min_v1 = (v1 <= v2);
3170  v = min_v1 ? v1 : v2;
3171  }
3172 
3174  value_type val() const {
3175  return v;
3176  }
3177 
3179  void computePartials(const value_type& bar,
3180  value_type partials[]) const {
3181  if (num_args1 > 0) {
3182  if (min_v1)
3183  expr1.computePartials(bar, partials);
3184  else
3185  expr1.computePartials(value_type(0.0), partials);
3186  }
3187  if (num_args2 > 0) {
3188  if (min_v1)
3189  expr2.computePartials(value_type(0.0), partials+num_args1);
3190  else
3191  expr2.computePartials(bar, partials+num_args1);
3192  }
3193  }
3194 
3196  void getTangents(int i, value_type dots[]) const {
3197  expr1.getTangents(i, dots);
3198  expr2.getTangents(i, dots+num_args1);
3199  }
3200 
3201  template <int Arg>
3203  value_type getTangent(int i) const {
3204  if (Arg < num_args1)
3205  return expr1.template getTangent<Arg>(i);
3206  else
3207  return expr2.template getTangent<Arg-num_args1>(i);
3208  }
3209 
3211  bool isLinear() const {
3212  return false;
3213  }
3214 
3216  bool hasFastAccess() const {
3217  return expr1.hasFastAccess() && expr2.hasFastAccess();
3218  }
3219 
3221  const value_type dx(int i) const {
3222  return min_v1 ? expr1.dx(i) : expr2.dx(i);
3223  }
3224 
3226  const value_type fastAccessDx(int i) const {
3227  return min_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
3228  }
3229 
3231  const value_type* getDx(int j) const {
3232  if (j < num_args1)
3233  return expr1.getDx(j);
3234  else
3235  return expr2.getDx(j-num_args1);
3236  }
3237 
3238  protected:
3239 
3240  const ExprT1& expr1;
3241  const ExprT2& expr2;
3242  mutable value_type v;
3243  mutable bool min_v1;
3244 
3245  };
3246 
3247  template <typename ExprT1, typename T2>
3248  class Expr< MinOp<ExprT1, ConstExpr<T2> > > {
3249 
3250  public:
3251 
3252  typedef ConstExpr<T2> ExprT2;
3253  typedef typename ExprT1::value_type value_type_1;
3254  typedef typename ExprT2::value_type value_type_2;
3255  typedef typename Sacado::Promote<value_type_1,
3256  value_type_2>::type value_type;
3257  typedef typename ExprT1::scalar_type scalar_type_1;
3258  typedef typename ExprT2::scalar_type scalar_type_2;
3259  typedef typename Sacado::Promote<scalar_type_1,
3260  scalar_type_2>::type scalar_type;
3261 
3262  typedef typename ExprT1::base_expr_type base_expr_type_1;
3263  typedef typename ExprT2::base_expr_type base_expr_type_2;
3264  typedef typename Sacado::Promote<base_expr_type_1,
3265  base_expr_type_2>::type base_expr_type;
3266 
3267  static const int num_args = ExprT1::num_args;
3268 
3269  static const bool is_linear = false;
3270 
3272  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3273  expr1(expr1_), expr2(expr2_) {}
3274 
3276  int size() const {
3277  return expr1.size();
3278  }
3279 
3280  template <int Arg>
3282  bool isActive() const {
3283  return expr1.template isActive<Arg>();
3284  }
3285 
3287  bool updateValue() const {
3288  return expr1.updateValue();
3289  }
3290 
3292  void cache() const {
3293  expr1.cache();
3294  const value_type_1 v1 = expr1.val();
3295  const value_type_2 v2 = expr2.val();
3296  min_v1 = (v1 <= v2);
3297  v = min_v1 ? v1 : v2;
3298  }
3299 
3301  value_type val() const {
3302  return v;
3303  }
3304 
3306  void computePartials(const value_type& bar,
3307  value_type partials[]) const {
3308  if (min_v1)
3309  expr1.computePartials(bar, partials);
3310  else
3311  expr1.computePartials(value_type(0.0), partials);
3312  }
3313 
3315  void getTangents(int i, value_type dots[]) const {
3316  expr1.getTangents(i, dots);
3317  }
3318 
3319  template <int Arg>
3321  value_type getTangent(int i) const {
3322  return expr1.template getTangent<Arg>(i);
3323  }
3324 
3326  bool isLinear() const {
3327  return false;
3328  }
3329 
3331  bool hasFastAccess() const {
3332  return expr1.hasFastAccess();
3333  }
3334 
3336  const value_type dx(int i) const {
3337  return min_v1 ? expr1.dx(i) : value_type(0.0);
3338  }
3339 
3341  const value_type fastAccessDx(int i) const {
3342  return min_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
3343  }
3344 
3346  const value_type* getDx(int j) const {
3347  return expr1.getDx(j);
3348  }
3349 
3350  protected:
3351 
3352  const ExprT1& expr1;
3353  ExprT2 expr2;
3354  mutable value_type v;
3355  mutable bool min_v1;
3356 
3357  };
3358 
3359  template <typename T1, typename ExprT2>
3360  class Expr< MinOp< ConstExpr<T1>,ExprT2> > {
3361 
3362  public:
3363 
3364  typedef ConstExpr<T1> ExprT1;
3365  typedef typename ExprT1::value_type value_type_1;
3366  typedef typename ExprT2::value_type value_type_2;
3367  typedef typename Sacado::Promote<value_type_1,
3368  value_type_2>::type value_type;
3369  typedef typename ExprT1::scalar_type scalar_type_1;
3370  typedef typename ExprT2::scalar_type scalar_type_2;
3371  typedef typename Sacado::Promote<scalar_type_1,
3372  scalar_type_2>::type scalar_type;
3373 
3374  typedef typename ExprT1::base_expr_type base_expr_type_1;
3375  typedef typename ExprT2::base_expr_type base_expr_type_2;
3376  typedef typename Sacado::Promote<base_expr_type_1,
3377  base_expr_type_2>::type base_expr_type;
3378 
3379  static const int num_args = ExprT2::num_args;
3380 
3381  static const bool is_linear = false;
3382 
3384  Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3385  expr1(expr1_), expr2(expr2_) {}
3386 
3388  int size() const {
3389  return expr2.size();
3390  }
3391 
3392  template <int Arg>
3394  bool isActive() const {
3395  return expr2.template isActive<Arg>();
3396  }
3397 
3399  bool updateValue() const {
3400  return expr2.updateValue();
3401  }
3402 
3404  void cache() const {
3405  expr2.cache();
3406  const value_type_1 v1 = expr1.val();
3407  const value_type_2 v2 = expr2.val();
3408  min_v1 = (v1 <= v2);
3409  v = min_v1 ? v1 : v2;
3410  }
3411 
3413  value_type val() const {
3414  return v;
3415  }
3416 
3418  void computePartials(const value_type& bar,
3419  value_type partials[]) const {
3420  if (min_v1)
3421  expr2.computePartials(value_type(0.0), partials);
3422  else
3423  expr2.computePartials(bar, partials);
3424  }
3425 
3427  void getTangents(int i, value_type dots[]) const {
3428  expr2.getTangents(i, dots);
3429  }
3430 
3431  template <int Arg>
3433  value_type getTangent(int i) const {
3434  return expr2.template getTangent<Arg>(i);
3435  }
3436 
3438  bool isLinear() const {
3439  return false;
3440  }
3441 
3443  bool hasFastAccess() const {
3444  return expr2.hasFastAccess();
3445  }
3446 
3448  const value_type dx(int i) const {
3449  return min_v1 ? value_type(0.0) : expr2.dx(i);
3450  }
3451 
3453  const value_type fastAccessDx(int i) const {
3454  return min_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3455  }
3456 
3458  const value_type* getDx(int j) const {
3459  return expr2.getDx(j);
3460  }
3461 
3462  protected:
3463 
3464  ExprT1 expr1;
3465  const ExprT2& expr2;
3466  mutable value_type v;
3467  mutable bool min_v1;
3468 
3469  };
3470 
3471  }
3472 
3473 }
3474 
3475 #define FAD_BINARYOP_MACRO(OPNAME,OP) \
3476 namespace Sacado { \
3477  namespace ELRCacheFad { \
3478  \
3479  template <typename T1, typename T2> \
3480  SACADO_INLINE_FUNCTION \
3481  SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \
3482  OPNAME (const T1& expr1, const T2& expr2) \
3483  { \
3484  typedef OP< T1, T2 > expr_t; \
3485  \
3486  return Expr<expr_t>(expr1, expr2); \
3487  } \
3488  \
3489  template <typename T> \
3490  SACADO_INLINE_FUNCTION \
3491  Expr< OP< Expr<T>, Expr<T> > > \
3492  OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
3493  { \
3494  typedef OP< Expr<T>, Expr<T> > expr_t; \
3495  \
3496  return Expr<expr_t>(expr1, expr2); \
3497  } \
3498  \
3499  template <typename T> \
3500  SACADO_INLINE_FUNCTION \
3501  Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
3502  Expr<T> > > \
3503  OPNAME (const typename Expr<T>::value_type& c, \
3504  const Expr<T>& expr) \
3505  { \
3506  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3507  typedef OP< ConstT, Expr<T> > expr_t; \
3508  \
3509  return Expr<expr_t>(ConstT(c), expr); \
3510  } \
3511  \
3512  template <typename T> \
3513  SACADO_INLINE_FUNCTION \
3514  Expr< OP< Expr<T>, \
3515  ConstExpr<typename Expr<T>::value_type> > > \
3516  OPNAME (const Expr<T>& expr, \
3517  const typename Expr<T>::value_type& c) \
3518  { \
3519  typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3520  typedef OP< Expr<T>, ConstT > expr_t; \
3521  \
3522  return Expr<expr_t>(expr, ConstT(c)); \
3523  } \
3524  \
3525  template <typename T> \
3526  SACADO_INLINE_FUNCTION \
3527  SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \
3528  OPNAME (const typename Expr<T>::scalar_type& c, \
3529  const Expr<T>& expr) \
3530  { \
3531  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3532  typedef OP< ConstT, Expr<T> > expr_t; \
3533  \
3534  return Expr<expr_t>(ConstT(c), expr); \
3535  } \
3536  \
3537  template <typename T> \
3538  SACADO_INLINE_FUNCTION \
3539  SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \
3540  OPNAME (const Expr<T>& expr, \
3541  const typename Expr<T>::scalar_type& c) \
3542  { \
3543  typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3544  typedef OP< Expr<T>, ConstT > expr_t; \
3545  \
3546  return Expr<expr_t>(expr, ConstT(c)); \
3547  } \
3548  } \
3549 }
3550 
3551 
3552 FAD_BINARYOP_MACRO(operator+, AdditionOp)
3555 FAD_BINARYOP_MACRO(operator/, DivisionOp)
3560 
3561 #undef FAD_BINARYOP_MACRO
3562 
3563 //-------------------------- Relational Operators -----------------------
3564 
3565 #define FAD_RELOP_MACRO(OP) \
3566 namespace Sacado { \
3567  namespace ELRCacheFad { \
3568  template <typename ExprT1, typename ExprT2> \
3569  SACADO_INLINE_FUNCTION \
3570  bool \
3571  operator OP (const Expr<ExprT1>& expr1, \
3572  const Expr<ExprT2>& expr2) \
3573  { \
3574  expr1.cache(); \
3575  expr2.cache(); \
3576  return expr1.val() OP expr2.val(); \
3577  } \
3578  \
3579  template <typename ExprT2> \
3580  SACADO_INLINE_FUNCTION \
3581  bool \
3582  operator OP (const typename Expr<ExprT2>::value_type& a, \
3583  const Expr<ExprT2>& expr2) \
3584  { \
3585  expr2.cache(); \
3586  return a OP expr2.val(); \
3587  } \
3588  \
3589  template <typename ExprT1> \
3590  SACADO_INLINE_FUNCTION \
3591  bool \
3592  operator OP (const Expr<ExprT1>& expr1, \
3593  const typename Expr<ExprT1>::value_type& b) \
3594  { \
3595  expr1.cache(); \
3596  return expr1.val() OP b; \
3597  } \
3598  } \
3599 }
3600 
3601 FAD_RELOP_MACRO(==)
3602 FAD_RELOP_MACRO(!=)
3603 FAD_RELOP_MACRO(<)
3604 FAD_RELOP_MACRO(>)
3605 FAD_RELOP_MACRO(<=)
3606 FAD_RELOP_MACRO(>=)
3607 FAD_RELOP_MACRO(<<=)
3608 FAD_RELOP_MACRO(>>=)
3609 FAD_RELOP_MACRO(&)
3610 FAD_RELOP_MACRO(|)
3611 
3612 #undef FAD_RELOP_MACRO
3613 
3614 namespace Sacado {
3615 
3616  namespace ELRCacheFad {
3617 
3618  template <typename ExprT>
3620  bool operator ! (const Expr<ExprT>& expr)
3621  {
3622  expr.cache();
3623  return ! expr.val();
3624  }
3625 
3626  } // namespace ELRCacheFad
3627 
3628 } // namespace Sacado
3629 
3630 //-------------------------- Boolean Operators -----------------------
3631 namespace Sacado {
3632 
3633  namespace ELRCacheFad {
3634 
3635  template <typename ExprT>
3637  bool toBool(const Expr<ExprT>& x) {
3638  x.cache();
3639  bool is_zero = (x.val() == 0.0);
3640  for (int i=0; i<x.size(); i++)
3641  is_zero = is_zero && (x.dx(i) == 0.0);
3642  return !is_zero;
3643  }
3644 
3645  } // namespace Fad
3646 
3647 } // namespace Sacado
3648 
3649 #define FAD_BOOL_MACRO(OP) \
3650 namespace Sacado { \
3651  namespace ELRCacheFad { \
3652  template <typename ExprT1, typename ExprT2> \
3653  SACADO_INLINE_FUNCTION \
3654  bool \
3655  operator OP (const Expr<ExprT1>& expr1, \
3656  const Expr<ExprT2>& expr2) \
3657  { \
3658  return toBool(expr1) OP toBool(expr2); \
3659  } \
3660  \
3661  template <typename ExprT2> \
3662  SACADO_INLINE_FUNCTION \
3663  bool \
3664  operator OP (const typename Expr<ExprT2>::value_type& a, \
3665  const Expr<ExprT2>& expr2) \
3666  { \
3667  return a OP toBool(expr2); \
3668  } \
3669  \
3670  template <typename ExprT1> \
3671  SACADO_INLINE_FUNCTION \
3672  bool \
3673  operator OP (const Expr<ExprT1>& expr1, \
3674  const typename Expr<ExprT1>::value_type& b) \
3675  { \
3676  return toBool(expr1) OP b; \
3677  } \
3678  } \
3679 }
3680 
3681 FAD_BOOL_MACRO(&&)
3682 FAD_BOOL_MACRO(||)
3683 
3684 #undef FAD_BOOL_MACRO
3685 
3686 //-------------------------- I/O Operators -----------------------
3687 
3688 namespace Sacado {
3689 
3690  namespace ELRCacheFad {
3691 
3692  template <typename ExprT>
3693  std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
3694  os << x.val() << " [";
3695 
3696  for (int i=0; i< x.size(); i++) {
3697  os << " " << x.dx(i);
3698  }
3699 
3700  os << " ]";
3701  return os;
3702  }
3703 
3704  } // namespace Fad
3705 
3706 } // namespace Sacado
3707 
3708 #endif // SACADO_CACHEFAD_OPS_HPP
cbrt(expr.val())
SACADO_INLINE_FUNCTION bool isActive() const
SACADO_INLINE_FUNCTION void cache() const
expr expr SinOp
SACADO_INLINE_FUNCTION const value_type dx(int i) const
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
asinh(expr.val())
SACADO_INLINE_FUNCTION value_type getTangent(int i) const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION value_type getTangent(int i) const
#define FAD_UNARYOP_MACRO(OPNAME, OP, USING, VALUE, DX, FASTACCESSDX)
asin(expr.val())
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
cosh(expr.val())
expr expr dx(i)
abs(expr.val())
atanh(expr.val())
SACADO_INLINE_FUNCTION const value_type dx(int i) const
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
expr expr CoshOp
expr expr ATanhOp
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
expr expr TanhOp
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION bool updateValue() const
expr expr SqrtOp
expr expr ASinhOp
expr bar
atan(expr.val())
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
SACADO_INLINE_FUNCTION bool toBool(const Expr< ExprT > &x)
SACADO_INLINE_FUNCTION bool isLinear() const
SACADO_INLINE_FUNCTION Expr< FAbsOp< Expr< T > > > fabs(const Expr< T > &expr)
SACADO_INLINE_FUNCTION bool hasFastAccess() 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()
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
tanh(expr.val())
expr expr CosOp
SACADO_INLINE_FUNCTION bool updateValue() 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)
SACADO_INLINE_FUNCTION value_type getTangent(int i) const
expr expr ATanOp
SACADO_INLINE_FUNCTION value_type val() const
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
SACADO_INLINE_FUNCTION Expr< UnaryPlusOp< Expr< T > > > operator+(const Expr< T > &expr)
expr expr ACosOp
#define FAD_RELOP_MACRO(OP)
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
sqrt(expr.val())
Wrapper for a generic expression template.
sinh(expr.val())
tan(expr.val())
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 expr1 expr1 c *expr2 expr1 c *expr2 expr1 c *expr2 expr1 DivisionOp
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
SACADO_INLINE_FUNCTION void cache() const
#define FAD_BOOL_MACRO(OP)
atan2(expr1.val(), expr2.val())
SACADO_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION Expr< AbsOp< Expr< T > > > abs(const Expr< T > &expr)
sin(expr.val())
SACADO_INLINE_FUNCTION const value_type dx(int i) const
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
SACADO_INLINE_FUNCTION T safe_sqrt(const T &x)
log(expr.val())
expr expr ACoshOp
expr expr Log10Op
expr expr SinhOp
acosh(expr.val())
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION Expr< UnaryMinusOp< Expr< T > > > operator-(const Expr< T > &expr)
SACADO_INLINE_FUNCTION const value_type dx(int i) const
acos(expr.val())
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
expr expr ASinOp
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION bool isActive() const
SACADO_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)
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
SACADO_INLINE_FUNCTION bool hasFastAccess() const
#define SACADO_INLINE_FUNCTION
exp(expr.val())
expr expr expr ExpOp
SACADO_INLINE_FUNCTION bool isLinear() const
fabs(expr.val())
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
expr expr TanOp
log10(expr.val())
Base template specification for Promote.
cos(expr.val())
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