Sacado Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
Sacado_ELRCacheFad_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_ELRCACHEFAD_OPS_HPP
53#define SACADO_ELRCACHEFAD_OPS_HPP
54
56#include "Sacado_cmath.hpp"
58#include <ostream> // for std::ostream
59
60namespace Sacado {
61 namespace ELRCacheFad {
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
77 typedef typename ExprT::base_expr_type base_expr_type;
78
79 static const int num_args = ExprT::num_args;
80
81 static const bool is_linear = true;
82
84 explicit Expr(const ExprT& expr_) : expr(expr_) {}
85
87 int size() const { return expr.size(); }
88
89 template <int Arg>
91 bool isActive() const { return expr.template isActive<Arg>(); }
92
94 bool updateValue() const { return expr.updateValue(); }
95
97 void cache() const {
98 expr.cache();
99 }
100
102 value_type val() const {
103 return expr.val();
104 }
105
108 value_type partials[]) const {
109 expr.computePartials(bar, partials);
110 }
111
113 void getTangents(int i, value_type dots[]) const {
114 expr.getTangents(i, dots); }
115
116 template <int Arg>
117 value_type getTangent(int i) const {
118 return expr.template getTangent<Arg>(i);
119 }
120
122 bool isLinear() const {
123 return expr.isLinear();
124 }
125
127 bool hasFastAccess() const {
128 return expr.hasFastAccess();
129 }
130
132 const value_type dx(int i) const {
133 return expr.dx(i);
134 }
135
137 const value_type fastAccessDx(int i) const {
138 return expr.fastAccessDx(i);
139 }
140
142 const value_type* getDx(int j) const {
143 return expr.getDx(j);
144 }
145
146 protected:
147
148 const ExprT& expr;
149 };
150
151 template <typename T>
154 operator+ (const Expr<T>& expr)
155 {
156 typedef UnaryPlusOp< Expr<T> > expr_t;
157
158 return Expr<expr_t>(expr);
159 }
160
161 //
162 // UnaryMinusOp
163 //
164 template <typename ExprT>
165 class UnaryMinusOp {};
166
167 template <typename ExprT>
168 class Expr< UnaryMinusOp<ExprT> > {
169 public:
170
171 typedef typename ExprT::value_type value_type;
172 typedef typename ExprT::scalar_type scalar_type;
173
174 typedef typename ExprT::base_expr_type base_expr_type;
175
176 static const int num_args = ExprT::num_args;
177
178 static const bool is_linear = true;
179
181 explicit Expr(const ExprT& expr_) : expr(expr_) {}
182
184 int size() const { return expr.size(); }
185
186 template <int Arg>
188 bool isActive() const { return expr.template isActive<Arg>(); }
189
191 bool updateValue() const { return expr.updateValue(); }
192
194 void cache() const {
195 expr.cache();
196 }
197
199 value_type val() const {
200 return -expr.val();
201 }
202
205 value_type partials[]) const {
206 expr.computePartials(-bar, partials);
207 }
208
210 void getTangents(int i, value_type dots[]) const {
211 expr.getTangents(i, dots); }
212
213 template <int Arg>
215 value_type getTangent(int i) const {
216 return expr.template getTangent<Arg>(i);
217 }
218
220 bool isLinear() const {
221 return expr.isLinear();
222 }
223
225 bool hasFastAccess() const {
226 return expr.hasFastAccess();
227 }
228
230 const value_type dx(int i) const {
231 return -expr.dx(i);
232 }
233
235 const value_type fastAccessDx(int i) const {
236 return -expr.fastAccessDx(i);
237 }
238
240 const value_type* getDx(int j) const {
241 return expr.getDx(j);
242 }
243
244 protected:
245
246 const ExprT& expr;
247 };
248
249 template <typename T>
252 operator- (const Expr<T>& expr)
253 {
254 typedef UnaryMinusOp< Expr<T> > expr_t;
255
256 return Expr<expr_t>(expr);
257 }
258
259 //
260 // AbsOp
261 //
262
263 template <typename ExprT>
264 class AbsOp {};
265
266 template <typename ExprT>
267 class Expr< AbsOp<ExprT> > {
268 public:
269
270 typedef typename ExprT::value_type value_type;
271 typedef typename ExprT::scalar_type scalar_type;
272
273 typedef typename ExprT::base_expr_type base_expr_type;
274
275 static const int num_args = ExprT::num_args;
276
277 static const bool is_linear = false;
278
280 explicit Expr(const ExprT& expr_) : expr(expr_) {}
281
283 int size() const { return expr.size(); }
284
285 template <int Arg>
287 bool isActive() const { return expr.template isActive<Arg>(); }
288
290 bool updateValue() const { return expr.updateValue(); }
291
293 void cache() const {
294 expr.cache();
295 v = expr.val();
296 v_pos = (v >= 0);
297 }
298
300 value_type val() const {
301 return std::abs(v);
302 }
303
306 value_type partials[]) const {
307 if (v_pos)
308 expr.computePartials(bar, partials);
309 else
310 expr.computePartials(-bar, partials);
311 }
312
314 void getTangents(int i, value_type dots[]) const {
315 expr.getTangents(i, dots); }
316
317 template <int Arg>
319 value_type getTangent(int i) const {
320 return expr.template getTangent<Arg>(i);
321 }
322
324 bool isLinear() const {
325 return false;
326 }
327
329 bool hasFastAccess() const {
330 return expr.hasFastAccess();
331 }
332
334 const value_type dx(int i) const {
335 if (v_pos) return expr.dx(i);
336 else return -expr.dx(i);
337 }
338
340 const value_type fastAccessDx(int i) const {
341 if (v_pos) return expr.fastAccessDx(i);
342 else return -expr.fastAccessDx(i);
343 }
344
346 const value_type* getDx(int j) const {
347 return expr.getDx(j);
348 }
349
350 protected:
351
352 const ExprT& expr;
353 mutable value_type v;
354 mutable bool v_pos;
355 };
356
357 template <typename T>
360 abs (const Expr<T>& expr)
361 {
362 typedef AbsOp< Expr<T> > expr_t;
363
364 return Expr<expr_t>(expr);
365 }
366
367 //
368 // FAbsOp
369 //
370
371 template <typename ExprT>
372 class FAbsOp {};
373
374 template <typename ExprT>
375 class Expr< FAbsOp<ExprT> > {
376 public:
377
378 typedef typename ExprT::value_type value_type;
379 typedef typename ExprT::scalar_type scalar_type;
380
381 typedef typename ExprT::base_expr_type base_expr_type;
382
383 static const int num_args = ExprT::num_args;
384
385 static const bool is_linear = false;
386
388 explicit Expr(const ExprT& expr_) : expr(expr_) {}
389
391 int size() const { return expr.size(); }
392
393 template <int Arg>
395 bool isActive() const { return expr.template isActive<Arg>(); }
396
398 bool updateValue() const { return expr.updateValue(); }
399
401 void cache() const {
402 expr.cache();
403 v = expr.val();
404 v_pos = (v >= 0);
405 }
406
408 value_type val() const {
409 return std::fabs(v);
410 }
411
414 value_type partials[]) const {
415 if (v_pos)
416 expr.computePartials(bar, partials);
417 else
418 expr.computePartials(-bar, partials);
419 }
420
422 void getTangents(int i, value_type dots[]) const {
423 expr.getTangents(i, dots); }
424
425 template <int Arg>
427 value_type getTangent(int i) const {
428 return expr.template getTangent<Arg>(i);
429 }
430
432 bool isLinear() const {
433 return false;
434 }
435
437 bool hasFastAccess() const {
438 return expr.hasFastAccess();
439 }
440
442 const value_type dx(int i) const {
443 if (v_pos) return expr.dx(i);
444 else return -expr.dx(i);
445 }
446
448 const value_type fastAccessDx(int i) const {
449 if (v_pos) return expr.fastAccessDx(i);
450 else return -expr.fastAccessDx(i);
451 }
452
454 const value_type* getDx(int j) const {
455 return expr.getDx(j);
456 }
457
458 protected:
459
460 const ExprT& expr;
461 mutable value_type v;
462 mutable bool v_pos;
463 };
464
465 template <typename T>
468 fabs (const Expr<T>& expr)
469 {
470 typedef FAbsOp< Expr<T> > expr_t;
471
472 return Expr<expr_t>(expr);
473 }
474
475 }
476}
477
478#define FAD_UNARYOP_MACRO(OPNAME,OP,PARTIAL,VALUE) \
479namespace Sacado { \
480 namespace ELRCacheFad { \
481 \
482 template <typename ExprT> \
483 class OP {}; \
484 \
485 template <typename ExprT> \
486 class Expr< OP<ExprT> > { \
487 public: \
488 \
489 typedef typename ExprT::value_type value_type; \
490 typedef typename ExprT::scalar_type scalar_type; \
491 \
492 typedef typename ExprT::base_expr_type base_expr_type; \
493 \
494 static const int num_args = ExprT::num_args; \
495 \
496 static const bool is_linear = false; \
497 \
498 SACADO_INLINE_FUNCTION \
499 explicit Expr(const ExprT& expr_) : expr(expr_) {} \
500 \
501 SACADO_INLINE_FUNCTION \
502 int size() const { return expr.size(); } \
503 \
504 template <int Arg> \
505 SACADO_INLINE_FUNCTION \
506 bool isActive() const { return expr.template isActive<Arg>(); } \
507 \
508 SACADO_INLINE_FUNCTION \
509 bool updateValue() const { return expr.updateValue(); } \
510 \
511 SACADO_INLINE_FUNCTION \
512 void cache() const { \
513 expr.cache(); \
514 v = expr.val(); \
515 PARTIAL; \
516 } \
517 \
518 SACADO_INLINE_FUNCTION \
519 value_type val() const { \
520 return VALUE; \
521 } \
522 \
523 SACADO_INLINE_FUNCTION \
524 void computePartials(const value_type& bar, \
525 value_type partials[]) const { \
526 expr.computePartials(bar*a, partials); \
527 } \
528 \
529 SACADO_INLINE_FUNCTION \
530 void getTangents(int i, value_type dots[]) const { \
531 expr.getTangents(i, dots); } \
532 \
533 template <int Arg> \
534 SACADO_INLINE_FUNCTION \
535 value_type getTangent(int i) const { \
536 return expr.template getTangent<Arg>(i); \
537 } \
538 \
539 SACADO_INLINE_FUNCTION \
540 bool isLinear() const { \
541 return false; \
542 } \
543 \
544 SACADO_INLINE_FUNCTION \
545 bool hasFastAccess() const { \
546 return expr.hasFastAccess(); \
547 } \
548 \
549 SACADO_INLINE_FUNCTION \
550 const value_type dx(int i) const { \
551 return expr.dx(i)*a; \
552 } \
553 \
554 SACADO_INLINE_FUNCTION \
555 const value_type fastAccessDx(int i) const { \
556 return expr.fastAccessDx(i)*a; \
557 } \
558 \
559 SACADO_INLINE_FUNCTION \
560 const value_type* getDx(int j) const { \
561 return expr.getDx(j); \
562 } \
563 \
564 protected: \
565 \
566 const ExprT& expr; \
567 mutable value_type v; \
568 mutable value_type a; \
569 }; \
570 \
571 template <typename T> \
572 SACADO_INLINE_FUNCTION \
573 Expr< OP< Expr<T> > > \
574 OPNAME (const Expr<T>& expr) \
575 { \
576 typedef OP< Expr<T> > expr_t; \
577 \
578 return Expr<expr_t>(expr); \
579 } \
580 } \
581}
582
584 ExpOp,
585 a = std::exp(v),
586 a)
589 a=scalar_type(1.0)/v,
590 std::log(v))
593 a = scalar_type(1.0)/(std::log(scalar_type(10.0))*v),
594 std::log10(v))
597 a = scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)),
598 std::sqrt(v))
599FAD_UNARYOP_MACRO(safe_sqrt,
601 a = (v == value_type(0.0) ? value_type(0.0) : value_type(scalar_type(1.0)/(scalar_type(2.0)*std::sqrt(v)))),
602 std::sqrt(v))
605 a = -std::sin(v),
606 std::cos(v))
609 a = std::cos(v),
610 std::sin(v))
613 a = scalar_type(1.0)+std::tan(v)*std::tan(v),
614 std::tan(v))
617 a = scalar_type(-1.0)/std::sqrt(scalar_type(1.0)-v*v),
618 std::acos(v))
621 a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)-v*v),
622 std::asin(v))
625 a = scalar_type(1.0)/(scalar_type(1.0)+v*v),
626 std::atan(v))
629 a = std::sinh(v),
630 std::cosh(v))
633 a = std::cosh(v),
634 std::sinh(v))
637 a = scalar_type(1.0)-std::tanh(v)*std::tanh(v),
638 std::tanh(v))
641 a = scalar_type(1.0)/std::sqrt((v-scalar_type(1.0))*(v+scalar_type(1.0))),
642 std::acosh(v))
645 a = scalar_type(1.0)/std::sqrt(scalar_type(1.0)+v*v),
646 std::asinh(v))
649 a = scalar_type(1.0)/(scalar_type(1.0)-v*v),
650 std::atanh(v))
653 a = scalar_type(1.0)/(scalar_type(3.0)*std::cbrt(v*v)),
654 std::cbrt(v))
655
656#undef FAD_UNARYOP_MACRO
657
658//
659// Binary operators
660//
661namespace Sacado {
662 namespace ELRCacheFad {
663
664 //
665 // AdditionOp
666 //
667
668 template <typename ExprT1, typename ExprT2>
669 class AdditionOp {};
670
671 template <typename ExprT1, typename ExprT2>
672 class Expr< AdditionOp<ExprT1,ExprT2> > {
673
674 public:
675
676 typedef typename ExprT1::value_type value_type_1;
677 typedef typename ExprT2::value_type value_type_2;
678 typedef typename Sacado::Promote<value_type_1,
679 value_type_2>::type value_type;
680 typedef typename ExprT1::scalar_type scalar_type_1;
681 typedef typename ExprT2::scalar_type scalar_type_2;
682 typedef typename Sacado::Promote<scalar_type_1,
683 scalar_type_2>::type scalar_type;
684
685 typedef typename ExprT1::base_expr_type base_expr_type_1;
686 typedef typename ExprT2::base_expr_type base_expr_type_2;
687 typedef typename Sacado::Promote<base_expr_type_1,
688 base_expr_type_2>::type base_expr_type;
689
690 static const int num_args1 = ExprT1::num_args;
691 static const int num_args2 = ExprT2::num_args;
692 static const int num_args = num_args1 + num_args2;
693
694 static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
695
697 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
698 expr1(expr1_), expr2(expr2_) {}
699
701 int size() const {
702 int sz1 = expr1.size(), sz2 = expr2.size();
703 return sz1 > sz2 ? sz1 : sz2;
704 }
705
706 template <int Arg>
708 bool isActive() const {
709 if (Arg < num_args1)
710 return expr1.template isActive<Arg>();
711 else
712 return expr2.template isActive<Arg-num_args1>();
713 }
714
716 bool updateValue() const {
717 return expr1.updateValue() && expr2.updateValue();
718 }
719
721 void cache() const {
722 expr1.cache();
723 expr2.cache();
724 }
725
727 value_type val() const {
728 return expr1.val()+expr2.val();
729 }
730
732 void computePartials(const value_type& bar,
733 value_type partials[]) const {
734 if (num_args1 > 0)
735 expr1.computePartials(bar, partials);
736 if (num_args2 > 0)
737 expr2.computePartials(bar, partials+num_args1);
738 }
739
741 void getTangents(int i, value_type dots[]) const {
742 expr1.getTangents(i, dots);
743 expr2.getTangents(i, dots+num_args1);
744 }
745
746 template <int Arg>
748 value_type getTangent(int i) const {
749 if (Arg < num_args1)
750 return expr1.template getTangent<Arg>(i);
751 else
752 return expr2.template getTangent<Arg-num_args1>(i);
753 }
754
756 bool isLinear() const {
757 return expr1.isLinear() && expr2.isLinear();
758 }
759
761 bool hasFastAccess() const {
762 return expr1.hasFastAccess() && expr2.hasFastAccess();
763 }
764
766 const value_type dx(int i) const {
767 return expr1.dx(i) + expr2.dx(i);
768 }
769
771 const value_type fastAccessDx(int i) const {
772 return expr1.fastAccessDx(i) + expr2.fastAccessDx(i);
773 }
774
776 const value_type* getDx(int j) const {
777 if (j < num_args1)
778 return expr1.getDx(j);
779 else
780 return expr2.getDx(j-num_args1);
781 }
782
783 protected:
784
785 const ExprT1& expr1;
786 const ExprT2& expr2;
787
788 };
789
790 template <typename ExprT1, typename T2>
791 class Expr< AdditionOp<ExprT1, ConstExpr<T2> > > {
792
793 public:
794
795 typedef ConstExpr<T2> ExprT2;
796 typedef typename ExprT1::value_type value_type_1;
797 typedef typename ExprT2::value_type value_type_2;
798 typedef typename Sacado::Promote<value_type_1,
799 value_type_2>::type value_type;
800 typedef typename ExprT1::scalar_type scalar_type_1;
801 typedef typename ExprT2::scalar_type scalar_type_2;
802 typedef typename Sacado::Promote<scalar_type_1,
803 scalar_type_2>::type scalar_type;
804
805 typedef typename ExprT1::base_expr_type base_expr_type_1;
806 typedef typename ExprT2::base_expr_type base_expr_type_2;
807 typedef typename Sacado::Promote<base_expr_type_1,
808 base_expr_type_2>::type base_expr_type;
809
810 static const int num_args = ExprT1::num_args;
811
812 static const bool is_linear = ExprT1::is_linear;
813
815 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
816 expr1(expr1_), expr2(expr2_) {}
817
819 int size() const {
820 return expr1.size();
821 }
822
823 template <int Arg>
825 bool isActive() const {
826 return expr1.template isActive<Arg>();
827 }
828
830 bool updateValue() const {
831 return expr1.updateValue();
832 }
833
835 void cache() const {
836 expr1.cache();
837 }
838
840 value_type val() const {
841 return expr1.val() + expr2.val();
842 }
843
845 void computePartials(const value_type& bar,
846 value_type partials[]) const {
847 expr1.computePartials(bar, partials);
848 }
849
851 void getTangents(int i, value_type dots[]) const {
852 expr1.getTangents(i, dots);
853 }
854
855 template <int Arg>
857 value_type getTangent(int i) const {
858 return expr1.template getTangent<Arg>(i);
859 }
860
862 bool isLinear() const {
863 return expr1.isLinear();
864 }
865
867 bool hasFastAccess() const {
868 return expr1.hasFastAccess();
869 }
870
872 const value_type dx(int i) const {
873 return expr1.dx(i);
874 }
875
877 const value_type fastAccessDx(int i) const {
878 return expr1.fastAccessDx(i);
879 }
880
882 const value_type* getDx(int j) const {
883 return expr1.getDx(j);
884 }
885
886 protected:
887
888 const ExprT1& expr1;
889 ExprT2 expr2;
890
891 };
892
893 template <typename T1, typename ExprT2>
894 class Expr< AdditionOp< ConstExpr<T1>,ExprT2> > {
895
896 public:
897
898 typedef ConstExpr<T1> ExprT1;
899 typedef typename ExprT1::value_type value_type_1;
900 typedef typename ExprT2::value_type value_type_2;
901 typedef typename Sacado::Promote<value_type_1,
902 value_type_2>::type value_type;
903 typedef typename ExprT1::scalar_type scalar_type_1;
904 typedef typename ExprT2::scalar_type scalar_type_2;
905 typedef typename Sacado::Promote<scalar_type_1,
906 scalar_type_2>::type scalar_type;
907
908 typedef typename ExprT1::base_expr_type base_expr_type_1;
909 typedef typename ExprT2::base_expr_type base_expr_type_2;
910 typedef typename Sacado::Promote<base_expr_type_1,
911 base_expr_type_2>::type base_expr_type;
912
913 static const int num_args = ExprT2::num_args;
914
915 static const bool is_linear = ExprT2::is_linear;
916
918 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
919 expr1(expr1_), expr2(expr2_) {}
920
922 int size() const {
923 return expr2.size();
924 }
925
926 template <int Arg>
928 bool isActive() const {
929 return expr2.template isActive<Arg>();
930 }
931
933 bool updateValue() const {
934 return expr2.updateValue();
935 }
936
938 void cache() const {
939 expr2.cache();
940 }
941
943 value_type val() const {
944 return expr1.val() + expr2.val();
945 }
946
948 void computePartials(const value_type& bar,
949 value_type partials[]) const {
950 expr2.computePartials(bar, partials);
951 }
952
954 void getTangents(int i, value_type dots[]) const {
955 expr2.getTangents(i, dots);
956 }
957
958 template <int Arg>
960 value_type getTangent(int i) const {
961 return expr2.template getTangent<Arg>(i);
962 }
963
965 bool isLinear() const {
966 return expr2.isLinear();
967 }
968
970 bool hasFastAccess() const {
971 return expr2.hasFastAccess();
972 }
973
975 const value_type dx(int i) const {
976 return expr2.dx(i);
977 }
978
980 const value_type fastAccessDx(int i) const {
981 return expr2.fastAccessDx(i);
982 }
983
985 const value_type* getDx(int j) const {
986 return expr2.getDx(j);
987 }
988
989 protected:
990
991 ExprT1 expr1;
992 const ExprT2& expr2;
993
994 };
995
996 //
997 // SubtractionOp
998 //
999
1000 template <typename ExprT1, typename ExprT2>
1001 class SubtractionOp {};
1002
1003 template <typename ExprT1, typename ExprT2>
1004 class Expr< SubtractionOp<ExprT1,ExprT2> > {
1005
1006 public:
1007
1008 typedef typename ExprT1::value_type value_type_1;
1009 typedef typename ExprT2::value_type value_type_2;
1010 typedef typename Sacado::Promote<value_type_1,
1011 value_type_2>::type value_type;
1012 typedef typename ExprT1::scalar_type scalar_type_1;
1013 typedef typename ExprT2::scalar_type scalar_type_2;
1014 typedef typename Sacado::Promote<scalar_type_1,
1015 scalar_type_2>::type scalar_type;
1016
1017 typedef typename ExprT1::base_expr_type base_expr_type_1;
1018 typedef typename ExprT2::base_expr_type base_expr_type_2;
1019 typedef typename Sacado::Promote<base_expr_type_1,
1020 base_expr_type_2>::type base_expr_type;
1021
1022 static const int num_args1 = ExprT1::num_args;
1023 static const int num_args2 = ExprT2::num_args;
1024 static const int num_args = num_args1 + num_args2;
1025
1026 static const bool is_linear = ExprT1::is_linear && ExprT2::is_linear;
1027
1029 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1030 expr1(expr1_), expr2(expr2_) {}
1031
1033 int size() const {
1034 int sz1 = expr1.size(), sz2 = expr2.size();
1035 return sz1 > sz2 ? sz1 : sz2;
1036 }
1037
1038 template <int Arg>
1040 bool isActive() const {
1041 if (Arg < num_args1)
1042 return expr1.template isActive<Arg>();
1043 else
1044 return expr2.template isActive<Arg-num_args1>();
1045 }
1046
1048 bool updateValue() const {
1049 return expr1.updateValue() && expr2.updateValue();
1050 }
1051
1053 void cache() const {
1054 expr1.cache();
1055 expr2.cache();
1056 }
1057
1059 value_type val() const {
1060 return expr1.val()-expr2.val();
1061 }
1062
1064 void computePartials(const value_type& bar,
1065 value_type partials[]) const {
1066 if (num_args1 > 0)
1067 expr1.computePartials(bar, partials);
1068 if (num_args2 > 0)
1069 expr2.computePartials(-bar, partials+num_args1);
1070 }
1071
1073 void getTangents(int i, value_type dots[]) const {
1074 expr1.getTangents(i, dots);
1075 expr2.getTangents(i, dots+num_args1);
1076 }
1077
1078 template <int Arg>
1080 value_type getTangent(int i) const {
1081 if (Arg < num_args1)
1082 return expr1.template getTangent<Arg>(i);
1083 else
1084 return expr2.template getTangent<Arg-num_args1>(i);
1085 }
1086
1088 bool isLinear() const {
1089 return expr1.isLinear() && expr2.isLinear();
1090 }
1091
1093 bool hasFastAccess() const {
1094 return expr1.hasFastAccess() && expr2.hasFastAccess();
1095 }
1096
1098 const value_type dx(int i) const {
1099 return expr1.dx(i) - expr2.dx(i);
1100 }
1101
1103 const value_type fastAccessDx(int i) const {
1104 return expr1.fastAccessDx(i) - expr2.fastAccessDx(i);
1105 }
1106
1108 const value_type* getDx(int j) const {
1109 if (j < num_args1)
1110 return expr1.getDx(j);
1111 else
1112 return expr2.getDx(j-num_args1);
1113 }
1114
1115 protected:
1116
1117 const ExprT1& expr1;
1118 const ExprT2& expr2;
1119
1120 };
1121
1122 template <typename ExprT1, typename T2>
1123 class Expr< SubtractionOp<ExprT1, ConstExpr<T2> > > {
1124
1125 public:
1126
1127 typedef ConstExpr<T2> ExprT2;
1128 typedef typename ExprT1::value_type value_type_1;
1129 typedef typename ExprT2::value_type value_type_2;
1130 typedef typename Sacado::Promote<value_type_1,
1131 value_type_2>::type value_type;
1132 typedef typename ExprT1::scalar_type scalar_type_1;
1133 typedef typename ExprT2::scalar_type scalar_type_2;
1134 typedef typename Sacado::Promote<scalar_type_1,
1135 scalar_type_2>::type scalar_type;
1136
1137 typedef typename ExprT1::base_expr_type base_expr_type_1;
1138 typedef typename ExprT2::base_expr_type base_expr_type_2;
1139 typedef typename Sacado::Promote<base_expr_type_1,
1140 base_expr_type_2>::type base_expr_type;
1141
1142 static const int num_args = ExprT1::num_args;
1143
1144 static const bool is_linear = ExprT1::is_linear;
1145
1147 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1148 expr1(expr1_), expr2(expr2_) {}
1149
1151 int size() const {
1152 return expr1.size();
1153 }
1154
1155 template <int Arg>
1157 bool isActive() const {
1158 return expr1.template isActive<Arg>();
1159 }
1160
1162 bool updateValue() const {
1163 return expr1.updateValue();
1164 }
1165
1167 void cache() const {
1168 expr1.cache();
1169 }
1170
1172 value_type val() const {
1173 return expr1.val() - expr2.val();
1174 }
1175
1177 void computePartials(const value_type& bar,
1178 value_type partials[]) const {
1179 expr1.computePartials(bar, partials);
1180 }
1181
1183 void getTangents(int i, value_type dots[]) const {
1184 expr1.getTangents(i, dots);
1185 }
1186
1187 template <int Arg>
1189 value_type getTangent(int i) const {
1190 return expr1.template getTangent<Arg>(i);
1191 }
1192
1194 bool isLinear() const {
1195 return expr1.isLinear();
1196 }
1197
1199 bool hasFastAccess() const {
1200 return expr1.hasFastAccess();
1201 }
1202
1204 const value_type dx(int i) const {
1205 return expr1.dx(i);
1206 }
1207
1209 const value_type fastAccessDx(int i) const {
1210 return expr1.fastAccessDx(i);
1211 }
1212
1214 const value_type* getDx(int j) const {
1215 return expr1.getDx(j);
1216 }
1217
1218 protected:
1219
1220 const ExprT1& expr1;
1221 ExprT2 expr2;
1222
1223 };
1224
1225 template <typename T1, typename ExprT2>
1226 class Expr< SubtractionOp< ConstExpr<T1>,ExprT2> > {
1227
1228 public:
1229
1230 typedef ConstExpr<T1> ExprT1;
1231 typedef typename ExprT1::value_type value_type_1;
1232 typedef typename ExprT2::value_type value_type_2;
1233 typedef typename Sacado::Promote<value_type_1,
1234 value_type_2>::type value_type;
1235 typedef typename ExprT1::scalar_type scalar_type_1;
1236 typedef typename ExprT2::scalar_type scalar_type_2;
1237 typedef typename Sacado::Promote<scalar_type_1,
1238 scalar_type_2>::type scalar_type;
1239
1240 typedef typename ExprT1::base_expr_type base_expr_type_1;
1241 typedef typename ExprT2::base_expr_type base_expr_type_2;
1242 typedef typename Sacado::Promote<base_expr_type_1,
1243 base_expr_type_2>::type base_expr_type;
1244
1245 static const int num_args = ExprT2::num_args;
1246
1247 static const bool is_linear = ExprT2::is_linear;
1248
1250 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1251 expr1(expr1_), expr2(expr2_) {}
1252
1254 int size() const {
1255 return expr2.size();
1256 }
1257
1258 template <int Arg>
1260 bool isActive() const {
1261 return expr2.template isActive<Arg>();
1262 }
1263
1265 bool updateValue() const {
1266 return expr2.updateValue();
1267 }
1268
1270 void cache() const {
1271 expr2.cache();
1272 }
1273
1275 value_type val() const {
1276 return expr1.val() - expr2.val();
1277 }
1278
1280 void computePartials(const value_type& bar,
1281 value_type partials[]) const {
1282 expr2.computePartials(-bar, partials);
1283 }
1284
1286 void getTangents(int i, value_type dots[]) const {
1287 expr2.getTangents(i, dots);
1288 }
1289
1290 template <int Arg>
1292 value_type getTangent(int i) const {
1293 return expr2.template getTangent<Arg>(i);
1294 }
1295
1297 bool isLinear() const {
1298 return expr2.isLinear();
1299 }
1300
1302 bool hasFastAccess() const {
1303 return expr2.hasFastAccess();
1304 }
1305
1307 const value_type dx(int i) const {
1308 return -expr2.dx(i);
1309 }
1310
1312 const value_type fastAccessDx(int i) const {
1313 return -expr2.fastAccessDx(i);
1314 }
1315
1317 const value_type* getDx(int j) const {
1318 return expr2.getDx(j);
1319 }
1320
1321 protected:
1322
1323 ExprT1 expr1;
1324 const ExprT2& expr2;
1325
1326 };
1327
1328 //
1329 // MultiplicationOp
1330 //
1331
1332 template <typename ExprT1, typename ExprT2>
1333 class MultiplicationOp {};
1334
1335 template <typename ExprT1, typename ExprT2>
1336 class Expr< MultiplicationOp<ExprT1,ExprT2> > {
1337
1338 public:
1339
1340 typedef typename ExprT1::value_type value_type_1;
1341 typedef typename ExprT2::value_type value_type_2;
1342 typedef typename Sacado::Promote<value_type_1,
1343 value_type_2>::type value_type;
1344 typedef typename ExprT1::scalar_type scalar_type_1;
1345 typedef typename ExprT2::scalar_type scalar_type_2;
1346 typedef typename Sacado::Promote<scalar_type_1,
1347 scalar_type_2>::type scalar_type;
1348
1349 typedef typename ExprT1::base_expr_type base_expr_type_1;
1350 typedef typename ExprT2::base_expr_type base_expr_type_2;
1351 typedef typename Sacado::Promote<base_expr_type_1,
1352 base_expr_type_2>::type base_expr_type;
1353
1354 static const int num_args1 = ExprT1::num_args;
1355 static const int num_args2 = ExprT2::num_args;
1356 static const int num_args = num_args1 + num_args2;
1357
1358 static const bool is_linear = false;
1359
1361 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1362 expr1(expr1_), expr2(expr2_) {}
1363
1365 int size() const {
1366 int sz1 = expr1.size(), sz2 = expr2.size();
1367 return sz1 > sz2 ? sz1 : sz2;
1368 }
1369
1370 template <int Arg>
1372 bool isActive() const {
1373 if (Arg < num_args1)
1374 return expr1.template isActive<Arg>();
1375 else
1376 return expr2.template isActive<Arg-num_args1>();
1377 }
1378
1380 bool updateValue() const {
1381 return expr1.updateValue() && expr2.updateValue();
1382 }
1383
1385 void cache() const {
1386 expr1.cache();
1387 expr2.cache();
1388 v1 = expr1.val();
1389 v2 = expr2.val();
1390 }
1391
1393 value_type val() const {
1394 return v1*v2;
1395 }
1396
1398 void computePartials(const value_type& bar,
1399 value_type partials[]) const {
1400 if (num_args1 > 0)
1401 expr1.computePartials(bar*v2, partials);
1402 if (num_args2 > 0)
1403 expr2.computePartials(bar*v1, partials+num_args1);
1404 }
1405
1407 void getTangents(int i, value_type dots[]) const {
1408 expr1.getTangents(i, dots);
1409 expr2.getTangents(i, dots+num_args1);
1410 }
1411
1412 template <int Arg>
1414 value_type getTangent(int i) const {
1415 if (Arg < num_args1)
1416 return expr1.template getTangent<Arg>(i);
1417 else
1418 return expr2.template getTangent<Arg-num_args1>(i);
1419 }
1420
1422 bool isLinear() const {
1423 return false;
1424 }
1425
1427 bool hasFastAccess() const {
1428 return expr1.hasFastAccess() && expr2.hasFastAccess();
1429 }
1430
1432 const value_type dx(int i) const {
1433 if (expr1.size() > 0 && expr2.size() > 0)
1434 return v1*expr2.dx(i) + expr1.dx(i)*v2;
1435 else if (expr1.size() > 0)
1436 return expr1.dx(i)*v2;
1437 else
1438 return v1*expr2.dx(i);
1439 }
1440
1442 const value_type fastAccessDx(int i) const {
1443 return v1*expr2.fastAccessDx(i) + expr1.fastAccessDx(i)*v2;
1444 }
1445
1447 const value_type* getDx(int j) const {
1448 if (j < num_args1)
1449 return expr1.getDx(j);
1450 else
1451 return expr2.getDx(j-num_args1);
1452 }
1453
1454 protected:
1455
1456 const ExprT1& expr1;
1457 const ExprT2& expr2;
1458 mutable value_type_1 v1;
1459 mutable value_type_2 v2;
1460
1461 };
1462
1463 template <typename ExprT1, typename T2>
1464 class Expr< MultiplicationOp<ExprT1, ConstExpr<T2> > > {
1465
1466 public:
1467
1468 typedef ConstExpr<T2> ExprT2;
1469 typedef typename ExprT1::value_type value_type_1;
1470 typedef typename ExprT2::value_type value_type_2;
1471 typedef typename Sacado::Promote<value_type_1,
1472 value_type_2>::type value_type;
1473 typedef typename ExprT1::scalar_type scalar_type_1;
1474 typedef typename ExprT2::scalar_type scalar_type_2;
1475 typedef typename Sacado::Promote<scalar_type_1,
1476 scalar_type_2>::type scalar_type;
1477
1478 typedef typename ExprT1::base_expr_type base_expr_type_1;
1479 typedef typename ExprT2::base_expr_type base_expr_type_2;
1480 typedef typename Sacado::Promote<base_expr_type_1,
1481 base_expr_type_2>::type base_expr_type;
1482
1483 static const int num_args = ExprT1::num_args;
1484
1485 static const bool is_linear = ExprT1::is_linear;
1486
1488 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1489 expr1(expr1_), expr2(expr2_) {}
1490
1492 int size() const {
1493 return expr1.size();
1494 }
1495
1496 template <int Arg>
1498 bool isActive() const {
1499 return expr1.template isActive<Arg>();
1500 }
1501
1503 bool updateValue() const {
1504 return expr1.updateValue();
1505 }
1506
1508 void cache() const {
1509 expr1.cache();
1510 }
1511
1513 value_type val() const {
1514 return expr1.val()*expr2.val();
1515 }
1516
1518 void computePartials(const value_type& bar,
1519 value_type partials[]) const {
1520 expr1.computePartials(bar*expr2.val(), partials);
1521 }
1522
1524 void getTangents(int i, value_type dots[]) const {
1525 expr1.getTangents(i, dots);
1526 }
1527
1528 template <int Arg>
1530 value_type getTangent(int i) const {
1531 return expr1.template getTangent<Arg>(i);
1532 }
1533
1535 bool isLinear() const {
1536 return expr1.isLinear();
1537 }
1538
1540 bool hasFastAccess() const {
1541 return expr1.hasFastAccess();
1542 }
1543
1545 const value_type dx(int i) const {
1546 return expr1.dx(i)*expr2.val();
1547 }
1548
1550 const value_type fastAccessDx(int i) const {
1551 return expr1.fastAccessDx(i)*expr2.val();
1552 }
1553
1555 const value_type* getDx(int j) const {
1556 return expr1.getDx(j);
1557 }
1558
1559 protected:
1560
1561 const ExprT1& expr1;
1562 ExprT2 expr2;
1563
1564 };
1565
1566 template <typename T1, typename ExprT2>
1567 class Expr< MultiplicationOp< ConstExpr<T1>,ExprT2> > {
1568
1569 public:
1570
1571 typedef ConstExpr<T1> ExprT1;
1572 typedef typename ExprT1::value_type value_type_1;
1573 typedef typename ExprT2::value_type value_type_2;
1574 typedef typename Sacado::Promote<value_type_1,
1575 value_type_2>::type value_type;
1576 typedef typename ExprT1::scalar_type scalar_type_1;
1577 typedef typename ExprT2::scalar_type scalar_type_2;
1578 typedef typename Sacado::Promote<scalar_type_1,
1579 scalar_type_2>::type scalar_type;
1580
1581 typedef typename ExprT1::base_expr_type base_expr_type_1;
1582 typedef typename ExprT2::base_expr_type base_expr_type_2;
1583 typedef typename Sacado::Promote<base_expr_type_1,
1584 base_expr_type_2>::type base_expr_type;
1585
1586 static const int num_args = ExprT2::num_args;
1587
1588 static const bool is_linear = ExprT2::is_linear;
1589
1591 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1592 expr1(expr1_), expr2(expr2_) {}
1593
1595 int size() const {
1596 return expr2.size();
1597 }
1598
1599 template <int Arg>
1601 bool isActive() const {
1602 return expr2.template isActive<Arg>();
1603 }
1604
1606 bool updateValue() const {
1607 return expr2.updateValue();
1608 }
1609
1611 void cache() const {
1612 expr2.cache();
1613 }
1614
1616 value_type val() const {
1617 return expr1.val()*expr2.val();
1618 }
1619
1621 void computePartials(const value_type& bar,
1622 value_type partials[]) const {
1623 expr2.computePartials(bar*expr1.val(), partials);
1624 }
1625
1627 void getTangents(int i, value_type dots[]) const {
1628 expr2.getTangents(i, dots);
1629 }
1630
1631 template <int Arg>
1633 value_type getTangent(int i) const {
1634 return expr2.template getTangent<Arg>(i);
1635 }
1636
1638 bool isLinear() const {
1639 return expr2.isLinear();
1640 }
1641
1643 bool hasFastAccess() const {
1644 return expr2.hasFastAccess();
1645 }
1646
1648 const value_type dx(int i) const {
1649 return expr1.val()*expr2.dx(i);
1650 }
1651
1653 const value_type fastAccessDx(int i) const {
1654 return expr1.val()*expr2.fastAccessDx(i);
1655 }
1656
1658 const value_type* getDx(int j) const {
1659 return expr2.getDx(j);
1660 }
1661
1662 protected:
1663
1664 ExprT1 expr1;
1665 const ExprT2& expr2;
1666
1667 };
1668
1669 //
1670 // DivisionOp
1671 //
1672
1673 template <typename ExprT1, typename ExprT2>
1674 class DivisionOp {};
1675
1676 template <typename ExprT1, typename ExprT2>
1677 class Expr< DivisionOp<ExprT1,ExprT2> > {
1678
1679 public:
1680
1681 typedef typename ExprT1::value_type value_type_1;
1682 typedef typename ExprT2::value_type value_type_2;
1683 typedef typename Sacado::Promote<value_type_1,
1684 value_type_2>::type value_type;
1685 typedef typename ExprT1::scalar_type scalar_type_1;
1686 typedef typename ExprT2::scalar_type scalar_type_2;
1687 typedef typename Sacado::Promote<scalar_type_1,
1688 scalar_type_2>::type scalar_type;
1689
1690 typedef typename ExprT1::base_expr_type base_expr_type_1;
1691 typedef typename ExprT2::base_expr_type base_expr_type_2;
1692 typedef typename Sacado::Promote<base_expr_type_1,
1693 base_expr_type_2>::type base_expr_type;
1694
1695 static const int num_args1 = ExprT1::num_args;
1696 static const int num_args2 = ExprT2::num_args;
1697 static const int num_args = num_args1 + num_args2;
1698
1699 static const bool is_linear = false;
1700
1702 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1703 expr1(expr1_), expr2(expr2_) {}
1704
1706 int size() const {
1707 int sz1 = expr1.size(), sz2 = expr2.size();
1708 return sz1 > sz2 ? sz1 : sz2;
1709 }
1710
1711 template <int Arg>
1713 bool isActive() const {
1714 if (Arg < num_args1)
1715 return expr1.template isActive<Arg>();
1716 else
1717 return expr2.template isActive<Arg-num_args1>();
1718 }
1719
1721 bool updateValue() const {
1722 return expr1.updateValue() && expr2.updateValue();
1723 }
1724
1726 void cache() const {
1727 expr1.cache();
1728 expr2.cache();
1729 const value_type_1 v1 = expr1.val();
1730 const value_type_2 v2 = expr2.val();
1731 a = scalar_type(1.0)/v2;
1732 v = v1*a;
1733 b = -v/v2;
1734 }
1735
1737 value_type val() const {
1738 return v;
1739 }
1740
1742 void computePartials(const value_type& bar,
1743 value_type partials[]) const {
1744 if (num_args1 > 0)
1745 expr1.computePartials(bar*a, partials);
1746 if (num_args2 > 0)
1747 expr2.computePartials(bar*b, partials+num_args1);
1748 }
1749
1751 void getTangents(int i, value_type dots[]) const {
1752 expr1.getTangents(i, dots);
1753 expr2.getTangents(i, dots+num_args1);
1754 }
1755
1756 template <int Arg>
1758 value_type getTangent(int i) const {
1759 if (Arg < num_args1)
1760 return expr1.template getTangent<Arg>(i);
1761 else
1762 return expr2.template getTangent<Arg-num_args1>(i);
1763 }
1764
1766 bool isLinear() const {
1767 return false;
1768 }
1769
1771 bool hasFastAccess() const {
1772 return expr1.hasFastAccess() && expr2.hasFastAccess();
1773 }
1774
1776 const value_type dx(int i) const {
1777 if (expr1.size() > 0 && expr2.size() > 0)
1778 return expr1.dx(i)*a + expr2.dx(i)*b;
1779 else if (expr1.size() > 0)
1780 return expr1.dx(i)*a;
1781 else
1782 return expr1.val()*b;
1783 }
1784
1786 const value_type fastAccessDx(int i) const {
1787 return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
1788 }
1789
1791 const value_type* getDx(int j) const {
1792 if (j < num_args1)
1793 return expr1.getDx(j);
1794 else
1795 return expr2.getDx(j-num_args1);
1796 }
1797
1798 protected:
1799
1800 const ExprT1& expr1;
1801 const ExprT2& expr2;
1802 mutable value_type v;
1803 mutable value_type a;
1804 mutable value_type b;
1805
1806 };
1807
1808 template <typename ExprT1, typename T2>
1809 class Expr< DivisionOp<ExprT1, ConstExpr<T2> > > {
1810
1811 public:
1812
1813 typedef ConstExpr<T2> ExprT2;
1814 typedef typename ExprT1::value_type value_type_1;
1815 typedef typename ExprT2::value_type value_type_2;
1816 typedef typename Sacado::Promote<value_type_1,
1817 value_type_2>::type value_type;
1818 typedef typename ExprT1::scalar_type scalar_type_1;
1819 typedef typename ExprT2::scalar_type scalar_type_2;
1820 typedef typename Sacado::Promote<scalar_type_1,
1821 scalar_type_2>::type scalar_type;
1822
1823 typedef typename ExprT1::base_expr_type base_expr_type_1;
1824 typedef typename ExprT2::base_expr_type base_expr_type_2;
1825 typedef typename Sacado::Promote<base_expr_type_1,
1826 base_expr_type_2>::type base_expr_type;
1827
1828 static const int num_args = ExprT1::num_args;
1829
1830 static const bool is_linear = ExprT1::is_linear;
1831
1833 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1834 expr1(expr1_), expr2(expr2_) {}
1835
1837 int size() const {
1838 return expr1.size();
1839 }
1840
1841 template <int Arg>
1843 bool isActive() const {
1844 return expr1.template isActive<Arg>();
1845 }
1846
1848 bool updateValue() const {
1849 return expr1.updateValue();
1850 }
1851
1853 void cache() const {
1854 expr1.cache();
1855 const value_type_1 v1 = expr1.val();
1856 a = scalar_type(1.0)/expr2.val();
1857 v = v1*a;
1858 }
1859
1861 value_type val() const {
1862 return v;
1863 }
1864
1866 void computePartials(const value_type& bar,
1867 value_type partials[]) const {
1868 expr1.computePartials(bar*a, partials);
1869 }
1870
1872 void getTangents(int i, value_type dots[]) const {
1873 expr1.getTangents(i, dots);
1874 }
1875
1876 template <int Arg>
1878 value_type getTangent(int i) const {
1879 return expr1.template getTangent<Arg>(i);
1880 }
1881
1883 bool isLinear() const {
1884 return expr1.isLinear();
1885 }
1886
1888 bool hasFastAccess() const {
1889 return expr1.hasFastAccess();
1890 }
1891
1893 const value_type dx(int i) const {
1894 return expr1.dx(i)*a;
1895 }
1896
1898 const value_type fastAccessDx(int i) const {
1899 return expr1.fastAccessDx(i)*a;
1900 }
1901
1903 const value_type* getDx(int j) const {
1904 return expr1.getDx(j);
1905 }
1906
1907 protected:
1908
1909 const ExprT1& expr1;
1910 ExprT2 expr2;
1911 mutable value_type v;
1912 mutable value_type a;
1913
1914 };
1915
1916 template <typename T1, typename ExprT2>
1917 class Expr< DivisionOp< ConstExpr<T1>,ExprT2> > {
1918
1919 public:
1920
1921 typedef ConstExpr<T1> ExprT1;
1922 typedef typename ExprT1::value_type value_type_1;
1923 typedef typename ExprT2::value_type value_type_2;
1924 typedef typename Sacado::Promote<value_type_1,
1925 value_type_2>::type value_type;
1926 typedef typename ExprT1::scalar_type scalar_type_1;
1927 typedef typename ExprT2::scalar_type scalar_type_2;
1928 typedef typename Sacado::Promote<scalar_type_1,
1929 scalar_type_2>::type scalar_type;
1930
1931 typedef typename ExprT1::base_expr_type base_expr_type_1;
1932 typedef typename ExprT2::base_expr_type base_expr_type_2;
1933 typedef typename Sacado::Promote<base_expr_type_1,
1934 base_expr_type_2>::type base_expr_type;
1935
1936 static const int num_args = ExprT2::num_args;
1937
1938 static const bool is_linear = false;
1939
1941 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
1942 expr1(expr1_), expr2(expr2_) {}
1943
1945 int size() const {
1946 return expr2.size();
1947 }
1948
1949 template <int Arg>
1951 bool isActive() const {
1952 return expr2.template isActive<Arg>();
1953 }
1954
1956 bool updateValue() const {
1957 return expr2.updateValue();
1958 }
1959
1961 void cache() const {
1962 expr2.cache();
1963 const value_type_2 v2 = expr2.val();
1964 v = expr1.val()/v2;
1965 b = -v/v2;
1966 }
1967
1969 value_type val() const {
1970 return v;
1971 }
1972
1974 void computePartials(const value_type& bar,
1975 value_type partials[]) const {
1976 expr2.computePartials(bar*b, partials);
1977 }
1978
1980 void getTangents(int i, value_type dots[]) const {
1981 expr2.getTangents(i, dots);
1982 }
1983
1984 template <int Arg>
1986 value_type getTangent(int i) const {
1987 return expr2.template getTangent<Arg>(i);
1988 }
1989
1991 bool isLinear() const {
1992 return false;
1993 }
1994
1996 bool hasFastAccess() const {
1997 return expr2.hasFastAccess();
1998 }
1999
2001 const value_type dx(int i) const {
2002 return expr2.dx(i)*b;
2003 }
2004
2006 const value_type fastAccessDx(int i) const {
2007 return expr2.fastAccessDx(i)*b;
2008 }
2009
2011 const value_type* getDx(int j) const {
2012 return expr2.getDx(j);
2013 }
2014
2015 protected:
2016
2017 ExprT1 expr1;
2018 const ExprT2& expr2;
2019 mutable value_type v;
2020 mutable value_type b;
2021
2022 };
2023
2024 //
2025 // Atan2Op
2026 //
2027
2028 template <typename ExprT1, typename ExprT2>
2029 class Atan2Op {};
2030
2031 template <typename ExprT1, typename ExprT2>
2032 class Expr< Atan2Op<ExprT1,ExprT2> > {
2033
2034 public:
2035
2036 typedef typename ExprT1::value_type value_type_1;
2037 typedef typename ExprT2::value_type value_type_2;
2038 typedef typename Sacado::Promote<value_type_1,
2039 value_type_2>::type value_type;
2040 typedef typename ExprT1::scalar_type scalar_type_1;
2041 typedef typename ExprT2::scalar_type scalar_type_2;
2042 typedef typename Sacado::Promote<scalar_type_1,
2043 scalar_type_2>::type scalar_type;
2044
2045 typedef typename ExprT1::base_expr_type base_expr_type_1;
2046 typedef typename ExprT2::base_expr_type base_expr_type_2;
2047 typedef typename Sacado::Promote<base_expr_type_1,
2048 base_expr_type_2>::type base_expr_type;
2049
2050 static const int num_args1 = ExprT1::num_args;
2051 static const int num_args2 = ExprT2::num_args;
2052 static const int num_args = num_args1 + num_args2;
2053
2054 static const bool is_linear = false;
2055
2057 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2058 expr1(expr1_), expr2(expr2_) {}
2059
2061 int size() const {
2062 int sz1 = expr1.size(), sz2 = expr2.size();
2063 return sz1 > sz2 ? sz1 : sz2;
2064 }
2065
2066 template <int Arg>
2068 bool isActive() const {
2069 if (Arg < num_args1)
2070 return expr1.template isActive<Arg>();
2071 else
2072 return expr2.template isActive<Arg-num_args1>();
2073 }
2074
2076 bool updateValue() const {
2077 return expr1.updateValue() && expr2.updateValue();
2078 }
2079
2081 void cache() const {
2082 expr1.cache();
2083 expr2.cache();
2084 const value_type_1 v1 = expr1.val();
2085 const value_type_2 v2 = expr2.val();
2086 a = scalar_type(1.0)/(v1*v1 + v2*v2);
2087 b = -v1*a;
2088 a = v2*a;
2089 v = std::atan2(v1,v2);
2090 }
2091
2093 value_type val() const {
2094 return v;
2095 }
2096
2098 void computePartials(const value_type& bar,
2099 value_type partials[]) const {
2100 if (num_args1 > 0)
2101 expr1.computePartials(bar*a, partials);
2102 if (num_args2 > 0)
2103 expr2.computePartials(bar*b, partials+num_args1);
2104 }
2105
2107 void getTangents(int i, value_type dots[]) const {
2108 expr1.getTangents(i, dots);
2109 expr2.getTangents(i, dots+num_args1);
2110 }
2111
2112 template <int Arg>
2114 value_type getTangent(int i) const {
2115 if (Arg < num_args1)
2116 return expr1.template getTangent<Arg>(i);
2117 else
2118 return expr2.template getTangent<Arg-num_args1>(i);
2119 }
2120
2122 bool isLinear() const {
2123 return false;
2124 }
2125
2127 bool hasFastAccess() const {
2128 return expr1.hasFastAccess() && expr2.hasFastAccess();
2129 }
2130
2132 const value_type dx(int i) const {
2133 if (expr1.size() > 0 && expr2.size() > 0)
2134 return expr1.dx(i)*a + expr2.dx(i)*b;
2135 else if (expr1.size() > 0)
2136 return expr1.dx(i)*a;
2137 else
2138 return expr1.val()*b;
2139 }
2140
2142 const value_type fastAccessDx(int i) const {
2143 return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
2144 }
2145
2147 const value_type* getDx(int j) const {
2148 if (j < num_args1)
2149 return expr1.getDx(j);
2150 else
2151 return expr2.getDx(j-num_args1);
2152 }
2153
2154 protected:
2155
2156 const ExprT1& expr1;
2157 const ExprT2& expr2;
2158 mutable value_type v;
2159 mutable value_type a;
2160 mutable value_type b;
2161
2162 };
2163
2164 template <typename ExprT1, typename T2>
2165 class Expr< Atan2Op<ExprT1, ConstExpr<T2> > > {
2166
2167 public:
2168
2169 typedef ConstExpr<T2> ExprT2;
2170 typedef typename ExprT1::value_type value_type_1;
2171 typedef typename ExprT2::value_type value_type_2;
2172 typedef typename Sacado::Promote<value_type_1,
2173 value_type_2>::type value_type;
2174 typedef typename ExprT1::scalar_type scalar_type_1;
2175 typedef typename ExprT2::scalar_type scalar_type_2;
2176 typedef typename Sacado::Promote<scalar_type_1,
2177 scalar_type_2>::type scalar_type;
2178
2179 typedef typename ExprT1::base_expr_type base_expr_type_1;
2180 typedef typename ExprT2::base_expr_type base_expr_type_2;
2181 typedef typename Sacado::Promote<base_expr_type_1,
2182 base_expr_type_2>::type base_expr_type;
2183
2184 static const int num_args = ExprT1::num_args;
2185
2186 static const bool is_linear = false;
2187
2189 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2190 expr1(expr1_), expr2(expr2_) {}
2191
2193 int size() const {
2194 return expr1.size();
2195 }
2196
2197 template <int Arg>
2199 bool isActive() const {
2200 return expr1.template isActive<Arg>();
2201 }
2202
2204 bool updateValue() const {
2205 return expr1.updateValue();
2206 }
2207
2209 void cache() const {
2210 expr1.cache();
2211 const value_type_1 v1 = expr1.val();
2212 const value_type_2 v2 = expr2.val();
2213 a = v2/(v1*v1 + v2*v2);
2214 v = std::atan2(v1,v2);
2215 }
2216
2218 value_type val() const {
2219 return v;
2220 }
2221
2223 void computePartials(const value_type& bar,
2224 value_type partials[]) const {
2225 expr1.computePartials(bar*a, partials);
2226 }
2227
2229 void getTangents(int i, value_type dots[]) const {
2230 expr1.getTangents(i, dots);
2231 }
2232
2233 template <int Arg>
2235 value_type getTangent(int i) const {
2236 return expr1.template getTangent<Arg>(i);
2237 }
2238
2240 bool isLinear() const {
2241 return false;
2242 }
2243
2245 bool hasFastAccess() const {
2246 return expr1.hasFastAccess();
2247 }
2248
2250 const value_type dx(int i) const {
2251 return expr1.dx(i)*a;
2252 }
2253
2255 const value_type fastAccessDx(int i) const {
2256 return expr1.fastAccessDx(i)*a;
2257 }
2258
2260 const value_type* getDx(int j) const {
2261 return expr1.getDx(j);
2262 }
2263
2264 protected:
2265
2266 const ExprT1& expr1;
2267 ExprT2 expr2;
2268 mutable value_type v;
2269 mutable value_type a;
2270
2271 };
2272
2273 template <typename T1, typename ExprT2>
2274 class Expr< Atan2Op< ConstExpr<T1>,ExprT2> > {
2275
2276 public:
2277
2278 typedef ConstExpr<T1> ExprT1;
2279 typedef typename ExprT1::value_type value_type_1;
2280 typedef typename ExprT2::value_type value_type_2;
2281 typedef typename Sacado::Promote<value_type_1,
2282 value_type_2>::type value_type;
2283 typedef typename ExprT1::scalar_type scalar_type_1;
2284 typedef typename ExprT2::scalar_type scalar_type_2;
2285 typedef typename Sacado::Promote<scalar_type_1,
2286 scalar_type_2>::type scalar_type;
2287
2288 typedef typename ExprT1::base_expr_type base_expr_type_1;
2289 typedef typename ExprT2::base_expr_type base_expr_type_2;
2290 typedef typename Sacado::Promote<base_expr_type_1,
2291 base_expr_type_2>::type base_expr_type;
2292
2293 static const int num_args = ExprT2::num_args;
2294
2295 static const bool is_linear = false;
2296
2298 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2299 expr1(expr1_), expr2(expr2_) {}
2300
2302 int size() const {
2303 return expr2.size();
2304 }
2305
2306 template <int Arg>
2308 bool isActive() const {
2309 return expr2.template isActive<Arg>();
2310 }
2311
2313 bool updateValue() const {
2314 return expr2.updateValue();
2315 }
2316
2318 void cache() const {
2319 expr2.cache();
2320 const value_type_1 v1 = expr1.val();
2321 const value_type_2 v2 = expr2.val();
2322 b = -v1/(v1*v1 + v2*v2);
2323 v = std::atan2(v1,v2);
2324 }
2325
2327 value_type val() const {
2328 return v;
2329 }
2330
2332 void computePartials(const value_type& bar,
2333 value_type partials[]) const {
2334 expr2.computePartials(bar*b, partials);
2335 }
2336
2338 void getTangents(int i, value_type dots[]) const {
2339 expr2.getTangents(i, dots);
2340 }
2341
2342 template <int Arg>
2344 value_type getTangent(int i) const {
2345 return expr2.template getTangent<Arg>(i);
2346 }
2347
2349 bool isLinear() const {
2350 return false;
2351 }
2352
2354 bool hasFastAccess() const {
2355 return expr2.hasFastAccess();
2356 }
2357
2359 const value_type dx(int i) const {
2360 return expr2.dx(i)*b;
2361 }
2362
2364 const value_type fastAccessDx(int i) const {
2365 return expr2.fastAccessDx(i)*b;
2366 }
2367
2369 const value_type* getDx(int j) const {
2370 return expr2.getDx(j);
2371 }
2372
2373 protected:
2374
2375 ExprT1 expr1;
2376 const ExprT2& expr2;
2377 mutable value_type v;
2378 mutable value_type b;
2379
2380 };
2381
2382 //
2383 // PowerOp
2384 //
2385
2386 template <typename ExprT1, typename ExprT2>
2387 class PowerOp {};
2388
2389 template <typename ExprT1, typename ExprT2>
2390 class Expr< PowerOp<ExprT1,ExprT2> > {
2391
2392 public:
2393
2394 typedef typename ExprT1::value_type value_type_1;
2395 typedef typename ExprT2::value_type value_type_2;
2396 typedef typename Sacado::Promote<value_type_1,
2397 value_type_2>::type value_type;
2398 typedef typename ExprT1::scalar_type scalar_type_1;
2399 typedef typename ExprT2::scalar_type scalar_type_2;
2400 typedef typename Sacado::Promote<scalar_type_1,
2401 scalar_type_2>::type scalar_type;
2402
2403 typedef typename ExprT1::base_expr_type base_expr_type_1;
2404 typedef typename ExprT2::base_expr_type base_expr_type_2;
2405 typedef typename Sacado::Promote<base_expr_type_1,
2406 base_expr_type_2>::type base_expr_type;
2407
2408 static const int num_args1 = ExprT1::num_args;
2409 static const int num_args2 = ExprT2::num_args;
2410 static const int num_args = num_args1 + num_args2;
2411
2412 static const bool is_linear = false;
2413
2415 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2416 expr1(expr1_), expr2(expr2_) {}
2417
2419 int size() const {
2420 int sz1 = expr1.size(), sz2 = expr2.size();
2421 return sz1 > sz2 ? sz1 : sz2;
2422 }
2423
2424 template <int Arg>
2426 bool isActive() const {
2427 if (Arg < num_args1)
2428 return expr1.template isActive<Arg>();
2429 else
2430 return expr2.template isActive<Arg-num_args1>();
2431 }
2432
2434 bool updateValue() const {
2435 return expr1.updateValue() && expr2.updateValue();
2436 }
2437
2439 void cache() const {
2440 expr1.cache();
2441 expr2.cache();
2442 const value_type_1 v1 = expr1.val();
2443 const value_type_2 v2 = expr2.val();
2444 v = std::pow(v1,v2);
2445 if (expr2.size() == 0 && v2 == scalar_type(1.0)) {
2446 a = scalar_type(1.0);
2447 b = scalar_type(0.0);
2448 }
2449 else if (v1 == scalar_type(0.0)) {
2450 a = scalar_type(0.0);
2451 b = scalar_type(0.0);
2452 }
2453 else {
2454 a = v*v2/v1;
2455 b = v*std::log(v1);
2456 }
2457 }
2458
2460 value_type val() const {
2461 return v;
2462 }
2463
2465 void computePartials(const value_type& bar,
2466 value_type partials[]) const {
2467 if (num_args1 > 0)
2468 expr1.computePartials(bar*a, partials);
2469 if (num_args2 > 0)
2470 expr2.computePartials(bar*b, partials+num_args1);
2471 }
2472
2474 void getTangents(int i, value_type dots[]) const {
2475 expr1.getTangents(i, dots);
2476 expr2.getTangents(i, dots+num_args1);
2477 }
2478
2479 template <int Arg>
2481 value_type getTangent(int i) const {
2482 if (Arg < num_args1)
2483 return expr1.template getTangent<Arg>(i);
2484 else
2485 return expr2.template getTangent<Arg-num_args1>(i);
2486 }
2487
2489 bool isLinear() const {
2490 return false;
2491 }
2492
2494 bool hasFastAccess() const {
2495 return expr1.hasFastAccess() && expr2.hasFastAccess();
2496 }
2497
2499 const value_type dx(int i) const {
2500 if (expr1.size() > 0 && expr2.size() > 0)
2501 return expr1.dx(i)*a + expr2.dx(i)*b;
2502 else if (expr1.size() > 0)
2503 return expr1.dx(i)*a;
2504 else
2505 return expr1.val()*b;
2506 }
2507
2509 const value_type fastAccessDx(int i) const {
2510 return expr1.fastAccessDx(i)*a + expr2.fastAccessDx(i)*b;
2511 }
2512
2514 const value_type* getDx(int j) const {
2515 if (j < num_args1)
2516 return expr1.getDx(j);
2517 else
2518 return expr2.getDx(j-num_args1);
2519 }
2520
2521 protected:
2522
2523 const ExprT1& expr1;
2524 const ExprT2& expr2;
2525 mutable value_type v;
2526 mutable value_type a;
2527 mutable value_type b;
2528
2529 };
2530
2531 template <typename ExprT1, typename T2>
2532 class Expr< PowerOp<ExprT1, ConstExpr<T2> > > {
2533
2534 public:
2535
2536 typedef ConstExpr<T2> ExprT2;
2537 typedef typename ExprT1::value_type value_type_1;
2538 typedef typename ExprT2::value_type value_type_2;
2539 typedef typename Sacado::Promote<value_type_1,
2540 value_type_2>::type value_type;
2541 typedef typename ExprT1::scalar_type scalar_type_1;
2542 typedef typename ExprT2::scalar_type scalar_type_2;
2543 typedef typename Sacado::Promote<scalar_type_1,
2544 scalar_type_2>::type scalar_type;
2545
2546 typedef typename ExprT1::base_expr_type base_expr_type_1;
2547 typedef typename ExprT2::base_expr_type base_expr_type_2;
2548 typedef typename Sacado::Promote<base_expr_type_1,
2549 base_expr_type_2>::type base_expr_type;
2550
2551 static const int num_args = ExprT1::num_args;
2552
2553 static const bool is_linear = false;
2554
2556 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2557 expr1(expr1_), expr2(expr2_) {}
2558
2560 int size() const {
2561 return expr1.size();
2562 }
2563
2564 template <int Arg>
2566 bool isActive() const {
2567 return expr1.template isActive<Arg>();
2568 }
2569
2571 bool updateValue() const {
2572 return expr1.updateValue();
2573 }
2574
2576 void cache() const {
2577 expr1.cache();
2578 const value_type_1 v1 = expr1.val();
2579 const value_type_2 v2 = expr2.val();
2580 v = std::pow(v1,v2);
2581 if (v2 == scalar_type(1.0)) {
2582 a = scalar_type(1.0);
2583 }
2584 else if (v1 == scalar_type(0.0)) {
2585 a = scalar_type(0.0);
2586 }
2587 else {
2588 a = v*v2/v1;
2589 }
2590 }
2591
2593 value_type val() const {
2594 return v;
2595 }
2596
2598 void computePartials(const value_type& bar,
2599 value_type partials[]) const {
2600 expr1.computePartials(bar*a, partials);
2601 }
2602
2604 void getTangents(int i, value_type dots[]) const {
2605 expr1.getTangents(i, dots);
2606 }
2607
2608 template <int Arg>
2610 value_type getTangent(int i) const {
2611 return expr1.template getTangent<Arg>(i);
2612 }
2613
2615 bool isLinear() const {
2616 return false;
2617 }
2618
2620 bool hasFastAccess() const {
2621 return expr1.hasFastAccess();
2622 }
2623
2625 const value_type dx(int i) const {
2626 return expr1.dx(i)*a;
2627 }
2628
2630 const value_type fastAccessDx(int i) const {
2631 return expr1.fastAccessDx(i)*a;
2632 }
2633
2635 const value_type* getDx(int j) const {
2636 return expr1.getDx(j);
2637 }
2638
2639 protected:
2640
2641 const ExprT1& expr1;
2642 ExprT2 expr2;
2643 mutable value_type v;
2644 mutable value_type a;
2645
2646 };
2647
2648 template <typename T1, typename ExprT2>
2649 class Expr< PowerOp< ConstExpr<T1>,ExprT2> > {
2650
2651 public:
2652
2653 typedef ConstExpr<T1> ExprT1;
2654 typedef typename ExprT1::value_type value_type_1;
2655 typedef typename ExprT2::value_type value_type_2;
2656 typedef typename Sacado::Promote<value_type_1,
2657 value_type_2>::type value_type;
2658 typedef typename ExprT1::scalar_type scalar_type_1;
2659 typedef typename ExprT2::scalar_type scalar_type_2;
2660 typedef typename Sacado::Promote<scalar_type_1,
2661 scalar_type_2>::type scalar_type;
2662
2663 typedef typename ExprT1::base_expr_type base_expr_type_1;
2664 typedef typename ExprT2::base_expr_type base_expr_type_2;
2665 typedef typename Sacado::Promote<base_expr_type_1,
2666 base_expr_type_2>::type base_expr_type;
2667
2668 static const int num_args = ExprT2::num_args;
2669
2670 static const bool is_linear = false;
2671
2673 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2674 expr1(expr1_), expr2(expr2_) {}
2675
2677 int size() const {
2678 return expr2.size();
2679 }
2680
2681 template <int Arg>
2683 bool isActive() const {
2684 return expr2.template isActive<Arg>();
2685 }
2686
2688 bool updateValue() const {
2689 return expr2.updateValue();
2690 }
2691
2693 void cache() const {
2694 expr2.cache();
2695 const value_type_1 v1 = expr1.val();
2696 const value_type_2 v2 = expr2.val();
2697 v = std::pow(v1,v2);
2698 if (v1 == scalar_type(0.0)) {
2699 b = scalar_type(0.0);
2700 }
2701 else {
2702 b = v*std::log(v1);
2703 }
2704 }
2705
2707 value_type val() const {
2708 return v;
2709 }
2710
2712 void computePartials(const value_type& bar,
2713 value_type partials[]) const {
2714 expr2.computePartials(bar*b, partials);
2715 }
2716
2718 void getTangents(int i, value_type dots[]) const {
2719 expr2.getTangents(i, dots);
2720 }
2721
2722 template <int Arg>
2724 value_type getTangent(int i) const {
2725 return expr2.template getTangent<Arg>(i);
2726 }
2727
2729 bool isLinear() const {
2730 return false;
2731 }
2732
2734 bool hasFastAccess() const {
2735 return expr2.hasFastAccess();
2736 }
2737
2739 const value_type dx(int i) const {
2740 return expr2.dx(i)*b;
2741 }
2742
2744 const value_type fastAccessDx(int i) const {
2745 return expr2.fastAccessDx(i)*b;
2746 }
2747
2749 const value_type* getDx(int j) const {
2750 return expr2.getDx(j);
2751 }
2752
2753 protected:
2754
2755 ExprT1 expr1;
2756 const ExprT2& expr2;
2757 mutable value_type v;
2758 mutable value_type b;
2759
2760 };
2761
2762 //
2763 // MaxOp
2764 //
2765
2766 template <typename ExprT1, typename ExprT2>
2767 class MaxOp {};
2768
2769 template <typename ExprT1, typename ExprT2>
2770 class Expr< MaxOp<ExprT1,ExprT2> > {
2771
2772 public:
2773
2774 typedef typename ExprT1::value_type value_type_1;
2775 typedef typename ExprT2::value_type value_type_2;
2776 typedef typename Sacado::Promote<value_type_1,
2777 value_type_2>::type value_type;
2778 typedef typename ExprT1::scalar_type scalar_type_1;
2779 typedef typename ExprT2::scalar_type scalar_type_2;
2780 typedef typename Sacado::Promote<scalar_type_1,
2781 scalar_type_2>::type scalar_type;
2782
2783 typedef typename ExprT1::base_expr_type base_expr_type_1;
2784 typedef typename ExprT2::base_expr_type base_expr_type_2;
2785 typedef typename Sacado::Promote<base_expr_type_1,
2786 base_expr_type_2>::type base_expr_type;
2787
2788 static const int num_args1 = ExprT1::num_args;
2789 static const int num_args2 = ExprT2::num_args;
2790 static const int num_args = num_args1 + num_args2;
2791
2792 static const bool is_linear = false;
2793
2795 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2796 expr1(expr1_), expr2(expr2_) {}
2797
2799 int size() const {
2800 int sz1 = expr1.size(), sz2 = expr2.size();
2801 return sz1 > sz2 ? sz1 : sz2;
2802 }
2803
2804 template <int Arg>
2806 bool isActive() const {
2807 if (Arg < num_args1)
2808 return expr1.template isActive<Arg>();
2809 else
2810 return expr2.template isActive<Arg-num_args1>();
2811 }
2812
2814 bool updateValue() const {
2815 return expr1.updateValue() && expr2.updateValue();
2816 }
2817
2819 void cache() const {
2820 expr1.cache();
2821 expr2.cache();
2822 const value_type_1 v1 = expr1.val();
2823 const value_type_2 v2 = expr2.val();
2824 max_v1 = (v1 >= v2);
2825 v = max_v1 ? v1 : v2;
2826 }
2827
2829 value_type val() const {
2830 return v;
2831 }
2832
2834 void computePartials(const value_type& bar,
2835 value_type partials[]) const {
2836 if (num_args1 > 0) {
2837 if (max_v1)
2838 expr1.computePartials(bar, partials);
2839 else
2840 expr1.computePartials(value_type(0.0), partials);
2841 }
2842 if (num_args2 > 0) {
2843 if (max_v1)
2844 expr2.computePartials(value_type(0.0), partials+num_args1);
2845 else
2846 expr2.computePartials(bar, partials+num_args1);
2847 }
2848 }
2849
2851 void getTangents(int i, value_type dots[]) const {
2852 expr1.getTangents(i, dots);
2853 expr2.getTangents(i, dots+num_args1);
2854 }
2855
2856 template <int Arg>
2858 value_type getTangent(int i) const {
2859 if (Arg < num_args1)
2860 return expr1.template getTangent<Arg>(i);
2861 else
2862 return expr2.template getTangent<Arg-num_args1>(i);
2863 }
2864
2866 bool isLinear() const {
2867 return false;
2868 }
2869
2871 bool hasFastAccess() const {
2872 return expr1.hasFastAccess() && expr2.hasFastAccess();
2873 }
2874
2876 const value_type dx(int i) const {
2877 return max_v1 ? expr1.dx(i) : expr2.dx(i);
2878 }
2879
2881 const value_type fastAccessDx(int i) const {
2882 return max_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
2883 }
2884
2886 const value_type* getDx(int j) const {
2887 if (j < num_args1)
2888 return expr1.getDx(j);
2889 else
2890 return expr2.getDx(j-num_args1);
2891 }
2892
2893 protected:
2894
2895 const ExprT1& expr1;
2896 const ExprT2& expr2;
2897 mutable value_type v;
2898 mutable bool max_v1;
2899
2900 };
2901
2902 template <typename ExprT1, typename T2>
2903 class Expr< MaxOp<ExprT1, ConstExpr<T2> > > {
2904
2905 public:
2906
2907 typedef ConstExpr<T2> ExprT2;
2908 typedef typename ExprT1::value_type value_type_1;
2909 typedef typename ExprT2::value_type value_type_2;
2910 typedef typename Sacado::Promote<value_type_1,
2911 value_type_2>::type value_type;
2912 typedef typename ExprT1::scalar_type scalar_type_1;
2913 typedef typename ExprT2::scalar_type scalar_type_2;
2914 typedef typename Sacado::Promote<scalar_type_1,
2915 scalar_type_2>::type scalar_type;
2916
2917 typedef typename ExprT1::base_expr_type base_expr_type_1;
2918 typedef typename ExprT2::base_expr_type base_expr_type_2;
2919 typedef typename Sacado::Promote<base_expr_type_1,
2920 base_expr_type_2>::type base_expr_type;
2921
2922 static const int num_args = ExprT1::num_args;
2923
2924 static const bool is_linear = false;
2925
2927 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
2928 expr1(expr1_), expr2(expr2_) {}
2929
2931 int size() const {
2932 return expr1.size();
2933 }
2934
2935 template <int Arg>
2937 bool isActive() const {
2938 return expr1.template isActive<Arg>();
2939 }
2940
2942 bool updateValue() const {
2943 return expr1.updateValue();
2944 }
2945
2947 void cache() const {
2948 expr1.cache();
2949 const value_type_1 v1 = expr1.val();
2950 const value_type_2 v2 = expr2.val();
2951 max_v1 = (v1 >= v2);
2952 v = max_v1 ? v1 : v2;
2953 }
2954
2956 value_type val() const {
2957 return v;
2958 }
2959
2961 void computePartials(const value_type& bar,
2962 value_type partials[]) const {
2963 if (max_v1)
2964 expr1.computePartials(bar, partials);
2965 else
2966 expr1.computePartials(value_type(0.0), partials);
2967 }
2968
2970 void getTangents(int i, value_type dots[]) const {
2971 expr1.getTangents(i, dots);
2972 }
2973
2974 template <int Arg>
2976 value_type getTangent(int i) const {
2977 return expr1.template getTangent<Arg>(i);
2978 }
2979
2981 bool isLinear() const {
2982 return false;
2983 }
2984
2986 bool hasFastAccess() const {
2987 return expr1.hasFastAccess();
2988 }
2989
2991 const value_type dx(int i) const {
2992 return max_v1 ? expr1.dx(i) : value_type(0.0);
2993 }
2994
2996 const value_type fastAccessDx(int i) const {
2997 return max_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
2998 }
2999
3001 const value_type* getDx(int j) const {
3002 return expr1.getDx(j);
3003 }
3004
3005 protected:
3006
3007 const ExprT1& expr1;
3008 ExprT2 expr2;
3009 mutable value_type v;
3010 mutable bool max_v1;
3011
3012 };
3013
3014 template <typename T1, typename ExprT2>
3015 class Expr< MaxOp< ConstExpr<T1>,ExprT2> > {
3016
3017 public:
3018
3019 typedef ConstExpr<T1> ExprT1;
3020 typedef typename ExprT1::value_type value_type_1;
3021 typedef typename ExprT2::value_type value_type_2;
3022 typedef typename Sacado::Promote<value_type_1,
3023 value_type_2>::type value_type;
3024 typedef typename ExprT1::scalar_type scalar_type_1;
3025 typedef typename ExprT2::scalar_type scalar_type_2;
3026 typedef typename Sacado::Promote<scalar_type_1,
3027 scalar_type_2>::type scalar_type;
3028
3029 typedef typename ExprT1::base_expr_type base_expr_type_1;
3030 typedef typename ExprT2::base_expr_type base_expr_type_2;
3031 typedef typename Sacado::Promote<base_expr_type_1,
3032 base_expr_type_2>::type base_expr_type;
3033
3034 static const int num_args = ExprT2::num_args;
3035
3036 static const bool is_linear = false;
3037
3039 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3040 expr1(expr1_), expr2(expr2_) {}
3041
3043 int size() const {
3044 return expr2.size();
3045 }
3046
3047 template <int Arg>
3049 bool isActive() const {
3050 return expr2.template isActive<Arg>();
3051 }
3052
3054 bool updateValue() const {
3055 return expr2.updateValue();
3056 }
3057
3059 void cache() const {
3060 expr2.cache();
3061 const value_type_1 v1 = expr1.val();
3062 const value_type_2 v2 = expr2.val();
3063 max_v1 = (v1 >= v2);
3064 v = max_v1 ? v1 : v2;
3065 }
3066
3068 value_type val() const {
3069 return v;
3070 }
3071
3073 void computePartials(const value_type& bar,
3074 value_type partials[]) const {
3075 if (max_v1)
3076 expr2.computePartials(value_type(0.0), partials);
3077 else
3078 expr2.computePartials(bar, partials);
3079 }
3080
3082 void getTangents(int i, value_type dots[]) const {
3083 expr2.getTangents(i, dots);
3084 }
3085
3086 template <int Arg>
3088 value_type getTangent(int i) const {
3089 return expr2.template getTangent<Arg>(i);
3090 }
3091
3093 bool isLinear() const {
3094 return false;
3095 }
3096
3098 bool hasFastAccess() const {
3099 return expr2.hasFastAccess();
3100 }
3101
3103 const value_type dx(int i) const {
3104 return max_v1 ? value_type(0.0) : expr2.dx(i);
3105 }
3106
3108 const value_type fastAccessDx(int i) const {
3109 return max_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3110 }
3111
3113 const value_type* getDx(int j) const {
3114 return expr2.getDx(j);
3115 }
3116
3117 protected:
3118
3119 ExprT1 expr1;
3120 const ExprT2& expr2;
3121 mutable value_type v;
3122 mutable bool max_v1;
3123
3124 };
3125
3126 //
3127 // MinOp
3128 //
3129
3130 template <typename ExprT1, typename ExprT2>
3131 class MinOp {};
3132
3133 template <typename ExprT1, typename ExprT2>
3134 class Expr< MinOp<ExprT1,ExprT2> > {
3135
3136 public:
3137
3138 typedef typename ExprT1::value_type value_type_1;
3139 typedef typename ExprT2::value_type value_type_2;
3140 typedef typename Sacado::Promote<value_type_1,
3141 value_type_2>::type value_type;
3142 typedef typename ExprT1::scalar_type scalar_type_1;
3143 typedef typename ExprT2::scalar_type scalar_type_2;
3144 typedef typename Sacado::Promote<scalar_type_1,
3145 scalar_type_2>::type scalar_type;
3146
3147 typedef typename ExprT1::base_expr_type base_expr_type_1;
3148 typedef typename ExprT2::base_expr_type base_expr_type_2;
3149 typedef typename Sacado::Promote<base_expr_type_1,
3150 base_expr_type_2>::type base_expr_type;
3151
3152 static const int num_args1 = ExprT1::num_args;
3153 static const int num_args2 = ExprT2::num_args;
3154 static const int num_args = num_args1 + num_args2;
3155
3156 static const bool is_linear = false;
3157
3159 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3160 expr1(expr1_), expr2(expr2_) {}
3161
3163 int size() const {
3164 int sz1 = expr1.size(), sz2 = expr2.size();
3165 return sz1 > sz2 ? sz1 : sz2;
3166 }
3167
3168 template <int Arg>
3170 bool isActive() const {
3171 if (Arg < num_args1)
3172 return expr1.template isActive<Arg>();
3173 else
3174 return expr2.template isActive<Arg-num_args1>();
3175 }
3176
3178 bool updateValue() const {
3179 return expr1.updateValue() && expr2.updateValue();
3180 }
3181
3183 void cache() const {
3184 expr1.cache();
3185 expr2.cache();
3186 const value_type_1 v1 = expr1.val();
3187 const value_type_2 v2 = expr2.val();
3188 min_v1 = (v1 <= v2);
3189 v = min_v1 ? v1 : v2;
3190 }
3191
3193 value_type val() const {
3194 return v;
3195 }
3196
3198 void computePartials(const value_type& bar,
3199 value_type partials[]) const {
3200 if (num_args1 > 0) {
3201 if (min_v1)
3202 expr1.computePartials(bar, partials);
3203 else
3204 expr1.computePartials(value_type(0.0), partials);
3205 }
3206 if (num_args2 > 0) {
3207 if (min_v1)
3208 expr2.computePartials(value_type(0.0), partials+num_args1);
3209 else
3210 expr2.computePartials(bar, partials+num_args1);
3211 }
3212 }
3213
3215 void getTangents(int i, value_type dots[]) const {
3216 expr1.getTangents(i, dots);
3217 expr2.getTangents(i, dots+num_args1);
3218 }
3219
3220 template <int Arg>
3222 value_type getTangent(int i) const {
3223 if (Arg < num_args1)
3224 return expr1.template getTangent<Arg>(i);
3225 else
3226 return expr2.template getTangent<Arg-num_args1>(i);
3227 }
3228
3230 bool isLinear() const {
3231 return false;
3232 }
3233
3235 bool hasFastAccess() const {
3236 return expr1.hasFastAccess() && expr2.hasFastAccess();
3237 }
3238
3240 const value_type dx(int i) const {
3241 return min_v1 ? expr1.dx(i) : expr2.dx(i);
3242 }
3243
3245 const value_type fastAccessDx(int i) const {
3246 return min_v1 ? expr1.fastAccessDx(i) : expr2.fastAccessDx(i);
3247 }
3248
3250 const value_type* getDx(int j) const {
3251 if (j < num_args1)
3252 return expr1.getDx(j);
3253 else
3254 return expr2.getDx(j-num_args1);
3255 }
3256
3257 protected:
3258
3259 const ExprT1& expr1;
3260 const ExprT2& expr2;
3261 mutable value_type v;
3262 mutable bool min_v1;
3263
3264 };
3265
3266 template <typename ExprT1, typename T2>
3267 class Expr< MinOp<ExprT1, ConstExpr<T2> > > {
3268
3269 public:
3270
3271 typedef ConstExpr<T2> ExprT2;
3272 typedef typename ExprT1::value_type value_type_1;
3273 typedef typename ExprT2::value_type value_type_2;
3274 typedef typename Sacado::Promote<value_type_1,
3275 value_type_2>::type value_type;
3276 typedef typename ExprT1::scalar_type scalar_type_1;
3277 typedef typename ExprT2::scalar_type scalar_type_2;
3278 typedef typename Sacado::Promote<scalar_type_1,
3279 scalar_type_2>::type scalar_type;
3280
3281 typedef typename ExprT1::base_expr_type base_expr_type_1;
3282 typedef typename ExprT2::base_expr_type base_expr_type_2;
3283 typedef typename Sacado::Promote<base_expr_type_1,
3284 base_expr_type_2>::type base_expr_type;
3285
3286 static const int num_args = ExprT1::num_args;
3287
3288 static const bool is_linear = false;
3289
3291 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3292 expr1(expr1_), expr2(expr2_) {}
3293
3295 int size() const {
3296 return expr1.size();
3297 }
3298
3299 template <int Arg>
3301 bool isActive() const {
3302 return expr1.template isActive<Arg>();
3303 }
3304
3306 bool updateValue() const {
3307 return expr1.updateValue();
3308 }
3309
3311 void cache() const {
3312 expr1.cache();
3313 const value_type_1 v1 = expr1.val();
3314 const value_type_2 v2 = expr2.val();
3315 min_v1 = (v1 <= v2);
3316 v = min_v1 ? v1 : v2;
3317 }
3318
3320 value_type val() const {
3321 return v;
3322 }
3323
3325 void computePartials(const value_type& bar,
3326 value_type partials[]) const {
3327 if (min_v1)
3328 expr1.computePartials(bar, partials);
3329 else
3330 expr1.computePartials(value_type(0.0), partials);
3331 }
3332
3334 void getTangents(int i, value_type dots[]) const {
3335 expr1.getTangents(i, dots);
3336 }
3337
3338 template <int Arg>
3340 value_type getTangent(int i) const {
3341 return expr1.template getTangent<Arg>(i);
3342 }
3343
3345 bool isLinear() const {
3346 return false;
3347 }
3348
3350 bool hasFastAccess() const {
3351 return expr1.hasFastAccess();
3352 }
3353
3355 const value_type dx(int i) const {
3356 return min_v1 ? expr1.dx(i) : value_type(0.0);
3357 }
3358
3360 const value_type fastAccessDx(int i) const {
3361 return min_v1 ? expr1.fastAccessDx(i) : value_type(0.0);
3362 }
3363
3365 const value_type* getDx(int j) const {
3366 return expr1.getDx(j);
3367 }
3368
3369 protected:
3370
3371 const ExprT1& expr1;
3372 ExprT2 expr2;
3373 mutable value_type v;
3374 mutable bool min_v1;
3375
3376 };
3377
3378 template <typename T1, typename ExprT2>
3379 class Expr< MinOp< ConstExpr<T1>,ExprT2> > {
3380
3381 public:
3382
3383 typedef ConstExpr<T1> ExprT1;
3384 typedef typename ExprT1::value_type value_type_1;
3385 typedef typename ExprT2::value_type value_type_2;
3386 typedef typename Sacado::Promote<value_type_1,
3387 value_type_2>::type value_type;
3388 typedef typename ExprT1::scalar_type scalar_type_1;
3389 typedef typename ExprT2::scalar_type scalar_type_2;
3390 typedef typename Sacado::Promote<scalar_type_1,
3391 scalar_type_2>::type scalar_type;
3392
3393 typedef typename ExprT1::base_expr_type base_expr_type_1;
3394 typedef typename ExprT2::base_expr_type base_expr_type_2;
3395 typedef typename Sacado::Promote<base_expr_type_1,
3396 base_expr_type_2>::type base_expr_type;
3397
3398 static const int num_args = ExprT2::num_args;
3399
3400 static const bool is_linear = false;
3401
3403 Expr(const ExprT1& expr1_, const ExprT2& expr2_) :
3404 expr1(expr1_), expr2(expr2_) {}
3405
3407 int size() const {
3408 return expr2.size();
3409 }
3410
3411 template <int Arg>
3413 bool isActive() const {
3414 return expr2.template isActive<Arg>();
3415 }
3416
3418 bool updateValue() const {
3419 return expr2.updateValue();
3420 }
3421
3423 void cache() const {
3424 expr2.cache();
3425 const value_type_1 v1 = expr1.val();
3426 const value_type_2 v2 = expr2.val();
3427 min_v1 = (v1 <= v2);
3428 v = min_v1 ? v1 : v2;
3429 }
3430
3432 value_type val() const {
3433 return v;
3434 }
3435
3437 void computePartials(const value_type& bar,
3438 value_type partials[]) const {
3439 if (min_v1)
3440 expr2.computePartials(value_type(0.0), partials);
3441 else
3442 expr2.computePartials(bar, partials);
3443 }
3444
3446 void getTangents(int i, value_type dots[]) const {
3447 expr2.getTangents(i, dots);
3448 }
3449
3450 template <int Arg>
3452 value_type getTangent(int i) const {
3453 return expr2.template getTangent<Arg>(i);
3454 }
3455
3457 bool isLinear() const {
3458 return false;
3459 }
3460
3462 bool hasFastAccess() const {
3463 return expr2.hasFastAccess();
3464 }
3465
3467 const value_type dx(int i) const {
3468 return min_v1 ? value_type(0.0) : expr2.dx(i);
3469 }
3470
3472 const value_type fastAccessDx(int i) const {
3473 return min_v1 ? value_type(0.0) : expr2.fastAccessDx(i);
3474 }
3475
3477 const value_type* getDx(int j) const {
3478 return expr2.getDx(j);
3479 }
3480
3481 protected:
3482
3483 ExprT1 expr1;
3484 const ExprT2& expr2;
3485 mutable value_type v;
3486 mutable bool min_v1;
3487
3488 };
3489
3490 }
3491
3492}
3493
3494#define FAD_BINARYOP_MACRO(OPNAME,OP) \
3495namespace Sacado { \
3496 namespace ELRCacheFad { \
3497 \
3498 template <typename T1, typename T2> \
3499 SACADO_INLINE_FUNCTION \
3500 SACADO_FAD_OP_ENABLE_EXPR_EXPR(OP) \
3501 OPNAME (const T1& expr1, const T2& expr2) \
3502 { \
3503 typedef OP< T1, T2 > expr_t; \
3504 \
3505 return Expr<expr_t>(expr1, expr2); \
3506 } \
3507 \
3508 template <typename T> \
3509 SACADO_INLINE_FUNCTION \
3510 Expr< OP< Expr<T>, Expr<T> > > \
3511 OPNAME (const Expr<T>& expr1, const Expr<T>& expr2) \
3512 { \
3513 typedef OP< Expr<T>, Expr<T> > expr_t; \
3514 \
3515 return Expr<expr_t>(expr1, expr2); \
3516 } \
3517 \
3518 template <typename T> \
3519 SACADO_INLINE_FUNCTION \
3520 Expr< OP< ConstExpr<typename Expr<T>::value_type>, \
3521 Expr<T> > > \
3522 OPNAME (const typename Expr<T>::value_type& c, \
3523 const Expr<T>& expr) \
3524 { \
3525 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3526 typedef OP< ConstT, Expr<T> > expr_t; \
3527 \
3528 return Expr<expr_t>(ConstT(c), expr); \
3529 } \
3530 \
3531 template <typename T> \
3532 SACADO_INLINE_FUNCTION \
3533 Expr< OP< Expr<T>, \
3534 ConstExpr<typename Expr<T>::value_type> > > \
3535 OPNAME (const Expr<T>& expr, \
3536 const typename Expr<T>::value_type& c) \
3537 { \
3538 typedef ConstExpr<typename Expr<T>::value_type> ConstT; \
3539 typedef OP< Expr<T>, ConstT > expr_t; \
3540 \
3541 return Expr<expr_t>(expr, ConstT(c)); \
3542 } \
3543 \
3544 template <typename T> \
3545 SACADO_INLINE_FUNCTION \
3546 SACADO_FAD_OP_ENABLE_SCALAR_EXPR(OP) \
3547 OPNAME (const typename Expr<T>::scalar_type& c, \
3548 const Expr<T>& expr) \
3549 { \
3550 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3551 typedef OP< ConstT, Expr<T> > expr_t; \
3552 \
3553 return Expr<expr_t>(ConstT(c), expr); \
3554 } \
3555 \
3556 template <typename T> \
3557 SACADO_INLINE_FUNCTION \
3558 SACADO_FAD_OP_ENABLE_EXPR_SCALAR(OP) \
3559 OPNAME (const Expr<T>& expr, \
3560 const typename Expr<T>::scalar_type& c) \
3561 { \
3562 typedef ConstExpr<typename Expr<T>::scalar_type> ConstT; \
3563 typedef OP< Expr<T>, ConstT > expr_t; \
3564 \
3565 return Expr<expr_t>(expr, ConstT(c)); \
3566 } \
3567 } \
3568}
3569
3570
3579
3580#undef FAD_BINARYOP_MACRO
3581
3582//-------------------------- Relational Operators -----------------------
3583
3584#define FAD_RELOP_MACRO(OP) \
3585namespace Sacado { \
3586 namespace ELRCacheFad { \
3587 template <typename ExprT1, typename ExprT2> \
3588 SACADO_INLINE_FUNCTION \
3589 bool \
3590 operator OP (const Expr<ExprT1>& expr1, \
3591 const Expr<ExprT2>& expr2) \
3592 { \
3593 expr1.cache(); \
3594 expr2.cache(); \
3595 return expr1.val() OP expr2.val(); \
3596 } \
3597 \
3598 template <typename ExprT2> \
3599 SACADO_INLINE_FUNCTION \
3600 bool \
3601 operator OP (const typename Expr<ExprT2>::value_type& a, \
3602 const Expr<ExprT2>& expr2) \
3603 { \
3604 expr2.cache(); \
3605 return a OP expr2.val(); \
3606 } \
3607 \
3608 template <typename ExprT1> \
3609 SACADO_INLINE_FUNCTION \
3610 bool \
3611 operator OP (const Expr<ExprT1>& expr1, \
3612 const typename Expr<ExprT1>::value_type& b) \
3613 { \
3614 expr1.cache(); \
3615 return expr1.val() OP b; \
3616 } \
3617 } \
3618}
3619
3626FAD_RELOP_MACRO(<<=)
3627FAD_RELOP_MACRO(>>=)
3630
3631#undef FAD_RELOP_MACRO
3632
3633namespace Sacado {
3634
3635 namespace ELRCacheFad {
3636
3637 template <typename ExprT>
3639 bool operator ! (const Expr<ExprT>& expr)
3640 {
3641 expr.cache();
3642 return ! expr.val();
3643 }
3644
3645 } // namespace ELRCacheFad
3646
3647} // namespace Sacado
3648
3649//-------------------------- Boolean Operators -----------------------
3650namespace Sacado {
3651
3652 namespace ELRCacheFad {
3653
3654 template <typename ExprT>
3656 bool toBool(const Expr<ExprT>& x) {
3657 x.cache();
3658 bool is_zero = (x.val() == 0.0);
3659 for (int i=0; i<x.size(); i++)
3660 is_zero = is_zero && (x.dx(i) == 0.0);
3661 return !is_zero;
3662 }
3663
3664 } // namespace Fad
3665
3666} // namespace Sacado
3667
3668#define FAD_BOOL_MACRO(OP) \
3669namespace Sacado { \
3670 namespace ELRCacheFad { \
3671 template <typename ExprT1, typename ExprT2> \
3672 SACADO_INLINE_FUNCTION \
3673 bool \
3674 operator OP (const Expr<ExprT1>& expr1, \
3675 const Expr<ExprT2>& expr2) \
3676 { \
3677 return toBool(expr1) OP toBool(expr2); \
3678 } \
3679 \
3680 template <typename ExprT2> \
3681 SACADO_INLINE_FUNCTION \
3682 bool \
3683 operator OP (const typename Expr<ExprT2>::value_type& a, \
3684 const Expr<ExprT2>& expr2) \
3685 { \
3686 return a OP toBool(expr2); \
3687 } \
3688 \
3689 template <typename ExprT1> \
3690 SACADO_INLINE_FUNCTION \
3691 bool \
3692 operator OP (const Expr<ExprT1>& expr1, \
3693 const typename Expr<ExprT1>::value_type& b) \
3694 { \
3695 return toBool(expr1) OP b; \
3696 } \
3697 } \
3698}
3699
3702
3703#undef FAD_BOOL_MACRO
3704
3705//-------------------------- I/O Operators -----------------------
3706
3707namespace Sacado {
3708
3709 namespace ELRCacheFad {
3710
3711 template <typename ExprT>
3712 std::ostream& operator << (std::ostream& os, const Expr<ExprT>& x) {
3713 os << x.val() << " [";
3714
3715 for (int i=0; i< x.size(); i++) {
3716 os << " " << x.dx(i);
3717 }
3718
3719 os << " ]";
3720 return os;
3721 }
3722
3723 } // namespace Fad
3724
3725} // namespace Sacado
3726
3727#endif // SACADO_CACHEFAD_OPS_HPP
#define SACADO_INLINE_FUNCTION
#define FAD_BINARYOP_MACRO(OPNAME, OP)
#define FAD_RELOP_MACRO(OP)
#define FAD_BOOL_MACRO(OP)
#define FAD_UNARYOP_MACRO(OPNAME, OP, PARTIAL, VALUE)
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 const value_type dx(int i) const
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
SACADO_INLINE_FUNCTION value_type getTangent(int i) const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION value_type getTangent(int i) const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION bool updateValue() const
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
SACADO_INLINE_FUNCTION bool hasFastAccess() const
SACADO_INLINE_FUNCTION const value_type dx(int i) const
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
SACADO_INLINE_FUNCTION value_type getTangent(int i) const
SACADO_INLINE_FUNCTION const value_type dx(int i) const
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
SACADO_INLINE_FUNCTION value_type val() const
SACADO_INLINE_FUNCTION void getTangents(int i, value_type dots[]) const
SACADO_INLINE_FUNCTION void computePartials(const value_type &bar, value_type partials[]) const
SACADO_INLINE_FUNCTION const value_type dx(int i) const
SACADO_INLINE_FUNCTION Expr(const ExprT &expr_)
SACADO_INLINE_FUNCTION const value_type * getDx(int j) const
SACADO_INLINE_FUNCTION const value_type fastAccessDx(int i) const
Wrapper for a generic expression template.
Namespace for expression-level reverse forward-mode AD classes.
SACADO_INLINE_FUNCTION bool toBool(const Expr< ExprT > &x)
SACADO_INLINE_FUNCTION Expr< UnaryMinusOp< Expr< T > > > operator-(const Expr< T > &expr)
SACADO_INLINE_FUNCTION bool operator!(const Expr< ExprT > &expr)
SACADO_INLINE_FUNCTION Expr< AbsOp< Expr< T > > > abs(const Expr< T > &expr)
SACADO_INLINE_FUNCTION Expr< FAbsOp< Expr< T > > > fabs(const Expr< T > &expr)
std::ostream & operator<<(std::ostream &os, const GeneralFad< T, Storage > &x)
SACADO_INLINE_FUNCTION Expr< UnaryPlusOp< 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.