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))
490 a = value_type(1)/(value_type(3)*std::cbrt(v*v)),
491 std::cbrt(v))
492
493#undef FAD_UNARYOP_MACRO
494
495//
496// Binary operators
497//
498namespace Sacado {
499 namespace CacheFad {
500
501 //
502 // AdditionOp
503 //
504
505 template <typename ExprT1, typename ExprT2>
506 class AdditionOp {};
507
508 template <typename ExprT1, typename ExprT2>
509 class Expr< AdditionOp<ExprT1,ExprT2> > {
510
511 public:
512
513 typedef typename ExprT1::value_type value_type_1;
514 typedef typename ExprT2::value_type value_type_2;
515 typedef typename Sacado::Promote<value_type_1,
516 value_type_2>::type value_type;
517
518 typedef typename ExprT1::scalar_type scalar_type_1;
519 typedef typename ExprT2::scalar_type scalar_type_2;
520 typedef typename Sacado::Promote<scalar_type_1,
521 scalar_type_2>::type scalar_type;
522
523 typedef typename ExprT1::base_expr_type base_expr_type_1;
524 typedef typename ExprT2::base_expr_type base_expr_type_2;
525 typedef typename Sacado::Promote<base_expr_type_1,
526 base_expr_type_2>::type base_expr_type;
527
529 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
530 expr1(expr1_), expr2(expr2_) {}
531
533 int size() const {
534 int sz1 = expr1.size(), sz2 = expr2.size();
535 return sz1 > sz2 ? sz1 : sz2;
536 }
537
539 bool updateValue() const {
540 return expr1.updateValue() && expr2.updateValue();
541 }
542
544 void cache() const {
545 expr1.cache();
546 expr2.cache();
547 }
548
550 value_type val() const {
551 return expr1.val()+expr2.val();
552 }
553
555 bool isLinear() const {
556 return expr1.isLinear() && expr2.isLinear();
557 }
558
560 bool hasFastAccess() const {
561 return expr1.hasFastAccess() && expr2.hasFastAccess();
562 }
563
565 const value_type dx(int i) const {
566 return expr1.dx(i) + expr2.dx(i);
567 }
568
570 const value_type fastAccessDx(int i) const {
571 return expr1.fastAccessDx(i) + expr2.fastAccessDx(i);
572 }
573
574 protected:
575
576 const ExprT1& expr1;
577 const ExprT2& expr2;
578
579 };
580
581 template <typename ExprT1, typename T2>
582 class Expr< AdditionOp<ExprT1, ConstExpr<T2> > > {
583
584 public:
585
586 typedef ConstExpr<T2> ExprT2;
587 typedef typename ExprT1::value_type value_type_1;
588 typedef typename ExprT2::value_type value_type_2;
589 typedef typename Sacado::Promote<value_type_1,
590 value_type_2>::type value_type;
591
592 typedef typename ExprT1::scalar_type scalar_type_1;
593 typedef typename ExprT2::scalar_type scalar_type_2;
594 typedef typename Sacado::Promote<scalar_type_1,
595 scalar_type_2>::type scalar_type;
596
597 typedef typename ExprT1::base_expr_type base_expr_type_1;
598 typedef typename ExprT2::base_expr_type base_expr_type_2;
599 typedef typename Sacado::Promote<base_expr_type_1,
600 base_expr_type_2>::type base_expr_type;
601
603 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
604 expr1(expr1_), expr2(expr2_) {}
605
607 int size() const {
608 return expr1.size();
609 }
610
612 bool updateValue() const {
613 return expr1.updateValue();
614 }
615
617 void cache() const {
618 expr1.cache();
619 }
620
622 value_type val() const {
623 return expr1.val() + expr2.val();
624 }
625
627 bool isLinear() const {
628 return expr1.isLinear();
629 }
630
632 bool hasFastAccess() const {
633 return expr1.hasFastAccess();
634 }
635
637 const value_type dx(int i) const {
638 return expr1.dx(i);
639 }
640
642 const value_type fastAccessDx(int i) const {
643 return expr1.fastAccessDx(i);
644 }
645
646 protected:
647
648 const ExprT1& expr1;
649 ExprT2 expr2;
650
651 };
652
653 template <typename T1, typename ExprT2>
654 class Expr< AdditionOp< ConstExpr<T1>,ExprT2> > {
655
656 public:
657
658 typedef ConstExpr<T1> ExprT1;
659 typedef typename ExprT1::value_type value_type_1;
660 typedef typename ExprT2::value_type value_type_2;
661 typedef typename Sacado::Promote<value_type_1,
662 value_type_2>::type value_type;
663
664 typedef typename ExprT1::scalar_type scalar_type_1;
665 typedef typename ExprT2::scalar_type scalar_type_2;
666 typedef typename Sacado::Promote<scalar_type_1,
667 scalar_type_2>::type scalar_type;
668
669 typedef typename ExprT1::base_expr_type base_expr_type_1;
670 typedef typename ExprT2::base_expr_type base_expr_type_2;
671 typedef typename Sacado::Promote<base_expr_type_1,
672 base_expr_type_2>::type base_expr_type;
673
675 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
676 expr1(expr1_), expr2(expr2_) {}
677
679 int size() const {
680 return expr2.size();
681 }
682
684 bool updateValue() const {
685 return expr2.updateValue();
686 }
687
689 void cache() const {
690 expr2.cache();
691 }
692
694 value_type val() const {
695 return expr1.val() + expr2.val();
696 }
697
699 bool isLinear() const {
700 return expr2.isLinear();
701 }
702
704 bool hasFastAccess() const {
705 return expr2.hasFastAccess();
706 }
707
709 const value_type dx(int i) const {
710 return expr2.dx(i);
711 }
712
714 const value_type fastAccessDx(int i) const {
715 return expr2.fastAccessDx(i);
716 }
717
718 protected:
719
720 ExprT1 expr1;
721 const ExprT2& expr2;
722
723 };
724
725 //
726 // SubtractionOp
727 //
728
729 template <typename ExprT1, typename ExprT2>
730 class SubtractionOp {};
731
732 template <typename ExprT1, typename ExprT2>
733 class Expr< SubtractionOp<ExprT1,ExprT2> > {
734
735 public:
736
737 typedef typename ExprT1::value_type value_type_1;
738 typedef typename ExprT2::value_type value_type_2;
739 typedef typename Sacado::Promote<value_type_1,
740 value_type_2>::type value_type;
741
742 typedef typename ExprT1::scalar_type scalar_type_1;
743 typedef typename ExprT2::scalar_type scalar_type_2;
744 typedef typename Sacado::Promote<scalar_type_1,
745 scalar_type_2>::type scalar_type;
746
747 typedef typename ExprT1::base_expr_type base_expr_type_1;
748 typedef typename ExprT2::base_expr_type base_expr_type_2;
749 typedef typename Sacado::Promote<base_expr_type_1,
750 base_expr_type_2>::type base_expr_type;
751
753 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
754 expr1(expr1_), expr2(expr2_) {}
755
757 int size() const {
758 int sz1 = expr1.size(), sz2 = expr2.size();
759 return sz1 > sz2 ? sz1 : sz2;
760 }
761
763 bool updateValue() const {
764 return expr1.updateValue() && expr2.updateValue();
765 }
766
768 void cache() const {
769 expr1.cache();
770 expr2.cache();
771 }
772
774 value_type val() const {
775 return expr1.val()-expr2.val();
776 }
777
779 bool isLinear() const {
780 return expr1.isLinear() && expr2.isLinear();
781 }
782
784 bool hasFastAccess() const {
785 return expr1.hasFastAccess() && expr2.hasFastAccess();
786 }
787
789 const value_type dx(int i) const {
790 return expr1.dx(i) - expr2.dx(i);
791 }
792
794 const value_type fastAccessDx(int i) const {
795 return expr1.fastAccessDx(i) - expr2.fastAccessDx(i);
796 }
797
798 protected:
799
800 const ExprT1& expr1;
801 const ExprT2& expr2;
802
803 };
804
805 template <typename ExprT1, typename T2>
806 class Expr< SubtractionOp<ExprT1, ConstExpr<T2> > > {
807
808 public:
809
810 typedef ConstExpr<T2> ExprT2;
811 typedef typename ExprT1::value_type value_type_1;
812 typedef typename ExprT2::value_type value_type_2;
813 typedef typename Sacado::Promote<value_type_1,
814 value_type_2>::type value_type;
815
816 typedef typename ExprT1::scalar_type scalar_type_1;
817 typedef typename ExprT2::scalar_type scalar_type_2;
818 typedef typename Sacado::Promote<scalar_type_1,
819 scalar_type_2>::type scalar_type;
820
821 typedef typename ExprT1::base_expr_type base_expr_type_1;
822 typedef typename ExprT2::base_expr_type base_expr_type_2;
823 typedef typename Sacado::Promote<base_expr_type_1,
824 base_expr_type_2>::type base_expr_type;
825
827 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
828 expr1(expr1_), expr2(expr2_) {}
829
831 int size() const {
832 return expr1.size();
833 }
834
836 bool updateValue() const {
837 return expr1.updateValue();
838 }
839
841 void cache() const {
842 expr1.cache();
843 }
844
846 value_type val() const {
847 return expr1.val() - expr2.val();
848 }
849
851 bool isLinear() const {
852 return expr1.isLinear();
853 }
854
856 bool hasFastAccess() const {
857 return expr1.hasFastAccess();
858 }
859
861 const value_type dx(int i) const {
862 return expr1.dx(i);
863 }
864
866 const value_type fastAccessDx(int i) const {
867 return expr1.fastAccessDx(i);
868 }
869
870 protected:
871
872 const ExprT1& expr1;
873 ExprT2 expr2;
874
875 };
876
877 template <typename T1, typename ExprT2>
878 class Expr< SubtractionOp< ConstExpr<T1>,ExprT2> > {
879
880 public:
881
882 typedef ConstExpr<T1> ExprT1;
883 typedef typename ExprT1::value_type value_type_1;
884 typedef typename ExprT2::value_type value_type_2;
885 typedef typename Sacado::Promote<value_type_1,
886 value_type_2>::type value_type;
887
888 typedef typename ExprT1::scalar_type scalar_type_1;
889 typedef typename ExprT2::scalar_type scalar_type_2;
890 typedef typename Sacado::Promote<scalar_type_1,
891 scalar_type_2>::type scalar_type;
892
893 typedef typename ExprT1::base_expr_type base_expr_type_1;
894 typedef typename ExprT2::base_expr_type base_expr_type_2;
895 typedef typename Sacado::Promote<base_expr_type_1,
896 base_expr_type_2>::type base_expr_type;
897
899 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
900 expr1(expr1_), expr2(expr2_) {}
901
903 int size() const {
904 return expr2.size();
905 }
906
908 bool updateValue() const {
909 return expr2.updateValue();
910 }
911
913 void cache() const {
914 expr2.cache();
915 }
916
918 value_type val() const {
919 return expr1.val() - expr2.val();
920 }
921
923 bool isLinear() const {
924 return expr2.isLinear();
925 }
926
928 bool hasFastAccess() const {
929 return expr2.hasFastAccess();
930 }
931
933 const value_type dx(int i) const {
934 return -expr2.dx(i);
935 }
936
938 const value_type fastAccessDx(int i) const {
939 return -expr2.fastAccessDx(i);
940 }
941
942 protected:
943
944 ExprT1 expr1;
945 const ExprT2& expr2;
946
947 };
948
949 //
950 // MultiplicationOp
951 //
952
953 template <typename ExprT1, typename ExprT2>
954 class MultiplicationOp {};
955
956 template <typename ExprT1, typename ExprT2>
957 class Expr< MultiplicationOp<ExprT1,ExprT2> > {
958
959 public:
960
961 typedef typename ExprT1::value_type value_type_1;
962 typedef typename ExprT2::value_type value_type_2;
963 typedef typename Sacado::Promote<value_type_1,
964 value_type_2>::type value_type;
965
966 typedef typename ExprT1::scalar_type scalar_type_1;
967 typedef typename ExprT2::scalar_type scalar_type_2;
968 typedef typename Sacado::Promote<scalar_type_1,
969 scalar_type_2>::type scalar_type;
970
971 typedef typename ExprT1::base_expr_type base_expr_type_1;
972 typedef typename ExprT2::base_expr_type base_expr_type_2;
973 typedef typename Sacado::Promote<base_expr_type_1,
974 base_expr_type_2>::type base_expr_type;
975
977 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
978 expr1(expr1_), expr2(expr2_) {}
979
981 int size() const {
982 int sz1 = expr1.size(), sz2 = expr2.size();
983 return sz1 > sz2 ? sz1 : sz2;
984 }
985
987 bool updateValue() const {
988 return expr1.updateValue() && expr2.updateValue();
989 }
990
992 void cache() const {
993 expr1.cache();
994 expr2.cache();
995 v1 = expr1.val();
996 v2 = expr2.val();
997 }
998
1000 value_type val() const {
1001 return v1*v2;
1002 }
1003
1005 bool isLinear() const {
1006 return false;
1007 }
1008
1010 bool hasFastAccess() const {
1011 return expr1.hasFastAccess() && expr2.hasFastAccess();
1012 }
1013
1015 const value_type dx(int i) const {
1016 if (expr1.size() > 0 && expr2.size() > 0)
1017 return v1*expr2.dx(i) + expr1.dx(i)*v2;
1018 else if (expr1.size() > 0)
1019 return expr1.dx(i)*v2;
1020 else
1021 return v1*expr2.dx(i);
1022 }
1023
1025 const value_type fastAccessDx(int i) const {
1026 return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
1027 }
1028
1029 protected:
1030
1031 const ExprT1& expr1;
1032 const ExprT2& expr2;
1033 mutable value_type_1 v1;
1034 mutable value_type_2 v2;
1035
1036 };
1037
1038 template <typename ExprT1, typename T2>
1039 class Expr< MultiplicationOp<ExprT1, ConstExpr<T2> > > {
1040
1041 public:
1042
1043 typedef ConstExpr<T2> ExprT2;
1044 typedef typename ExprT1::value_type value_type_1;
1045 typedef typename ExprT2::value_type value_type_2;
1046 typedef typename Sacado::Promote<value_type_1,
1047 value_type_2>::type value_type;
1048
1049 typedef typename ExprT1::scalar_type scalar_type_1;
1050 typedef typename ExprT2::scalar_type scalar_type_2;
1051 typedef typename Sacado::Promote<scalar_type_1,
1052 scalar_type_2>::type scalar_type;
1053
1054 typedef typename ExprT1::base_expr_type base_expr_type_1;
1055 typedef typename ExprT2::base_expr_type base_expr_type_2;
1056 typedef typename Sacado::Promote<base_expr_type_1,
1057 base_expr_type_2>::type base_expr_type;
1058
1060 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1061 expr1(expr1_), expr2(expr2_) {}
1062
1064 int size() const {
1065 return expr1.size();
1066 }
1067
1069 bool updateValue() const {
1070 return expr1.updateValue();
1071 }
1072
1074 void cache() const {
1075 expr1.cache();
1076 }
1077
1079 value_type val() const {
1080 return expr1.val()*expr2.val();
1081 }
1082
1084 bool isLinear() const {
1085 return expr1.isLinear();
1086 }
1087
1089 bool hasFastAccess() const {
1090 return expr1.hasFastAccess();
1091 }
1092
1094 const value_type dx(int i) const {
1095 return expr1.dx(i)*expr2.val();
1096 }
1097
1099 const value_type fastAccessDx(int i) const {
1100 return expr1.fastAccessDx(i)*expr2.val();
1101 }
1102
1103 protected:
1104
1105 const ExprT1& expr1;
1106 ExprT2 expr2;
1107
1108 };
1109
1110 template <typename T1, typename ExprT2>
1111 class Expr< MultiplicationOp< ConstExpr<T1>,ExprT2> > {
1112
1113 public:
1114
1115 typedef ConstExpr<T1> ExprT1;
1116 typedef typename ExprT1::value_type value_type_1;
1117 typedef typename ExprT2::value_type value_type_2;
1118 typedef typename Sacado::Promote<value_type_1,
1119 value_type_2>::type value_type;
1120
1121 typedef typename ExprT1::scalar_type scalar_type_1;
1122 typedef typename ExprT2::scalar_type scalar_type_2;
1123 typedef typename Sacado::Promote<scalar_type_1,
1124 scalar_type_2>::type scalar_type;
1125
1126 typedef typename ExprT1::base_expr_type base_expr_type_1;
1127 typedef typename ExprT2::base_expr_type base_expr_type_2;
1128 typedef typename Sacado::Promote<base_expr_type_1,
1129 base_expr_type_2>::type base_expr_type;
1130
1132 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1133 expr1(expr1_), expr2(expr2_) {}
1134
1136 int size() const {
1137 return expr2.size();
1138 }
1139
1141 bool updateValue() const {
1142 return expr2.updateValue();
1143 }
1144
1146 void cache() const {
1147 expr2.cache();
1148 }
1149
1151 value_type val() const {
1152 return expr1.val()*expr2.val();
1153 }
1154
1156 bool isLinear() const {
1157 return expr2.isLinear();
1158 }
1159
1161 bool hasFastAccess() const {
1162 return expr2.hasFastAccess();
1163 }
1164
1166 const value_type dx(int i) const {
1167 return expr1.val()*expr2.dx(i);
1168 }
1169
1171 const value_type fastAccessDx(int i) const {
1172 return expr1.val()*expr2.fastAccessDx(i);
1173 }
1174
1175 protected:
1176
1177 ExprT1 expr1;
1178 const ExprT2& expr2;
1179
1180 };
1181
1182 //
1183 // DivisionOp
1184 //
1185
1186 template <typename ExprT1, typename ExprT2>
1187 class DivisionOp {};
1188
1189 template <typename ExprT1, typename ExprT2>
1190 class Expr< DivisionOp<ExprT1,ExprT2> > {
1191
1192 public:
1193
1194 typedef typename ExprT1::value_type value_type_1;
1195 typedef typename ExprT2::value_type value_type_2;
1196 typedef typename Sacado::Promote<value_type_1,
1197 value_type_2>::type value_type;
1198
1199 typedef typename ExprT1::scalar_type scalar_type_1;
1200 typedef typename ExprT2::scalar_type scalar_type_2;
1201 typedef typename Sacado::Promote<scalar_type_1,
1202 scalar_type_2>::type scalar_type;
1203
1204 typedef typename ExprT1::base_expr_type base_expr_type_1;
1205 typedef typename ExprT2::base_expr_type base_expr_type_2;
1206 typedef typename Sacado::Promote<base_expr_type_1,
1207 base_expr_type_2>::type base_expr_type;
1208
1210 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1211 expr1(expr1_), expr2(expr2_) {}
1212
1214 int size() const {
1215 int sz1 = expr1.size(), sz2 = expr2.size();
1216 return sz1 > sz2 ? sz1 : sz2;
1217 }
1218
1220 bool updateValue() const {
1221 return expr1.updateValue() && expr2.updateValue();
1222 }
1223
1225 void cache() const {
1226 expr1.cache();
1227 expr2.cache();
1228 const value_type_1 v1 = expr1.val();
1229 const value_type_2 v2 = expr2.val();
1230 a = value_type(1)/v2;
1231 v = v1*a;
1232 b = -v/v2;
1233 }
1234
1236 value_type val() const {
1237 return v;
1238 }
1239
1241 bool isLinear() const {
1242 return false;
1243 }
1244
1246 bool hasFastAccess() const {
1247 return expr1.hasFastAccess() && expr2.hasFastAccess();
1248 }
1249
1251 const value_type dx(int i) const {
1252 if (expr1.size() > 0 && expr2.size() > 0)
1253 return expr1.dx(i)*a + expr2.dx(i)*b;
1254 else if (expr1.size() > 0)
1255 return expr1.dx(i)*a;
1256 else
1257 return expr1.val()*b;
1258 }
1259
1261 const value_type fastAccessDx(int i) const {
1262 return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1263 }
1264
1265 protected:
1266
1267 const ExprT1& expr1;
1268 const ExprT2& expr2;
1269 mutable value_type v;
1270 mutable value_type a;
1271 mutable value_type b;
1272
1273 };
1274
1275 template <typename ExprT1, typename T2>
1276 class Expr< DivisionOp<ExprT1, ConstExpr<T2> > > {
1277
1278 public:
1279
1280 typedef ConstExpr<T2> ExprT2;
1281 typedef typename ExprT1::value_type value_type_1;
1282 typedef typename ExprT2::value_type value_type_2;
1283 typedef typename Sacado::Promote<value_type_1,
1284 value_type_2>::type value_type;
1285
1286 typedef typename ExprT1::scalar_type scalar_type_1;
1287 typedef typename ExprT2::scalar_type scalar_type_2;
1288 typedef typename Sacado::Promote<scalar_type_1,
1289 scalar_type_2>::type scalar_type;
1290
1291 typedef typename ExprT1::base_expr_type base_expr_type_1;
1292 typedef typename ExprT2::base_expr_type base_expr_type_2;
1293 typedef typename Sacado::Promote<base_expr_type_1,
1294 base_expr_type_2>::type base_expr_type;
1295
1297 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1298 expr1(expr1_), expr2(expr2_) {}
1299
1301 int size() const {
1302 return expr1.size();
1303 }
1304
1306 bool updateValue() const {
1307 return expr1.updateValue();
1308 }
1309
1311 void cache() const {
1312 expr1.cache();
1313 const value_type_1 v1 = expr1.val();
1314 a = value_type(1)/expr2.val();
1315 v = v1*a;
1316 }
1317
1319 value_type val() const {
1320 return v;
1321 }
1322
1324 bool isLinear() const {
1325 return expr1.isLinear();
1326 }
1327
1329 bool hasFastAccess() const {
1330 return expr1.hasFastAccess();
1331 }
1332
1334 const value_type dx(int i) const {
1335 return expr1.dx(i)*a;
1336 }
1337
1339 const value_type fastAccessDx(int i) const {
1340 return expr1.fastAccessDx(i)*a;
1341 }
1342
1343 protected:
1344
1345 const ExprT1& expr1;
1346 ExprT2 expr2;
1347 mutable value_type v;
1348 mutable value_type a;
1349
1350 };
1351
1352 template <typename T1, typename ExprT2>
1353 class Expr< DivisionOp< ConstExpr<T1>,ExprT2> > {
1354
1355 public:
1356
1357 typedef ConstExpr<T1> ExprT1;
1358 typedef typename ExprT1::value_type value_type_1;
1359 typedef typename ExprT2::value_type value_type_2;
1360 typedef typename Sacado::Promote<value_type_1,
1361 value_type_2>::type value_type;
1362
1363 typedef typename ExprT1::scalar_type scalar_type_1;
1364 typedef typename ExprT2::scalar_type scalar_type_2;
1365 typedef typename Sacado::Promote<scalar_type_1,
1366 scalar_type_2>::type scalar_type;
1367
1368 typedef typename ExprT1::base_expr_type base_expr_type_1;
1369 typedef typename ExprT2::base_expr_type base_expr_type_2;
1370 typedef typename Sacado::Promote<base_expr_type_1,
1371 base_expr_type_2>::type base_expr_type;
1372
1374 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1375 expr1(expr1_), expr2(expr2_) {}
1376
1378 int size() const {
1379 return expr2.size();
1380 }
1381
1383 bool updateValue() const {
1384 return expr2.updateValue();
1385 }
1386
1388 void cache() const {
1389 expr2.cache();
1390 const value_type_2 v2 = expr2.val();
1391 v = expr1.val()/v2;
1392 b = -v/v2;
1393 }
1394
1396 value_type val() const {
1397 return v;
1398 }
1399
1401 bool isLinear() const {
1402 return false;
1403 }
1404
1406 bool hasFastAccess() const {
1407 return expr2.hasFastAccess();
1408 }
1409
1411 const value_type dx(int i) const {
1412 return expr2.dx(i)*b;
1413 }
1414
1416 const value_type fastAccessDx(int i) const {
1417 return expr2.fastAccessDx(i)*b;
1418 }
1419
1420 protected:
1421
1422 ExprT1 expr1;
1423 const ExprT2& expr2;
1424 mutable value_type v;
1425 mutable value_type b;
1426
1427 };
1428
1429 //
1430 // Atan2Op
1431 //
1432
1433 template <typename ExprT1, typename ExprT2>
1434 class Atan2Op {};
1435
1436 template <typename ExprT1, typename ExprT2>
1437 class Expr< Atan2Op<ExprT1,ExprT2> > {
1438
1439 public:
1440
1441 typedef typename ExprT1::value_type value_type_1;
1442 typedef typename ExprT2::value_type value_type_2;
1443 typedef typename Sacado::Promote<value_type_1,
1444 value_type_2>::type value_type;
1445
1446 typedef typename ExprT1::scalar_type scalar_type_1;
1447 typedef typename ExprT2::scalar_type scalar_type_2;
1448 typedef typename Sacado::Promote<scalar_type_1,
1449 scalar_type_2>::type scalar_type;
1450
1451 typedef typename ExprT1::base_expr_type base_expr_type_1;
1452 typedef typename ExprT2::base_expr_type base_expr_type_2;
1453 typedef typename Sacado::Promote<base_expr_type_1,
1454 base_expr_type_2>::type base_expr_type;
1455
1457 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1458 expr1(expr1_), expr2(expr2_) {}
1459
1461 int size() const {
1462 int sz1 = expr1.size(), sz2 = expr2.size();
1463 return sz1 > sz2 ? sz1 : sz2;
1464 }
1465
1467 bool updateValue() const {
1468 return expr1.updateValue() && expr2.updateValue();
1469 }
1470
1472 void cache() const {
1473 expr1.cache();
1474 expr2.cache();
1475 const value_type_1 v1 = expr1.val();
1476 const value_type_2 v2 = expr2.val();
1477 a = value_type(1)/(v1*v1 + v2*v2);
1478 b = -v1*a;
1479 a = v2*a;
1480 v = std::atan2(v1,v2);
1481 }
1482
1484 value_type val() const {
1485 return v;
1486 }
1487
1489 bool isLinear() const {
1490 return false;
1491 }
1492
1494 bool hasFastAccess() const {
1495 return expr1.hasFastAccess() && expr2.hasFastAccess();
1496 }
1497
1499 const value_type dx(int i) const {
1500 if (expr1.size() > 0 && expr2.size() > 0)
1501 return expr1.dx(i)*a + expr2.dx(i)*b;
1502 else if (expr1.size() > 0)
1503 return expr1.dx(i)*a;
1504 else
1505 return expr1.val()*b;
1506 }
1507
1509 const value_type fastAccessDx(int i) const {
1510 return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1511 }
1512
1513 protected:
1514
1515 const ExprT1& expr1;
1516 const ExprT2& expr2;
1517 mutable value_type v;
1518 mutable value_type a;
1519 mutable value_type b;
1520
1521 };
1522
1523 template <typename ExprT1, typename T2>
1524 class Expr< Atan2Op<ExprT1, ConstExpr<T2> > > {
1525
1526 public:
1527
1528 typedef ConstExpr<T2> ExprT2;
1529 typedef typename ExprT1::value_type value_type_1;
1530 typedef typename ExprT2::value_type value_type_2;
1531 typedef typename Sacado::Promote<value_type_1,
1532 value_type_2>::type value_type;
1533
1534 typedef typename ExprT1::scalar_type scalar_type_1;
1535 typedef typename ExprT2::scalar_type scalar_type_2;
1536 typedef typename Sacado::Promote<scalar_type_1,
1537 scalar_type_2>::type scalar_type;
1538
1539 typedef typename ExprT1::base_expr_type base_expr_type_1;
1540 typedef typename ExprT2::base_expr_type base_expr_type_2;
1541 typedef typename Sacado::Promote<base_expr_type_1,
1542 base_expr_type_2>::type base_expr_type;
1543
1545 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1546 expr1(expr1_), expr2(expr2_) {}
1547
1549 int size() const {
1550 return expr1.size();
1551 }
1552
1554 bool updateValue() const {
1555 return expr1.updateValue();
1556 }
1557
1559 void cache() const {
1560 expr1.cache();
1561 const value_type_1 v1 = expr1.val();
1562 const value_type_2 v2 = expr2.val();
1563 a = v2/(v1*v1 + v2*v2);
1564 v = std::atan2(v1,v2);
1565 }
1566
1568 value_type val() const {
1569 return v;
1570 }
1571
1573 bool isLinear() const {
1574 return false;
1575 }
1576
1578 bool hasFastAccess() const {
1579 return expr1.hasFastAccess();
1580 }
1581
1583 const value_type dx(int i) const {
1584 return expr1.dx(i)*a;
1585 }
1586
1588 const value_type fastAccessDx(int i) const {
1589 return expr1.fastAccessDx(i)*a;
1590 }
1591
1592 protected:
1593
1594 const ExprT1& expr1;
1595 ExprT2 expr2;
1596 mutable value_type v;
1597 mutable value_type a;
1598
1599 };
1600
1601 template <typename T1, typename ExprT2>
1602 class Expr< Atan2Op< ConstExpr<T1>,ExprT2> > {
1603
1604 public:
1605
1606 typedef ConstExpr<T1> ExprT1;
1607 typedef typename ExprT1::value_type value_type_1;
1608 typedef typename ExprT2::value_type value_type_2;
1609 typedef typename Sacado::Promote<value_type_1,
1610 value_type_2>::type value_type;
1611
1612 typedef typename ExprT1::scalar_type scalar_type_1;
1613 typedef typename ExprT2::scalar_type scalar_type_2;
1614 typedef typename Sacado::Promote<scalar_type_1,
1615 scalar_type_2>::type scalar_type;
1616
1617 typedef typename ExprT1::base_expr_type base_expr_type_1;
1618 typedef typename ExprT2::base_expr_type base_expr_type_2;
1619 typedef typename Sacado::Promote<base_expr_type_1,
1620 base_expr_type_2>::type base_expr_type;
1621
1623 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1624 expr1(expr1_), expr2(expr2_) {}
1625
1627 int size() const {
1628 return expr2.size();
1629 }
1630
1632 bool updateValue() const {
1633 return expr2.updateValue();
1634 }
1635
1637 void cache() const {
1638 expr2.cache();
1639 const value_type_1 v1 = expr1.val();
1640 const value_type_2 v2 = expr2.val();
1641 b = -v1/(v1*v1 + v2*v2);
1642 v = std::atan2(v1,v2);
1643 }
1644
1646 value_type val() const {
1647 return v;
1648 }
1649
1651 bool isLinear() const {
1652 return false;
1653 }
1654
1656 bool hasFastAccess() const {
1657 return expr2.hasFastAccess();
1658 }
1659
1661 const value_type dx(int i) const {
1662 return expr2.dx(i)*b;
1663 }
1664
1666 const value_type fastAccessDx(int i) const {
1667 return expr2.fastAccessDx(i)*b;
1668 }
1669
1670 protected:
1671
1672 ExprT1 expr1;
1673 const ExprT2& expr2;
1674 mutable value_type v;
1675 mutable value_type b;
1676
1677 };
1678
1679 //
1680 // PowerOp
1681 //
1682
1683 template <typename ExprT1, typename ExprT2>
1684 class PowerOp {};
1685
1686 template <typename ExprT1, typename ExprT2>
1687 class Expr< PowerOp<ExprT1,ExprT2> > {
1688
1689 public:
1690
1691 typedef typename ExprT1::value_type value_type_1;
1692 typedef typename ExprT2::value_type value_type_2;
1693 typedef typename Sacado::Promote<value_type_1,
1694 value_type_2>::type value_type;
1695
1696 typedef typename ExprT1::scalar_type scalar_type_1;
1697 typedef typename ExprT2::scalar_type scalar_type_2;
1698 typedef typename Sacado::Promote<scalar_type_1,
1699 scalar_type_2>::type scalar_type;
1700
1701 typedef typename ExprT1::base_expr_type base_expr_type_1;
1702 typedef typename ExprT2::base_expr_type base_expr_type_2;
1703 typedef typename Sacado::Promote<base_expr_type_1,
1704 base_expr_type_2>::type base_expr_type;
1705
1707 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1708 expr1(expr1_), expr2(expr2_) {}
1709
1711 int size() const {
1712 int sz1 = expr1.size(), sz2 = expr2.size();
1713 return sz1 > sz2 ? sz1 : sz2;
1714 }
1715
1717 bool updateValue() const {
1718 return expr1.updateValue() && expr2.updateValue();
1719 }
1720
1722 void cache() const {
1723 expr1.cache();
1724 expr2.cache();
1725 const value_type_1 v1 = expr1.val();
1726 const value_type_2 v2 = expr2.val();
1727 v = std::pow(v1,v2);
1728 if (expr2.size() == 0 && v2 == value_type(1)) {
1729 a = value_type(1);
1730 b = value_type(0);
1731 }
1732 else if (v1 == value_type(0)) {
1733 a = value_type(0);
1734 b = value_type(0);
1735 }
1736 else {
1737 a = v*v2/v1;
1738 b = v*std::log(v1);
1739 }
1740 }
1741
1743 value_type val() const {
1744 return v;
1745 }
1746
1748 bool isLinear() const {
1749 return false;
1750 }
1751
1753 bool hasFastAccess() const {
1754 return expr1.hasFastAccess() && expr2.hasFastAccess();
1755 }
1756
1758 const value_type dx(int i) const {
1759 if (expr1.size() > 0 && expr2.size() > 0)
1760 return expr1.dx(i)*a + expr2.dx(i)*b;
1761 else if (expr1.size() > 0)
1762 return expr1.dx(i)*a;
1763 else
1764 return expr1.val()*b;
1765 }
1766
1768 const value_type fastAccessDx(int i) const {
1769 return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1770 }
1771
1772 protected:
1773
1774 const ExprT1& expr1;
1775 const ExprT2& expr2;
1776 mutable value_type v;
1777 mutable value_type a;
1778 mutable value_type b;
1779
1780 };
1781
1782 template <typename ExprT1, typename T2>
1783 class Expr< PowerOp<ExprT1, ConstExpr<T2> > > {
1784
1785 public:
1786
1787 typedef ConstExpr<T2> ExprT2;
1788 typedef typename ExprT1::value_type value_type_1;
1789 typedef typename ExprT2::value_type value_type_2;
1790 typedef typename Sacado::Promote<value_type_1,
1791 value_type_2>::type value_type;
1792
1793 typedef typename ExprT1::scalar_type scalar_type_1;
1794 typedef typename ExprT2::scalar_type scalar_type_2;
1795 typedef typename Sacado::Promote<scalar_type_1,
1796 scalar_type_2>::type scalar_type;
1797
1798 typedef typename ExprT1::base_expr_type base_expr_type_1;
1799 typedef typename ExprT2::base_expr_type base_expr_type_2;
1800 typedef typename Sacado::Promote<base_expr_type_1,
1801 base_expr_type_2>::type base_expr_type;
1802
1804 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1805 expr1(expr1_), expr2(expr2_) {}
1806
1808 int size() const {
1809 return expr1.size();
1810 }
1811
1813 bool updateValue() const {
1814 return expr1.updateValue();
1815 }
1816
1818 void cache() const {
1819 expr1.cache();
1820 const value_type_1 v1 = expr1.val();
1821 const value_type_2 v2 = expr2.val();
1822 v = std::pow(v1,v2);
1823 if (v2 == value_type_1(1)) {
1824 a = value_type(1);
1825 }
1826 else if (v1 == value_type_1(0)) {
1827 a = value_type(0);
1828 }
1829 else {
1830 a = v*v2/v1;
1831 }
1832 }
1833
1835 value_type val() const {
1836 return v;
1837 }
1838
1840 bool isLinear() const {
1841 return false;
1842 }
1843
1845 bool hasFastAccess() const {
1846 return expr1.hasFastAccess();
1847 }
1848
1850 const value_type dx(int i) const {
1851 return expr1.dx(i)*a;
1852 }
1853
1855 const value_type fastAccessDx(int i) const {
1856 return expr1.fastAccessDx(i)*a;
1857 }
1858
1859 protected:
1860
1861 const ExprT1& expr1;
1862 ExprT2 expr2;
1863 mutable value_type v;
1864 mutable value_type a;
1865
1866 };
1867
1868 template <typename T1, typename ExprT2>
1869 class Expr< PowerOp< ConstExpr<T1>,ExprT2> > {
1870
1871 public:
1872
1873 typedef ConstExpr<T1> ExprT1;
1874 typedef typename ExprT1::value_type value_type_1;
1875 typedef typename ExprT2::value_type value_type_2;
1876 typedef typename Sacado::Promote<value_type_1,
1877 value_type_2>::type value_type;
1878
1879 typedef typename ExprT1::scalar_type scalar_type_1;
1880 typedef typename ExprT2::scalar_type scalar_type_2;
1881 typedef typename Sacado::Promote<scalar_type_1,
1882 scalar_type_2>::type scalar_type;
1883
1884 typedef typename ExprT1::base_expr_type base_expr_type_1;
1885 typedef typename ExprT2::base_expr_type base_expr_type_2;
1886 typedef typename Sacado::Promote<base_expr_type_1,
1887 base_expr_type_2>::type base_expr_type;
1888
1890 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1891 expr1(expr1_), expr2(expr2_) {}
1892
1894 int size() const {
1895 return expr2.size();
1896 }
1897
1899 bool updateValue() const {
1900 return expr2.updateValue();
1901 }
1902
1904 void cache() const {
1905 expr2.cache();
1906 const value_type_1 v1 = expr1.val();
1907 const value_type_2 v2 = expr2.val();
1908 v = std::pow(v1,v2);
1909 if (v1 == value_type(0)) {
1910 b = value_type(0);
1911 }
1912 else {
1913 b = v*std::log(v1);
1914 }
1915 }
1916
1918 value_type val() const {
1919 return v;
1920 }
1921
1923 bool isLinear() const {
1924 return false;
1925 }
1926
1928 bool hasFastAccess() const {
1929 return expr2.hasFastAccess();
1930 }
1931
1933 const value_type dx(int i) const {
1934 return expr2.dx(i)*b;
1935 }
1936
1938 const value_type fastAccessDx(int i) const {
1939 return expr2.fastAccessDx(i)*b;
1940 }
1941
1942 protected:
1943
1944 ExprT1 expr1;
1945 const ExprT2& expr2;
1946 mutable value_type v;
1947 mutable value_type b;
1948
1949 };
1950
1951 //
1952 // MaxOp
1953 //
1954
1955 template <typename ExprT1, typename ExprT2>
1956 class MaxOp {};
1957
1958 template <typename ExprT1, typename ExprT2>
1959 class Expr< MaxOp<ExprT1,ExprT2> > {
1960
1961 public:
1962
1963 typedef typename ExprT1::value_type value_type_1;
1964 typedef typename ExprT2::value_type value_type_2;
1965 typedef typename Sacado::Promote<value_type_1,
1966 value_type_2>::type value_type;
1967
1968 typedef typename ExprT1::scalar_type scalar_type_1;
1969 typedef typename ExprT2::scalar_type scalar_type_2;
1970 typedef typename Sacado::Promote<scalar_type_1,
1971 scalar_type_2>::type scalar_type;
1972
1973 typedef typename ExprT1::base_expr_type base_expr_type_1;
1974 typedef typename ExprT2::base_expr_type base_expr_type_2;
1975 typedef typename Sacado::Promote<base_expr_type_1,
1976 base_expr_type_2>::type base_expr_type;
1977
1979 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1980 expr1(expr1_), expr2(expr2_) {}
1981
1983 int size() const {
1984 int sz1 = expr1.size(), sz2 = expr2.size();
1985 return sz1 > sz2 ? sz1 : sz2;
1986 }
1987
1989 bool updateValue() const {
1990 return expr1.updateValue() && expr2.updateValue();
1991 }
1992
1994 void cache() const {
1995 expr1.cache();
1996 expr2.cache();
1997 const value_type_1 v1 = expr1.val();
1998 const value_type_2 v2 = expr2.val();
1999 max_v1 = (v1 >= v2);
2000 v = max_v1 ? v1 : v2;
2001 }
2002
2004 value_type val() const {
2005 return v;
2006 }
2007
2009 bool isLinear() const {
2010 return false;
2011 }
2012
2014 bool hasFastAccess() const {
2015 return expr1.hasFastAccess() && expr2.hasFastAccess();
2016 }
2017
2019 const value_type dx(int i) const {
2020 return max_v1 ? expr1.dx(i) : expr2.dx(i);
2021 }
2022
2024 const value_type fastAccessDx(int i) const {
2025 return max_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2026 }
2027
2028 protected:
2029
2030 const ExprT1& expr1;
2031 const ExprT2& expr2;
2032 mutable value_type v;
2033 mutable bool max_v1;
2034
2035 };
2036
2037 template <typename ExprT1, typename T2>
2038 class Expr< MaxOp<ExprT1, ConstExpr<T2> > > {
2039
2040 public:
2041
2042 typedef ConstExpr<T2> ExprT2;
2043 typedef typename ExprT1::value_type value_type_1;
2044 typedef typename ExprT2::value_type value_type_2;
2045 typedef typename Sacado::Promote<value_type_1,
2046 value_type_2>::type value_type;
2047
2048 typedef typename ExprT1::scalar_type scalar_type_1;
2049 typedef typename ExprT2::scalar_type scalar_type_2;
2050 typedef typename Sacado::Promote<scalar_type_1,
2051 scalar_type_2>::type scalar_type;
2052
2053 typedef typename ExprT1::base_expr_type base_expr_type_1;
2054 typedef typename ExprT2::base_expr_type base_expr_type_2;
2055 typedef typename Sacado::Promote<base_expr_type_1,
2056 base_expr_type_2>::type base_expr_type;
2057
2059 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2060 expr1(expr1_), expr2(expr2_) {}
2061
2063 int size() const {
2064 return expr1.size();
2065 }
2066
2068 bool updateValue() const {
2069 return expr1.updateValue();
2070 }
2071
2073 void cache() const {
2074 expr1.cache();
2075 const value_type_1 v1 = expr1.val();
2076 const value_type_2 v2 = expr2.val();
2077 max_v1 = (v1 >= v2);
2078 v = max_v1 ? v1 : v2;
2079 }
2080
2082 value_type val() const {
2083 return v;
2084 }
2085
2087 bool isLinear() const {
2088 return false;
2089 }
2090
2092 bool hasFastAccess() const {
2093 return expr1.hasFastAccess();
2094 }
2095
2097 const value_type dx(int i) const {
2098 return max_v1 ? expr1.dx(i) : value_type(0);
2099 }
2100
2102 const value_type fastAccessDx(int i) const {
2103 return max_v1 ? expr1.fastAccessDx(i) : value_type(0);
2104 }
2105
2106 protected:
2107
2108 const ExprT1& expr1;
2109 ExprT2 expr2;
2110 mutable value_type v;
2111 mutable bool max_v1;
2112
2113 };
2114
2115 template <typename T1, typename ExprT2>
2116 class Expr< MaxOp< ConstExpr<T1>,ExprT2> > {
2117
2118 public:
2119
2120 typedef ConstExpr<T1> ExprT1;
2121 typedef typename ExprT1::value_type value_type_1;
2122 typedef typename ExprT2::value_type value_type_2;
2123 typedef typename Sacado::Promote<value_type_1,
2124 value_type_2>::type value_type;
2125
2126 typedef typename ExprT1::scalar_type scalar_type_1;
2127 typedef typename ExprT2::scalar_type scalar_type_2;
2128 typedef typename Sacado::Promote<scalar_type_1,
2129 scalar_type_2>::type scalar_type;
2130
2131 typedef typename ExprT1::base_expr_type base_expr_type_1;
2132 typedef typename ExprT2::base_expr_type base_expr_type_2;
2133 typedef typename Sacado::Promote<base_expr_type_1,
2134 base_expr_type_2>::type base_expr_type;
2135
2137 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2138 expr1(expr1_), expr2(expr2_) {}
2139
2141 int size() const {
2142 return expr2.size();
2143 }
2144
2146 bool updateValue() const {
2147 return expr2.updateValue();
2148 }
2149
2151 void cache() const {
2152 expr2.cache();
2153 const value_type_1 v1 = expr1.val();
2154 const value_type_2 v2 = expr2.val();
2155 max_v1 = (v1 >= v2);
2156 v = max_v1 ? v1 : v2;
2157 }
2158
2160 value_type val() const {
2161 return v;
2162 }
2163
2165 bool isLinear() const {
2166 return false;
2167 }
2168
2170 bool hasFastAccess() const {
2171 return expr2.hasFastAccess();
2172 }
2173
2175 const value_type dx(int i) const {
2176 return max_v1 ? value_type(0) : expr2.dx(i);
2177 }
2178
2180 const value_type fastAccessDx(int i) const {
2181 return max_v1 ? value_type(0) : expr2.fastAccessDx(i);
2182 }
2183
2184 protected:
2185
2186 ExprT1 expr1;
2187 const ExprT2& expr2;
2188 mutable value_type v;
2189 mutable bool max_v1;
2190
2191 };
2192
2193 //
2194 // MinOp
2195 //
2196
2197 template <typename ExprT1, typename ExprT2>
2198 class MinOp {};
2199
2200 template <typename ExprT1, typename ExprT2>
2201 class Expr< MinOp<ExprT1,ExprT2> > {
2202
2203 public:
2204
2205 typedef typename ExprT1::value_type value_type_1;
2206 typedef typename ExprT2::value_type value_type_2;
2207 typedef typename Sacado::Promote<value_type_1,
2208 value_type_2>::type value_type;
2209
2210 typedef typename ExprT1::scalar_type scalar_type_1;
2211 typedef typename ExprT2::scalar_type scalar_type_2;
2212 typedef typename Sacado::Promote<scalar_type_1,
2213 scalar_type_2>::type scalar_type;
2214
2215 typedef typename ExprT1::base_expr_type base_expr_type_1;
2216 typedef typename ExprT2::base_expr_type base_expr_type_2;
2217 typedef typename Sacado::Promote<base_expr_type_1,
2218 base_expr_type_2>::type base_expr_type;
2219
2221 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2222 expr1(expr1_), expr2(expr2_) {}
2223
2225 int size() const {
2226 int sz1 = expr1.size(), sz2 = expr2.size();
2227 return sz1 > sz2 ? sz1 : sz2;
2228 }
2229
2231 bool updateValue() const {
2232 return expr1.updateValue() && expr2.updateValue();
2233 }
2234
2236 void cache() const {
2237 expr1.cache();
2238 expr2.cache();
2239 const value_type_1 v1 = expr1.val();
2240 const value_type_2 v2 = expr2.val();
2241 min_v1 = (v1 <= v2);
2242 v = min_v1 ? v1 : v2;
2243 }
2244
2246 value_type val() const {
2247 return v;
2248 }
2249
2251 bool isLinear() const {
2252 return false;
2253 }
2254
2256 bool hasFastAccess() const {
2257 return expr1.hasFastAccess() && expr2.hasFastAccess();
2258 }
2259
2261 const value_type dx(int i) const {
2262 return min_v1 ? expr1.dx(i) : expr2.dx(i);
2263 }
2264
2266 const value_type fastAccessDx(int i) const {
2267 return min_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2268 }
2269
2270 protected:
2271
2272 const ExprT1& expr1;
2273 const ExprT2& expr2;
2274 mutable value_type v;
2275 mutable bool min_v1;
2276
2277 };
2278
2279 template <typename ExprT1, typename T2>
2280 class Expr< MinOp<ExprT1, ConstExpr<T2> > > {
2281
2282 public:
2283
2284 typedef ConstExpr<T2> ExprT2;
2285 typedef typename ExprT1::value_type value_type_1;
2286 typedef typename ExprT2::value_type value_type_2;
2287 typedef typename Sacado::Promote<value_type_1,
2288 value_type_2>::type value_type;
2289
2290 typedef typename ExprT1::scalar_type scalar_type_1;
2291 typedef typename ExprT2::scalar_type scalar_type_2;
2292 typedef typename Sacado::Promote<scalar_type_1,
2293 scalar_type_2>::type scalar_type;
2294
2295 typedef typename ExprT1::base_expr_type base_expr_type_1;
2296 typedef typename ExprT2::base_expr_type base_expr_type_2;
2297 typedef typename Sacado::Promote<base_expr_type_1,
2298 base_expr_type_2>::type base_expr_type;
2299
2301 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2302 expr1(expr1_), expr2(expr2_) {}
2303
2305 int size() const {
2306 return expr1.size();
2307 }
2308
2310 bool updateValue() const {
2311 return expr1.updateValue();
2312 }
2313
2315 void cache() const {
2316 expr1.cache();
2317 const value_type_1 v1 = expr1.val();
2318 const value_type_2 v2 = expr2.val();
2319 min_v1 = (v1 <= v2);
2320 v = min_v1 ? v1 : v2;
2321 }
2322
2324 value_type val() const {
2325 return v;
2326 }
2327
2329 bool isLinear() const {
2330 return false;
2331 }
2332
2334 bool hasFastAccess() const {
2335 return expr1.hasFastAccess();
2336 }
2337
2339 const value_type dx(int i) const {
2340 return min_v1 ? expr1.dx(i) : value_type(0);
2341 }
2342
2344 const value_type fastAccessDx(int i) const {
2345 return min_v1 ? expr1.fastAccessDx(i) : value_type(0);
2346 }
2347
2348 protected:
2349
2350 const ExprT1& expr1;
2351 ExprT2 expr2;
2352 mutable value_type v;
2353 mutable bool min_v1;
2354
2355 };
2356
2357 template <typename T1, typename ExprT2>
2358 class Expr< MinOp< ConstExpr<T1>,ExprT2> > {
2359
2360 public:
2361
2362 typedef ConstExpr<T1> ExprT1;
2363 typedef typename ExprT1::value_type value_type_1;
2364 typedef typename ExprT2::value_type value_type_2;
2365 typedef typename Sacado::Promote<value_type_1,
2366 value_type_2>::type value_type;
2367
2368 typedef typename ExprT1::scalar_type scalar_type_1;
2369 typedef typename ExprT2::scalar_type scalar_type_2;
2370 typedef typename Sacado::Promote<scalar_type_1,
2371 scalar_type_2>::type scalar_type;
2372
2373 typedef typename ExprT1::base_expr_type base_expr_type_1;
2374 typedef typename ExprT2::base_expr_type base_expr_type_2;
2375 typedef typename Sacado::Promote<base_expr_type_1,
2376 base_expr_type_2>::type base_expr_type;
2377
2379 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2380 expr1(expr1_), expr2(expr2_) {}
2381
2383 int size() const {
2384 return expr2.size();
2385 }
2386
2388 bool updateValue() const {
2389 return expr2.updateValue();
2390 }
2391
2393 void cache() const {
2394 expr2.cache();
2395 const value_type_1 v1 = expr1.val();
2396 const value_type_2 v2 = expr2.val();
2397 min_v1 = (v1 <= v2);
2398 v = min_v1 ? v1 : v2;
2399 }
2400
2402 value_type val() const {
2403 return v;
2404 }
2405
2407 bool isLinear() const {
2408 return false;
2409 }
2410
2412 bool hasFastAccess() const {
2413 return expr2.hasFastAccess();
2414 }
2415
2417 const value_type dx(int i) const {
2418 return min_v1 ? value_type(0) : expr2.dx(i);
2419 }
2420
2422 const value_type fastAccessDx(int i) const {
2423 return min_v1 ? value_type(0) : expr2.fastAccessDx(i);
2424 }
2425
2426 protected:
2427
2428 ExprT1 expr1;
2429 const ExprT2& expr2;
2430 mutable value_type v;
2431 mutable bool min_v1;
2432
2433 };
2434
2435 }
2436
2437}
2438
2439#define FAD_BINARYOP_MACRO(OPNAME,OP) \
2440namespace Sacado { \
2441 namespace CacheFad { \
2442 \
2443 template <typename T1, typename T2> \
2444 SACADO_INLINE_FUNCTION \
2445 SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \
2446 OPNAME (const T1& expr1, const T2& expr2) \
2447 { \
2448 typedef OP< T1, T2 > expr_t; \
2449 \
2450 return Expr<expr_t>(expr1, expr2); \
2451 } \
2452 \
2453 template <typename T> \
2454 SACADO_INLINE_FUNCTION \
2455 Expr< OP< Expr<T>, Expr<T> > > \
2456 OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
2457 { \
2458 typedef OP< Expr<T>, Expr<T> > expr_t; \
2459 \
2460 return Expr<expr_t>(expr1, expr2); \
2461 } \
2462 \
2463 template <typename T> \
2464 SACADO_INLINE_FUNCTION \
2465 Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
2466 Expr<T> > > \
2467 OPNAME (const typename Expr<T>::value_type& c, \
2468 const Expr<T>& expr) \
2469 { \
2470 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
2471 typedef OP< ConstT, Expr<T> > expr_t; \
2472 \
2473 return Expr<expr_t>(ConstT(c), expr); \
2474 } \
2475 \
2476 template <typename T> \
2477 SACADO_INLINE_FUNCTION \
2478 Expr< OP< Expr<T>, \
2479 ConstExpr<typename Expr<T>::value_type> > > \
2480 OPNAME (const Expr<T>& expr, \
2481 const typename Expr<T>::value_type& c) \
2482 { \
2483 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
2484 typedef OP< Expr<T>, ConstT > expr_t; \
2485 \
2486 return Expr<expr_t>(expr, ConstT(c)); \
2487 } \
2488 \
2489 template <typename T> \
2490 SACADO_INLINE_FUNCTION \
2491 SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \
2492 OPNAME (const typename Expr<T>::scalar_type& c, \
2493 const Expr<T>& expr) \
2494 { \
2495 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
2496 typedef OP< ConstT, Expr<T> > expr_t; \
2497 \
2498 return Expr<expr_t>(ConstT(c), expr); \
2499 } \
2500 \
2501 template <typename T> \
2502 SACADO_INLINE_FUNCTION \
2503 SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \
2504 OPNAME (const Expr<T>& expr, \
2505 const typename Expr<T>::scalar_type& c) \
2506 { \
2507 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
2508 typedef OP< Expr<T>, ConstT > expr_t; \
2509 \
2510 return Expr<expr_t>(expr, ConstT(c)); \
2511 } \
2512 } \
2513}
2514
2515
2524
2525#undef FAD_BINARYOP_MACRO
2526
2527//-------------------------- Relational Operators -----------------------
2528
2529#define FAD_RELOP_MACRO(OP) \
2530namespace Sacado { \
2531 namespace CacheFad { \
2532 template <typename ExprT1, typename ExprT2> \
2533 SACADO_INLINE_FUNCTION \
2534 bool \
2535 operator OP (const Expr<ExprT1>& expr1, \
2536 const Expr<ExprT2>& expr2) \
2537 { \
2538 expr1.cache(); \
2539 expr2.cache(); \
2540 return expr1.val() OP expr2.val(); \
2541 } \
2542 \
2543 template <typename ExprT2> \
2544 SACADO_INLINE_FUNCTION \
2545 bool \
2546 operator OP (const typename Expr<ExprT2>::value_type& a, \
2547 const Expr<ExprT2>& expr2) \
2548 { \
2549 expr2.cache(); \
2550 return a OP expr2.val(); \
2551 } \
2552 \
2553 template <typename ExprT1> \
2554 SACADO_INLINE_FUNCTION \
2555 bool \
2556 operator OP (const Expr<ExprT1>& expr1, \
2557 const typename Expr<ExprT1>::value_type& b) \
2558 { \
2559 expr1.cache(); \
2560 return expr1.val() OP b; \
2561 } \
2562 } \
2563}
2564
2571FAD_RELOP_MACRO(<<=)
2572FAD_RELOP_MACRO(>>=)
2575
2576#undef FAD_RELOP_MACRO
2577
2578namespace Sacado {
2579
2580 namespace CacheFad {
2581
2582 template <typename ExprT>
2584 bool operator ! (const Expr<ExprT>& expr)
2585 {
2586 expr.cache();
2587 return ! expr.val();
2588 }
2589
2590 } // namespace CacheFad
2591
2592} // namespace Sacado
2593
2594//-------------------------- Boolean Operators -----------------------
2595namespace Sacado {
2596
2597 namespace CacheFad {
2598
2599 template <typename ExprT>
2601 bool toBool(const Expr<ExprT>& x) {
2602 x.cache();
2603 bool is_zero = (x.val() == 0.0);
2604 for (int i=0; i<x.size(); i++)
2605 is_zero = is_zero && (x.dx(i) == 0.0);
2606 return !is_zero;
2607 }
2608
2609 } // namespace Fad
2610
2611} // namespace Sacado
2612
2613#define FAD_BOOL_MACRO(OP) \
2614namespace Sacado { \
2615 namespace CacheFad { \
2616 template <typename ExprT1, typename ExprT2> \
2617 SACADO_INLINE_FUNCTION \
2618 bool \
2619 operator OP (const Expr<ExprT1>& expr1, \
2620 const Expr<ExprT2>& expr2) \
2621 { \
2622 return toBool(expr1) OP toBool(expr2); \
2623 } \
2624 \
2625 template <typename ExprT2> \
2626 SACADO_INLINE_FUNCTION \
2627 bool \
2628 operator OP (const typename Expr<ExprT2>::value_type& a, \
2629 const Expr<ExprT2>& expr2) \
2630 { \
2631 return a OP toBool(expr2); \
2632 } \
2633 \
2634 template <typename ExprT1> \
2635 SACADO_INLINE_FUNCTION \
2636 bool \
2637 operator OP (const Expr<ExprT1>& expr1, \
2638 const typename Expr<ExprT1>::value_type& b) \
2639 { \
2640 return toBool(expr1) OP b; \
2641 } \
2642 } \
2643}
2644
2647
2648#undef FAD_BOOL_MACRO
2649
2650//-------------------------- I/O Operators -----------------------
2651
2652namespace Sacado {
2653
2654 namespace CacheFad {
2655
2656 template <typename ExprT>
2657 std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
2658 x.cache();
2659 os << x.val() << " [";
2660
2661 for (int i=0; i< x.size(); i++) {
2662 os << " " << x.dx(i);
2663 }
2664
2665 os << " ]";
2666 return os;
2667 }
2668
2669 } // namespace CacheFad
2670
2671} // namespace Sacado
2672
2673#endif // SACADO_CACHEFAD_OPS_HPP
#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
asinh(expr.val())
log(expr.val())
tan(expr.val())
expr expr SinOp
expr expr SinhOp
cos(expr.val())
expr expr SqrtOp
expr expr dx(i)
expr expr ACosOp
expr2 expr1 expr2 expr2 c *expr2 c *expr1 c *expr2 c *expr1 MaxOp
expr expr ATanOp
cosh(expr.val())
expr expr ACoshOp
acos(expr.val())
sin(expr.val())
sinh(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
expr expr ASinOp
cbrt(expr.val())
log10(expr.val())
expr expr TanhOp
expr expr TanOp
expr expr CoshOp
#define FAD_RELOP_MACRO(OP)
expr expr ASinhOp
exp(expr.val())
atan(expr.val())
expr expr Log10Op
#define FAD_BOOL_MACRO(OP)
acosh(expr.val())
expr expr expr ExpOp
expr expr expr fastAccessDx(i)) FAD_UNARYOP_MACRO(exp
expr val()
atan2(expr1.val(), expr2.val())
sqrt(expr.val())
expr expr ATanhOp
tanh(expr.val())
atanh(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
expr expr CosOp
expr1 expr1 expr2 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 MultiplicationOp
asin(expr.val())
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 PowerOp
#define T1(r, f)
#define T2(r, f)
adouble max(const adouble &a, const adouble &b)
adouble min(const adouble &a, const adouble &b)
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.
Namespace for forward-mode AD classes w/caching.
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)
ACosExprType< T >::expr_type acos(const Expr< T > &expr)
PowExprType< Expr< T1 >, Expr< T2 > >::expr_type pow(const Expr< T1 > &expr1, const Expr< T2 > &expr2)
Log10ExprType< T >::expr_type log10(const Expr< T > &expr)
ATanExprType< T >::expr_type atan(const Expr< T > &expr)
TanhExprType< T >::expr_type tanh(const Expr< T > &expr)
TanExprType< T >::expr_type tan(const Expr< T > &expr)
ASinExprType< T >::expr_type asin(const Expr< T > &expr)
Base template specification for Promote.