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