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