Sacado Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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
60namespace 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) \
350namespace 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))
436FAD_UNARYOP_MACRO(safe_sqrt,
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
496
497//
498// Binary operators
499//
500namespace 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) \
2442namespace 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
2526
2527#undef FAD_BINARYOP_MACRO
2528
2529//-------------------------- Relational Operators -----------------------
2530
2531#define FAD_RELOP_MACRO(OP) \
2532namespace 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
2573FAD_RELOP_MACRO(<<=)
2574FAD_RELOP_MACRO(>>=)
2577
2578#undef FAD_RELOP_MACRO
2579
2580namespace 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 -----------------------
2597namespace 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) \
2616namespace 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
2649
2650#undef FAD_BOOL_MACRO
2651
2652//-------------------------- I/O Operators -----------------------
2653
2654namespace 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
#define FAD_BINARYOP_MACRO(OPNAME, OP)
#define FAD_RELOP_MACRO(OP)
#define FAD_BOOL_MACRO(OP)
#define FAD_UNARYOP_MACRO(OPNAME, OP, PARTIAL, VALUE)
#define SACADO_INLINE_FUNCTION
expr expr dx(i)
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
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
expr expr expr ExpOp
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
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 expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 Atan2Op
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
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
#define T1(r, f)
#define T2(r, f)
SACADO_INLINE_FUNCTION void cache() const
SACADO_INLINE_FUNCTION int size() const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION const value_type dx(int i) const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SACADO_INLINE_FUNCTION bool isLinear() const
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION int size() const
SACADO_INLINE_FUNCTION void cache() const
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION const value_type dx(int i) const
SACADO_INLINE_FUNCTION bool isLinear() const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION const value_type dx(int i) const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION const value_type dx(int i) const
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION bool isLinear() const
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION bool updateValue() const
Wrapper for a generic expression template.
SACADO_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
SACADO_INLINE_FUNCTION bool toBool(const Expr< ExprT > &x)
SACADO_INLINE_FUNCTION Expr< UnaryPlusOp< Expr< T > > > operator+(const Expr< T > &expr)
SACADO_INLINE_FUNCTION Expr< AbsOp< Expr< T > > > abs(const Expr< T > &expr)
std::ostream & operator<<(std::ostream &os, const Expr< ExprT > &x)
SACADO_INLINE_FUNCTION Expr< FAbsOp< Expr< T > > > fabs(const Expr< T > &expr)
SACADO_INLINE_FUNCTION Expr< UnaryMinusOp< Expr< T > > > operator-(const Expr< T > &expr)
Base template specification for Promote.